コード例 #1
0
 def create_default_game_state(self):
     supply = UnorderedCardStack()
     supply.add(cards=[1])
     supply.add(cards=[2, 2])
     names = ['p1', 'p2']
     logger = TestLogger()
     game_state = GameState(
         player_names=names, supply=supply, starting_deck=[], logger=logger
     )
     game_state.set_agents([TestAgent(name) for name in names])
     return game_state
コード例 #2
0
ファイル: game.py プロジェクト: plough/myPySnake
    def __init__(self):
        pygame.init()

        self.game_state = GameState()  # 当前游戏状态
        self.snake = self._create_snake()  # 蛇

        self.board = GameBoard(self.game_state)  # 画板
        self.board.add_sprite(self.snake)

        self.fps_clock = pygame.time.Clock()  # 控制帧率
        self.direction_lock = SimpleLock()  # 方向锁,防止在一个时钟周期内,连续改变方向,导致撞到蛇身第二节

        pygame.display.set_caption(TITLE)
コード例 #3
0
ファイル: network.py プロジェクト: sillle14/splendor
    def take_turn(self, game_state: GameState) -> Tuple[GameState, int]:
        # First, we need to calculate the outcome of the next game states.
        possible_next_states, _ = game_state.get_possible_moves()
        next_scores = {
            self.feed_forward(state.to_1P_array()): state
            for state in possible_next_states
        }

        best_score = max(next_scores)
        next_score = best_score if (game_state.has_player_won() is None
                                    ) else game_state.has_player_won()
        next_state = next_scores.get(best_score).copy()
        return next_state, next_score
コード例 #4
0
ファイル: network.py プロジェクト: sillle14/splendor
    def run_game(self, game_state: GameState, game_id, debug=False):
        start_time = time.time()
        while not game_state.is_game_over():

            next_state, next_score = self.take_turn(game_state)
            # Back propagate for new weights.
            self.back_propagate(game_state.to_array(), next_score)
            game_state = next_state
            if debug:
                print(f"moved to state with score {best_score}")
        end_time = time.time()
        if debug:
            print(f"Game {game_id} ended with {game_state.has_player_won()}!"
                  f" Turns: {game_state.turns}, Time: {end_time-start_time}s")
        return game_state.has_player_won(), game_state.turns
コード例 #5
0
 def take_turn(self, game_state: GameState):
     # tries to take the turn
     try:
         if self.is_drawing:
             game_state.draw_gems(self.selected_gems)
             self.selected_gems = None
         else:
             (i, j) = self.selected_card
             card = game_state.display[i * 4 + j]
             game_state.buy_card(card)
             self.selected_card = None
         self.exception_text = ""
     except Exception as exc:
         self.exception_text = str(exc)
         self.selected_card = None
         self.selected_gems = None
コード例 #6
0
ファイル: GUI.py プロジェクト: sillle14/splendor
def init(data, names):
    # load data.xyz as appropriate
    data.game = GameState(names)
    data.controller = Controller()
    data.network = Network()

    data.game_list = [data.game]
コード例 #7
0
 def test_create_game_state(self):
     supply = UnorderedCardStack()
     supply.add(cards=[1])
     supply.add(cards=[2, 2])
     names = ['p1', 'p2']
     logger = TestLogger()
     game_state = GameState(
         player_names=names, supply=supply, starting_deck=[], logger=logger
     )
     # Check trash exists
     trash = game_state.get_location(Location(None, LocationName.TRASH))
     self.assertEqual(type(trash), UnorderedCardStack)
     # Check player hands exist
     for name in names:
         hand = game_state.get_location(Location(name, LocationName.HAND))
         self.assertEqual(type(trash), UnorderedCardStack)
コード例 #8
0
 def create_game_state(self, starting_deck, supply):
     starting_deck = starting_deck
     names = ['p1', 'p2']
     logger = NullLogger()
     game_state = GameState(player_names=names,
                            supply=supply,
                            starting_deck=starting_deck,
                            logger=logger)
     return game_state
コード例 #9
0
 def create_game_state(self, starting_deck):
     supply = UnorderedCardStack([VassalCard])
     starting_deck = starting_deck
     names = ['p1', 'p2']
     logger = NullLogger()
     game_state = GameState(player_names=names,
                            supply=supply,
                            starting_deck=starting_deck,
                            logger=logger)
     return game_state
コード例 #10
0
ファイル: network.py プロジェクト: sillle14/splendor
 def run_epoch(self, length, debug=False):
     turns_per_game = []
     for i in trange(length,
                     desc='Training...',
                     unit='game',
                     dynamic_ncols=True,
                     smoothing=0):
         if i % 100 == 0 and i != 0:
             total = len(turns_per_game)
             avg = sum(turns_per_game) / total
             print(
                 f"Games {i-100} to {i} ended with {total} wins in avg of {avg} turns per game."
             )
             self.save_weights()
             turns_per_game = []
         g = GameState(["Michael"])
         result = self.run_game(g, i, debug)
         if result[0]:
             turns_per_game.append(result[1])
     print("End of epoch")
コード例 #11
0
class GameController(object):
    """
    The Game manages the control flow, soliciting actions from Players.
    """
    def __init__(self, players, card_set, log):
        self.players = players  # array of agents
        self.num_players = len(players)
        # all agents need to implement a .name() method
        self.game_state = None
        # Array of cards that kingdom will be chosen from
        self.card_set = card_set
        # Player index = index of player whose turn it is
        self.player_index = 0  # TODO: randomize start player
        self.starting_player_index = self.player_index
        self.log = log

    def get_starting_supply(self):
        """
        - choose 10 kingdom cards from card_set
        - initialize victory card supply
        - initalize treasure supply
        - initialize curse supply if Witch in play
        """
        # TODO cards need hasRandomizer method
        randomizer_cards = [x for x in self.card_set if x.hasRandomizer()]
        num_to_sample = min(NUM_KINGDOM_CARDS, len(self.card_set))
        kingdom_cards = sample(randomizer_cards,
                               num_to_sample) * INITIAL_SUPPLY_COUNT
        treasure_cards = ([GoldCard] * STARTING_GOLD_SUPPLY +
                          [SilverCard] * STARTING_SILVER_SUPPLY +
                          [CopperCard] * STARTING_COPPER_SUPPLY)

        victory_starting_supply = STARTING_VICTORY_CARD_SUPPLY_BY_PLAYER_COUNT[
            self.num_players]
        victory_cards = [[card] * victory_starting_supply
                         for card in [EstateCard, DuchyCard, ProvinceCard]]
        flattened_victory_cards = list(
            itertools.chain.from_iterable(victory_cards))

        curse_starting_supply = STARTING_CURSE_SUPPLY_BY_PLAYER_COUNT[
            self.num_players]
        curse_cards = [CurseCard] * curse_starting_supply
        # TODO: how to handle gardens etc. which depend on num_players
        return UnorderedCardStack(kingdom_cards + treasure_cards +
                                  flattened_victory_cards)

    def get_starting_deck(self):
        return ([CopperCard] * NUM_COPPERS_IN_STARTING_HAND +
                [EstateCard] * NUM_ESTATES_IN_STARTING_HAND)

    def _increment_player_index(self, index):
        next_index = (index + 1) % self.num_players
        return next_index

    def increment_player_turn_index(self):
        next_player = self._increment_player_index(self.player_index)
        self.game_state._current_player_index = next_player
        return next_player

    def actions_left(self):
        return self.game_state.get_counter(CounterId(None,
                                                     CounterName.ACTIONS))

    def buys_left(self):
        return self.game_state.get_counter(CounterId(None, CounterName.BUYS))

    def money_in_play(self):
        return self.game_state.get_counter(CounterId(None, CounterName.COINS))

    def action_cards_in_hand(self, player):
        hand = self.game_state.get_location(
            Location(player.name(), LocationName.HAND))
        return [card for card in hand if CardType.ACTION in card.types]

    def game_over(self):
        supply = self.game_state.get_location(
            Location(None, LocationName.SUPPLY))
        if supply.distribution.count(ProvinceCard) == 0:
            return True
        cards_to_counts = supply.distribution.cards_to_counts()
        if list(cards_to_counts.values()).count(0) >= 3:
            return True
        return False

    def generate_buy_decision(self, player):
        """
        Params:
          player: Player agent object

        Returns:
            BuyDecision with options being all the available
            supply cards that the player can afford
        """
        money = self.money_in_play()
        available_cards = set(
            list(
                self.game_state.get_location(
                    Location(None, LocationName.SUPPLY))))
        affordable_cards = [
            card for card in available_cards
            if card.cost(self.game_state) <= money
        ]
        return BuyDecision(options=affordable_cards, min=0, max=1)

    def generate_action_decision(self, player):
        """
        Params:
          player: Player agent object

        Returns:
            PlayActionDecision with options being all action cards in player's hand
        """
        return PlayActionDecision(options=self.action_cards_in_hand(player),
                                  min=0,
                                  max=1)

    def generate_play_treasures_decision(self, player):
        """
        Params:
          player: Player agent object

        Returns:
            PlayTreasureDecision with options being all treasure cards in player's hand
        """
        hand_stack = self.game_state.get_location(
            Location(player.name(), LocationName.HAND))
        treasures_in_hand = [
            card for card in hand_stack if CardType.TREASURE in card.types
        ]
        return PlayTreasureDecision(options=treasures_in_hand,
                                    min=0,
                                    max=len(treasures_in_hand))

    def take_buy_action(self, player, card):
        """
        Params:
          player_name: string
          card: Card class

        Moves card from supply to player discard pile
        """
        cost = card.cost(self.game_state)
        self.game_state.update_counter(CounterId(None, CounterName.BUYS), -1)
        self.game_state.update_counter(CounterId(None, CounterName.COINS),
                                       0 - cost)
        self.game_state.gain(card)

    def play_treasures(self, player, treasures):
        """
        Params:
          player_name: string
          treasures: array of Card class, must all be treasure type cards

        Moves cards from HAND to IN_PLAY
        Increments COINS counter by the sum of `treasures`
        """
        for treasure in treasures:
            self.game_state.play(treasure)
            treasure.play(self.game_state)

    def player_name_to_vp(self):
        """
        Counts up all players victory points
        Returns: map of player name to VP
        """
        player_name_to_vp = {}
        for player_name in list(map(lambda p: p.name(), self.players)):
            deck = self.game_state.get_deck(player_name)
            victory_points = sum([
                card.victory_points(player_name, self.game_state)
                for card in deck
            ])
            player_name_to_vp[player_name] = victory_points
        return player_name_to_vp

    def give_decision(self, decision, agent):
        """
        Give the agent a decision and return it's choices.
        """
        viewable_state = self.game_state.get_state_known_to(agent.name())
        choices = agent.make_decision(decision, viewable_state)
        return choices

    def get_winner_indices(self, start_turn_index, next_turn_index, scores):
        """
        Returns a list of the indices of the winning players. There can be multiple if there is a tie.

        Parameters:
            start_turn_index (int): The index of the player that started first.
            next_turn_index (int): The index of the player whose turn would be next if the game
                wasn't over.
            scores (list of int): The final score for each player. The score at index i is the
                score for the player at index i.
        """
        top_score = max(scores)
        cur_index = next_turn_index
        players_have_one_less_turn = True
        winners = []
        while True:
            if cur_index == start_turn_index:
                if winners:
                    return winners
                players_have_one_less_turn = False
            if scores[cur_index] == top_score:
                winners.append(cur_index)
            cur_index = self._increment_player_index(cur_index)
            if cur_index == next_turn_index:
                break
        return winners

    def get_winners(self):
        """
        Returns a list of the winning player names.
        """
        player_name_to_vp = self.player_name_to_vp()
        scores = []
        for player in self.players:
            scores.append(player_name_to_vp[player.name()])
        winner_indices = self.get_winner_indices(self.starting_player_index,
                                                 self.player_index, scores)
        winners = [self.players[ind].name() for ind in winner_indices]
        return winners

    def run(self):
        """
        Main control loop for game play
        """
        #################
        # Initialization
        #################

        starting_supply = self.get_starting_supply()
        starting_deck = self.get_starting_deck()
        self.game_state = GameState(
            list(map(lambda x: x.name(), self.players)), starting_supply,
            starting_deck, self.log)
        # TODO: inform Players of initial state for learning agents
        self.game_state.set_agents(self.players)
        for player in self.players:
            # shuffle player decks
            self.game_state.shuffle(
                Location(player.name(), LocationName.DRAW_PILE))
            # draw starting hands
            self.game_state.draw(NUM_CARDS_IN_HAND, player.name())

        #################
        # Gameplay loop
        #################
        turn_number = 1
        while not self.game_over():
            # Fetch the next player
            player = self.players[self.player_index]
            ### Setup Phase
            self.game_state.reset_counters_for_new_turn()

            ### Action phase

            while (self.actions_left() > 0
                   and len(self.action_cards_in_hand(player)) > 0):
                decision = self.generate_action_decision(player)
                choices = self.give_decision(decision, player)
                action_card = choices[0] if choices else None
                # TODO: validate choice legality
                if not action_card:
                    break
                self.game_state.update_counter(
                    CounterId(None, CounterName.ACTIONS), -1)
                self.game_state.play(action_card)
                action_card.play(self.game_state)

            ### Buy phase
            decision = self.generate_play_treasures_decision(player)
            treasures = self.give_decision(decision, player)
            self.play_treasures(player, treasures)

            while self.buys_left() > 0:
                decision = self.generate_buy_decision(player)
                choices = self.give_decision(decision, player)
                choice = choices[0] if choices else None
                # TODO: validate choice legality
                if not choice:
                    break
                self.take_buy_action(player, choice)

            ### Discard cards in play and in hand
            self.game_state.discard_location(
                Location(player.name(), LocationName.IN_PLAY))
            self.game_state.discard_location(
                Location(player.name(), LocationName.HAND))

            ### Draw next hand
            self.game_state.draw(NUM_CARDS_IN_HAND, player.name())

            # TODO: inform Players of after turn state for learning agents

            # rotate player index
            self.player_index = self.increment_player_turn_index()
            turn_number += 1
            # Safety to avoid bots getting stuck in infinite game.
            if turn_number > MAX_TURNS:
                break

        #################
        # Resolve game
        #################
        print('\nGAME OVER on Turn %d\n-----------------\n' %
              (turn_number / 2))
        for name, vp in self.player_name_to_vp().items():
            print('%s: %d' % (name, vp))
        winners = self.get_winners()
        if len(winners) == 1:
            print('Winner: ' + winners[0])
        elif len(winners) == 2:
            tied_player_names = ' and '.join(winners)
            print('Tie between %s' % tied_player_names)
        return winners
コード例 #12
0
    def run(self):
        """
        Main control loop for game play
        """
        #################
        # Initialization
        #################

        starting_supply = self.get_starting_supply()
        starting_deck = self.get_starting_deck()
        self.game_state = GameState(
            list(map(lambda x: x.name(), self.players)), starting_supply,
            starting_deck, self.log)
        # TODO: inform Players of initial state for learning agents
        self.game_state.set_agents(self.players)
        for player in self.players:
            # shuffle player decks
            self.game_state.shuffle(
                Location(player.name(), LocationName.DRAW_PILE))
            # draw starting hands
            self.game_state.draw(NUM_CARDS_IN_HAND, player.name())

        #################
        # Gameplay loop
        #################
        turn_number = 1
        while not self.game_over():
            # Fetch the next player
            player = self.players[self.player_index]
            ### Setup Phase
            self.game_state.reset_counters_for_new_turn()

            ### Action phase

            while (self.actions_left() > 0
                   and len(self.action_cards_in_hand(player)) > 0):
                decision = self.generate_action_decision(player)
                choices = self.give_decision(decision, player)
                action_card = choices[0] if choices else None
                # TODO: validate choice legality
                if not action_card:
                    break
                self.game_state.update_counter(
                    CounterId(None, CounterName.ACTIONS), -1)
                self.game_state.play(action_card)
                action_card.play(self.game_state)

            ### Buy phase
            decision = self.generate_play_treasures_decision(player)
            treasures = self.give_decision(decision, player)
            self.play_treasures(player, treasures)

            while self.buys_left() > 0:
                decision = self.generate_buy_decision(player)
                choices = self.give_decision(decision, player)
                choice = choices[0] if choices else None
                # TODO: validate choice legality
                if not choice:
                    break
                self.take_buy_action(player, choice)

            ### Discard cards in play and in hand
            self.game_state.discard_location(
                Location(player.name(), LocationName.IN_PLAY))
            self.game_state.discard_location(
                Location(player.name(), LocationName.HAND))

            ### Draw next hand
            self.game_state.draw(NUM_CARDS_IN_HAND, player.name())

            # TODO: inform Players of after turn state for learning agents

            # rotate player index
            self.player_index = self.increment_player_turn_index()
            turn_number += 1
            # Safety to avoid bots getting stuck in infinite game.
            if turn_number > MAX_TURNS:
                break

        #################
        # Resolve game
        #################
        print('\nGAME OVER on Turn %d\n-----------------\n' %
              (turn_number / 2))
        for name, vp in self.player_name_to_vp().items():
            print('%s: %d' % (name, vp))
        winners = self.get_winners()
        if len(winners) == 1:
            print('Winner: ' + winners[0])
        elif len(winners) == 2:
            tied_player_names = ' and '.join(winners)
            print('Tie between %s' % tied_player_names)
        return winners
コード例 #13
0
ファイル: game.py プロジェクト: plough/myPySnake
class SnakeGame:
    def __init__(self):
        pygame.init()

        self.game_state = GameState()  # 当前游戏状态
        self.snake = self._create_snake()  # 蛇

        self.board = GameBoard(self.game_state)  # 画板
        self.board.add_sprite(self.snake)

        self.fps_clock = pygame.time.Clock()  # 控制帧率
        self.direction_lock = SimpleLock()  # 方向锁,防止在一个时钟周期内,连续改变方向,导致撞到蛇身第二节

        pygame.display.set_caption(TITLE)

    def start(self):
        self.board.draw()

        # 游戏主循环
        while True:
            self.direction_lock.unlock()

            for event in pygame.event.get():
                self.handle_key_event(event)

            if self.game_state.is_play():
                if self.snake.is_dead():
                    self.game_state.set_over()
                else:
                    self.snake.move_forward()

            self.board.draw()

            self.fps_clock.tick(self.game_state.speed)

    def handle_key_event(self, event):
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                sys.exit()

            if event.key == K_f:
                self.board.toggle_screen()

            elif self.game_state.is_over() and event.key == K_RETURN:
                self.restart()

            elif event.key == K_SPACE:
                self.game_state.toggle_state()

            elif self.game_state.is_play(
            ) and not self.direction_lock.is_locked():
                direction = DirectionManager.get_direction_by_key(event.key)
                if self.snake.is_valid_direction(direction):
                    self.snake.set_direction(direction)
                    self.direction_lock.lock()

        if event.type == QUIT:
            sys.exit()

    def restart(self):
        """重新开始游戏时,对游戏初始化"""
        self.game_state.reset()
        self.direction_lock.unlock()
        self.snake.reset()
        sound_manager.replay_music()

    def _create_snake(self):
        snake = Snake()

        def on_eat_food():
            self.game_state.add_score()

        snake.register_eat_food_listener(on_eat_food)
        return snake
コード例 #14
0
from core.network import Network
from core.game_state import GameState

# print("hello")
n = Network(new_weights=True)

g1 = GameState(["Michael"])

n.run_epoch(1001)

コード例 #15
0
model.add(Dense(18, init='uniform', activation='relu'))
model.add(Dense(10, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='linear'))

model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

# Parameters
D = deque()  # Register where the actions will be stored

observetime = 500  # Number of timesteps we will be acting on the game and observing results
epsilon = 0.7  # Probability of doing a random move
gamma = 0.9  # Discounted future reward. How much we care about steps further in time
mb_size = 500  # Learning minibatch size

# FIRST STEP: Knowing what each action does (Observing)
observation = GameState(["Michael"])  # Game begins
state = observation.to_array()
done = False
turns = 0
for t in range(observetime):
    possible_moves = observation.get_possible_moves()[0]
    if (DEBUG):
        if t < 10 or t % 20 == 0:
            print("t = " + str(t))
            print(observation)
            print("len = " + str(len(possible_moves)))
    if (t % 100 == 0 and turns >= 100):
        observation = GameState(["Michael"])  # Game begins
        state = observation.to_array()
        done = False
        turns = 0