Esempio n. 1
0
def optimal_stalemate(pos1, pos2, pos3):
    """
    Returns the least amount of goats required to stalemate the tigers and the
    board at the end of the game
    """

    # Clear Board
    board = Board()

    board.place_tiger(pos1)
    board.place_tiger(pos2)
    board.place_tiger(pos3)

    tiger_positions = pos1, pos2, pos3

    positions = board.positions

    for tiger_addr in tiger_positions:

        tiger_pos = board.get_pos(tiger_addr)
        tiger: Tiger = tiger_pos.piece

        # place goats in all positions adjacent to the tiger
        for adj_pos in tiger_pos.get_adjacent_positions():
            if adj_pos.is_empty():
                adj_pos.place_goat()

        # place goats in all capturing positions
        for capturing_addr in tiger.get_capturing_moves():
            board.place_goat(capturing_addr)

    num_goats = board.num_pieces()[1]

    return num_goats, board
Esempio n. 2
0
def edit_distance(board: Board) -> int:
    # Determines the edit distance between the board positions and the stalemate positions
    # input: board positions
    # return: edit distance value

    tigers = board.get_all_tiger_positions()
    numGoats = len(board.get_all_goat_positions())

    _, stalemate_board = optimal_stalemate(tigers[0].address,
                                           tigers[1].address,
                                           tigers[2].address)
    # _, stalematePositions = stalemate(tigers[0], tigers[1], tigers[2])
    possible_pos = board.get_all_addresses()
    # Initializing Bipartite graph
    B = nx.Graph()
    B.add_nodes_from(list(range(23)), bipartite=0)
    B.add_nodes_from(possible_pos, bipartite=1)

    # Populate graph
    for i, pos in enumerate(possible_pos):
        for stalematePos in stalemate_board.get_all_positions():

            # print('DEBUG: pos ', pos, ' stalematePos ',stalematePos)
            # print('DEBUG: possible_pos[pos] ', boardPosition[possible_pos[pos]], ' stalematePositions[stalematePos] ', stalematePositions[stalematePos])
            # print('DEBUG: pos ', possible_pos[pos], ' stalematePos ',stalematePos)
            # print(10 - num_moves(pos,stalematePos))
            if (board.get_pos(stalematePos.address).is_goat()
                    and stalematePos.is_goat()):

                # print('stalematePos',stalematePos, 'weight',10 - num_moves(possible_pos[pos],stalematePos))
                B.add_edge(
                    i,
                    stalematePos,
                    weight=-10 + num_moves(pos, stalematePos.address),
                )
            # elif boardPosition[possible_pos[pos]] == stalematePositions[stalematePos] and possible_pos[pos] == stalematePos:
            #     B.add_edge(pos,stalematePos, weight = -1e20)
            else:
                B.add_edge(i, stalematePos.address, weight=1e20)

    # Bipartite Max Matching
    # print(B.edges(data=True))

    maxMatching = bipartite.minimum_weight_full_matching(B)
    # print(maxMatching)
    Sum = 0
    # Collect sum of weights
    n = 0
    for key, item in maxMatching.items():
        if n == 23:
            break
        # # print(B.get_edge_data(key,item)['weight'])
        if board.get_pos(possible_pos[key]).is_goat():
            Sum = Sum + num_moves(possible_pos[key], item)
        # print(Sum)
        n = n + 1

    return Sum
Esempio n. 3
0
def get_optimal_stalemate(pos1: str, pos2: str, pos3: str) -> Board:
    """
    Returns the least amount of goats required to stalemate the tigers and the
    board at the end of the game
    """

    # create a new board
    board = Board()

    # start by placing the three tigers
    board.place_tiger(pos1)
    board.place_tiger(pos2)
    board.place_tiger(pos3)

    tigers = board.get_all_tigers()

    positions = board.positions

    # first pass: place goats in all positions adjacent to the tigers
    for tiger in tigers:

        # place goats in all positions adjacent to the tiger
        for adj_pos in tiger.pos.get_adjacent_positions():
            if adj_pos.is_empty():
                adj_pos.place_goat()

    # second pass: place goats to block all capturing moves
    for tiger in tigers:

        # place goats in all capturing positions
        for capturing_addr in tiger.get_capturing_moves():
            board.place_goat(capturing_addr)

    return board
Esempio n. 4
0
def compute_tiger_move(board: Board) -> Optional[tuple]:
    """Compute a move as the Tiger.

    If a move was found, a tuple is returned containing the
    start and end positions if a piece needs to be moved,
    or a tuple containing a position if a piece needs to be placed.
    """

    # Randomize tiger positions
    tiger_list = board.get_all_tiger_positions()
    if len(tiger_list) < 3:
        # place tigers
        empty_list = board.get_all_empty_positions()
        empty_pos_choice = random.choice(empty_list)
        return (empty_pos_choice.address, )
    else:
        # move tiger
        if len(board.get_tiger_possible_moves()) == 0:
            return None  # cannot do a move

        move_choice = None

        # try to find a capturing move first
        # XXX: makes it difficult for CPU goats to win
        # for tiger_pos in tiger_list:
        #     capturing_moves = tiger_pos.piece.get_capturing_moves()
        #     if capturing_moves:
        #         tiger_pos_choice = tiger_pos
        #         move_choice = random.choice(capturing_moves)
        #         break

        # find a random move
        while move_choice is None:
            tiger_pos_choice = random.choice(tiger_list)
            valid_moves = tiger_pos_choice.piece.get_valid_moves()
            if valid_moves:
                move_choice = random.choice(valid_moves)

        return (tiger_pos_choice.address, move_choice)
Esempio n. 5
0
    fontSize = 15
    buttonStyle = 30
elif platform == "win32" or platform == "cygwin":
    # Windows
    boardSize = 500
    fontSize = 12
    buttonStyle = 0
elif platform == "linux":
    # Linux
    boardSize = 500
    fontSize = 12
    buttonStyle = 0

boardSize = 500

board = Board()
board.clear()

possible_pos = [
    "a1",
    "a2",
    "a3",
    "b0",
    "b1",
    "b2",
    "b3",
    "b4",
    "c1",
    "c2",
    "c3",
    "c4",
Esempio n. 6
0
def compute_goat_move(board: Board) -> Optional[tuple]:
    """Compute a move as the Goat.

    If a move was found, a tuple is returned containing the
    start and end positions if a piece needs to be moved,
    or a tuple containing a position if a piece needs to be placed.
    """

    # list of goats that are about to be captured
    danger_goats = board.get_tiger_capturing_moves()

    goat_list = board.get_all_goat_positions()
    tiger_list = board.get_all_tiger_positions()

    if len(tiger_list) < 3:
        # skip this turn, wait until all tigers are placed
        return None
    elif not board.is_all_goats_placed:
        # place a goat
        # ------------
        if danger_goats:
            # choose a position that saves a goat
            landing_pos, goat_pos = random.choice(danger_goats)
            pos_choice = landing_pos
        else:
            # try to choose a position that blocks a tiger
            pos_choice = None
            empty_list = board.get_all_empty_positions()

            for pos in empty_list:
                if board.is_pos_blocking(pos.address) and board.is_pos_safe(
                        pos.address):
                    pos_choice = pos
                    break

            # if cannot find a blocking move, choose a random position
            if pos_choice is None:
                pos_choice = random.choice(empty_list)

        if pos_choice:
            return (pos_choice.address, )
        else:
            return None

    else:
        # move goat
        # ---------
        goat_pos_choice = None
        move_choice = None

        if danger_goats:
            # try to move the goat in danger somewhere else
            landing_pos, goat_pos = random.choice(danger_goats)
            goat_pos_choice = goat_pos
            move_choice = random.choice(goat_pos.piece.get_valid_moves())
        else:
            # try to find a safe move
            for goat_pos in goat_list:
                # this goat is blocking a tiger, try to find another one
                if board.is_pos_blocking(goat_pos.address):
                    continue

                for move in goat_pos.piece.get_valid_moves():
                    if board.is_pos_safe(move):
                        goat_pos_choice = goat_pos
                        move_choice = move
                        break

        # if couldn't find a goat yet, pick one at random
        if goat_pos_choice is None:
            goat_pos_choice = random.choice(goat_list)

        # if couldn't find a move yet, pick one at random
        if move_choice is None:
            valid_moves = goat_pos_choice.piece.get_valid_moves()
            if valid_moves:
                move_choice = random.choice(valid_moves)

        if move_choice:
            return (goat_pos_choice.address, move_choice)
        else:
            return None