txlyre 15 hours ago
parent
commit
d6a3b9eed3
2 changed files with 62 additions and 11 deletions
  1. 31 11
      chess0.py
  2. 31 0
      commands.py

+ 31 - 11
chess0.py

@@ -14,6 +14,20 @@ class IllegalMove(Exception):
     pass
     pass
 
 
 
 
+def board2svg(board, size=256, shallow=False):
+    arrows = []
+    if board.move_stack and board.move_stack[-1] != chess.Move.null():
+        arrows.append((board.move_stack[-1].from_square, board.move_stack[-1].to_square))
+
+        if not shallow and len(board.move_stack) > 1 and board.move_stack[-2] != chess.Move.null():
+            arrows.append((board.move_stack[-2].from_square, board.move_stack[-2].to_square))
+          
+    if board.is_check():
+        return chess.svg.board(board, orientation=board.turn, size=size, arrows=arrows, fill={checker: "#cc0000cc" for checker in board.checkers()}, check=board.king(board.turn))
+
+    return chess.svg.board(board, orientation=board.turn, size=size, arrows=arrows)
+
+
 class ChessSession:
 class ChessSession:
     def __init__(self, engine):
     def __init__(self, engine):
         self.engine = engine
         self.engine = engine
@@ -163,17 +177,7 @@ class ChessManager:
         if not session:
         if not session:
             raise KeyError(id)
             raise KeyError(id)
 
 
-        arrows = []
-        if session.board.move_stack and session.board.move_stack[-1] != chess.Move.null():
-            arrows.append((session.board.move_stack[-1].from_square, session.board.move_stack[-1].to_square))
-
-            if not shallow and len(session.board.move_stack) > 1 and session.board.move_stack[-2] != chess.Move.null():
-                arrows.append((session.board.move_stack[-2].from_square, session.board.move_stack[-2].to_square))
-          
-        if session.board.is_check():
-            return chess.svg.board(session.board, orientation=session.board.turn, size=size, arrows=arrows, fill={checker: "#cc0000cc" for checker in session.board.checkers()}, check=session.board.king(session.board.turn))
-
-        return chess.svg.board(session.board, orientation=session.board.turn, size=size, arrows=arrows)
+        return board2svg(session.board, size=size, shallow=shallow)
 
 
     def ascii(self, id):
     def ascii(self, id):
         session = self.sessions.get(id)
         session = self.sessions.get(id)
@@ -215,3 +219,19 @@ class ChessManager:
 
 
         return session.board.turn
         return session.board.turn
 
 
+    def animate(self, id, count=2, size=256, shallow=False):
+        session = self.sessions.get(id)
+        if not session:
+            raise KeyError(id)
+
+        board = chess.Board()
+        frames = []
+
+        frames.append(board2svg(board, size=size, shallow=shallow))
+
+        for move in session.board.move_stack:
+            board.push(move)
+
+            frames.append(board2svg(board, size=size, shallow=shallow))
+
+        return frames

+ 31 - 0
commands.py

@@ -14,6 +14,8 @@ from aiohttp import ClientSession
 from emoji import is_emoji
 from emoji import is_emoji
 from cairosvg import svg2png
 from cairosvg import svg2png
 
 
+from PIL import Image
+
 from actions import (
 from actions import (
     find_action,
     find_action,
     create_action,
     create_action,
@@ -837,6 +839,32 @@ async def chess_moves_handler(chess, id):
     return [text]
     return [text]
 
 
 
 
+async def chess_anim_handler(chess, id, count):
+    try:
+        count = int(count)
+
+        if count < 2:
+            raise ValueError
+    except Exception:
+        return ["Некорректное значение аргумента."]
+
+    try:
+        frames = chess.animate(id, shallow=isinstance(id, str))
+    except KeyError:
+        return ["Нет активной игры."]
+
+    if not frames:
+        return ["Ходов ещё не сделано."]
+
+    frames = list(map(lambda f: Image.open(BytesIO(svg2png(f))), frames))
+    
+    buffer = BytesIO()
+    buffer.name = "board.gif"
+    frames[0].save(fp=buffer, format="GIF", append_images=frames[1:], save_all=True, duration=500, loop=0)
+    buffer.seek(0)
+
+    return [buffer.read()]
+
 CHESS_COMMANDS = {
 CHESS_COMMANDS = {
     "start": (chess_start_handler, "Начать новую игру", 0),
     "start": (chess_start_handler, "Начать новую игру", 0),
     "from": (chess_from_handler, "Начать новую игру с доской в указанном состоянии", 1, True),
     "from": (chess_from_handler, "Начать новую игру с доской в указанном состоянии", 1, True),
@@ -850,6 +878,8 @@ CHESS_COMMANDS = {
 
 
     "create": (chess_start_handler, "Создать общую доску", 0),
     "create": (chess_start_handler, "Создать общую доску", 0),
     "createfrom": (chess_from_handler, "Создать общую доску в указанном состоянии", 1, True),
     "createfrom": (chess_from_handler, "Создать общую доску в указанном состоянии", 1, True),
+
+    "anim": (chess_anim_handler, "Создать анимацию последних N ходов", 1),
 }
 }
 
 
 CHESS_ALIASES = {
 CHESS_ALIASES = {
@@ -864,6 +894,7 @@ CHESS_ALIASES = {
     "i": "moves",
     "i": "moves",
     "c": "create",
     "c": "create",
     "cf": "createfrom",
     "cf": "createfrom",
+    "a": "anim",
 }
 }