def __init__(self, players, display=True, bot_time_limit_ms=5000, disable_time_limit=False, pieces=None, cols=7, rows=17): self.display = display self._running = True self._display_surf = None self.size = self.weight, self.height = 640, 400 self.bot_time_limit = bot_time_limit_ms self.disable_time_limit = disable_time_limit self.hex_radius = 20 self.hex_size = hex_coords.Point(self.hex_radius, self.hex_radius) self.piece_radius = 9 self.layout = Layout(hex_coords.layout_flat, self.hex_size, hex_coords.Point(50, 50)) self.controllers = [] for i in range(len(players)): p = players[i] if p == PlayerType.HUMAN: self.controllers.append(None) elif p == PlayerType.RANDOM: from bots.randombot import RandomBot self.controllers.append(RandomBot()) elif p == PlayerType.TRIVIAL_MCTS: from bots.trivial_mcts import MctsPlayer self.controllers.append(MctsPlayer(i, bot_time_limit_ms)) elif p == PlayerType.EBL_MCTS: import bots.ebl_mcts as ebl_mcts self.controllers.append(ebl_mcts.Player(i)) elif p == PlayerType.K2BD_MCTS: from bots.k2bd_mcts import KevBot self.controllers.append(KevBot(i, bot_time_limit_ms)) elif p == PlayerType.MJ: from bots.mj import PengWin self.controllers.append(PengWin(i, bot_time_limit_ms)) elif p == PlayerType.WARIO: from bots.wariobot import WarioBot self.controllers.append(WarioBot(i)) self.board = GameBoard(len(players), pieces=pieces, cols=cols, rows=rows) self.pending_action = None self.score_pos = (300, 30) self.score_spacing = 30 self.selected_piece = None
def on_event(self, event): mpos = pygame.mouse.get_pos() sel_hex = hex_coords.pixel_to_hex(self.layout, hex_coords.Point(mpos[0], mpos[1])) selected = hex_coords.hex_round(sel_hex) if event.type == pygame.QUIT: self._running = False if self.controllers[self.board.current_player] is None: # Local player if (event.type == pygame.MOUSEBUTTONDOWN) \ and (self.selected_piece is None) \ and pygame.mouse.get_pressed()[0]: # Left click when there is no piece selected self.selected_piece = None if selected in self.board.board.keys(): for i in range(self.board.pieces_per_player): player = self.board.players[self.board.current_player] if player.pieces[i].tile.coords == selected: self.selected_piece = player.pieces[i] break elif event.type == pygame.MOUSEBUTTONDOWN \ and (self.selected_piece is not None) \ and any([pygame.mouse.get_pressed()[0], pygame.mouse.get_pressed()[2]]): # If we have a piece selected, and we left or right click if self.selected_piece is not None: action = (self.selected_piece.tile.coords, selected) if action in self.board.getPossibleActions(): self.pending_action = action elif pygame.mouse.get_pressed()[0]: self.selected_piece = None
def on_loop(self): # Player or AI moves if self.pending_action is not None: self.board = self.board.takeAction(self.pending_action) self.selected_piece = None self.pending_action = None elif self.controllers[self.board.current_player] is not None: self.selected_piece = None # Pass in a deep copy of the board in case the bot wants to make # any changes or monkey patch the reward function c_time = pygame.time.get_ticks() board = copy.deepcopy(self.board) new_board = self.board.takeAction( self.controllers[self.board.current_player].get_move(board)) time_taken = pygame.time.get_ticks() - c_time if time_taken <= self.bot_time_limit: self.board = new_board else: msg = "Bot {} took too long by {} ms! Taking random action." print( msg.format(self.board.current_player, time_taken - self.bot_time_limit)) if self.disable_time_limit: self.board = new_board else: self.board = self.board.takeAction( random.choice(self.board.getPossibleActions())) # Tile Highlighting for tile in self.board.board.values(): tile.highlighted = False mpos = pygame.mouse.get_pos() selected = hex_coords.hex_round( hex_coords.pixel_to_hex(self.layout, hex_coords.Point(mpos[0], mpos[1]))) if selected in self.board.board.keys(): self.board.board[selected].highlighted = True orig_player = self.board.current_player while len(self.board.getPossibleActions()) == 0: self.board.current_player = (self.board.current_player + 1) % self.board.nplayers if self.board.current_player == orig_player: for i in range(len(self.board.players)): player = self.board.players[i] # Add all the player's current piece tiles to their score for piece in player.pieces: player.points += piece.tile.value print(i, player.points) self._running = False break