def check_escape(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2]: if node.board().is_check() or util.is_capture(node): return False if node.parent.board().legal_moves.count() < 3: return False if node.parent.board().is_check(): return True return False
def intermezzo(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2][1:]: if util.is_capture(node): capture_move = node.move capture_square = node.move.to_square op_node = node.parent assert isinstance(op_node, ChildNode) prev_pov_node = node.parent.parent assert isinstance(prev_pov_node, ChildNode) if not op_node.move.from_square in prev_pov_node.board().attackers(not puzzle.pov, capture_square): if prev_pov_node.move.to_square != capture_square: prev_op_node = prev_pov_node.parent assert isinstance(prev_op_node, ChildNode) return ( prev_op_node.move.to_square == capture_square and util.is_capture(prev_op_node) and capture_move in prev_op_node.board().legal_moves ) return False
def defensive_move(puzzle: Puzzle) -> bool: # like quiet_move, but on last move # at least 3 legal moves if puzzle.mainline[-2].board().legal_moves.count() < 3: return False node = puzzle.mainline[-1] # no check given, no piece taken if node.board().is_check() or util.is_capture(node): return False # no piece attacked if util.attacked_opponent_pieces(node.board(), node.move.to_square, puzzle.pov): return False # no advanced pawn push return not util.is_advanced_pawn_move(node)
def x_ray(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2][1:]: if not util.is_capture(node): continue prev_op_node = node.parent assert isinstance(prev_op_node, ChildNode) if prev_op_node.move.to_square != node.move.to_square or util.moved_piece_type(prev_op_node) == KING: continue prev_pl_node = prev_op_node.parent assert isinstance(prev_pl_node, ChildNode) if prev_pl_node.move.to_square != prev_op_node.move.to_square: continue if prev_op_node.move.from_square in SquareSet.between(node.move.from_square, node.move.to_square): return True return False
def discovered_attack(puzzle: Puzzle) -> bool: if discovered_check(puzzle): return True for node in puzzle.mainline[1::2][1:]: if util.is_capture(node): between = SquareSet.between(node.move.from_square, node.move.to_square) assert isinstance(node.parent, ChildNode) if node.parent.move.to_square == node.move.to_square: return False prev = node.parent.parent assert isinstance(prev, ChildNode) if ( prev.move.from_square in between and node.move.to_square != prev.move.to_square and node.move.from_square != prev.move.to_square and not util.is_castling(prev) ): return True return False
def quiet_move(puzzle: Puzzle) -> bool: for node in puzzle.mainline: if ( # on player move, not the last move of the puzzle node.turn() != puzzle.pov and not node.is_end() and # no check given or escaped not node.board().is_check() and not node.parent.board().is_check() and # no capture made or threatened not util.is_capture(node) and not util.attacked_opponent_pieces(node.board(), node.move.to_square, puzzle.pov) and # no advanced pawn push not util.is_advanced_pawn_move(node) and util.moved_piece_type(node) != KING ): return True return False
def side_attack(puzzle: Puzzle, corner_file: int, king_files: List[int], nb_pieces: int) -> bool: back_rank = 7 if puzzle.pov else 0 init_board = puzzle.mainline[0].board() king_square = init_board.king(not puzzle.pov) if ( not king_square or square_rank(king_square) != back_rank or square_file(king_square) not in king_files or len(init_board.piece_map()) < nb_pieces or not any(node.board().is_check() for node in puzzle.mainline[1::2]) # no endgames ): return False score = 0 corner = chess.square(corner_file, back_rank) for node in puzzle.mainline[1::2]: corner_dist = square_distance(corner, node.move.to_square) if node.board().is_check(): score += 1 if util.is_capture(node) and corner_dist <= 3: score += 1 elif corner_dist >= 5: score -= 1 return score >= 2