-
Notifications
You must be signed in to change notification settings - Fork 911
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #374 from sahilrw/chess-game
Chess game
- Loading branch information
Showing
41 changed files
with
1,181 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class Color: | ||
def __init__(self, light, dark): | ||
self.light = light | ||
self.dark = dark |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import pygame | ||
import os | ||
|
||
from sound import Sound | ||
from theme import Theme | ||
|
||
|
||
class Config: | ||
def __init__(self): | ||
# themes code | ||
self.themes = [] | ||
self._add_themes() | ||
self.idx = 0 | ||
self.theme = self.themes[self.idx] | ||
# font | ||
self.font = pygame.font.SysFont("monospace", 18, bold=True) | ||
# sound file path | ||
self.move_sound = Sound(os.path.join("assets/sounds/move.wav")) | ||
self.capture_sound = Sound(os.path.join("assets/sounds/capture.wav")) | ||
|
||
def change_theme(self): | ||
self.idx += 1 | ||
self.idx %= len(self.themes) | ||
self.theme = self.themes[self.idx] | ||
|
||
def _add_themes(self): | ||
green = Theme( | ||
(234, 235, 200), | ||
(119, 154, 88), | ||
(244, 247, 116), | ||
(172, 195, 51), | ||
"#C86464", | ||
"#C84646", | ||
) | ||
brown = Theme( | ||
(235, 209, 166), | ||
(165, 117, 80), | ||
(245, 234, 100), | ||
(209, 185, 59), | ||
"#C86464", | ||
"#C84646", | ||
) | ||
blue = Theme( | ||
(229, 228, 200), | ||
(60, 95, 135), | ||
(124, 187, 227), | ||
(43, 119, 191), | ||
"#C86464", | ||
"#C84646", | ||
) | ||
gray = Theme( | ||
(128, 119, 118), | ||
(86, 85, 84), | ||
(99, 126, 143), | ||
(82, 102, 128), | ||
"#C86464", | ||
"#C84646", | ||
) | ||
|
||
self.themes = [green, brown, blue, gray] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Screen dimensions | ||
WIDTH = 700 | ||
HEIGHT = 700 | ||
|
||
# Board dimensions | ||
ROWS = 8 | ||
COLS = 8 | ||
SQSIZE = WIDTH // COLS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import pygame | ||
|
||
from const import * | ||
|
||
|
||
class Dragger: | ||
def __init__(self): | ||
self.piece = None | ||
self.dragging = False | ||
self.mouseX = 0 | ||
self.mouseY = 0 | ||
self.initial_row = 0 | ||
self.initial_col = 0 | ||
|
||
# blit method | ||
|
||
def update_blit(self, surface): | ||
# texture | ||
self.piece.set_texture(size=80) | ||
texture = self.piece.texture | ||
# image | ||
img = pygame.image.load(texture) | ||
|
||
# drag coordinates | ||
img_center = (self.mouseX, self.mouseY) | ||
self.piece.texture_rect = img.get_rect(center=img_center) | ||
|
||
# update blit | ||
surface.blit(img, self.piece.texture_rect) | ||
|
||
# other dragging methods | ||
|
||
def update_mouse(self, pos): | ||
self.mouseX, self.mouseY = pos | ||
|
||
def save_initial(self, pos): | ||
self.initial_row = pos[1] // SQSIZE | ||
self.initial_col = pos[0] // SQSIZE | ||
|
||
def drag_piece(self, piece): | ||
self.piece = piece | ||
self.dragging = True | ||
|
||
def undrag_piece(self): | ||
self.piece = None | ||
self.dragging = False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import pygame | ||
|
||
from const import * | ||
from board import Board | ||
from dragger import Dragger | ||
from config import Config | ||
from square import Square | ||
|
||
|
||
class Game: | ||
def __init__(self): | ||
self.next_player = "white" | ||
self.hovered_sqr = None | ||
self.board = Board() | ||
self.dragger = Dragger() | ||
self.config = Config() | ||
|
||
# background display | ||
def show_bg(self, surface): | ||
theme = self.config.theme | ||
|
||
for row in range(ROWS): | ||
for col in range(COLS): | ||
# color | ||
color = theme.bg.light if (row + col) % 2 == 0 else theme.bg.dark | ||
# rect | ||
rect = (col * SQSIZE, row * SQSIZE, SQSIZE, SQSIZE) | ||
# blit | ||
pygame.draw.rect(surface, color, rect) | ||
|
||
# row coordinates | ||
if col == 0: | ||
# color | ||
color = theme.bg.dark if row % 2 == 0 else theme.bg.light | ||
# label | ||
lbl = self.config.font.render(str(ROWS - row), 1, color) | ||
lbl_pos = (5, 5 + row * SQSIZE) | ||
# blit | ||
surface.blit(lbl, lbl_pos) | ||
|
||
# col coordinates | ||
if row == 7: | ||
# color | ||
color = theme.bg.dark if (row + col) % 2 == 0 else theme.bg.light | ||
# label | ||
lbl = self.config.font.render(Square.get_alphacol(col), 1, color) | ||
lbl_pos = (col * SQSIZE + SQSIZE - 20, HEIGHT - 20) | ||
# blit | ||
surface.blit(lbl, lbl_pos) | ||
|
||
def show_pieces(self, surface): | ||
for row in range(ROWS): | ||
for col in range(COLS): | ||
if self.board.squares[row][col].has_piece(): | ||
piece = self.board.squares[row][col].piece | ||
if piece is not self.dragger.piece: | ||
piece.set_texture(size=80) | ||
img = pygame.image.load(piece.texture) | ||
img_center = ( | ||
col * SQSIZE + SQSIZE // 2, | ||
row * SQSIZE + SQSIZE // 2, | ||
) | ||
piece.texture_rect = img.get_rect(center=img_center) | ||
surface.blit(img, piece.texture_rect) | ||
|
||
def show_moves(self, surface): | ||
theme = self.config.theme | ||
if self.dragger.dragging: | ||
piece = self.dragger.piece | ||
|
||
# loop all valid moves | ||
for move in piece.moves: | ||
# color | ||
color = ( | ||
theme.moves.light | ||
if (move.final.row + move.final.col) % 2 == 0 | ||
else theme.moves.dark | ||
) | ||
# rect | ||
rect = ( | ||
move.final.col * SQSIZE, | ||
move.final.row * SQSIZE, | ||
SQSIZE, | ||
SQSIZE, | ||
) | ||
# blit | ||
pygame.draw.rect(surface, color, rect) | ||
|
||
# circle | ||
# center_x = move.final.col * SQSIZE + SQSIZE // 2 | ||
# center_y = move.final.row * SQSIZE + SQSIZE // 2 | ||
# radius = SQSIZE // 6 | ||
# blit | ||
# pygame.draw.circle(surface, color, (center_x, center_y), radius) | ||
|
||
def show_last_move(self, surface): | ||
theme = self.config.theme | ||
|
||
if self.board.last_move: | ||
initial = self.board.last_move.initial | ||
final = self.board.last_move.final | ||
|
||
for pos in [initial, final]: | ||
# color | ||
color = ( | ||
theme.trace.light | ||
if (pos.row + pos.col) % 2 == 0 | ||
else theme.trace.dark | ||
) | ||
# rect | ||
rect = (pos.col * SQSIZE, pos.row * SQSIZE, SQSIZE, SQSIZE) | ||
# blit | ||
pygame.draw.rect(surface, color, rect) | ||
|
||
def show_hover(self, surface): | ||
if self.hovered_sqr: | ||
# color | ||
color = (180, 180, 180) | ||
# rect | ||
rect = ( | ||
self.hovered_sqr.col * SQSIZE, | ||
self.hovered_sqr.row * SQSIZE, | ||
SQSIZE, | ||
SQSIZE, | ||
) | ||
# blit | ||
pygame.draw.rect(surface, color, rect, width=3) | ||
|
||
def next_turn(self): | ||
self.next_player = "white" if self.next_player == "black" else "black" | ||
|
||
def set_hover(self, row, col): | ||
if 0 <= row < ROWS and 0 <= col < COLS: | ||
self.hovered_sqr = self.board.squares[row][col] | ||
else: | ||
# Handle the case where the indices are out of range | ||
# print(f"Invalid indices: row={row}, col={col}") | ||
self.hovered_sqr = None | ||
|
||
def change_theme(self): | ||
self.config.change_theme() | ||
|
||
def play_sound(self, captured=False): | ||
if captured: | ||
self.config.capture_sound.play() | ||
else: | ||
self.config.move_sound.play() | ||
|
||
def reset(self): | ||
self.__init__() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import pygame | ||
import sys | ||
|
||
from const import * | ||
from game import Game | ||
from square import Square | ||
from move import Move | ||
|
||
|
||
class Main: | ||
def __init__(self): | ||
pygame.init() | ||
self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) | ||
pygame.display.set_caption("Chess") | ||
self.game = Game() | ||
|
||
def mainloop(self): | ||
screen = self.screen | ||
game = self.game | ||
board = self.game.board | ||
dragger = self.game.dragger | ||
|
||
while True: | ||
# display methods | ||
game.show_bg(screen) | ||
game.show_last_move(screen) | ||
game.show_moves(screen) | ||
game.show_pieces(screen) | ||
|
||
game.show_hover(screen) | ||
|
||
if dragger.dragging: | ||
dragger.update_blit(screen) | ||
|
||
for event in pygame.event.get(): | ||
# click | ||
if event.type == pygame.MOUSEBUTTONDOWN: | ||
dragger.update_mouse(event.pos) | ||
# print(event.pos) | ||
|
||
clicked_row = dragger.mouseY // SQSIZE | ||
clicked_col = dragger.mouseX // SQSIZE | ||
|
||
# print(dragger.mouseY, clicked_row) | ||
# print(dragger.mouseX, clicked_col) | ||
|
||
# if clicked square has a piece | ||
if board.squares[clicked_row][clicked_col].has_piece(): | ||
piece = board.squares[clicked_row][clicked_col].piece | ||
if piece.color == game.next_player: | ||
board.calc_moves(piece, clicked_row, clicked_col, bool=True) | ||
dragger.save_initial(event.pos) | ||
dragger.drag_piece(piece) | ||
# display methods | ||
game.show_bg(screen) | ||
game.show_last_move(screen) | ||
game.show_moves(screen) | ||
game.show_pieces(screen) | ||
|
||
# dragging the pieces | ||
elif event.type == pygame.MOUSEMOTION: | ||
motion_row = event.pos[1] // SQSIZE | ||
motion_col = event.pos[0] // SQSIZE | ||
game.set_hover(motion_row, motion_col) | ||
if dragger.dragging: | ||
dragger.update_mouse(event.pos) | ||
# display methods | ||
game.show_bg(screen) | ||
game.show_last_move(screen) | ||
game.show_moves(screen) | ||
game.show_pieces(screen) | ||
game.show_hover(screen) | ||
dragger.update_blit(screen) | ||
|
||
# mouse release | ||
elif event.type == pygame.MOUSEBUTTONUP: | ||
if dragger.dragging: | ||
dragger.update_mouse(event.pos) | ||
released_row = dragger.mouseY // SQSIZE | ||
released_col = dragger.mouseX // SQSIZE | ||
|
||
initial = Square(dragger.initial_row, dragger.initial_col) | ||
final = Square(released_row, released_col) | ||
move = Move(initial, final) | ||
|
||
if board.valid_move(dragger.piece, move): | ||
captured = board.squares[released_row][ | ||
released_col | ||
].has_piece() | ||
|
||
board.move(dragger.piece, move) | ||
board.set_true_en_passant(dragger.piece) | ||
game.play_sound(captured) | ||
# display move methods | ||
game.show_bg(screen) | ||
game.show_last_move(screen) | ||
game.show_pieces(screen) | ||
|
||
# next turn | ||
game.next_turn() | ||
|
||
dragger.undrag_piece() | ||
|
||
# key press | ||
elif event.type == pygame.KEYDOWN: | ||
# change themes | ||
if event.key == pygame.K_t: | ||
game.change_theme() | ||
|
||
# restart event | ||
if event.key == pygame.K_r: | ||
game.reset() | ||
game = self.game | ||
board = self.game.board | ||
dragger = self.game.dragger | ||
|
||
# quit application | ||
elif event.type == pygame.QUIT: | ||
pygame.quit() | ||
sys.exit() | ||
|
||
pygame.display.update() | ||
|
||
|
||
main = Main() | ||
main.mainloop() |
Oops, something went wrong.