txlyre 20 hours ago
parent
commit
3bca080e7c
2 changed files with 59 additions and 46 deletions
  1. 22 1
      chess0.py
  2. 37 45
      commands.py

+ 22 - 1
chess0.py

@@ -14,10 +14,24 @@ class IllegalMove(Exception):
     pass
     pass
 
 
 
 
+class MyBoard(chess.Board):
+    def __init__(self):
+        chess.Board.__init__(self)
+
+        self.captured_black = []
+        self.captured_white = []
+
+    def _push_capture(self, move, capture_square, piece_type, was_promoted):
+        if self.turn == chess.WHITE:
+            self.captured_black.push(piece_type)
+        else:
+            self.captured_white.push(piece_type)
+
+
 class ChessSession:
 class ChessSession:
     def __init__(self, engine):
     def __init__(self, engine):
         self.engine = engine
         self.engine = engine
-        self.board = chess.Board()
+        self.board = MyBoard()
 
 
         self.ts = time.time()
         self.ts = time.time()
         self.move_ts = time.time()
         self.move_ts = time.time()
@@ -204,3 +218,10 @@ class ChessManager:
             moves = session.board.move_stack
             moves = session.board.move_stack
 
 
         return " ".join(map(str, moves))
         return " ".join(map(str, moves))
+
+    def captured(self, id):
+        session = self.sessions.get(id)
+        if not session:
+            raise KeyError(id)
+
+        return (session.board.captured_black, session.board.captured_white)

+ 37 - 45
commands.py

@@ -658,18 +658,39 @@ async def chess_start_handler(chess, id):
     return [svg2png(chess.svg(id))]
     return [svg2png(chess.svg(id))]
 
 
 
 
+def chess_game_stats(chess, id):
+    if not chess.has_moves(id):
+        return "Ходов ещё не сделано."
+
+    text = f"Последние два хода: {chess.moves(id, 2)}\nВсе ходы (первый ход - игрока) [{chess.moves_count(id)}]: {chess.moves(id)}"
+
+    if chess.is_check(id):
+        text = f"Шах!\n{text}"
+
+    captured_b, captured_w = chess.captured(id)
+    text += f"\nЗахвачено белых фигур: {len(captured_w)}\nЗахвачено чёрных фигур: {len(captured_b)}"
+
+    return text
+
+
+async def chess_game_over(chess, id, e):
+    board = svg2png(chess.svg(id))
+    stats = chess_game_stats(chess, id)
+
+    await chess.end(id)
+
+    return [
+      board,
+      f"Конец игры: {str(e)}",
+      stats
+    ]
+
+
 async def chess_from_handler(chess, id, moves):
 async def chess_from_handler(chess, id, moves):
     try:
     try:
         await chess.begin(id, moves)
         await chess.begin(id, moves)
     except GameOver as e:
     except GameOver as e:
-        board = svg2png(chess.svg(id))
-
-        await chess.end(id)
-
-        return [
-            board,
-            f"Конец игры: {str(e)}",
-        ]
+        return await chess_game_over(chess, id, e)
     except IllegalMove as e:
     except IllegalMove as e:
         await chess.end(id)
         await chess.end(id)
 
 
@@ -702,14 +723,7 @@ async def chess_move_handler(chess, id, move):
     except KeyError:
     except KeyError:
         return ["Нет активной игры."]
         return ["Нет активной игры."]
     except GameOver as e:
     except GameOver as e:
-        board = svg2png(chess.svg(id))
-
-        await chess.end(id)
-
-        return [
-            board,
-            f"Конец игры: {str(e)}",
-        ]
+        return await chess_game_over(chess, id, e)
     except IllegalMove:
     except IllegalMove:
         return ["Некорректный ход."]
         return ["Некорректный ход."]
 
 
@@ -732,6 +746,7 @@ async def chess_undo_handler(chess, id):
 
 
     return ["Последний ход отменён.", svg2png(chess.svg(id))]
     return ["Последний ход отменён.", svg2png(chess.svg(id))]
 
 
+
 async def chess_skip_handler(chess, id):
 async def chess_skip_handler(chess, id):
     try:
     try:
         await chess.skip(id)
         await chess.skip(id)
@@ -739,17 +754,7 @@ async def chess_skip_handler(chess, id):
     except KeyError:
     except KeyError:
         return ["Нет активной игры."]
         return ["Нет активной игры."]
     except GameOver as e:
     except GameOver as e:
-        board = svg2png(chess.svg(id))
-        moves = chess.moves(id)
-        moves_count = chess.moves_count(id)
-
-        await chess.end(id)
-
-        return [
-            board,
-            f"Конец игры: {str(e)}",
-            f"Ходы (всего {moves_count}, первый ход - игрока): {moves}"
-        ]
+        return await chess_game_over(chess, id, e)
 
 
     reply = [svg2png(chess.svg(id))]
     reply = [svg2png(chess.svg(id))]
 
 
@@ -766,14 +771,7 @@ async def chess_pass_handler(chess, id):
     except KeyError:
     except KeyError:
         return ["Нет активной игры."]
         return ["Нет активной игры."]
     except GameOver as e:
     except GameOver as e:
-        board = svg2png(chess.svg(id))
-
-        await chess.end(id)
-
-        return [
-            board,
-            f"Конец игры: {str(e)}",
-        ]
+        return await chess_game_over(chess, id, e)
 
 
     reply = [svg2png(chess.svg(id))]
     reply = [svg2png(chess.svg(id))]
 
 
@@ -799,17 +797,11 @@ async def chess_board_handler(chess, id):
 
 
 async def chess_moves_handler(chess, id):
 async def chess_moves_handler(chess, id):
     try:
     try:
-        if not chess.has_moves(id):
-            moves = "Ходов ещё не сделано."
-        else:
-            moves = f"Последние два хода: {chess.moves(id, 2)}\nВсе ходы (первый ход - игрока) [{chess.moves_count(id)}]: {chess.moves(id)}"
-
-            if chess.is_check(id):
-                moves = f"Шах!\n{moves}"
+        text = chess_game_stats(chess, id)
     except KeyError:
     except KeyError:
         return ["Нет активной игры."]
         return ["Нет активной игры."]
 
 
-    return [moves]
+    return [text]
 
 
 
 
 CHESS_COMMANDS = {
 CHESS_COMMANDS = {
@@ -820,8 +812,8 @@ CHESS_COMMANDS = {
     "undo": (chess_undo_handler, "Отменить ход", 0),
     "undo": (chess_undo_handler, "Отменить ход", 0),
     "skip": (chess_skip_handler, "Пропустить ход", 0),
     "skip": (chess_skip_handler, "Пропустить ход", 0),
     "pass": (chess_pass_handler, "Сделать ход вместо вас", 0),
     "pass": (chess_pass_handler, "Сделать ход вместо вас", 0),
-    "board": (chess_board_handler, "Показать состояние доски", 0),
-    "moves": (chess_moves_handler, "Показать историю ходов", 0),
+    "board": (chess_board_handler, "Показать доску", 0),
+    "moves": (chess_moves_handler, "Показать историю ходов и состояние игры", 0),
 }
 }
 
 
 CHESS_ALIASES = {
 CHESS_ALIASES = {