From 03053f4ff243ea6c8025aabe2d749c2e53299c2e Mon Sep 17 00:00:00 2001 From: muneer320 Date: Mon, 21 Oct 2024 15:16:46 +0530 Subject: [PATCH] Added Chess game. --- Chess/README.md | 33 +++++ Chess/main.py | 301 +++++++++++++++++++++++++++++++++++++++++++ Chess/pieces/b_b.png | Bin 0 -> 879 bytes Chess/pieces/b_k.png | Bin 0 -> 1390 bytes Chess/pieces/b_n.png | Bin 0 -> 1138 bytes Chess/pieces/b_p.png | Bin 0 -> 530 bytes Chess/pieces/b_q.png | Bin 0 -> 1565 bytes Chess/pieces/b_r.png | Bin 0 -> 404 bytes Chess/pieces/w_b.png | Bin 0 -> 1287 bytes Chess/pieces/w_k.png | Bin 0 -> 1334 bytes Chess/pieces/w_n.png | Bin 0 -> 1371 bytes Chess/pieces/w_p.png | Bin 0 -> 886 bytes Chess/pieces/w_q.png | Bin 0 -> 1186 bytes Chess/pieces/w_r.png | Bin 0 -> 528 bytes 14 files changed, 334 insertions(+) create mode 100644 Chess/README.md create mode 100644 Chess/main.py create mode 100644 Chess/pieces/b_b.png create mode 100644 Chess/pieces/b_k.png create mode 100644 Chess/pieces/b_n.png create mode 100644 Chess/pieces/b_p.png create mode 100644 Chess/pieces/b_q.png create mode 100644 Chess/pieces/b_r.png create mode 100644 Chess/pieces/w_b.png create mode 100644 Chess/pieces/w_k.png create mode 100644 Chess/pieces/w_n.png create mode 100644 Chess/pieces/w_p.png create mode 100644 Chess/pieces/w_q.png create mode 100644 Chess/pieces/w_r.png diff --git a/Chess/README.md b/Chess/README.md new file mode 100644 index 00000000..5dee2abc --- /dev/null +++ b/Chess/README.md @@ -0,0 +1,33 @@ +# Chess + +## Overview +This is a Python-based Chess game that allows two players to compete against each other or one player to face a bot on the same machine. The game includes the full set of chess rules, such as castling, en passant, and pawn promotion. Currently, there are two bot difficulty levels: `Easy` and `Medium`, both explained in the script. A `Hard` mode is also available but commented out as its logic hasn't been implemented yet. Feel free to challenge yourself by completing it! + +## Features +- Complete implementation of chess rules +- Playable with two players or against a simple bot +- Graphical user interface (GUI) using Pygame +- Move validation, check, and checkmate detection +- Game restart functionality + +## Requirements +- Python 3.x +- [Pygame](https://pypi.org/project/pygame/) library +- [Chess](https://pypi.org/project/chess/) library + +## How to Play +To start the game, run the following command: + +```sh +python main.py +``` + +## Contributing +Feel free to fork this project and contribute to its development! Some potential updates include: + +- Implement the `Hard` mode bot logic (then uncomment all its references). +- Add a countdown timer and support time increments for matches. +- Improve the GUI styling (e.g., buttons, title, etc.). +- Add an "Exit" button alongside the "Restart" button on the main screen. + +Contributions in any form are welcome—be it code, bug reports, or feature suggestions! diff --git a/Chess/main.py b/Chess/main.py new file mode 100644 index 00000000..6eae6441 --- /dev/null +++ b/Chess/main.py @@ -0,0 +1,301 @@ +import pygame +import chess +import random + +# Initialize pygame and chess board +pygame.init() +board = chess.Board() + +# Constants for window dimensions and colors +WIDTH, HEIGHT = 600, 750 +BOARD_SIZE = 512 +MARGIN = (WIDTH - BOARD_SIZE) // 2 +TITLE_HEIGHT = 50 +SQ_SIZE = BOARD_SIZE // 8 +LIGHT = (235, 236, 208) +DARK = (115, 149, 82) +LIGHT_HIGHLIGHT = (245, 246, 130) +DARK_HIGHLIGHT = (185, 202, 67) +BOT_HIGHLIGHT_COLOR = (255, 0, 0) +BACKGROUND_COLOR = (48, 46, 43) + +# Load chess piece images +pieces = {f'{color}_{piece}': pygame.image.load(f'Chess/pieces/{color}_{piece}.png') for color in ['w', 'b'] for piece in ['p', 'r', 'n', 'b', 'q', 'k']} + +# Create screen +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +pygame.display.set_caption("Chess Bot") + +# Fonts for the title and endgame message +title_font = pygame.font.Font(None, 48) +endgame_font = pygame.font.Font(None, 64) + +# Variables for game state +mode = None +selected_square = None +bot_last_move = None +game_over_message = None +running = True +game_mode = None +bot_difficulty = None +show_difficulty_selection = False +confirmation_active = False +confirm_restart_rect = None +cancel_restart_rect = None + + +def draw_board(selected_square=None, bot_move_square=None): + for row in range(8): + for col in range(8): + color = LIGHT if (row + col) % 2 == 0 else DARK + if selected_square == chess.square(col, 7 - row): + color = LIGHT_HIGHLIGHT if ( + row + col) % 2 == 0 else DARK_HIGHLIGHT + if bot_move_square == chess.square(col, 7 - row): + color = BOT_HIGHLIGHT_COLOR + square_rect = pygame.Rect( + MARGIN + col * SQ_SIZE, TITLE_HEIGHT + row * SQ_SIZE, SQ_SIZE, SQ_SIZE) + pygame.draw.rect(screen, color, square_rect) + + +def draw_pieces(): + for square in chess.SQUARES: + piece = board.piece_at(square) + if piece: + piece_image = pieces[f'{"w" if piece.color else "b"}_{ + piece.symbol().lower()}'] + x = MARGIN + \ + chess.square_file(square) * SQ_SIZE + \ + (SQ_SIZE - piece_image.get_width()) // 2 + y = TITLE_HEIGHT + (7 - chess.square_rank(square)) * \ + SQ_SIZE + (SQ_SIZE - piece_image.get_height()) // 2 + screen.blit(piece_image, pygame.Rect(x, y, SQ_SIZE, SQ_SIZE)) + + +def draw_title(): + title_surface = title_font.render("Chess Bot", True, (255, 255, 255)) + title_rect = title_surface.get_rect(center=(WIDTH // 2, TITLE_HEIGHT // 2)) + screen.blit(title_surface, title_rect) + + +def draw_endgame_message(message): + message_surface = endgame_font.render(message, True, (255, 255, 255)) + message_rect = message_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2)) + screen.blit(message_surface, message_rect) + + +def get_square_under_mouse(): + mouse_pos = pygame.Vector2(pygame.mouse.get_pos()) + x, y = [int((v - MARGIN) // SQ_SIZE) for v in mouse_pos] + if 0 <= x < 8 and TITLE_HEIGHT <= y * SQ_SIZE + TITLE_HEIGHT < TITLE_HEIGHT + BOARD_SIZE: + return chess.square(x, 7 - int((mouse_pos[1] - TITLE_HEIGHT) // SQ_SIZE)) + return None + + +def is_pawn_promotion(move): + return board.piece_at(move.from_square).piece_type == chess.PAWN and (chess.square_rank(move.to_square) == 0 or chess.square_rank(move.to_square) == 7) + + +def pawn_promotion(): + return chess.QUEEN + + +def check_game_over(): + if board.is_checkmate(): + if game_mode == "pvp": + return "Checkmate! Black Wins!" if board.turn else "Checkmate! White Wins!" + else: + return "Checkmate! Bot Wins!" if board.turn else "Checkmate! You Win!" + elif board.is_stalemate(): + return "Stalemate! It's a Draw!" + elif board.is_insufficient_material(): + return "Draw due to Insufficient Material!" + elif board.is_seventyfive_moves(): + return "Draw by 75-move Rule!" + elif board.is_fivefold_repetition(): + return "Draw by Repetition!" + elif board.is_variant_draw(): + return "Draw by Variant!" + return None + + +def draw_mode_selection(): + screen.fill(BACKGROUND_COLOR) + title_surface = title_font.render( + "Choose Game Mode", True, (255, 255, 255)) + title_rect = title_surface.get_rect(center=(WIDTH // 2, HEIGHT // 4)) + screen.blit(title_surface, title_rect) + pvp_surface = endgame_font.render( + "Player vs Player", True, (255, 255, 255)) + pvp_rect = pvp_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2)) + screen.blit(pvp_surface, pvp_rect) + pvb_surface = endgame_font.render("Player vs Bot", True, (255, 255, 255)) + pvb_rect = pvb_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 100)) + screen.blit(pvb_surface, pvb_rect) + return pvp_rect, pvb_rect + + +def draw_difficulty_selection(): + screen.fill(BACKGROUND_COLOR) + title_surface = title_font.render( + "Select Bot Difficulty", True, (255, 255, 255)) + title_rect = title_surface.get_rect(center=(WIDTH // 2, HEIGHT // 4)) + screen.blit(title_surface, title_rect) + easy_surface = endgame_font.render("Easy", True, (255, 255, 255)) + easy_rect = easy_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 50)) + screen.blit(easy_surface, easy_rect) + medium_surface = endgame_font.render("Medium", True, (255, 255, 255)) + medium_rect = medium_surface.get_rect( + center=(WIDTH // 2, HEIGHT // 2 + 50)) + screen.blit(medium_surface, medium_rect) + # Logic for hard mode is not implemented yet... [You can work on it if you want] + # hard_surface = endgame_font.render("Hard", True, (255, 255, 255)) + # hard_rect = hard_surface.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 150)) + # screen.blit(hard_surface, hard_rect) + # return easy_rect, medium_rect, hard_rect + return easy_rect, medium_rect + + +def draw_restart_button(): + restart_surface = endgame_font.render("Restart", True, (255, 255, 255)) + restart_rect = restart_surface.get_rect(center=(WIDTH // 2, HEIGHT - 50)) + screen.blit(restart_surface, restart_rect) + return restart_rect + + +def reset_game(): + global board, game_mode, bot_difficulty, show_difficulty_selection, game_over_message, selected_square, confirmation_active + board.reset() + game_mode = None + bot_difficulty = None + show_difficulty_selection = False + game_over_message = None + selected_square = None + confirmation_active = False + + +def draw_confirmation_box(): + box_width, box_height = 400, 150 + confirmation_box_rect = pygame.Rect( + WIDTH // 2 - box_width // 2, HEIGHT // 2 - box_height // 2, box_width, box_height) + pygame.draw.rect(screen, (50, 50, 50), confirmation_box_rect) + pygame.draw.rect(screen, (255, 255, 255), confirmation_box_rect, 3) + confirm_text = endgame_font.render("Restart game?", True, (255, 255, 255)) + screen.blit(confirm_text, (confirmation_box_rect.x + + 60, confirmation_box_rect.y + 20)) + yes_surface = endgame_font.render("Yes", True, (255, 255, 255)) + no_surface = endgame_font.render("No", True, (255, 255, 255)) + confirm_restart_rect = yes_surface.get_rect( + center=(confirmation_box_rect.x + 100, confirmation_box_rect.y + 100)) + cancel_restart_rect = no_surface.get_rect( + center=(confirmation_box_rect.x + 300, confirmation_box_rect.y + 100)) + screen.blit(yes_surface, confirm_restart_rect) + screen.blit(no_surface, cancel_restart_rect) + return confirm_restart_rect, cancel_restart_rect + + +''' +Main bot logic + +The bot has two difficulty levels: 'easy' and 'medium' [for now]. +- In 'easy' mode, the bot makes a random legal move. +- In 'medium' mode, the bot prioritizes capturing moves. + - If there are capturing moves available, it selects the capture with the highest piece value. + - If no capturing moves are available, it makes a random legal move. + +''' +def bot_move(mode): + moves = list(board.legal_moves) + + if mode == 'easy': + return random.choice(moves) if moves else None + elif mode == 'medium': + captures = [move for move in moves if board.is_capture(move)] + if captures: + piece_values = {chess.PAWN: 1, chess.KNIGHT: 3, + chess.BISHOP: 3, chess.ROOK: 5, chess.QUEEN: 9, chess.KING: 0} + captures_by_value = {} + for capture in captures: + value = piece_values[board.piece_at( + capture.to_square).piece_type] + captures_by_value.setdefault(value, []).append(capture) + best_captures = captures_by_value[max(captures_by_value.keys())] + return random.choice(best_captures) + return random.choice(moves) + return None + + +while running: + screen.fill(BACKGROUND_COLOR) + + if game_mode is None: + pvp_rect, pvb_rect = draw_mode_selection() + elif show_difficulty_selection: + # easy_rect, medium_rect, hard_rect = draw_difficulty_selection() + easy_rect, medium_rect = draw_difficulty_selection() + else: + draw_title() + draw_board(selected_square, bot_last_move) + draw_pieces() + if game_over_message: + draw_endgame_message(game_over_message) + restart_rect = draw_restart_button() + if confirmation_active: + confirm_restart_rect, cancel_restart_rect = draw_confirmation_box() + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + if event.type == pygame.MOUSEBUTTONDOWN: + mouse_pos = pygame.mouse.get_pos() + if game_mode is None: + if pvp_rect.collidepoint(mouse_pos): + game_mode = 'pvp' + elif pvb_rect.collidepoint(mouse_pos): + game_mode = 'pvb' + show_difficulty_selection = True + elif show_difficulty_selection: + if easy_rect.collidepoint(mouse_pos): + bot_difficulty = 'easy' + show_difficulty_selection = False + elif medium_rect.collidepoint(mouse_pos): + bot_difficulty = 'medium' + show_difficulty_selection = False + # elif hard_rect.collidepoint(mouse_pos): + # bot_difficulty = 'hard' + # show_difficulty_selection = False + else: + if restart_rect.collidepoint(mouse_pos) and not confirmation_active: + confirmation_active = True + if confirmation_active: + if confirm_restart_rect and confirm_restart_rect.collidepoint(mouse_pos): + reset_game() + elif cancel_restart_rect and cancel_restart_rect.collidepoint(mouse_pos): + confirmation_active = False + square = get_square_under_mouse() + if square is not None: + if selected_square is None: + if board.piece_at(square): + selected_square = square + else: + move = chess.Move(selected_square, square) + if is_pawn_promotion(move): + move = chess.Move( + selected_square, square, promotion=pawn_promotion()) + if move in board.legal_moves: + board.push(move) + pygame.display.flip() + selected_square = None + game_over_message = check_game_over() + if not game_over_message and game_mode == 'pvb': + bot_last_move = bot_move(bot_difficulty) + if bot_last_move: + board.push(bot_last_move) + game_over_message = check_game_over() + else: + selected_square = None + + pygame.display.flip() + + +pygame.quit() diff --git a/Chess/pieces/b_b.png b/Chess/pieces/b_b.png new file mode 100644 index 0000000000000000000000000000000000000000..0d4f0a425e12e10837f7a3511ecea93f3347e460 GIT binary patch literal 879 zcmV-#1CacQP)JN6HySyKj{yuiI&8Rni{Jq#6oC6T2WC*@SV zClC4`82t=02=D;73rqlIpxy;PzF`#j3^Y+hoBDpVm!w+Z3D5wBP@Shkz?U&0==|_yt_m z&kq&Gfj8_$*SZmR^tFV~5$^<9;17G`+++v%4P<)4(t;bn7Oe?eiEnAWp5Qzxa{CBJ zqfwckpOO{Pu_0IKz^h+ngfMhZm5fRB`G6zMxXzJLsdRzx?V(VSP;V{W$l6X80 zKs+8NnM@K6hwb`)xFCrrO zd|q<7oTO4Iw=`J|itsS1dvmQ4*=$xsM6%gzt7_5&hJqq}AelrWA*E7D5{ZPDG8hPH zfS(@7c#$6_&P}VwYgE1M1P$O-hc?>6EG_cdgEY0Bwqcr2AAqN*6N!wCjfF-=Mp`Ou zZ*NnrRt44ZJ<)ao$D?#Q-E=I@E=Z@-P2gcCPCMPXrz(|7Xl`x}uaT})Dk0!>hklJQ z%l_Wkt28joXXqf(u~_VWEEW?(b*a^A_iD9TusK~U7T4OzWjl(+;+m;%<8#~O*ou4eMhC%OHN0C%c#hl0FI(Mz1@5~jv6pdXxVLD2Q1e*YRdElHN08Zx*Pi0Kh%6= z8I?AhrZ02^$ZH4ozt}2uyw~g9^>!Q9HS4JMp!L_vhLgZYk3_m9OPYsgEZPiM=gnT7 zZnUx1&HkbjIk%ji0bZbbggUB9d_v{jUsOI1+jMqkAXU9~8MP0lfitKRc+{p-*Dp7U z+Aq_-QMCk3J49{sZ?UM@Z|u@N@tG002ovPDHLk FV1mdyn&AKd literal 0 HcmV?d00001 diff --git a/Chess/pieces/b_k.png b/Chess/pieces/b_k.png new file mode 100644 index 0000000000000000000000000000000000000000..c8d0d83fadd8684af72bfb1c47e9d7b84c1c9712 GIT binary patch literal 1390 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK3=%maw1R#1+UT6126o;Zo`5=7ua) zT3QO>8WgoK2Jg@Ftn9v&bmDk=&j#l^*eBoK&z0gz#6Xb2=t zOiawp%`Gi0foz~HKtV@GM<9Fq_U*pDzCZ>Xu(PuR*+3Ggthl%s$Oh^)H8t()>+A3D z->_lB#*G_+f=oAmrELpmA>9S?ZR;*aD za^=d^t5>gIzkbuEP209@+r4}D;lqcI9656I=+R@xj-5Dh;?${AXU?2Cd-m*w3l}b4 zym^XIQ#y?Xun^_w?u zK79D_>C>mrpFe;7`t|$w?>~P0`1$kauV24@|Ni~w&!4}4|Ni^;@Bjb*5B8@x07Evs zB*-tAfsu)YTR>1qOhQ&kMMF#5*v#7A!O15eFe)Y~DLJ>Ks=B77t)sVZ>Vkz!mM&kp zdhOaR+jk#03UuMQn;`c*e(~b{hfm+W|M&^E0AvFQ9KTQrO5%)3-tI0ZWOs$10!Cz< zr;B5V$MNI@iJc9H8=6_JDm_$kSv}R*kl);V;^NM%OEFH1vi$BA#QG(Pezy3*^26eT z!15UlO`JM&nTd3B5<^5`0~7P^HPdEJohW497A3~J z|J(*w<3E@0Tn$;UYU)+nOMlXJxZZxboZuLGCd=~uk%y+*+vi!B*Pli<8OtOlW&Lg5`>-HjW4)(O#hFWgpK>hR*IebX>aG72g(Zhh z_nqaNU%W;n@=1&Aq^#S*9&D}c=JRKiF5-+_@TtXgQr6ts;EAfr;d3J-8+8nF*PBhs zTKG>{^2DaA>Z>O1oaz26KA)Kp#l^H;qu zFUDZ$_T}ZLntI*+-^`D<{QHB=z3z<3i8PCkH#%h}cO^gc>(HII=kbw^oNYM~m)HC` z^eZFb*9nca**SS@w0+r^O@HyL^^?Wtyo$2hn+~fdJovC_+nRzoKO>jqeC$jnNlSN2Xi0EU^PAoxp45`S=vUso z{+LkH>Z64#o)xeC%ID6yZ|k}mi_@~2vkT@k?6|}*zd%}ZPwIq*RXf!~Hn#6v#qe-b n*Uaz`ry!>((<^^m>0t=FV4AS1A?O7#*)e#!`njxgN@xNA;|fNM literal 0 HcmV?d00001 diff --git a/Chess/pieces/b_n.png b/Chess/pieces/b_n.png new file mode 100644 index 0000000000000000000000000000000000000000..907c776c441e776eebf72bea86d3c58cfa9c9ee2 GIT binary patch literal 1138 zcmV-&1daQNP)xkyP{B*PPoBxkUBPBu^H{#u;5HjdtT zGjnJ3E&SlmaL=5>`R@OobM848uDRx#Yc7*Vfd+^FUIO|q(WNY&0aE#RrRcv8fgE6A zs64BkecO^-)v$GcPBjBsG@D1QTpl~=W%d#X%RgyF@F<}8;)_*rNY*EK7+c7#iDoI*gT(p37H`4F85Xk|%IP6D?qrJUdmSriM z%_b7_^8yDY>Yt0@;bBSA z($bPJd-RI=9>@g(0c~z>YIAc_fk42i!xP|N;DdtpeU%6U>hA77-5OwqSYxHqcYtH^ zOOnUqDV5Dy4W_VV_EiRt<#bw_BO+{@7Dv>RWR4OG&>gnkb z@TQZT(?q-j9OWeov9ASu3%rXt#n?QXZ<}-KuoSzyy8y&uF(|Rmc9Px!-ohN23i0KI zwt)9IdsFSecbMZ?Rol#ig98Ba!{ez+rNKC}grjP)W-jfdYg*F3EJ2T{n%P#eLZk^lez07*qoM6N<$ Ef{d*gQ~&?~ literal 0 HcmV?d00001 diff --git a/Chess/pieces/b_p.png b/Chess/pieces/b_p.png new file mode 100644 index 0000000000000000000000000000000000000000..e4e0690ecfefd11d1f20437558501aeceaee2601 GIT binary patch literal 530 zcmV+t0`2{YP)kkULabdxNJ6lCuh>B}3pqG&1Wjug8 z_g zfqUQ~fjUko0=GZ_^Z;M~2Ed)Zo;m6$!Kk=SPi;7Jz!z$DhY9<@Cot=xn5(~R7nmn{ zj}(9foo9_J>8@ekx1)Mam+6BPB4=ljANUkwmp4;+GG-ZeP3*BrMFQlCm{gJHbrfvrzU(KU@!d= z^S)=xx>lSKZzG{tpc8oQNkWddM_Q#J{91JzSKDB0QGW7?X7qK zykXuN;TCD5&MOn841B~84vW8|=KMsM0a_NqVeyuJUgF$X$__?7Y2j5=TSOi9rQxI6 zWLY91otIa@BJRGI6o8U`ZelbUKiZ_>p~hw+Y&w=5j15x}NqZa#a^rAlnkbR3B0un( z5&-+A$r9;xl9Tp;HPd8?bV-;mp$IHVl1)ikx@4LxnYT4yMXX~^n+$wj$jM2AA2_!b U^~6ZUh5!Hn07*qoM6N<$g18muHvj+t literal 0 HcmV?d00001 diff --git a/Chess/pieces/b_q.png b/Chess/pieces/b_q.png new file mode 100644 index 0000000000000000000000000000000000000000..e501cbff979f63c0425941b25f7b4d9fb10119a0 GIT binary patch literal 1565 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK3=%maw1RA~5?#>POlsi~=zmDSCgH-T(s zW@Z)^7It=a4h{}(Zf;&)UI76C2?+^FNl9sGX&D(AB_$;t9UWa=U7$Gz1_p+PhGu4F zHa0f4wze)VF0QVw9v&V*zXt{e1_uX+goK2KhDJn0L`FtNMMb5irsm}2eI= z6ciQ~mY0{;*Vi{RG_<$3cXV`gc6Rpm_V)Gl_4oHrm@r}D#ECO!&Rnoy!IC9QmM&eo zV#SJ8t5&U9vu5kot=qP3+qZAu;lqcI96564%$XZEZUEhX_wL>M_wPS?^yu;9$IqWX zfBpLPyLazCe*F09)2Gj$KY#uD^~aANzkmP!^XJe1|Np?ySp4s=GHC;#_2at7sn8f<4>o)tQK(rYiw&{!a7@QBgn&_s#D3mb|!9aS~j8(%J*IQ=)@aUnfUC5fpH4JtxYLJ#+< zUHCs;ewuGtdVBkNyZ-(DwpZVWgkSY3_52_Gbl=y&!gIkZ7d}lj^qlCwHecLj7w7(KTOl zO#}j`ci%8l^O&S&=sD?&+UZ4HE?52<%&VNVS?_G7?Awz_q2JgM3IOS6=xZW_WU3yY3ZB|I?La$kAAJn{S zuSawly>R-Vy=0}_l`mDt80!4qnLpU8U;E$iyOC~e zUuXIw{`u7E1hIX52eP|)DpL3E|HP@H87i@1>1Lh-Ld-K%8PdX5vaVNh5NEs*%CkCvUCwOb!*Z<=Q5*cgBl?bAM}B|2_XL`oG08+>F0JkL2Abd+<}BYE5;) z+cWnZuKeD&|J#9H-i5!{Wbb=@XYOn9b8_}UyZ3)P@o}^Gy8DIi@;>jfOI*mK6S?tY z`?a%kW2e5m^XK)>UTrTnyTTTp+QmgbZ~fSK`Rnrjqu1-gB1KNu{gTe~DWM4f%t}xQ literal 0 HcmV?d00001 diff --git a/Chess/pieces/b_r.png b/Chess/pieces/b_r.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8e456ba33849d1f265989f9df2b22574df21af GIT binary patch literal 404 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK3=%mav;s(F2Ka=y0%`JqfPjEB7yz~V`T0dh zM|*pFdwO~Tx#HsD#>U2OZf>EWp{rJ{I&?RpSCfN) z>((__|J(>Y{l297|MZ++ij#`nBRG^k{n_;(amS9=FDk9$osPE5Iy^~aOR4`0OC3+= z+k50fP1d}+KWSp_0rfYZ`ZO2bwK3q`(##`vlIhQ(zbRX?j~x-`e_^(EXP!*@xvD3- z|B9EL&I{E(eepovRRPbU8eoP(6eMGJxWOf`URqLSkZKN=iyVE+;1^7Z(=~4-YRd zFCQNtKR>^Sh={njxTdD2wzjs8j*h;*zJY;(p`oFPi3!A5pc(-I0iY~U3MdE+Pl&j! zt*xD%ov*JiT*Su4#@pK)C=w755EK*?92^`P8X6uR9uW}{7Z;b1kdTy=l#-H?m6es9 zot>YbUshIDUS3{NQBhMTO%{Q1k4EnB&A<*HSy zwr}6QW5({T}zJ2@t{rk_KKmY#y`|sbs|NsAQ;J0T4I=#Fk$S;_I zk%^gwm7Rl&n@?O$UO`b^+t|d~#@@lnGdwakzo4YFyrRCLvAMOQw}0aF88he1o4;tu zvXz@QZ`r=%@R6g(Po6$|{`#$lj~+jM`t0Saw;w)!{_^F=uiqf>2MqwN2LYfHfWU+O znE)vClDyqrHs8wqUk6OLVxBIJArg{L5B{{DTqwivp?{W)$r)Cntun=syDuEfByRC*6{b{fA(LQS>q<7A(CHm zr$pkh?J!%%go0hZGIPHMpE$JS^Wx&7MyEfU7bitWGPQ^<{_*qX zSFxB<(eSNzD*m}1N#gL{*D>u<)1EakdJ5IbP0l+XkKN$TQZ literal 0 HcmV?d00001 diff --git a/Chess/pieces/w_k.png b/Chess/pieces/w_k.png new file mode 100644 index 0000000000000000000000000000000000000000..d582cfc3e7e63e07e6cd8239dc63de753fc26eaf GIT binary patch literal 1334 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK3=%maw1R4fFFCQPDkdTnDurQD-E-o%1A)%l5=9ZS0PEJlPE-tRFuD-s$etv%b{{8_00byZbiHV6x zNl9sGX}P(%d3kyH`S}F}1%-u$#l^*?rKRQN zy%Q%+oHS|D({T}v}x1k&6~Gx-@bF_&Rx59?cTk6 z&z?Pd_wL=lfB%642Tq?pedf%WvuDqqJ9qB<`STYpT)2Gs^0jN%u3x`?`}Xa-cke!W z^ytZxC(oWed-dwo>({T}ym|BX?b~Ow6t~f_Dx-|aM99b%U7-4w0X-&$NzyH9%UoiLw z2Jq?BFXt_do95%PQmk+8mh|)UJU1TtAyTL< z6*)7@W3!=#OCIa0dqRrm59lq<%t~EyqIcmmS6c&{En64XBZSXCtq9ToZs6D{tH=I7)FO2Kr}76*y*`fV_5~?9 z^Dl-?oI6ow_MC~a7tNBbJu({CZ&s*sdbpkc)eXzlHkxL3o0sg`xO3w!6=OTIl{Mea z^(j=>oiRDFOk7%Yc9eCk^c~jQ%dRhBI{M|thGmgEZ=@wSyo)khx_|ZN)%B-7#U5CY z-8c2{%<|`YdHNnbt&K;TzNr=$K1-i?W6g~nf39_Mhv(ngocZ-or|!=}2f>(COOr2G zUt4(O)UJ73A~NTsoo{SQ@XFybVR`!QOWq_kC(Tkj7rm$GO^STRo%FRaHgR grE+Gw|5*+Ohy5LAY|n|l046R5Pgg&ebxsLQ08&g54gdfE literal 0 HcmV?d00001 diff --git a/Chess/pieces/w_n.png b/Chess/pieces/w_n.png new file mode 100644 index 0000000000000000000000000000000000000000..62e6b53559ee97b3cf503621e8ddf810f58214c1 GIT binary patch literal 1371 zcmV-h1*H0kP)3q9BtNgnQ z_kQ<~+)-+h<|b+Np&!UY&cEO1o_o&k+B+<){k*_+SHF3L+q-T#!;O z0C;~@U6&BT0AM05|H|+o0Q!7BQ`58*fQC%@ApmA;Yb&>G*V6 zw{O>#QZWFhq?EJ4V9-dVQmm`1GXP8gH~^sPrP^k2ODUhVx3@DIjZ#W!0-%)A92*-W zNw&4M(cy3q05f&d0QvzmzAR~%l=9!>$B&aFlgT6(78aOFrMQyW+1a_ehmpB}y8xOtTDn&V!3Pf>a1H)g`6rP`aA077H8nLl(i?RUfO{i^4+$a6&dyFg zdGdraGc)<5|IAjnxVXsEr%zK#X)2|D2C#EIg8~WHOhu zk?)G4(J0++x1L$=>$X`h2qDagi3zr}v=9KjUN4uHmh!pfWqf>`PN&n5QjPbjm+ z=+2!xg=|ltWl(nl`z6_ilZ0 zanY7=B9Wlm?dGv##|moS)zw8!)0P0dQL1z+07fDaTf!uH^5jVZ;N;|FLG5F)n6+0v zFGW~WN=?<)*6M4m-PK&bew{)H3L$Lu3xz_4QtGEtq}u@S+O=!80uK)l)8TL!nx;Kc zN||>0oA%u0V9#Yi6j zz)P1daddQ)qobpFgPEquo}L~8pb#PoU@L$hg27Bj*Xz}vKYwm}rX!JvwXWZ` zD}71`VOo!#@p#-yVdnh&Jp23mt$~LCytb{;8wBzgb-eQWHnUFlt#ru`EP z291G%0d{wH69B8LtM!qQ5lSgdA;h2ThgD}l?H&1q?C^` z0}ufB?b}C}%cU!&egWWF)xKIv`FmAWmA=NyL0*=ZmnnoW0en%6Gyn*s6TM$b`8@zC zrS1Y)y(@Q0DSvahT>8Cx_lg#_$fUimij`i82B0!axlbwetH9oafQ-t7)I#o)vE}F%J&t_<#K6wF)NjYt(vAK zj~qEtwi&i)YHFeo;>TQpbDfBVaL6=G*NGD+N*E$LLWsQerAWV1Sy^f9-@m_vA+kdf zB+Xp)rL5^{r_-sOJ9n;xA+i&X$AR?OPz_& literal 0 HcmV?d00001 diff --git a/Chess/pieces/w_p.png b/Chess/pieces/w_p.png new file mode 100644 index 0000000000000000000000000000000000000000..bfd45479c59e2c39cbbd5224eafbbf09ca173fd0 GIT binary patch literal 886 zcmV-+1Bv{JP)(yP#V$FMOS{TbSM6U zQYg}`tJY2FA1DaA=_U$VZRy5kva^j6$R<#wX6M3ITQg-oP8Vjt(jm@tCXS0dFfe4! zob%*zxc4wXn>KCQw7JPdT9ESzfH?qn0el0n4&YM@>I8xS@D>28s%qqNIV+J!7yuZ+ zyTEz5C8yog&j|5RHs6NvGK-YE0hnIf;9Z2%sC7K@HOT`U$kolYB#)xH!3fQ>)cjRaHYu`8jOo#{hVBb+xIm&C1G(y^A~wQ~FIuM~A6tnk(sgz0UD? z+ywC2Pf@>H-asak;aDu@DmWgGBa_K6fI&Y+{YsM%-cmH;$xl(g(g)RQ6`H2G3f43Y z)oK+0zWOQZSNi?=`8lnxue%D)=kuu7>jYrSXI)%=H>!D&F1Ilg<%-O0B*Z|$BV!y0E~~1d-ZC{*w~nT`!LYN z4PGgV;(FkBi>7I;D2fH(rCSj%E8W}M+iSTU_}vnV#gIrOOaQ9ecch2>x1^L}XJ^N| z*%d^iQ30Sc@WcQ<;$nMh)%C%xh?novSpeN0;=OVLAoR}*ZQ6vvAFGb=#l+Kye*gdg M07*qoM6N<$f>0Zz*#H0l literal 0 HcmV?d00001 diff --git a/Chess/pieces/w_q.png b/Chess/pieces/w_q.png new file mode 100644 index 0000000000000000000000000000000000000000..ac780bf6f35e05086b0270bafecbfad120365c07 GIT binary patch literal 1186 zcmV;T1YP@yP)m|5mJhwniP_&+4&`U2 z)3{UKyO}e2?=y4W^Ua(Y>AC(_%GGwARHG*Td(;wjs9jZIW$bU(EeNc$XJnq~NLx#d zEB1?h9x=?QC&h^i7{3g7j;EJ!jUwfr`xMikI=SJo))2&QT1m+ zJ&Bi28qm}2Nn3^Keq^y1g}wNwHr+y7QxX#G`9+KhKxz~w(Dbm%@P;$+hLsW4(@h}M z_!xmA|1m-$fMdcNRB_^&9Uca439AL-9fTHy^%jGNb|l=z-k{L2r@qBGT`$UVbCkX&DfBq`GShJ!bW^h%Nr<@$pZ#olgN#4*YR>6U>8D{qCNmb zeO(f}04Vo$T>GuN49twHGc~&25Cb+Nr`r`iKtB;DR*#Tbjfl8@04jXlmfH-(Fe!%^ z4)Pb^0dsw^Fc`tDLVOvbcOX`|k;j#RDD{VcpT`(tVvrB{o%azhP(c|pn2g9FhitN3 zrV|rffh%SXxrkMCGQdvclt0GTwl|Q0hr%nL5;u?eETftl)>1%@3|>cK&!<$xoXHF(C6Y{iO(HX}XBA0zpU?D$N?a>loaY*S z^bsS*FfdGv7=83{jq`NTN{RD^G;=&Z78(shX{0=a8NF%JQp*IlhkDkqh;n8VC7*0W zHu*%EO*xBLLp^(#;2vAWV``SYXAoJGQbi4GsbeDzG|<3C>R3w+Rg{v2FxY#Vl|K4V zo_~t|Gy>`86nWvYNK4+8>T#UvYP>7yk{60k#)007P-S}P72*VU2-3g?+~EX5E7C(3 z+I}Idn;NeSR#HPPb!-a9xQRMysbM9R!PK~QLfC#4rW?sLE!PHZ*FkkhdhCtNTXw+S zH^agV+xvDP^On64=~1^1YP&XQxu!k;)AXO!-|HzTbSMN%5dZ)H07*qoM6N<$f=vY{ AqW}N^ literal 0 HcmV?d00001 diff --git a/Chess/pieces/w_r.png b/Chess/pieces/w_r.png new file mode 100644 index 0000000000000000000000000000000000000000..20f414ef39d804486db70bb40ccb58b4d25c2794 GIT binary patch literal 528 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK3=%mav;s&i4e$wZ1=6GfCMG5p78W20*T@J4 z%*@O{aaLAVHa0eEYipn^P#DM-7Z;b7mR3?yvaqlKird@UJ2*ImhK5E(Mb*~UHa9nS zbaZrgcQ0MKboJ`hn>TO1ckkZo*RS8bd-w6<$3K7m{Qv)d{b#;hpU z`QFk~TJ)Q5{*y`DdZu*QFnmy&>OFDE+lbd9f`Y+wy$$p2rv|-RSgL3Et)hC-jXuxY z?o#u&tUdT=&8e7a%H8`43?pQ`Qf0)P4}Nv`nUp;-Md?S`w{N>n?EAj-XYAp3|K4`p zx_oxkiL_IvbI*9Cr{8$?B=($;-XR9t2gtty{b!c(-qxdf$aDbM>cMw8e_+^q#8s)h`#x-+JKc?9V{2GkCiC KxvX