def build(self): """Initialize the Kivy screen""" # Set sky color Window.clearcolor = 63 / 255, 191 / 255, 191 / 255, 0.3 # Create main widget self.load_observations() self.create_players() self.main_widget = FishingDerby(fishes=self.fishes, players=self.players, settings=self.settings) self.init_clock() self.init_specific() # Run initial update self.fishes_next_move() self.update_scheduled = Clock.schedule_interval( self.update, 1.0 / self.settings.frames_per_second) # Kivy receives main widget and draws it return self.main_widget
class FishingDerbyMinimaxApp(FishingDerbyApp, Fishes, PrintScore2Players, GamesWithBoats): def __init__(self): super().__init__() self.minimax_agent_opponent = None # Implemented minimax model used by the second player self.space_subdivisions = None # self.current_player = 0 # Player that starts moving self.time_sent = None # Time of last sent state to player loop self.time_received = None # Time of last receive state from player loop self.n_timeouts = 0 self.load_observations() def update_clock(self, dl): super().update_clock(dl) self.print_score() def update(self, dt): # update game if self._cnt_steps % self.settings.frames_per_action == 0 and self._cnt_steps > 0: # Set position of caught fish to position of hook for k,fish in self.fishes.items(): if fish.caught is not None: fish.position.set_y(fish.caught.hook.position.y) # Check if a fish is to be caught by any of the players self.check_fishes_caught() # Check if there are fish left and if not, execute action if len(self.fishes) == 0: self.do_when_no_fish_left() # Check if game is about to timeout if self.time >= self.total_time: self.main_widget.game_over = True # Continue updating self.current_player = 1 - self.current_player # Send current state to player_controller class if self.send_state_or_display_stats() is False: return # Update decisions self.calculate_strategy_for_next_frame_action() self.update_fishes_position_and_increase_steps() self.execute_action() def build(self): """Initialize the Kivy screen""" # Set sky color Window.clearcolor = 63 / 255, 191 / 255, 191 / 255, 0.3 # Create main widget self.load_observations() self.create_players() self.main_widget = FishingDerby(fishes=self.fishes, players=self.players, settings=self.settings) self.init_clock() self.init_specific() # Run initial update self.fishes_next_move() self.update_scheduled = Clock.schedule_interval( self.update, 1.0 / self.settings.frames_per_second) # Kivy receives main widget and draws it return self.main_widget def send_first_message(self): msg = {} for name, fish in self.fishes.items(): msg[name] = {"type": fish.type_fish, "score": fish.score} msg["game_over"] = False self.sender(msg) def init_minimax(self): self.space_subdivisions = self.settings.space_subdivisions self.send_first_message() initial_data = {} for name, fish in self.fishes.items(): initial_data[name] = {"type": fish.type_fish, "score": fish.score} initial_data["game_over"] = False # Initialize opponent self.minimax_agent_opponent = opponent.MinimaxModel(initial_data, self.space_subdivisions) def init_specific(self): self.init_fishes() self.init_minimax() self.introduce_boats_to_screen(2) def calculate_strategy_for_next_frame_action(self): # Receive action from player_controller if self.current_player == 0: msg = self.receiver() self.latest_msg = msg # Added this for printing search time. self.time_received = time() self.check_time_threshold() self.new_action(msg) # Calculate fishes next move self.fishes_next_move() def build_minimax_msg(self, msg): msg["hooks_positions"] = {} msg["fishes_positions"] = {} msg["observations"] = {} msg["fish_scores"] = {} for i, player in enumerate(self.players): boat = player.boat msg["hooks_positions"][i] = ( boat.hook.position.x, boat.hook.position.y) for k, fish in self.fishes.items(): n = int(k[4:]) msg["fishes_positions"][n] = (fish.position.x, fish.position.y) st = fish.updates_cnt msg["observations"][n] = fish.observations_sequence[st:] msg["fish_scores"][n] = fish.score caught_fish_names = {0: None, 1: None} for p in range(len(self.players)): if self.players[p].boat.has_fish is not None: caught_fish_names[p] = int( self.players[p].boat.has_fish.name[4:]) msg["player_scores"] = {} msg["player_scores"][0] = self.players[0].score msg["player_scores"][1] = self.players[1].score msg["caught_fish"] = caught_fish_names return msg def update_specific(self, msg): msg = self.build_minimax_msg(msg) if self.current_player == 0: self.sender(msg) self.time_sent = time() else: initial_tree_node = Node(message=msg, player=1) self.action = self.minimax_agent_opponent.next_move(initial_tree_node) def do_when_no_fish_left(self): self.main_widget.game_over = True self.reinitialize_count() def execute_action(self): if self.players[self.current_player].boat.has_fish: self.action = "up" self.main_widget.act(self.action, player=self.current_player) def reinitialize_count(self): self._cnt_steps = 0 def check_time_threshold(self): if self.time_received - self.time_sent > self.settings.time_threshold: self.n_timeouts += 1 if self.n_timeouts >= 3: raise TimeoutError else: self.n_timeouts = 0 @staticmethod def set_seed(seed): random.seed(seed) np.random.seed(seed)