ability to create new games as white or black
This commit is contained in:
parent
7e721e7940
commit
39a3e33a06
|
@ -1 +1,2 @@
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
data/
|
||||||
|
|
|
@ -1,20 +1,36 @@
|
||||||
from cinput import ControlInput, Button
|
from os import path
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
|
import re
|
||||||
|
import itertools
|
||||||
|
from cinput import ControlInput, Button
|
||||||
from graphics import Graphics
|
from graphics import Graphics
|
||||||
from .draw import Draw
|
from .draw import Draw
|
||||||
from .sunfish import initial
|
from . import sunfish
|
||||||
|
|
||||||
class GameState(Enum):
|
class GameState(Enum):
|
||||||
MAIN_MENU = auto()
|
MAIN_MENU = auto()
|
||||||
|
PLAYING = auto()
|
||||||
THINKING = auto()
|
THINKING = auto()
|
||||||
CHOOSE_ROW = auto()
|
CHOOSE_ROW = auto()
|
||||||
CHOOSE_COL = auto()
|
CHOOSE_COL = auto()
|
||||||
GAME_OVER = auto()
|
GAME_OVER = auto()
|
||||||
|
|
||||||
|
SAVE_FILE = path.join("data", "chess_state.fen")
|
||||||
|
|
||||||
def execute(cinput: ControlInput, graphics: Graphics, _):
|
def execute(cinput: ControlInput, graphics: Graphics, _):
|
||||||
graphics.clear()
|
graphics.clear()
|
||||||
draw = Draw(graphics)
|
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
|
state = GameState.MAIN_MENU
|
||||||
menu_index = 0
|
menu_index = 0
|
||||||
|
@ -22,6 +38,8 @@ def execute(cinput: ControlInput, graphics: Graphics, _):
|
||||||
while True:
|
while True:
|
||||||
if state == GameState.MAIN_MENU:
|
if state == GameState.MAIN_MENU:
|
||||||
draw.draw_menu(menu_index)
|
draw.draw_menu(menu_index)
|
||||||
|
elif state == GameState.PLAYING:
|
||||||
|
draw.draw_state()
|
||||||
|
|
||||||
key = cinput.get_one_shot()
|
key = cinput.get_one_shot()
|
||||||
if state == GameState.MAIN_MENU:
|
if state == GameState.MAIN_MENU:
|
||||||
|
@ -31,5 +49,52 @@ def execute(cinput: ControlInput, graphics: Graphics, _):
|
||||||
menu_index = 0
|
menu_index = 0
|
||||||
elif key == Button.DIR_D:
|
elif key == Button.DIR_D:
|
||||||
menu_index += 1
|
menu_index += 1
|
||||||
if menu_index > 2:
|
if menu_index > 3:
|
||||||
menu_index = 2
|
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 = [
|
MENU = [
|
||||||
|
"Play",
|
||||||
|
"Quit",
|
||||||
"New (W)",
|
"New (W)",
|
||||||
"New (B)",
|
"New (B)"]
|
||||||
"Quit"]
|
|
||||||
|
|
||||||
def __init__(self, graphics: Graphics):
|
def __init__(self, graphics: Graphics):
|
||||||
self._graphics = graphics
|
self._graphics = graphics
|
||||||
|
@ -78,11 +79,12 @@ class Draw:
|
||||||
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
|
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
|
||||||
|
|
||||||
def draw_board(self, board: str):
|
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)
|
self._graphics.fill_rect(0, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
|
||||||
nb = "".join(board.split())
|
nb = "".join(board.split())
|
||||||
c = True
|
c = True
|
||||||
for row in range(8):
|
for row in range(8):
|
||||||
c = not c
|
|
||||||
for col in range(8):
|
for col in range(8):
|
||||||
if c:
|
if c:
|
||||||
x = col * self.SQUARE_SIZE
|
x = col * self.SQUARE_SIZE
|
||||||
|
@ -90,9 +92,10 @@ class Draw:
|
||||||
self._graphics.fill_rect(x, y, self.SQUARE_SIZE, self.SQUARE_SIZE, 1)
|
self._graphics.fill_rect(x, y, self.SQUARE_SIZE, self.SQUARE_SIZE, 1)
|
||||||
p = nb[(row * 8) + col]
|
p = nb[(row * 8) + col]
|
||||||
if p.lower() in self.PIECES:
|
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
|
||||||
|
c = not c
|
||||||
self._graphics.show()
|
self._graphics.show()
|
||||||
|
|
||||||
def draw_menu(self, menu_index: int):
|
def draw_menu(self, menu_index: int):
|
||||||
|
@ -102,3 +105,7 @@ class Draw:
|
||||||
marker = "> " if i == menu_index else " "
|
marker = "> " if i == menu_index else " "
|
||||||
self._graphics.text(marker + self.MENU[i], 12, i + 2, 1)
|
self._graphics.text(marker + self.MENU[i], 12, i + 2, 1)
|
||||||
self._graphics.show()
|
self._graphics.show()
|
||||||
|
|
||||||
|
def draw_state(self):
|
||||||
|
self._clear_info()
|
||||||
|
self._graphics.show()
|
||||||
|
|
Reference in New Issue