txlyre 22 hours ago
parent
commit
29fe84ca80
2 changed files with 54 additions and 2 deletions
  1. 25 2
      chess0.py
  2. 29 0
      commands.py

+ 25 - 2
chess0.py

@@ -51,6 +51,26 @@ class ChessSession:
 
         self.check_game_over()
 
+    def from_moves(self, moves):
+        self.board.reset()
+
+        moves = moves.strip().split(" ")
+        if len(moves) > 2048 or len(moves) % 2 != 0:
+            raise IllegalMove
+
+        for move in moves:
+            try:
+                move = chess.Move.from_uci(move)
+            except chess.InvalidMoveError:
+                raise IllegalMove(move)
+
+            if move not in self.board.legal_moves:
+                raise IllegalMove(move)
+
+            self.board.push(move)
+
+            self.check_game_over()
+
     def skip(self):
         self.board.push(chess.Move.null())
         self.move_ts = time.time()
@@ -73,7 +93,7 @@ class ChessManager:
             ):
                 await self.end(id)
 
-    async def begin(self, id):
+    async def begin(self, id, moves=None):
         if id in self.sessions:
             await self.end(id)
 
@@ -82,6 +102,9 @@ class ChessManager:
 
         self.sessions[id] = ChessSession(self.engine)
 
+        if moves is not None:
+            self.sessions[id].from_moves(moves)
+
     async def end(self, id):
         session = self.sessions.get(id)
         if not session:
@@ -172,4 +195,4 @@ class ChessManager:
         else:
             moves = session.board.move_stack
 
-        return " ".join(map(lambda m: "пропуск" if m == chess.Move.null() else str(m), moves))
+        return " ".join(map(str, moves))

+ 29 - 0
commands.py

@@ -658,6 +658,34 @@ async def chess_start_handler(chess, id):
     return [svg2png(chess.svg(id))]
 
 
+async def chess_from_handler(chess, id, moves):
+    try:
+        await chess.begin(id, moves)
+    except GameOver as e:
+        board = svg2png(chess.svg(id))
+
+        await chess.end(id)
+
+        return [
+            board,
+            f"Конец игры: {str(e)}",
+        ]
+    except IllegalMove as e:
+        move = str(e)
+
+        if move:
+            return [f"Некорректный ход: {move}"]
+
+        return ["Некорректный последовательность ходов."]
+
+    reply = [svg2png(chess.svg(id))]
+
+    if chess.is_check(id):
+        reply.append("Шах!")
+
+    return reply
+
+
 async def chess_stop_handler(chess, id):
     if await chess.end(id):
         return ["Игра завершена."]
@@ -784,6 +812,7 @@ async def chess_moves_handler(chess, id):
 
 CHESS_COMMANDS = {
     "start": (chess_start_handler, "Начать новую игру", 0),
+    "from": (chess_from_handler, "Начать новую игру с доской в указанном состоянии", 1),
     "end": (chess_stop_handler, "Завершить игру", 0),
     "move": (chess_move_handler, "Сделать ход", 1),
     "undo": (chess_undo_handler, "Отменить ход", 0),