From 02d088043a6d48120247436978d02f5bf7b9c001 Mon Sep 17 00:00:00 2001 From: DannyAbdi <dannyabdi13@gmail.com> Date: Tue, 27 Feb 2024 01:33:31 +0000 Subject: [PATCH] Implemented minmax algorithm for multi-agent navigation --- minmax.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 minmax.py diff --git a/minmax.py b/minmax.py new file mode 100644 index 0000000..e991a2f --- /dev/null +++ b/minmax.py @@ -0,0 +1,88 @@ +class MinMax: + """ + Initializes a MinMax object. + + :param maze: The maze used for navigation and solving. + """ + def __init__(self, maze): + self.maze = maze + + """ + Gets the valid moves that an enemy agent can take. + + :param player_position: The current position of the player agent. + :return: A list of valid moves for the enemy agent. + """ + def get_valid_moves(self, player_position): + valid_moves = [] + for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]: + x, y = player_position[1] + dx, player_position[0] + dy + if (0 <= x < len(self.maze.current_level[0]) and 0 <= y < len(self.maze.current_level) and + self.maze.current_level[y][x] != 1): + valid_moves.append((y, x)) + return valid_moves + + """ + Checks if a move to a given position is valid. + + :param position: The position to move to. + :return: True if the move is valid, False otherwise. + """ + def is_valid_move(self, position): + x, y = position[1], position[0] + return (0 <= x < len(self.maze.current_level[0]) and 0 <= y < len(self.maze.current_level) and + self.maze.current_level[y][x] != 1) + + """ + Performs the MinMax algorithm to determine the best move the enemy can take. + + :param player_position: The current position of the player agent. + :param enemy_position: The current position of the enemy agent. + :param depth: The depth of the MinMax search tree. + :param maximising_player: True if maximising player (enemy), False if minimising player (player). + :return: The best move for the enemy agent. + """ + def minmax(self, player_position, enemy_position, depth, maximising_player): + if depth == 0 or self.game_over(): + # Evaluate the current game state + return self.evaluate(player_position, enemy_position) + + if maximising_player: + max_eval = float('-inf') + valid_moves = self.get_valid_moves(enemy_position) + best_move = None + for move in valid_moves: + if self.is_valid_move(move): + eval = self.minmax(player_position, move, depth - 1, False) + if eval > max_eval: + max_eval = eval + best_move = move + return max_eval if depth == 1 else best_move + else: + min_eval = float('inf') + valid_moves = self.get_valid_moves(player_position) + for move in valid_moves: + if self.is_valid_move(move): + eval = self.minmax(move, enemy_position, depth - 1, True) + min_eval = min(min_eval, eval) + return min_eval + + """ + Evaluate the current game state. + + :param player_position: The current position of the player agent. + :param enemy_position: The current position of the enemy agent. + :return: The evaluation of the current game state. + """ + def evaluate(self, player_position, enemy_position): + # Implement the evaluation logic here + pass + + """ + Check if the game is over. + + :return: True if the game is over, False otherwise. + """ + def game_over(self): + # Implement the game over condition here + pass -- GitLab