Full chess game demo

This commit is contained in:
MikeTheWatchGuy 2018-10-11 15:17:44 -04:00
parent b6fdd93850
commit 2ef86d3a70
19 changed files with 34072 additions and 154 deletions

BIN
Chess/ChessPiecesArray.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

174
Chess/Demo_Chess_Board.py Normal file
View File

@ -0,0 +1,174 @@
import PySimpleGUI as sg
import os
import io
from PIL import Image, ImageDraw, ImageTk, ImageFont
import sys
from random import randint as rand
import chess
import chess.pgn
import copy
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
# path to the chess pieces
CHESS_PATH = '.'
BLANK = 0 # piece names
PAWNB = 1
KNIGHTB = 2
BISHOPB = 3
ROOKB = 4
KINGB = 5
QUEENB = 6
PAWNW = 7
KNIGHTW = 8
BISHOPW = 9
ROOKW = 10
KINGW = 11
QUEENW = 12
initial_board = [[ROOKB, KNIGHTB, BISHOPB, KINGB, QUEENB, BISHOPB, KNIGHTB, ROOKB ],
[PAWNB,]*8,
[BLANK,]*8,
[BLANK,]*8,
[BLANK,]*8,
[BLANK,]*8,
[PAWNW,]*8,
[ROOKW, KNIGHTW, BISHOPW, KINGW, QUEENW, BISHOPW, KNIGHTW, ROOKW]]
blank = os.path.join(CHESS_PATH, 'blank.png')
bishopB = os.path.join(CHESS_PATH, 'bishopb.png')
bishopW = os.path.join(CHESS_PATH, 'bishopw.png')
pawnB = os.path.join(CHESS_PATH, 'pawnb.png')
pawnW = os.path.join(CHESS_PATH, 'pawnw.png')
knightB = os.path.join(CHESS_PATH, 'knightb.png')
knightW = os.path.join(CHESS_PATH, 'knightw.png')
rookB = os.path.join(CHESS_PATH, 'rookb.png')
rookW = os.path.join(CHESS_PATH, 'rookw.png')
queenB = os.path.join(CHESS_PATH, 'queenB.png')
queenW = os.path.join(CHESS_PATH, 'queenW.png')
kingB = os.path.join(CHESS_PATH, 'kingb.png')
kingW = os.path.join(CHESS_PATH, 'kingw.png')
images = {BISHOPB: bishopB, BISHOPW: bishopW, PAWNB: pawnB, PAWNW: pawnW, KNIGHTB: knightB, KNIGHTW: knightW,
ROOKB: rookB, ROOKW: rookW, KINGB: kingB, KINGW: kingW, QUEENB: queenB, QUEENW: queenW, BLANK: blank}
def get_a_move():
pgn = open('C:/Python/PycharmProjects/GooeyGUI/Chess/game.pgn')
first_game = chess.pgn.read_game(pgn)
for move in first_game.main_line():
print(move)
yield move
def open_pgn_file(filename):
pgn = open(filename)
first_game = chess.pgn.read_game(pgn)
moves = [move for move in first_game.main_line()]
return moves
def render_square(image, key, location):
if (location[0] + location[1]) % 2:
color = '#B58863'
else:
color = '#F0D9B5'
return sg.RButton('', image_filename=image, size=(1, 1), button_color=('white', color), pad=(0, 0), key=key)
def redraw_board(window, board):
for i in range(8):
for j in range(8):
if (i+j) % 2:
color = '#B58863'
else:
color = '#F0D9B5'
piece_image = images[board[i][j]]
elem = window.FindElement(key=(i,j))
elem.Update(button_color = ('white', color),
image_filename=piece_image,)
def PlayGame():
menu_def = [['&File', ['&Open PGN File', 'E&xit' ]],
['&Help', '&About...'],]
sg.SetOptions(auto_size_buttons=True, margins=(0,0))
# create initial board setup
board = copy.deepcopy(initial_board)
# the main board display layout
board_layout = [[sg.T(' ')] + [sg.T(f'{a}', pad=((23,27),0), font='Any 13') for a in 'abcdefgh']]
# loop though board and create buttons with images
for i in range(8):
row = [sg.T(str(8-i)+' ', font='Any 13')]
for j in range(8):
piece_image = images[board[i][j]]
row.append(render_square(piece_image, key=(i,j), location=(i,j)))
row.append(sg.T(str(8-i)+' ', font='Any 13'))
board_layout.append(row)
# add the labels across bottom of board
board_layout.append([sg.T(' ')] + [sg.T(f'{a}', pad=((23,27),0), font='Any 13') for a in 'abcdefgh'])
# setup the controls on the right side of screen
openings = ('Any', 'Defense', 'Attack', 'Trap', 'Gambit','Counter', 'Sicillian', 'English','French', 'Queen\'s openings', 'King\'s Openings','Indian Openings')
board_controls = [[sg.RButton('New Game', key='Open PGN File'), sg.RButton('Draw')],
[sg.RButton('Resign Game'), sg.RButton('Set FEN')],
[sg.RButton('Player Odds'),sg.RButton('Training') ],
[sg.Drop(openings),sg.Text('Opening/Style')],
[sg.CBox('Play a White', key='_white_')],
[sg.Text('Move List')],
[sg.Multiline([], do_not_clear=True, autoscroll=True, size=(15,10),key='_movelist_')],]
# layouts for the tabs
controls_layout = [[sg.Text('Performance Parameters', font='_ 20')],
[sg.T('Put stuff like AI engine tuning parms on this tab')]]
statistics_layout = [[sg.Text('Statistics', font=('_ 20'))],
[sg.T('Game statistics go here?')]]
board_tab = [[sg.Column(board_layout)]]
# the main window layout
layout = [[sg.Menu(menu_def, tearoff=False)],
[sg.TabGroup([[sg.Tab('Board',board_tab),
sg.Tab('Controls', controls_layout),
sg.Tab('Statistics', statistics_layout)]]),
sg.Column(board_controls)],
[sg.Text('Click anywhere on board for next move', font='_ 14')]]
window = sg.Window('Chess',
default_button_element_size=(12,1),
auto_size_buttons=False,
icon='kingb.ico').Layout(layout)
# ---===--- Loop taking in user input --- #
i = 0
moves = None
while True:
button, value = window.Read()
if button in (None, 'Exit'):
break
if button == 'Open PGN File':
filename = sg.PopupGetFile('', no_window=True)
if filename is not None:
moves = open_pgn_file(filename)
i = 0
board = copy.deepcopy(initial_board)
window.FindElement('_movelist_').Update(value='')
if button == 'About...':
sg.Popup('Powerd by Engine Kibitz Chess Engine')
if type(button) is tuple and moves is not None and i < len(moves):
move = moves[i] # get the current move
window.FindElement('_movelist_').Update(value='{} {}\n'.format(i+1, str(move)), append=True)
move_from = move.from_square # parse the move-from and move-to squares
move_to = move.to_square
row = move_from // 8
col = move_from % 8
piece = board[row][col] # get the move-from piece
board[row][col] = BLANK # place blank where piece was
row = move_to // 8 # compute move-to square
col = move_to % 8
board[row][col] = piece # place piece in the move-to square
redraw_board(window, board)
i += 1
PlayGame()

33862
Chess/Malakhov.pgn Normal file

File diff suppressed because it is too large Load Diff

BIN
Chess/bishopb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
Chess/bishopw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
Chess/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

36
Chess/game.pgn Normal file
View File

@ -0,0 +1,36 @@
[Event "Wch U12"]
[Site "Duisburg"]
[Date "1992.??.??"]
[Round "1"]
[White "Malakhov, Vladimir"]
[Black "Ab Rahman, M."]
[Result "1-0"]
[WhiteElo ""]
[BlackElo ""]
[ECO "A05"]
1.Nf3 Nf6 2.b3 g6 3.Bb2 Bg7 4.g3 d6 5.Bg2 O-O 6.O-O c6 7.d3 e5 8.c4 Ne8 9.Nbd2 f5
10.Qc2 Na6 11.c5 Nxc5 12.Nxe5 Qe7 13.d4 Na6 14.Qc4+ Kh8 15.Nef3 Be6 16.Qc3 f4
17.gxf4 Rxf4 18.Qe3 Rf8 19.Ng5 Nec7 20.Nc4 Rae8 21.Nxe6 Qxe6 22.Qxe6 Rxe6
23.e3 d5 24.Ne5 g5 25.Ba3 Rff6 26.Bh3 Re8 27.Bd7 Rd8 28.Be7 Rxd7 29.Bxf6 1-0
[Event "Wch U12"]
[Site "Duisburg"]
[Date "1992.??.??"]
[Round "2"]
[White "Malakhov, Vladimir"]
[Black "Berescu, Alin"]
[Result "1-0"]
[WhiteElo ""]
[BlackElo ""]
[ECO "D05"]
1.d4 Nf6 2.Nd2 d5 3.Ngf3 e6 4.e3 c5 5.c3 Nbd7 6.Bd3 Bd6 7.O-O O-O 8.Re1 b6
9.e4 dxe4 10.Nxe4 Be7 11.Ne5 Bb7 12.Ng5 g6 13.Qe2 Nxe5 14.dxe5 Nh5 15.Ne4 Qd5
16.f4 Rfd8 17.Bc2 Qc6 18.Be3 Rd7 19.Rad1 Rad8 20.Rxd7 Rxd7 21.Nd2 Ng7 22.Be4 Qc8
23.g4 Qd8 24.Bxb7 Rxb7 25.Ne4 Rd7 26.c4 h5 27.h3 h4 28.Kh2 Ne8 29.f5 Qc7
30.Bf4 Rd4 31.Qf2 Rxc4 32.f6 Qb7 33.Ng5 Bf8 34.b3 Rc3 35.Qd2 Rf3 36.Nxf3 Qxf3
37.Qe3 Qd5 38.Qe4 Qd7 39.Qf3 Nc7 40.Rd1 Nd5 41.Bg5 Qc7 42.Re1 b5 43.Qd1 c4
44.Qc1 Bb4 45.Bd2 Bxd2 46.Qxd2 Nxf6 47.bxc4 bxc4 48.Qd6 Qa5 49.Rf1 Nd5 50.Qd7 Qd2+
51.Kh1 f5 52.exf6 1-0

BIN
Chess/kingb.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
Chess/kingb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Chess/kingw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Chess/knightb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
Chess/knightw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
Chess/pawnb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 B

BIN
Chess/pawnw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
Chess/queenb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
Chess/queenw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
Chess/rookb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

BIN
Chess/rookw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

View File

@ -1,154 +0,0 @@
import PySimpleGUI as sg
import os
import io
from PIL import Image, ImageDraw, ImageTk, ImageFont
import sys
from random import randint as rand
import chess
import chess.pgn
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
ROOT_PATH = './' if sys.platform == 'linux' else 'C:\\Python\\PycharmProjects\\GooeyGUI\\'
CHESS_PATH = 'C:/Python/PycharmProjects/GooeyGUI/Chess'
# piece names
BLANK = 0
PAWNB = 1
KNIGHTB = 2
BISHOPB = 3
ROOKB = 4
KINGB = 5
QUEENB = 6
PAWNW = 7
KNIGHTW = 8
BISHOPW = 9
ROOKW = 10
KINGW = 11
QUEENW = 12
initial_board = [[ROOKB, KNIGHTB, BISHOPB, KINGB, QUEENB, BISHOPB, KNIGHTB, ROOKB ],
[PAWNB for _ in range(8)],
[BLANK for _ in range(8)],
[BLANK for _ in range(8)],
[BLANK for _ in range(8)],
[BLANK for _ in range(8)],
[PAWNW for _ in range(8)],
[ROOKW, KNIGHTW, BISHOPW, KINGW, QUEENW, BISHOPW, KNIGHTW, ROOKW]]
blank = os.path.join(CHESS_PATH, 'blank.png')
bishopB = os.path.join(CHESS_PATH, 'bishopb.png')
bishopW = os.path.join(CHESS_PATH, 'bishopw.png')
pawnB = os.path.join(CHESS_PATH, 'pawnb.png')
pawnW = os.path.join(CHESS_PATH, 'pawnw.png')
knightB = os.path.join(CHESS_PATH, 'knightb.png')
knightW = os.path.join(CHESS_PATH, 'knightw.png')
rookB = os.path.join(CHESS_PATH, 'rookb.png')
rookW = os.path.join(CHESS_PATH, 'rookw.png')
queenB = os.path.join(CHESS_PATH, 'queenB.png')
queenW = os.path.join(CHESS_PATH, 'queenW.png')
kingB = os.path.join(CHESS_PATH, 'kingb.png')
kingW = os.path.join(CHESS_PATH, 'kingw.png')
images = {BISHOPB: bishopB, BISHOPW: bishopW, PAWNB: pawnB, PAWNW: pawnW, KNIGHTB: knightB, KNIGHTW: knightW,
ROOKB: rookB, ROOKW: rookW, KINGB: kingB, KINGW: kingW, QUEENB: queenB, QUEENW: queenW, BLANK: blank}
def get_a_move():
board = chess.Board()
pgn = open('C:/Python/PycharmProjects/GooeyGUI/Chess/game.pgn')
first_game = chess.pgn.read_game(pgn)
for move in first_game.main_line():
print(move)
yield move
def render_square(image, key, location):
if (location[0] + location[1]) % 2:
color = '#B58863'
else:
color = '#F0D9B5'
return sg.RButton('', image_filename=image, size=(1, 1), button_color=('white', color), pad=(0, 0), key=key)
def redraw_board(window, board):
for i in range(8):
for j in range(8):
if (i+j) % 2:
color = '#B58863'
else:
color = '#F0D9B5'
piece_image = images[board[i][j]]
elem = window.FindElement(key=(i,j))
elem.Update(button_color = ('white', color),
image_filename=piece_image,)
def update_board(board):
# board[5][5] = KINGB
return board
def DrawBoard():
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
brn = sg.RButton('',image_filename=blank, size=(1,1), button_color=('white','#B58863') ,pad=(0,0), key='_close_')
tan = sg.RButton('', image_filename=blank, size=(4,3), button_color=('white','#F0D9B5') ,pad=(0,0))
board = initial_board
board_layout = [[sg.T(' ')] + [sg.T(f'{a}', pad=((23,27),0), font='Any 13') for a in 'abcdefgh']]
for i in range(8):
row = [sg.T(str(8-i)+' ', font='Any 13')]
for j in range(8):
piece_image = images[board[i][j]]
row.append(render_square(piece_image, key=(i,j), location=(i,j)))
# if (i+j) % 2:
# row.append(render_tan(piece_image, key=(i,j)))
# else:
# row.append(render_brn(piece_image, key=(i,j)))
row.append(sg.T(str(8-i)+' ', font='Any 13'))
board_layout.append(row)
board_layout.append([sg.T(' ')] + [sg.T(f'{a}', pad=((23,27),0), font='Any 13') for a in 'abcdefgh'])
controls_layout = [[sg.Text('Performance Parameters', font='Any 20')]]
statistics_layout = [[sg.Text('Statistics', font=('Any 20'))]]
layout = [[sg.TabGroup([[sg.Tab('Board',board_layout),
sg.Tab('Controls', controls_layout),
sg.Tab('Statistics', statistics_layout)]])]]
window = sg.Window('Chess',
no_titlebar=False,
grab_anywhere=True,
keep_on_top=True,
icon='kingb.ico').Layout(layout)
pgn = open('C:/Python/PycharmProjects/GooeyGUI/Chess/game.pgn')
first_game = chess.pgn.read_game(pgn)
moves = [move for move in first_game.main_line()]
# ---===--- Loop taking in user input --- #
i = 0
while True:
board = update_board(board)
button, value = window.Read()
if button is None:
break
move = moves[i]
move_from = move.from_square
move_to = move.to_square
print(move_from, move_to)
row = move_from//8
col = move_from%8
print(row, col)
piece = board[row][col]
board[row][col] = BLANK
row = move_to//8
col = move_to % 8
board[row][col] = piece
print(piece)
redraw_board(window, board)
i += 1
DrawBoard()