def clearance(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2][1:]: board = node.board() if not node.parent.board().piece_at(node.move.to_square): piece = board.piece_at(node.move.to_square) if piece and piece.piece_type in util.ray_piece_types: prev = node.parent.parent assert prev prev_move = prev.move assert prev_move assert isinstance(node.parent, ChildNode) if (not prev_move.promotion and prev_move.to_square != node.move.from_square and prev_move.to_square != node.move.to_square and not node.parent.board().is_check() and (not board.is_check() or util.moved_piece_type(node.parent) != KING)): if (prev_move.from_square == node.move.to_square or prev_move.from_square in SquareSet.between( node.move.from_square, node.move.to_square)): if prev.parent and not prev.parent.board().piece_at( prev_move.to_square) or util.is_in_bad_spot( prev.board(), prev_move.to_square): return True return False
def skewer(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2][1:]: prev = node.parent assert isinstance(prev, ChildNode) capture = prev.board().piece_at(node.move.to_square) if capture and util.moved_piece_type( node ) in util.ray_piece_types and not node.board().is_checkmate(): between = SquareSet.between(node.move.from_square, node.move.to_square) op_move = prev.move assert op_move if (op_move.to_square == node.move.to_square or not op_move.from_square in between): continue if (util.king_values[util.moved_piece_type(prev)] > util.king_values[capture.piece_type] and util.is_in_bad_spot(prev.board(), node.move.to_square)): return True return False
def fork(puzzle: Puzzle) -> bool: for node in puzzle.mainline[1::2][:-1]: if util.moved_piece_type(node) is not KING: board = node.board() if util.is_in_bad_spot(board, node.move.to_square): continue nb = 0 for (piece, square) in util.attacked_opponent_squares( board, node.move.to_square, puzzle.pov): if piece.piece_type == PAWN: continue if (util.king_values[piece.piece_type] > util.king_values[util.moved_piece_type(node)] or (util.is_hanging(board, piece, square) and square not in board.attackers( not puzzle.pov, node.move.to_square))): nb += 1 if nb > 1: return True return False