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__/
data/

View File

@ -15,6 +15,10 @@ menu_config = [
MenuType.PLUGIN,
{"plugin": "chess",
"arg": None}),
MenuItem("Cube Timer",
MenuType.PLUGIN,
{"plugin": "cube",
"arg": None}),
]}),
MenuItem("Information",
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 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(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:
key = cinput.get_one_shot(5)
if key == Button.BTN_A:
return
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:
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):
self._graphics = graphics
@ -68,13 +74,17 @@ class Draw:
elif pixel =='-':
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())
self._graphics.clear()
c = True
for row in range(8):
c = not c
for col in range(8):
if c:
x = col * self.SQUARE_SIZE
@ -82,7 +92,20 @@ 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):
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()