Compare commits

...

2 Commits

Author SHA1 Message Date
Rudis Muiznieks 39a3e33a06
ability to create new games as white or black 2022-04-24 15:43:34 -05:00
Rudis Muiznieks 7e721e7940
made menu for chess 2022-04-24 13:32:14 -05:00
4 changed files with 125 additions and 10 deletions

1
.gitignore vendored
View File

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

View File

@ -15,6 +15,10 @@ menu_config = [
MenuType.PLUGIN, MenuType.PLUGIN,
{"plugin": "chess", {"plugin": "chess",
"arg": None}), "arg": None}),
MenuItem("Cube Timer",
MenuType.PLUGIN,
{"plugin": "cube",
"arg": None}),
]}), ]}),
MenuItem("Information", MenuItem("Information",
MenuType.PLUGIN, MenuType.PLUGIN,

View File

@ -1,13 +1,100 @@
from os import path
from enum import Enum, auto
import re
import itertools
from cinput import ControlInput, Button 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):
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, _): def execute(cinput: ControlInput, graphics: Graphics, _):
graphics.clear()
draw = Draw(graphics) draw = Draw(graphics)
draw.draw(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
while True: while True:
key = cinput.get_one_shot(5) if state == GameState.MAIN_MENU:
if key == Button.BTN_A: draw.draw_menu(menu_index)
return elif state == GameState.PLAYING:
draw.draw_state()
key = cinput.get_one_shot()
if state == GameState.MAIN_MENU:
if key == Button.DIR_U:
menu_index -= 1
if menu_index < 0:
menu_index = 0
elif key == Button.DIR_D:
menu_index += 1
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

@ -51,6 +51,12 @@ class Draw:
" . ■ ■ ■ ■ . "], " . ■ ■ ■ ■ . "],
} }
MENU = [
"Play",
"Quit",
"New (W)",
"New (B)"]
def __init__(self, graphics: Graphics): def __init__(self, graphics: Graphics):
self._graphics = graphics self._graphics = graphics
@ -68,13 +74,17 @@ class Draw:
elif pixel =='-': elif pixel =='-':
self._graphics.pixel(x, y, c if filled else sqc) self._graphics.pixel(x, y, c if filled else sqc)
def _clear_info(self):
self._graphics.fill_rect(
self.BOARD_SIZE, 0, self.BOARD_SIZE, self.BOARD_SIZE, 0)
def draw(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)
nb = "".join(board.split()) nb = "".join(board.split())
self._graphics.clear()
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
@ -82,7 +92,20 @@ 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()
def draw_menu(self, menu_index: int):
self._clear_info()
self._graphics.text("Menu:", 12, 0, 1)
for i in range(len(self.MENU)):
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() self._graphics.show()