예제 #1
0
 def test_winner_2(self):
     """Get the winner."""
     board = Board([[1, 2, 3, 4, 3, 2]],
                   workers={
                       self.workers[0]: (0, 0),
                       self.workers[2]: (0, 1)
                   })
     self.assertFalse(rulechecker.get_winner(board))
     board.move_worker(self.workers[2], Direction.EAST)
     self.assertEqual(rulechecker.get_winner(board), "player2")
예제 #2
0
    def _play_game(self, players):
        """ Plays a game out and returns the result of the game.
        :param list players: List of two Uuids in order of who goes first
        :rtype tuple(PlayerResult, Uuid): the result of the game
        """
        # start phase
        for player in players:
            player_guard = self.uuids_to_player[player]
            try:
                player_guard.start_of_game()
            except PlayerError:
                return (PlayerResult.NEFARIOUS, player)
        # placement phase
        for worker_num in range(Worker.NUM_WORKERS):
            for player in players:
                current_player_guard = self.uuids_to_player[player]
                place_result = self._place_worker(current_player_guard)
                if place_result is PlayerResult.OK:
                    continue
                else:
                    return (place_result, player)
        # play phase
        id_and_players = zip(players, [self.uuids_to_player[player] for player in players])
        for player_uuid, player in itertools.cycle(id_and_players):
            turn_result = self._play_turn(player)
            if turn_result is PlayerResult.OK:
                continue
            else:
                return (turn_result, player_uuid)

            workers = [w for w in self.board.workers if w.player == player_uuid]
            if rulechecker.is_game_over(copy.deepcopy(self.board), workers):
                return (PlayerResult.OK, rulechecker.get_winner(self.board))
예제 #3
0
 def test_winner_move_no_build(self):
     board = Board(
         [[0, 0, 1, 0], [0, 4, 4], [4, 4]],
         workers={
             self.workers[0]: (0, 0),
             self.workers[1]: (1, 0),
             self.workers[2]: (0, 1),
             self.workers[3]: (0, 3)
         })
     self.assertEqual(rulechecker.get_winner(board), "player2")
예제 #4
0
 def test_winner_lock_in(self):
     board = Board(
         [[0, 1, 3, 4, 3, 0], [1, 2, 4, 4, 4, 3]],
         workers={
             self.workers[0]: (0, 0),
             self.workers[1]: (0, 5),
             self.workers[2]: (1, 0),
             self.workers[3]: (0, 1)
         })
     self.assertEqual(rulechecker.get_winner(board), "player2")
예제 #5
0
    def do_survive(board,
                   pname,
                   depth,
                   worker=None,
                   move_dir=None,
                   build_dir=None):
        """Given a game state, and a look-ahead depth and an
        optional turn, return whether or not the given player name
        survives up to the depth number of rounds.

        :param Board board: A game board
        :param str pname: A player name
        :param int depth: the number of look-ahead rounds
        :param Worker worker: an optional worker to move and/or build
        :param Direction move_dir: The direction to move the given
                                   worker if a worker was given
        :param Direction build_dir: An optional direction the worker builds in
        :rtype bool: if we survived depth number of rounds
        """
        copied_board = copy.deepcopy(board)
        if move_dir:
            copied_board.move_worker(worker, move_dir)
            if build_dir:
                copied_board.build_floor(worker, build_dir)
            else:
                # if there's no build, you must win this turn
                return rulechecker.get_winner(copied_board) == pname

        checkwin = rulechecker.get_winner(copied_board)
        if checkwin == pname:
            # if we won, we survived
            logger.info(
                str(pname) + " won a case Board:" + str(board) + " at Depth:" +
                str(depth))
            depth -= 1
            return True
        elif checkwin:
            logger.info(
                str(pname) + " won a case Board:" + str(board) + " at Depth:" +
                str(depth))
            # if we lost, we died
            return False

        # base case, if there's no winner, we survived
        if depth == 0:
            logger.info("player" + pname + "lived with this move:" +
                        str(copied_board) + " depth:" + str(depth))
            return not rulechecker.get_winner(copied_board)

        # recursive case
        opp_workers = [w for w in copied_board.workers if pname != w.player]
        our_workers = [w for w in copied_board.workers if pname == w.player]
        enemy_turns = TreeStrategy.next_turn(opp_workers, copied_board)
        viable_move = False
        if move_dir:
            for enemy_worker, enemy_move, enemy_build in enemy_turns:
                next_board = copy.deepcopy(copied_board)
                next_board.move_worker(enemy_worker, enemy_move)
                if enemy_build:
                    next_board.build_floor(enemy_worker, enemy_build)
                winner = rulechecker.get_winner(next_board)
                if (winner and winner != pname):
                    #enemy found a way to kill you on their move, return False
                    logger.info("player " + str(winner) +
                                " kills with this move:" + str(next_board) +
                                " depth:" + str(depth))
                    return False

                if depth > 1:
                    our_turns = TreeStrategy.next_turn(our_workers, next_board)
                    safe = False
                    # check that we have a safe move
                    for our_worker, our_move, our_build in our_turns:
                        if TreeStrategy.do_survive(next_board,
                                                   pname,
                                                   depth - 2,
                                                   worker=our_worker,
                                                   move_dir=our_move,
                                                   build_dir=our_build):
                            logger.info("player " + str(pname) +
                                        " survived with this move:" +
                                        str(next_board) + " depth:" +
                                        str(depth))
                            continue
                        else:
                            safe = True
                            break
                    if safe:
                        viable_move = True
            # fell through
            # if depth was 1, that means that we were checking if the enemy could kill us, and if so that means this should
            # be True cause they failed to kill us
            # if depth was 2 or more that means searching for more moves failed, and we died
            logger.info("player " + str(pname) + " depth:" + str(depth) +
                        " viable_move" + str(viable_move))
            return depth < 2 or viable_move
        else:
            our_turns = TreeStrategy.next_turn(our_workers, copied_board)
            for our_worker, our_move, our_build in our_turns:
                if TreeStrategy.do_survive(copied_board,
                                           pname,
                                           depth - 2,
                                           worker=our_worker,
                                           move_dir=our_move,
                                           build_dir=our_build):
                    logger.info("player " + str(pname) +
                                " survived with this move:" +
                                str(copied_board) + " depth:" + str(depth))
                    return True
            logger.info("player " + str(pname) +
                        " can't survive with this board:" + str(copied_board) +
                        " depth:" + str(depth))
            return False
예제 #6
0
 def test_no_winner(self):
     """Get the winner."""
     board = Board(workers={self.workers[0]: (0, 2)})
     self.assertFalse(rulechecker.get_winner(board))
예제 #7
0
 def test_winner_1(self):
     """Get the winner."""
     board = Board([[0, 0, 3, 0, 0, 0]], workers={self.workers[0]: (0, 2)})
     self.assertEqual(rulechecker.get_winner(board), "player1")