|  | @@ -39,6 +39,9 @@ class ChessSession:
 | 
	
		
			
				|  |  |          self.ts = time.time()
 | 
	
		
			
				|  |  |          self.move_ts = time.time()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        self.game_over = None
 | 
	
		
			
				|  |  | +        self.checkmate = False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def parse_move(self, move):
 | 
	
		
			
				|  |  |          move = move.strip()
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -50,18 +53,36 @@ class ChessSession:
 | 
	
		
			
				|  |  |          return move
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |      def check_game_over(self):
 | 
	
		
			
				|  |  | +        if self.game_over is not None:
 | 
	
		
			
				|  |  | +            raise self.game_over
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          outcome = self.board.outcome(claim_draw=True)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          if outcome is not None:
 | 
	
		
			
				|  |  | -            raise GameOver(f"{outcome.result()} {outcome.termination.name}")
 | 
	
		
			
				|  |  | +            self.game_over = GameOver(f"{outcome.result()} {outcome.termination.name}")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if outcome.termination == chess.Termination.CHECKMATE:
 | 
	
		
			
				|  |  | +                self.checkmate = True
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            raise self.game_over
 | 
	
		
			
				|  |  |          elif self.board.status() & chess.STATUS_NO_WHITE_KING:
 | 
	
		
			
				|  |  | -            raise GameOver(f"0-1 CHECKMATE")
 | 
	
		
			
				|  |  | +            self.game_over = GameOver(f"0-1 CHECKMATE")
 | 
	
		
			
				|  |  | +            self.checkmate = True
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            raise self.game_over
 | 
	
		
			
				|  |  |          elif self.board.status() & chess.STATUS_NO_BLACK_KING:
 | 
	
		
			
				|  |  | -            raise GameOver(f"1-0 CHECKMATE")
 | 
	
		
			
				|  |  | +            self.game_over = GameOver(f"1-0 CHECKMATE")
 | 
	
		
			
				|  |  | +            self.checkmate = True
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            raise self.game_over
 | 
	
		
			
				|  |  |          elif not self.board.is_valid():
 | 
	
		
			
				|  |  | -            raise GameOver(f"Некорректное состояние доски.")
 | 
	
		
			
				|  |  | +            self.game_over = GameOver(f"1/2-1/2 STALEMATE")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            raise self.game_over
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      async def move(self, move=None):
 | 
	
		
			
				|  |  | +        self.check_game_over(self)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          if move is not None:
 | 
	
		
			
				|  |  |              move = self.parse_move(move)
 | 
	
		
			
				|  |  |          else:
 | 
	
	
		
			
				|  | @@ -105,6 +126,8 @@ class ChessSession:
 | 
	
		
			
				|  |  |              self.check_game_over()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      def skip(self):
 | 
	
		
			
				|  |  | +        self.check_game_over(self)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          self.board.push(chess.Move.null())
 | 
	
		
			
				|  |  |          self.move_ts = time.time()
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -168,6 +191,13 @@ class ChessManager:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          return session.board.is_check()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    def is_checkmate(self, id):
 | 
	
		
			
				|  |  | +        session = self.sessions.get(id)
 | 
	
		
			
				|  |  | +        if not session:
 | 
	
		
			
				|  |  | +            raise KeyError(id)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return session.checkmate
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      async def skip(self, id):
 | 
	
		
			
				|  |  |          session = self.sessions.get(id)
 | 
	
		
			
				|  |  |          if not session:
 |