diff --git a/pyproject.toml b/pyproject.toml index bb9e713..a04cf1e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,5 +9,6 @@ dependencies = [ "chess==1.10.0", "numpy==1.26.3", "stockfish==3.28.0", + "aiohttp==3.9.1", ] requires-python = ">= 3.10" diff --git a/requirements.txt b/requirements.txt index b83defa..2e4154a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ chess==1.10.0 numpy==1.26.3 -stockfish==3.28.0 \ No newline at end of file +stockfish==3.28.0 +aiohttp \ No newline at end of file diff --git a/src/chesspp/res/bB.png b/src/chesspp/res/bB.png new file mode 100644 index 0000000..be3007d Binary files /dev/null and b/src/chesspp/res/bB.png differ diff --git a/src/chesspp/res/bK.png b/src/chesspp/res/bK.png new file mode 100644 index 0000000..de9880c Binary files /dev/null and b/src/chesspp/res/bK.png differ diff --git a/src/chesspp/res/bN.png b/src/chesspp/res/bN.png new file mode 100644 index 0000000..e31a6d0 Binary files /dev/null and b/src/chesspp/res/bN.png differ diff --git a/src/chesspp/res/bP.png b/src/chesspp/res/bP.png new file mode 100644 index 0000000..afa0c9d Binary files /dev/null and b/src/chesspp/res/bP.png differ diff --git a/src/chesspp/res/bQ.png b/src/chesspp/res/bQ.png new file mode 100644 index 0000000..4649bb8 Binary files /dev/null and b/src/chesspp/res/bQ.png differ diff --git a/src/chesspp/res/bR.png b/src/chesspp/res/bR.png new file mode 100644 index 0000000..c7eb127 Binary files /dev/null and b/src/chesspp/res/bR.png differ diff --git a/src/chesspp/res/index.html b/src/chesspp/res/index.html new file mode 100644 index 0000000..e73b4fb --- /dev/null +++ b/src/chesspp/res/index.html @@ -0,0 +1,43 @@ + + + +ChessPP + + + + + + + + + + +
+ + + + + + + diff --git a/src/chesspp/res/wB.png b/src/chesspp/res/wB.png new file mode 100644 index 0000000..70e0e14 Binary files /dev/null and b/src/chesspp/res/wB.png differ diff --git a/src/chesspp/res/wK.png b/src/chesspp/res/wK.png new file mode 100644 index 0000000..bbf5664 Binary files /dev/null and b/src/chesspp/res/wK.png differ diff --git a/src/chesspp/res/wN.png b/src/chesspp/res/wN.png new file mode 100644 index 0000000..237250c Binary files /dev/null and b/src/chesspp/res/wN.png differ diff --git a/src/chesspp/res/wP.png b/src/chesspp/res/wP.png new file mode 100644 index 0000000..5f9315c Binary files /dev/null and b/src/chesspp/res/wP.png differ diff --git a/src/chesspp/res/wQ.png b/src/chesspp/res/wQ.png new file mode 100644 index 0000000..c3dfc15 Binary files /dev/null and b/src/chesspp/res/wQ.png differ diff --git a/src/chesspp/res/wR.png b/src/chesspp/res/wR.png new file mode 100644 index 0000000..cc69760 Binary files /dev/null and b/src/chesspp/res/wR.png differ diff --git a/src/chesspp/web.py b/src/chesspp/web.py new file mode 100644 index 0000000..e828175 --- /dev/null +++ b/src/chesspp/web.py @@ -0,0 +1,79 @@ +import os +import asyncio +import aiohttp +from aiohttp import web + +import chess +from chesspp import engine + +_DIR = os.path.abspath(os.path.dirname(__file__)) +_INDEX = os.path.join(_DIR, "res/index.html") + +def load_index(): + with open(_INDEX, 'r') as fp: + return fp.read() + + +index_data = load_index() + +async def handle_index(request): + #raise web.HTTPFound('/index.html') + return web.Response(text=load_index(), content_type='text/html') + +class Simulate: + def __init__(self): + self.white = engine.ClassicMctsEngine(chess.WHITE) + self.black = engine.ClassicMctsEngine(chess.BLACK) + + def run(self): + board = chess.Board() + + is_white_playing = True + while not board.is_game_over(): + play_result = self.white.play(board) if is_white_playing else self.black.play(board) + yield play_result.move + board.push(play_result.move) + is_white_playing = not is_white_playing + + +async def websocket_handler(request): + ws = web.WebSocketResponse() + await ws.prepare(request) + + async def wait_msg(): + async for msg in ws: + if msg.type == aiohttp.WSMsgType.TEXT: + if msg.data == 'close': + await ws.close() + elif msg.type == aiohttp.WSMsgType.ERROR: + print(f'ws connection closed with exception {ws.exception()}') + + async def turns(): + runner = Simulate().run() + def sim(): + return next(runner, None) + + turn = await asyncio.to_thread(sim) + while turn is not None: + await ws.send_str(turn.uci()) + turn = await asyncio.to_thread(sim) + + async with asyncio.TaskGroup() as tg: + tg.create_task(wait_msg()) + tg.create_task(turns()) + + print('websocket connection closed') + + return ws + + +app = web.Application() +app.add_routes([ + web.get('/', handle_index), + #web.static('/', os.path.join(_DIR, 'res')), + web.static('/img/chesspieces/wikipedia/', os.path.join(_DIR, 'res')), + web.get('/ws', websocket_handler), +]) + +if __name__ == '__main__': + web.run_app(app)