ability to create new games as white or black
This commit is contained in:
parent
7e721e7940
commit
39a3e33a06
3 changed files with 83 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
__pycache__/
|
||||
data/
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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()
|
||||
|
|
Reference in a new issue