Ejemplo n.º 1
0
def test_winning_condition():
    board = [[1, 1337, 2], [69, 13, 42], [4, 2, 0]]
    res = game.check_win_condition(board, 1337)
    assert (res == True)
    res = game.check_win_condition(board, 1336)
    assert (res == True)
    res = game.check_win_condition(board, 1338)
    assert (res == False)
Ejemplo n.º 2
0
def game_move(match_id: str, token: str, card_name: str,
              move: str) -> CommandResponse:
    object_id = ObjectId(match_id)
    match = matches.find_one({"_id": object_id})
    if match is None:
        return error_msg("Match not found", "move", match_id)
    if match["gameState"] == GameState.ENDED.value:
        return error_msg("Game ended", "move", match_id)

    if token == match["tokenBlue"]:
        colour = "blue"
    elif token == match["tokenRed"]:
        colour = "red"
    else:
        return error_msg("Token is incorrect", "move", match_id)

    if move[0] not in "abdce" or move[1] not in "12345" or move[
            2] not in "abcde" or move[3] not in "12345":
        move = "none"
    if card_name not in ALL_BASE_CARD_NAMES:
        card_name = "none"
    if move == "none" or card_name == "none":
        return error_msg("'move' or 'card' not given properly", "move",
                         match_id)

    board = str_to_board(match["board"])
    piece_pos = notation_to_pos(move[:2])

    if board[piece_pos.y][piece_pos.x].colour.value != colour:
        return error_msg("Cannot move opponent's pieces or empty squares",
                         "move", match_id)

    move_pos = notation_to_pos(move[2:])
    move_card = get_card_from_name(card_name)
    cards = get_cards_from_names(match["cards"][colour])
    new_board: Optional[Board] = apply_move(piece_pos, move_pos, move_card,
                                            cards, board)

    if new_board is None:
        return error_msg("Invalid move", "move", match_id)

    winner = check_win_condition(new_board)
    state = GameState.ENDED.value if winner != Player.NONE else GameState.IN_PROGRESS.value

    moves = match["moves"]
    moves.append(f"{card_name}:{move}")
    side_card: str = match["cards"]["side"]
    new_cards: List[str] = match["cards"][colour]
    new_cards[new_cards.index(card_name)] = side_card

    enemy = "red" if colour == "blue" else "blue"
    enemy_cards = match["cards"][enemy]

    matches.find_one_and_update({"_id": object_id}, {
        "$set": {
            "board": board_to_str(new_board),
            "moves": moves,
            "currentTurn": "blue" if colour == "red" else "red",
            "cards": {
                enemy: enemy_cards,
                colour: new_cards,
                "side": card_name
            },
            "gameState": state,
            "winner": winner.value
        }
    })

    return {"messageType": "move", "matchId": match_id}
Ejemplo n.º 3
0
    def apply_command(matches: Collection, query: str) -> List[Message]:
        # Command format: move [match_id] [token] [card] [move]
        # Example: move 5f9c394ee71e1740c218587b iq2V39W9WNm0EZpDqEcqzoLRhSkdD3lY boar a1a2
        split = query.split(" ")
        match_id, token, card_name, move = split

        check: Union[Message,
                     ObjectId] = Command.check_match_id(match_id, "move")
        if isinstance(check, Message):
            return [check]

        object_id = check
        match = matches.find_one({"_id": object_id})
        if match is None:
            return [Command.error_msg("Match not found", "move", match_id)]
        if match["gameState"] == GameState.ENDED.value:
            return [Command.error_msg("Game ended", "move", match_id)]

        if token == match["tokenBlue"]:
            color = "blue"
        elif token == match["tokenRed"]:
            color = "red"
        else:
            return [Command.error_msg("Token is incorrect", "move", match_id)]

        if move[0] not in "abdce" or move[1] not in "12345" or move[
                2] not in "abcde" or move[3] not in "12345":
            move = "none"
        if card_name not in ALL_BASE_CARD_NAMES:
            card_name = "none"
        if move == "none" or card_name == "none":
            return [
                Command.error_msg("'move' or 'card' not given properly",
                                  "move", match_id)
            ]

        board = str_to_board(match["board"])
        piece_pos = notation_to_pos(move[:2])

        if match["currentTurn"] != color:
            return [
                Command.error_msg("Cannot move when it is not your turn",
                                  "move", match_id)
            ]

        if board[piece_pos.y][piece_pos.x].color.value != color:
            return [
                Command.error_msg(
                    "Cannot move opponent's pieces or empty squares", "move",
                    match_id)
            ]

        move_pos = notation_to_pos(move[2:])
        move_card = get_card_from_name(card_name)
        cards = get_cards_from_names(match["cards"][color])
        new_board: Optional[Board] = apply_move(piece_pos, move_pos, move_card,
                                                cards, board)

        if new_board is None:
            return [Command.error_msg("Invalid move", "move", match_id)]

        winner = check_win_condition(new_board)
        state = GameState.ENDED.value if winner != Player.NONE else GameState.IN_PROGRESS.value

        moves = match["moves"]
        moves.append(f"{card_name}:{move}")
        side_card: str = match["cards"]["side"]
        new_cards: List[str] = match["cards"][color]
        new_cards[new_cards.index(card_name)] = side_card

        enemy = "red" if color == "blue" else "blue"
        enemy_cards = match["cards"][enemy]

        matches.find_one_and_update({"_id": object_id}, {
            "$set": {
                "board": board_to_str(new_board),
                "moves": moves,
                "currentTurn": "blue" if color == "red" else "red",
                "cards": {
                    enemy: enemy_cards,
                    color: new_cards,
                    "side": card_name
                },
                "gameState": state,
                "winner": winner.value
            }
        })

        return [
            Message({
                "messageType": "move",
                "matchId": match_id
            }, True, match_id),
            Message(
                Command.generate_state_dict(
                    matches.find_one({"_id": object_id})),  # type: ignore
                False,
                match_id)
        ]