ability to create new games as white or black

This commit is contained in:
Rudis Muiznieks 2022-04-24 15:43:34 -05:00
parent 7e721e7940
commit 39a3e33a06
Signed by: rudism
GPG key ID: CABF2F86EF7884F9
3 changed files with 83 additions and 10 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
__pycache__/
data/

View file

@ -1,20 +1,36 @@
from cinput import ControlInput, Button
from os import path
from enum import Enum, auto
import re
import itertools
from cinput import ControlInput, Button
from graphics import Graphics
from .draw import Draw
from .sunfish import initial
from . import sunfish
class GameState(Enum):
MAIN_MENU = auto()
PLAYING = auto()
THINKING = auto()
CHOOSE_ROW = auto()
CHOOSE_COL = auto()
GAME_OVER = auto()
SAVE_FILE = path.join("data", "chess_state.fen")
def execute(cinput: ControlInput, graphics: Graphics, _):
graphics.clear()
draw = Draw(graphics)
draw.draw_board(initial)
pos: sunfish.Position
if path.exists(SAVE_FILE):
with open(SAVE_FILE, "r") as fen:
fenstr = fen.read()
pos = parseFEN(fenstr)
else:
pos = sunfish.Position(
sunfish.initial, 0, (True,True), (True,True), 0, 0)
draw.draw_board(pos.board)
state = GameState.MAIN_MENU
menu_index = 0
@ -22,6 +38,8 @@ def execute(cinput: ControlInput, graphics: Graphics, _):
while True:
if state == GameState.MAIN_MENU:
draw.draw_menu(menu_index)
elif state == GameState.PLAYING:
draw.draw_state()
key = cinput.get_one_shot()
if state == GameState.MAIN_MENU:
@ -31,5 +49,52 @@ def execute(cinput: ControlInput, graphics: Graphics, _):
menu_index = 0
elif key == Button.DIR_D:
menu_index += 1
if menu_index > 2:
menu_index = 2
if menu_index > 3:
menu_index = 3
elif key == Button.BTN_B:
if menu_index == 0:
state = GameState.PLAYING
elif menu_index == 1:
with open(SAVE_FILE, "w") as fen:
fen.write(renderFEN(pos))
return
elif menu_index == 2 or menu_index == 3:
pos = sunfish.Position(
sunfish.initial, 0, (True,True), (True,True), 0, 0)
if menu_index == 3:
pos = pos.rotate()
draw.draw_board(pos.board)
state = GameState.PLAYING
elif state == GameState.PLAYING:
if key == Button.BTN_A:
state = GameState.MAIN_MENU
def get_color(pos):
return 1 if pos.board.startswith('\n') else 0
def parseFEN(fen):
""" Parses a string in Forsyth-Edwards Notation into a Position """
board, color, castling, enpas, _, _ = fen.split()
board = re.sub(r'\d', (lambda m: '.'*int(m.group(0))), board)
board = list(21*' ' + ' '.join(board.split('/')) + 21*' ')
board[9::10] = ['\n']*12
board = ''.join(board)
wc = ('Q' in castling, 'K' in castling)
bc = ('k' in castling, 'q' in castling)
ep = sunfish.parse(enpas) if enpas != '-' else 0
score = sum(sunfish.pst[p][i] for i,p in enumerate(board) if p.isupper())
score -= sum(sunfish.pst[p.upper()][119-i] for i,p in enumerate(board) if p.islower())
pos = sunfish.Position(board, score, wc, bc, ep, 0)
return pos if color == 'w' else pos.rotate()
def renderFEN(pos, half_move_clock=0, full_move_clock=1):
color = 'wb'[get_color(pos)]
if get_color(pos) == 1:
pos = pos.rotate()
board = '/'.join(pos.board.split())
board = re.sub(r'\.+', (lambda m: str(len(m.group(0)))), board)
castling = ''.join(itertools.compress('KQkq', pos.wc[::-1]+pos.bc)) or '-'
ep = sunfish.render(pos.ep) if not pos.board[pos.ep].isspace() else '-'
clock = '{} {}'.format(half_move_clock, full_move_clock)
return ' '.join((board, color, castling, ep, clock))

View file

@ -52,9 +52,10 @@ class Draw:
}
MENU = [
"Play",
"Quit",
"New (W)",
"New (B)",
"Quit"]
"New (B)"]
def __init__(self, graphics: Graphics):
self._graphics = graphics
@ -78,11 +79,12 @@ class Draw:
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
def draw_board(self, board: str):
ic(board)
is_black = board.startswith('\n')
self._graphics.fill_rect(0, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
nb = "".join(board.split())
c = True
for row in range(8):
c = not c
for col in range(8):
if c:
x = col * self.SQUARE_SIZE
@ -90,9 +92,10 @@ class Draw:
self._graphics.fill_rect(x, y, self.SQUARE_SIZE, self.SQUARE_SIZE, 1)
p = nb[(row * 8) + col]
if p.lower() in self.PIECES:
self._draw_piece(self.PIECES[p.lower()], p.isupper(), col, row, c)
self._draw_piece(
self.PIECES[p.lower()], p.isupper() if not is_black else p.islower(), col, row, c)
c = not c
c = not c
self._graphics.show()
def draw_menu(self, menu_index: int):
@ -102,3 +105,7 @@ class Draw:
marker = "> " if i == menu_index else " "
self._graphics.text(marker + self.MENU[i], 12, i + 2, 1)
self._graphics.show()
def draw_state(self):
self._clear_info()
self._graphics.show()