Skip to content

Commit

Permalink
Merge pull request #374 from sahilrw/chess-game
Browse files Browse the repository at this point in the history
Chess game
  • Loading branch information
larymak authored Feb 15, 2024
2 parents 01eea30 + 6785fb7 commit 5456f25
Show file tree
Hide file tree
Showing 41 changed files with 1,181 additions and 0 deletions.
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 added GAMES/chess/assets/images/imgs-80px/black_pawn.png
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 added GAMES/chess/assets/images/imgs-80px/black_rook.png
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 added GAMES/chess/assets/sounds/capture.wav
Binary file not shown.
Binary file added GAMES/chess/assets/sounds/move.wav
Binary file not shown.
455 changes: 455 additions & 0 deletions GAMES/chess/src/board.py

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions GAMES/chess/src/color.py
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
60 changes: 60 additions & 0 deletions GAMES/chess/src/config.py
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]
8 changes: 8 additions & 0 deletions GAMES/chess/src/const.py
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
46 changes: 46 additions & 0 deletions GAMES/chess/src/dragger.py
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
150 changes: 150 additions & 0 deletions GAMES/chess/src/game.py
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__()
126 changes: 126 additions & 0 deletions GAMES/chess/src/main.py
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()
Loading

0 comments on commit 5456f25

Please sign in to comment.