def test_fill(self): b = Board(3, 3) b.fill('ZZZ', row=1) self.assertEqual(b[1].count('ZZZ'), 3) b.fill(1.5, col=2) self.assertEqual(b[0][2], 1.5) self.assertEqual(b[1][2], 1.5) self.assertEqual(b[2][2], 1.5) b.fill(-3) for i in range(b.nrows): self.assertTrue(all(v == -3 for v in b[i]))
class BlobwarGui: def __init__(self, simulation_mode=False): """:cvar """ env = get_environment("blobwar")() env.seed(10) self.images = {1: "blob_blue", 2: "blob_orange"} self.images_selected = { 1: "blob_blue_selected", 2: "blob_orange_selected" } self.images_candidates = { 1: "blob_blue_candidate", 2: "blob_orange_candidate" } self.env = env self.human_player = Human() try: self.ai_player_1 = PPO(self.env, size=self.env.core.board.shape[0]) except Exception as e: print("PPO not yet trained for : ", self.env.core.board.shape[0]) self.ai_player_1 = GreedyPlayer() self.ai_player_2 = GreedyPlayer() self.player1 = self.player2 = None if simulation_mode: self.state = GameState.WAITING_FIRST_CLICK self.player1 = self.ai_player_1 self.player2 = self.player1 return self.game = Board(self.env.core.board.shape[0], self.env.core.board.shape[1]) self.game.cell_size = 70 self.game.cell_spacing = 1 self.game.fill(None) self.game.margin_color = self.game.grid_color = "wheat4" self.game.cell_color = "white" self.game.title = "Blobwar" self.game.create_output(font_size=11) self.state = GameState.GAME_OVER self.move_start_case = None self.move_candidates_case = [] def __player_num__(self, num): return min(2 - num, 2) # 1=>1, -1 =>2 def initialize(self, game_type=GameType.HUMAN_AI): """:cvar Initiliaze game and set automove if current player is not human """ if game_type == GameType.HUMAN_AI: self.player1 = self.human_player self.player2 = self.ai_player_1 elif game_type == GameType.HUMAN_HUMAN: self.player1 = self.human_player self.player2 = self.human_player else: self.player1 = self.ai_player_1 self.player2 = self.ai_player_2 self.env.core.reset() self.state = GameState.WAITING_FIRST_CLICK self.move_start_case = None self.move_candidates_case = [] self.render() if not isinstance(self.player1, Human) and not isinstance( self.player2, Human): self.autoplay() else: self.state = GameState.WAITING_FIRST_CLICK self.print_status() if not isinstance(self.player1, Human): movement = self.player1.choose_action(self.env) self.env.core.apply_movement(movement) self.print_status() self.render() def render(self): for x in range(self.env.core.board.shape[0]): for y in range(self.env.core.board.shape[1]): if self.env.core.board[x][y] == 0: self.game[x][y] = None continue self.game[x][y] = self.images[self.__player_num__( self.env.core.board[x][y])] if self.move_start_case is not None: self.render_selected() def fnkbd(self, key): if key == "Escape": self.game.close() elif key == "F2": self.initialize(game_type=GameType.HUMAN_AI) elif key == "F3": self.initialize(game_type=GameType.HUMAN_HUMAN) elif key == "F4": self.initialize(game_type=GameType.AI_AI) def setup(self): self.game.on_mouse_click = self.on_click self.game.on_key_press = self.fnkbd self.game.on_start = lambda: self.initialize() self.game.show() def on_click(self, btn, x, y): current_player = self.player1 if self.__player_num__( self.env.core.current_player) == 1 else self.player2 if not isinstance(current_player, Human): return if self.state == GameState.GAME_OVER: return if self.state == GameState.WAITING_FIRST_CLICK: self.__on_first_click(btn, x, y) return if self.state == GameState.WAITING_SECOND_CLICK: self.__on_second_click(btn, x, y) return def __on_first_click(self, btn, x, y): if self.env.core.board[x][y] == 0: return current_player = self.__player_num__(self.env.core.current_player) if self.__player_num__(self.env.core.board[x][y]) != current_player: return else: self.move_start_case = (x, y) self.move_candidates_case = self.env.core.neighbours(x, y) self.render() self.state = GameState.WAITING_SECOND_CLICK def __on_second_click(self, btn, x, y): current_player = self.__player_num__(self.env.core.current_player) if (x, y) == self.move_start_case: self.move_start_case = None self.move_candidates_case = [] self.render() self.state = GameState.WAITING_FIRST_CLICK return movement = [self.move_start_case, (x, y)] if self.env.core.check_move(movement): self.env.core.apply_movement(movement) self.print_status() (x_start, y_start) = self.move_start_case self.game[x_start][y_start] = self.images[current_player] self.move_start_case = None self.move_candidates_case = [] self.state = GameState.WAITING_FIRST_CLICK self.render() ###Automatic play def after_move(): current_player = self.player1 if self.__player_num__( self.env.core.current_player) == 1 else self.player2 if self.env.core.game_over(): self.state = GameState.GAME_OVER winner_id = self.env.core.leading_player() self.render() self.print_status() return self.print_status() if not isinstance(current_player, Human): movement = current_player.choose_action(self.env) # self.pause(1000) self.env.core.apply_movement(movement) self.print_status() else: if len(self.env.core.movements()) == 0: self.env.core.apply_movement(None) self.print_status() after_move() self.render() else: x_old, y_old = self.move_start_case self.game[x_old][y_old] = self.images[current_player] self.move_candidates_case = [] if self.game[x][y] == self.images[current_player]: self.move_start_case = x, y self.move_candidates_case = self.env.core.neighbours(x, y) self.state = GameState.WAITING_SECOND_CLICK else: self.move_start_case = None self.move_candidates_case = [] self.state = GameState.WAITING_FIRST_CLICK self.render() return if self.env.core.game_over(): self.state = GameState.GAME_OVER self.print_status() def render_selected(self): if self.move_start_case is None: return current_player_num = self.__player_num__(self.env.core.current_player) x, y = self.move_start_case self.game[x][y] = self.images_selected[current_player_num] for (x_cand, y_cand) in self.move_candidates_case: self.game[x_cand][y_cand] = self.images_candidates[ current_player_num] def autoplay(self): """:cvar Game Autoplay between two IA players """ while self.state != GameState.GAME_OVER: current_player = self.player1 if self.__player_num__( self.env.core.current_player) == 1 else self.player2 movement = current_player.choose_action(self.env) self.env.core.apply_movement(movement) if self.env.core.game_over(): self.state = GameState.GAME_OVER self.print_status() self.pause(50) self.render() def simulate(self): """:cvar Game Autoplay between two IA players """ while self.state != GameState.GAME_OVER: current_player = self.player1 movement = current_player.choose_action(self.env) self.env.core.apply_movement(movement) if self.env.core.game_over(): self.state = GameState.GAME_OVER self.env.core.reset() def print_status(self): current_player, current_player_color = ( self.player1, PLAYER1_COLOR) if self.__player_num__( self.env.core.current_player) == 1 else (self.player2, PLAYER2_COLOR) player0_value = int(self.env.core.player_value(1)) # scores=f" {self.player1.name}({PLAYER1_COLOR}) : {player0_value} , {self.player2.name}({PLAYER2_COLOR}) : {-1*player0_value}" header = f"\t{self.player1.name}({PLAYER1_COLOR}): {player0_value} VS {self.player2.name}({PLAYER2_COLOR}): {-player0_value}" restart_message = "\n \tF2:Human vs AI F3:Human vs Human F4:AI vs AI " if self.env.core.game_over(): winner_id = self.env.core.leading_player() winner = self.__player_num__(winner_id) winner_player = self.player1 if winner == 1 else self.player2 winner_color = PLAYER1_COLOR if winner == 1 else PLAYER2_COLOR if player0_value == 0: current_message = f"\tDraw" else: current_message = f"\t{winner_player.name}({winner_color}) won!!" else: current_message = f"\t{current_player.name}({current_player_color}) playing ..." text = header + "\n" + current_message + "\n" + restart_message self.game.print(text) def pause(self, millis): self.game.pause(millis)