diff --git a/enemy.py b/enemy.py index 6c32d2a22acf0c67b8661eeb841620d09e28ad76..86df1c22eba2258054ca0e277a5e908febd312bd 100644 --- a/enemy.py +++ b/enemy.py @@ -4,6 +4,8 @@ from config import * """ Class representing an enemy agent in the game. """ + + class Enemy: """ Initialise the Enemy object. @@ -12,6 +14,7 @@ class Enemy: :param x (int): The x-coordinate of the enemy's position. :param y (int): The y-coordinate of the enemy's position. """ + def __init__(self, maze): self.maze = maze self.x, self.y = self.reset_position() @@ -21,6 +24,7 @@ class Enemy: :return: tuple: A tuple containing the x and y coordinates of the enemy's position. """ + def reset_position(self): while True: num_rows = self.maze.num_rows() @@ -41,5 +45,6 @@ class Enemy: :param screen: The Pygame screen surface to draw on. """ + def draw(self, screen): pygame.draw.rect(screen, 'blue', (self.x, self.y, TILE_SIZE, TILE_SIZE)) diff --git a/testAStar.py b/testAStar.py new file mode 100644 index 0000000000000000000000000000000000000000..1d98f7205f82ab795181044ad59934998f0e9de7 --- /dev/null +++ b/testAStar.py @@ -0,0 +1,68 @@ +import unittest +from aStar import AStar + + +class TestAStar(unittest.TestCase): + def setUp(self): + self.maze = [ + [1, 0, 0, 0], + [0, 1, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 0] + ] + self.a_star_solver = AStar(self.maze) + + def test_heuristic1(self): + current_position = (1, 1) + visited_corners = set() + heuristic_result = self.a_star_solver.heuristic1(current_position, self.a_star_solver.corners, visited_corners) + self.assertEqual(heuristic_result, 3) + + current_position = (2, 2) + visited_corners = set() + heuristic_result = self.a_star_solver.heuristic1(current_position, self.a_star_solver.corners, visited_corners) + self.assertEqual(heuristic_result, ...) + + def test_heuristic2(self): + current_position = (1, 1) + visited_corners = set() + heuristic_result = self.a_star_solver.heuristic2(current_position, self.a_star_solver.corners, visited_corners) + self.assertEqual(heuristic_result, ...) + + current_position = (2, 2) + visited_corners = set() + heuristic_result = self.a_star_solver.heuristic2(current_position, self.a_star_solver.corners, visited_corners) + self.assertEqual(heuristic_result, ...) + + def test_all_corners_visited(self): + corners = {(1, 1), (2, 2), (3, 3)} + visited_corners = {(1, 1), (2, 2)} + result = self.a_star_solver.all_corners_visited(corners, visited_corners) + self.assertFalse(result) + + def test_find_goal_position(self): + maze_with_goal = ... + goal_position = self.a_star_solver.find_goal_position(maze_with_goal) + self.assertIsNotNone(goal_position) + + maze_without_goal = ... + goal_position = self.a_star_solver.find_goal_position(maze_without_goal) + self.assertIsNone(goal_position) + + def test_find_shortest_path_with_valid_heuristic(self): + def valid_heuristic(current, corners, visited_corners): + return 0 + + path = self.a_star_solver.find_shortest_path(valid_heuristic) + self.assertIsNotNone(path) + + def test_find_shortest_path_with_invalid_heuristic(self): + def invalid_heuristic(current, corners, visited_corners): + return None + + path = self.a_star_solver.find_shortest_path(invalid_heuristic) + self.assertIsNone(path) + + +if __name__ == '__main__': + unittest.main() diff --git a/testBFS.py b/testBFS.py new file mode 100644 index 0000000000000000000000000000000000000000..3d5f40a612fb751e77bbb5a6e97c0df132cf16a6 --- /dev/null +++ b/testBFS.py @@ -0,0 +1,109 @@ +import unittest +from collections import deque +from bfs import BFS + + +class TestBFS(unittest.TestCase): + def setUp(self): + self.bfs_solver = BFS() + + def test_init(self): + bfs = BFS() + self.assertEqual(len(bfs.visited), 0) + self.assertIsInstance(bfs.queue, deque) + self.assertEqual(len(bfs.parent), 0) + self.assertEqual(len(bfs.path), 0) + + def test_get_neighbours(self): + bfs = BFS() + maze = [ + [0, 0, 0], + [0, 1, 0], + [0, 0, 0] + ] + neighbours = bfs.get_neighbours(maze, 1, 1) + expected_neighbours = [(0, 1), (1, 0), (1, 2), (2, 1)] + self.assertEqual(neighbours, expected_neighbours) + + maze = [ + [1, 1, 1], + [1, 1, 1], + [1, 1, 1] + ] + neighbours = bfs.get_neighbours(maze, 1, 1) + self.assertEqual(neighbours, []) + + def test_bfs_path_found(self): + maze = [ + [0, 0, 0], + [1, 1, 0], + [0, 0, 0] + ] + start = (0, 0) + goal = (2, 2) + self.assertTrue(self.bfs_solver.bfs(maze, start, goal)) + + def test_bfs_no_path(self): + maze = [ + [0, 1, 0], + [1, 1, 0], + [0, 1, 0] + ] + start = (0, 0) + goal = (2, 2) + self.assertFalse(self.bfs_solver.bfs(maze, start, goal)) + + def test_bfs_empty_maze(self): + maze = [] + start = (0, 0) + goal = (2, 2) + self.assertFalse(self.bfs_solver.bfs(maze, start, goal)) + + def test_bfs_unreachable_goal(self): + maze = [ + [0, 0, 0], + [1, 1, 0], + [0, 0, 1] + ] + start = (0, 0) + goal = (2, 2) + self.assertFalse(self.bfs_solver.bfs(maze, start, goal)) + + def test_bfs_unreachable_start(self): + maze = [ + [1, 0, 0], + [1, 1, 0], + [0, 0, 0] + ] + start = (0, 0) + goal = (2, 2) + self.assertFalse(self.bfs_solver.bfs(maze, start, goal)) + + def test_bfs_single_cell_maze(self): + maze = [[0]] + start = (0, 0) + goal = (0, 0) + self.assertTrue(self.bfs_solver.bfs(maze, start, goal)) + + def test_construct_path(self): + start = (0, 0) + goal = (2, 2) + parent = { + (1, 1): (0, 1), + (1, 2): (1, 1), + (2, 2): (1, 2), + (0, 1): (0, 0) + } + self.bfs_solver.parent = parent + self.bfs_solver.construct_path(start, goal) + expected_path = [(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)] + self.assertEqual(self.bfs_solver.path, expected_path) + + def test_get_path(self): + self.bfs_solver.path = [(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)] + expected_path = [(2, 2), (1, 2), (1, 1), (0, 1), (0, 0)] + self.assertEqual(self.bfs_solver.get_path(), expected_path) + + +if __name__ == "__main__": + unittest.main() diff --git a/testButton.py b/testButton.py new file mode 100644 index 0000000000000000000000000000000000000000..c191dbb79ffa96b48d751bcae0a48949d6618f6c --- /dev/null +++ b/testButton.py @@ -0,0 +1,56 @@ +import unittest +from unittest.mock import Mock +from button import Button + + +class TestButton(unittest.TestCase): + def setUp(self): + pygame = Mock() + self.mock_screen = pygame.display.set_mode.return_value + self.mock_player_controller = Mock() + self.mock_maze = Mock() + self.mock_image = Mock() + self.mock_image.get_width.return_value = 100 + self.mock_image.get_height.return_value = 50 + self.button = Button(self.mock_image, 100, 100, 1, None) + + def test_draw(self): + mock_image = Mock() + button = Button(mock_image, 100, 100, 1, Mock()) + + button.draw() + + expected_calls = [ + ((mock_image, (100, 100)),), + ] + self.assertEqual(self.mock_screen.blit.call_args_list, expected_calls) + + def test_handle_mouse_click_when_clicked(self): + button = Button(Mock(), 100, 100, 1, self.mock_player_controller) + + button.handle_mouse_click((110, 110), self.mock_maze) + + self.mock_maze.set_level.assert_called_once_with(1) + self.mock_player_controller.reset_player_position.assert_called_once() + self.assertTrue(button.is_clicked) + + def test_handle_mouse_click_when_not_clicked(self): + button = Button(Mock(), 100, 100, 1, self.mock_player_controller) + + button.handle_mouse_click((90, 90), self.mock_maze) + + self.assertFalse(self.mock_maze.set_level.called) + self.assertFalse(self.mock_player_controller.reset_player_position.called) + self.assertFalse(button.is_clicked) + + def test_check_click_within_boundaries(self): + result = self.button.check_click((150, 125)) + self.assertTrue(result) + + def test_check_click_outside_boundaries(self): + result = self.button.check_click((50, 75)) + self.assertFalse(result) + + +if __name__ == "__main__": + unittest.main() diff --git a/testDFS.py b/testDFS.py new file mode 100644 index 0000000000000000000000000000000000000000..53afc4f601ee51e5d64849b576ebd9c439b65815 --- /dev/null +++ b/testDFS.py @@ -0,0 +1,80 @@ +import unittest +from dfs import DFS + + +class TestDFS(unittest.TestCase): + def test_init(self): + dfs = DFS() + self.assertEqual(dfs.visited, set()) + self.assertEqual(dfs.path, []) + + def test_get_neighbours(self): + maze = [ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ] + dfs = DFS() + + self.assertEqual(dfs.get_neighbours(maze, 0, 0), [(0, 1), (1, 0)]) + self.assertEqual(dfs.get_neighbours(maze, 1, 1), [(1, 2), (2, 1)]) + self.assertEqual(dfs.get_neighbours(maze, 2, 2), [(2, 1), (3, 2)]) + + def test_dfs(self): + maze = [ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ] + dfs = DFS() + + start = (0, 0) + goal = (3, 3) + self.assertTrue(dfs.dfs(maze, start, goal)) + + start = (0, 0) + goal = (2, 2) + self.assertFalse(dfs.dfs(maze, start, goal)) + + def test__dfs(self): + maze = [ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ] + dfs = DFS() + + start = (0, 0) + goal = (3, 3) + self.assertTrue(dfs._dfs(maze, start, goal)) + + start = (0, 0) + goal = (2, 2) + self.assertFalse(dfs._dfs(maze, start, goal)) + + def test_get_path(self): + maze = [ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ] + dfs = DFS() + + start = (0, 0) + goal = (3, 3) + dfs._dfs(maze, start, goal) + expected_path = [(0, 0), (0, 1), (1, 1), (2, 1), (3, 1), (3, 2), (3, 3)] + self.assertEqual(dfs.get_path(), expected_path) + + start = (0, 0) + goal = (2, 2) + dfs._dfs(maze, start, goal) + self.assertEqual(dfs.get_path(), []) + + +if __name__ == "__main__": + unittest.main() diff --git a/testDijkstra.py b/testDijkstra.py new file mode 100644 index 0000000000000000000000000000000000000000..b6e6804cf8973bfbc71d1cbe2d6cb602e9951a7a --- /dev/null +++ b/testDijkstra.py @@ -0,0 +1,79 @@ +import unittest +from dijkstra import Dijkstra + + +class TestDijkstra(unittest.TestCase): + def setUp(self): + self.dijkstra_solver = Dijkstra(None) + + def test_calculate_cost_empty(self): + cell_type = 0 + cost = self.dijkstra_solver.calculate_cost(cell_type) + self.assertEqual(cost, 1) + + def test_calculate_cost_wall(self): + cell_type = 1 + cost = self.dijkstra_solver.calculate_cost(cell_type) + self.assertEqual(cost, float('inf')) + + def test_calculate_cost_goal(self): + cell_type = 2 + cost = self.dijkstra_solver.calculate_cost(cell_type) + self.assertEqual(cost, 100) + + def test_calculate_cost_start(self): + cell_type = 3 + cost = self.dijkstra_solver.calculate_cost(cell_type) + self.assertEqual(cost, 1) + + def test_find_shortest_path_simple(self): + + start_position = (0, 0) + goal_position = (3, 3) + path = self.dijkstra_solver.find_shortest_path(start_position, goal_position) + expected_path = [(0, 0), (1, 0), (2, 0), (3, 0), (3, 1), (3, 2), (3, 3)] + self.assertEqual(path, expected_path) + + def test_find_shortest_path_blocked_goal(self): + + start_position = (0, 0) + goal_position = (3, 3) + path = self.dijkstra_solver.find_shortest_path(start_position, goal_position) + expected_path = [] + self.assertEqual(path, expected_path) + + def test_find_shortest_path_complex(self): + + start_position = (0, 0) + goal_position = (4, 4) + path = self.dijkstra_solver.find_shortest_path(start_position, goal_position) + expected_path = [(0, 0), (1, 0), (2, 0), (2, 1), (2, 2), (2, 3), (3, 3), (4, 3), (4, 4)] + self.assertEqual(path, expected_path) + + def test_get_neighbors_middle(self): + maze = Dijkstra([ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ]) + cell = (1, 1) + neighbors = maze.get_neighbors(cell) + expected_neighbors = [(0, 1), (2, 1), (1, 0), (1, 2)] + self.assertEqual(neighbors, expected_neighbors) + + def test_get_neighbors_corner(self): + maze = Dijkstra([ + [0, 0, 0, 1], + [1, 1, 0, 0], + [0, 1, 0, 1], + [0, 0, 0, 0] + ]) + cell = (0, 0) + neighbors = maze.get_neighbors(cell) + expected_neighbors = [(1, 0), (0, 1)] + self.assertEqual(neighbors, expected_neighbors) + + +if __name__ == "__main__": + unittest.main() diff --git a/testEnemy.py b/testEnemy.py new file mode 100644 index 0000000000000000000000000000000000000000..048d0ff97b33adeaca1e1dc0c18c7eff30aeffcc --- /dev/null +++ b/testEnemy.py @@ -0,0 +1,46 @@ +import unittest +from unittest.mock import MagicMock, patch +from enemy import Enemy +from config import TILE_SIZE + + +class TestEnemy(unittest.TestCase): + @patch('enemy.random') + def test_init(self, mock_random): + mock_maze = MagicMock() + + mock_random.randint.return_value = 2 + mock_maze.num_rows.return_value = 5 + mock_maze.num_columns.return_value = 6 + mock_maze.__getitem__.return_value = 0 + + enemy = Enemy(mock_maze) + + self.assertEqual(enemy.x, 2 * 32) + self.assertEqual(enemy.y, 0) + + @patch('enemy.random') + def test_reset_position(self, mock_random): + mock_maze = MagicMock() + + mock_random.randint.return_value = 2 + mock_maze.num_rows.return_value = 5 + mock_maze.num_columns.return_value = 6 + mock_maze.__getitem__.return_value = 0 + + enemy = Enemy(mock_maze) + enemy.reset_position() + + self.assertEqual(enemy.x, 2 * 32) + self.assertEqual(enemy.y, 0) + + def test_draw(self): + mock_screen = MagicMock() + + enemy = Enemy(None) + enemy.draw(mock_screen) + mock_screen.assert_called_once_with('blue', (enemy.x, enemy.y, enemy.TILE_SIZE, enemy.TILE_SIZE)) + + +if __name__ == "__main__": + unittest.main() diff --git a/testExpectimax.py b/testExpectimax.py new file mode 100644 index 0000000000000000000000000000000000000000..d45612290dc8363954bca8c28c5cdb80d481a6be --- /dev/null +++ b/testExpectimax.py @@ -0,0 +1,69 @@ +import unittest +from expectimax import Expectimax + + +class TestExpectimax(unittest.TestCase): + + def test_valid_scenario(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + expectimax_solver = Expectimax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = 3 + maximizing_player = True + result = expectimax_solver.expectimax(player_position, enemy_position, depth, maximizing_player) + self.assertIsNotNone(result) + + def test_invalid_scenario_negative_depth(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + expectimax_solver = Expectimax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = -1 + maximizing_player = True + with self.assertRaises(ValueError): + expectimax_solver.expectimax(player_position, enemy_position, depth, maximizing_player) + + def test_no_valid_moves(self): + maze = [[1, 1, 1], + [1, 1, 1], + [1, 1, 1]] + expectimax_solver = Expectimax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = 3 + maximizing_player = True + result = expectimax_solver.expectimax(player_position, enemy_position, depth, maximizing_player) + self.assertEqual(result, 0) + + def test_game_over(self): + maze = [[0, 0, 0], + [0, 0, 0], + [0, 0, 0]] + expectimax_solver = Expectimax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = 3 + maximizing_player = True + result = expectimax_solver.expectimax(player_position, enemy_position, depth, maximizing_player) + self.assertEqual(result, 0) + + def test_max_depth(self): + maze = [[0, 0, 0], + [0, 0, 0], + [0, 0, 0]] + expectimax_solver = Expectimax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = 10 + maximizing_player = True + result = expectimax_solver.expectimax(player_position, enemy_position, depth, maximizing_player) + self.assertIsNotNone(result) + + +if __name__ == '__main__': + unittest.main() diff --git a/testGame.py b/testGame.py new file mode 100644 index 0000000000000000000000000000000000000000..dbbfc54c2eb16d4dd496b80802ff488b8c291bd2 --- /dev/null +++ b/testGame.py @@ -0,0 +1,60 @@ +import unittest +from game import Game + + +class TestGame(unittest.TestCase): + + def setUp(self): + self.maze = [ + [1, 1, 1, 1, 1], + [1, 0, 0, 0, 1], + [1, 0, 1, 0, 1], + [1, 0, 0, 0, 1], + [1, 1, 1, 1, 1] + ] + self.game = Game(self.maze) + + def test_init(self): + maze = [ + [1, 1, 1, 1, 1], + [1, 0, 0, 0, 1], + [1, 0, 1, 0, 1], + [1, 0, 0, 0, 1], + [1, 1, 1, 1, 1] + ] + + game = Game(maze) + + self.assertEqual(game.maze, maze) + self.assertEqual(game.player_position, (1, 1)) + self.assertEqual(game.enemy_positions, [(2, 2)]) + + def test_get_player_position(self): + maze = [ + [1, 1, 1, 1, 1], + [1, 0, 0, 0, 1], + [1, 0, 1, 0, 1], + [1, 0, 0, 0, 1], + [1, 1, 1, 1, 1] + ] + + game = Game(maze) + player_position = game.get_player_position() + self.assertEqual(player_position, (1, 1)) + + def test_get_enemy_positions(self): + enemy_positions = self.game.get_enemy_positions() + self.assertEqual(enemy_positions, [(2, 2)]) + + def test_update_positions(self): + self.game.update_positions() + self.assertEqual(self.game.player_position, (1, 1)) + self.assertEqual(self.game.enemy_positions, [(2, 2)]) + + def test_check_game_over(self): + game_over = self.game.check_game_over() + self.assertFalse(game_over) + + +if __name__ == "__main__": + unittest.main() diff --git a/testMaze.py b/testMaze.py new file mode 100644 index 0000000000000000000000000000000000000000..da1c135eb80caf949fac65e68d7a24d51b5fbb2f --- /dev/null +++ b/testMaze.py @@ -0,0 +1,92 @@ +import unittest +from unittest.mock import Mock + +import pygame + +from maze import Maze + + +class TestMaze(unittest.TestCase): + def test_num_rows(self): + initial_level = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + maze = Maze(initial_level) + self.assertEqual(maze.num_rows(), 3) + + def test_num_columns(self): + initial_level = [ + [0, 0, 0, 0], + [0, 0, 0, 0], + [0, 0, 0, 0] + ] + maze = Maze(initial_level) + self.assertEqual(maze.num_columns(), 4) + + def test_getitem(self): + initial_level = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + maze = Maze(initial_level) + self.assertEqual(maze[0], [0, 0, 0]) + self.assertEqual(maze[1], [0, 0, 0]) + self.assertEqual(maze[2], [0, 0, 0]) + + def test_set_level(self): + initial_level = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + maze = Maze(initial_level) + new_level = [ + [1, 1, 1], + [1, 1, 1], + [1, 1, 1] + ] + maze.set_level(new_level) + self.assertEqual(maze.current_level, new_level) + + def test_update_screen_size(self): + initial_level = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + maze = Maze(initial_level) + pygame.display.set_mode((800, 600)) + maze.update_screen_size() + self.assertEqual(pygame.display.get_surface().get_size(), (3 * 32, 3 * 32)) + + def test_draw(self): + initial_level = [ + [0, 0, 0], + [0, 1, 0], + [0, 0, 0] + ] + maze = Maze(initial_level) + tiles = {0: Mock(), 1: Mock()} + maze.tiles = tiles + + maze.draw() + + expected_calls = [ + ((tiles[0], (0, 0)),), + ((tiles[0], (32, 0)),), + ((tiles[0], (64, 0)),), + ((tiles[0], (0, 32)),), + ((tiles[1], (32, 32)),), + ((tiles[0], (64, 32)),), + ((tiles[0], (0, 64)),), + ((tiles[0], (32, 64)),), + ((tiles[0], (64, 64)),), + ] + self.assertEqual(self.mock_screen.blit.call_args_list, expected_calls) + + +if __name__ == "__main__": + unittest.main() diff --git a/testMinMax.py b/testMinMax.py new file mode 100644 index 0000000000000000000000000000000000000000..a3ae88d188803daeb64f27b027b60db0c44b6c1f --- /dev/null +++ b/testMinMax.py @@ -0,0 +1,112 @@ +import unittest +from minmax import MinMax + + +class TestMinMax(unittest.TestCase): + + def test_get_valid_moves_middle(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + player_position = (1, 1) + valid_moves = minmax.get_valid_moves(player_position) + expected_moves = [(0, 1), (2, 1), (1, 0), (1, 2)] + self.assertEqual(valid_moves, expected_moves) + + def test_get_valid_moves_corner(self): + maze = [[0, 1, 0], + [1, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + player_position = (0, 0) + valid_moves = minmax.get_valid_moves(player_position) + expected_moves = [(1, 0), (0, 1)] + self.assertEqual(valid_moves, expected_moves) + + def test_valid_move(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + valid_position = (1, 0) + self.assertTrue(minmax.is_valid_move(valid_position)) + + def test_invalid_move_wall(self): + maze = [[0, 1, 0], + [1, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + wall_position = (0, 1) + self.assertFalse(minmax.is_valid_move(wall_position)) + + def test_invalid_move_outside(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + outside_position = (3, 0) + self.assertFalse(minmax.is_valid_move(outside_position)) + + def test_minmax(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax = MinMax(maze) + player_position = (0, 0) + enemy_position = (2, 2) + depth = 3 + alpha = float('-inf') + beta = float('inf') + maximizing_player = True + result = minmax.minmax(player_position, enemy_position, depth, alpha, beta, maximizing_player) + self.assertIsInstance(result, int) + + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + player_position = (0, 0) + enemy_position = (2, 2) + depth = 1 + + result = minmax.minmax(player_position, enemy_position, depth, float('-inf'), float('inf'), maximizing_player) + print("Result:", result) + + def test_evaluate(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax_object = MinMax(maze) + print("Testing the evaluate method...") + + player_position = (1, 1) + enemy_position = (1, 1) + evaluation_result = minmax_object.evaluate(player_position, enemy_position) + print("Evaluation result when player and enemy are at the same position:", evaluation_result) + + player_position = (2, 2) + enemy_position = (1, 1) + evaluation_result = minmax_object.evaluate(player_position, enemy_position) + print("Evaluation result when player is closer to the goal than the enemy:", evaluation_result) + + player_position = (1, 1) + enemy_position = (2, 2) + evaluation_result = minmax_object.evaluate(player_position, enemy_position) + print("Evaluation result when enemy is closer to the goal than the player:", evaluation_result) + + def test_game_over(self): + maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + minmax_object = MinMax(maze) + print("Testing the game_over method...") + + game_over_result = minmax_object.game_over() + print("Game over result when the game is not over:", game_over_result) + + game_over_result = minmax_object.game_over() + print("Game over result when the game is over:", game_over_result) + + +if __name__ == '__main__': + unittest.main() diff --git a/testPlayer.py b/testPlayer.py new file mode 100644 index 0000000000000000000000000000000000000000..a3386ccba128d2c066951e94242dc0d4a78f333a --- /dev/null +++ b/testPlayer.py @@ -0,0 +1,18 @@ +import unittest +from unittest.mock import Mock, patch +from config import TILE_SIZE +from player import Player + + +class TestPlayer(unittest.TestCase): + @patch('pygame.draw.rect') + def test_draw(self, mock_rect): + # Mock the screen surface + screen_surface_mock = Mock() + player = Player(10, 20) + player.draw(screen_surface_mock) + mock_rect.assert_called_once_with(screen_surface_mock, 'white', (10, 20, TILE_SIZE, TILE_SIZE)) + + +if __name__ == "__main__": + unittest.main() diff --git a/testPlayerController.py b/testPlayerController.py new file mode 100644 index 0000000000000000000000000000000000000000..591c2179f12201a860d8c6e5efb15291d07ca09e --- /dev/null +++ b/testPlayerController.py @@ -0,0 +1,226 @@ +import unittest +from unittest.mock import Mock + +import pygame + +from config import TILE_SIZE +from player import Player +from playerController import PlayerController # Import the PlayerController class + + +class TestPlayerController(unittest.TestCase): + def setUp(self): + self.player_mock = Mock() + self.maze_mock = Mock() + self.player_controller = PlayerController(self.player_mock, self.maze_mock) + + def test_move_player_up(self): + direction = {pygame.K_UP: True, pygame.K_DOWN: False, pygame.K_LEFT: False, pygame.K_RIGHT: False} + self.player_controller.move_player(direction) + self.assertEqual(self.player_mock.y, self.player_mock.y - TILE_SIZE) + + def test_move_player_down(self): + direction = {pygame.K_UP: False, pygame.K_DOWN: True, pygame.K_LEFT: False, pygame.K_RIGHT: False} + self.player_controller.move_player(direction) + self.assertEqual(self.player_mock.y, self.player_mock.y + TILE_SIZE) + + def test_move_player_left(self): + direction = {pygame.K_UP: False, pygame.K_DOWN: False, pygame.K_LEFT: True, pygame.K_RIGHT: False} + self.player_controller.move_player(direction) + self.assertEqual(self.player_mock.x, self.player_mock.x - TILE_SIZE) + + def test_move_player_right(self): + direction = {pygame.K_UP: False, pygame.K_DOWN: False, pygame.K_LEFT: False, pygame.K_RIGHT: True} + self.player_controller.move_player(direction) + self.assertEqual(self.player_mock.x, self.player_mock.x + TILE_SIZE) + + def test_valid_position_within_maze(self): + position = (1, 1) + self.assertTrue(self.player_controller.is_valid_position(position)) + + def test_position_outside_maze_bounds(self): + position = (-1, 1) + self.assertFalse(self.player_controller.is_valid_position(position)) + position = (10, 5) + self.assertFalse(self.player_controller.is_valid_position(position)) + position = (1, 10) + self.assertFalse(self.player_controller.is_valid_position(position)) + + def test_position_collides_with_wall(self): + self.player_controller.maze = Mock(current_level=[[0, 0, 0], + [0, 1, 0], + [0, 0, 0]]) + position = (1, 1) + self.assertFalse(self.player_controller.is_valid_position(position)) + position = (0, 1) + self.assertTrue(self.player_controller.is_valid_position(position)) + + def test_collision_with_wall(self): + self.player_controller.maze = [[0, 0, 0], + [0, 1, 0], + [0, 0, 0]] + x, y = 50, 50 + self.assertTrue(self.player_controller.check_collision(x, y)) + + def test_no_collision_with_wall(self): + self.player_controller.maze = [[0, 0, 0], + [0, 0, 0], + [0, 0, 0]] + x, y = 50, 50 + self.assertFalse(self.player_controller.check_collision(x, y)) + + def test_reset_player_position(self): + initial_x, initial_y = 100, 100 + self.player_controller.player = Player(initial_x, initial_y) + self.player_controller.reset_player_position() + self.assertEqual(self.player_controller.player.x, TILE_SIZE) + self.assertEqual(self.player_controller.player.y, TILE_SIZE) + + def test_set_dfs_solver(self): + dfs_solver_mock = Mock() + self.player_controller.set_dfs_solver(dfs_solver_mock) + self.assertEqual(self.player_controller.dfs_solver, dfs_solver_mock) + + def test_set_bfs_solver(self): + bfs_solver_mock = Mock() + self.player_controller.set_bfs_solver(bfs_solver_mock) + self.assertEqual(self.player_controller.bfs_solver, bfs_solver_mock) + + def test_set_dijkstra_solver(self): + dijkstra_solver_mock = Mock() + self.player_controller.set_dijkstra_solver(dijkstra_solver_mock) + self.assertEqual(self.player_controller.dijkstra_solver, dijkstra_solver_mock) + + def test_set_astar_solver(self): + astar_solver_mock = Mock() + self.player_controller.set_astar_solver(astar_solver_mock) + self.assertEqual(self.player_controller.astar_solver, astar_solver_mock) + + def test_move_to_goal_dfs(self): + dfs_solver_mock = Mock() + dfs_solver_mock.dfs.return_value = True + dfs_solver_mock.get_path.return_value = [(1, 1), (1, 2), (1, 3)] + + self.player_controller.set_dfs_solver(dfs_solver_mock) + self.player_controller.maze = Mock() + self.player_controller.maze.current_level = [ + [0, 0, 0, 0], + [0, 0, 3, 0], + [0, 0, 0, 0], + ] + + self.player_controller.player.x = TILE_SIZE + self.player_controller.player.y = TILE_SIZE + self.player_controller.move_to_goal_dfs() + + expected_path = [(1 * TILE_SIZE, 1 * TILE_SIZE), (1 * TILE_SIZE, 2 * TILE_SIZE), (1 * TILE_SIZE, 3 * TILE_SIZE)] + self.assertEqual( + [(self.player_controller.player.x, self.player_controller.player.y) for _ in range(len(expected_path))], + expected_path) + + def test_move_to_goal_bfs(self): + bfs_solver_mock = Mock() + bfs_solver_mock.bfs.return_value = True + bfs_solver_mock.get_path.return_value = [(1, 1), (1, 2), (1, 3)] + + self.player_controller.set_bfs_solver(bfs_solver_mock) + self.player_controller.maze = Mock() + self.player_controller.maze.current_level = [ + [0, 0, 0, 0], + [0, 0, 3, 0], + [0, 0, 0, 0], + ] + + self.player_controller.player.x = TILE_SIZE + self.player_controller.player.y = TILE_SIZE + self.player_controller.move_to_goal_bfs() + + expected_path = [(1 * TILE_SIZE, 1 * TILE_SIZE), (1 * TILE_SIZE, 2 * TILE_SIZE), (1 * TILE_SIZE, 3 * TILE_SIZE)] + self.assertEqual( + [(self.player_controller.player.x, self.player_controller.player.y) for _ in range(len(expected_path))], + expected_path) + + def test_move_to_goal_dijkstra(self): + dijkstra_solver_mock = Mock() + dijkstra_solver_mock.find_shortest_path.return_value = [(1, 1), (1, 2), (1, 3)] # Simulate a path + + self.player_controller.set_dijkstra_solver(dijkstra_solver_mock) + self.player_controller.maze = Mock() + self.player_controller.maze.current_level = [ + [0, 0, 0, 0], + [0, 0, 3, 0], + [0, 0, 0, 0], + ] + + self.player_controller.player.x = TILE_SIZE + self.player_controller.player.y = TILE_SIZE + self.player_controller.move_to_goal_dijkstra() + + expected_path = [(1 * TILE_SIZE, 1 * TILE_SIZE), (1 * TILE_SIZE, 2 * TILE_SIZE), (1 * TILE_SIZE, 3 * TILE_SIZE)] + self.assertEqual( + [(self.player_controller.player.x, self.player_controller.player.y) for _ in range(len(expected_path))], + expected_path) + + def test_move_to_goal_astar(self): + astar_solver_mock = Mock() + astar_solver_mock.find_goal_position.return_value = (2, 2) # Simulate a goal position + astar_solver_mock.find_shortest_path.return_value = [(1, 1), (1, 2), (1, 3)] # Simulate a path + + self.player_controller.set_astar_solver(astar_solver_mock) + self.player_controller.maze = Mock() + self.player_controller.maze.current_level = [ + [0, 0, 0, 0], + [0, 0, 3, 0], + [0, 0, 0, 0], + ] + + self.player_controller.player.x = TILE_SIZE + self.player_controller.player.y = TILE_SIZE + self.player_controller.move_to_goal_astar() + + expected_path = [(1 * TILE_SIZE, 1 * TILE_SIZE), (1 * TILE_SIZE, 2 * TILE_SIZE), (1 * TILE_SIZE, 3 * TILE_SIZE)] + self.assertEqual( + [(self.player_controller.player.x, self.player_controller.player.y) for _ in range(len(expected_path))], + expected_path) + + def test_follow_path(self): + player_mock = Mock() + self.player_controller.player = player_mock + maze_mock = Mock() + self.player_controller.maze = maze_mock + path = [(0, 0), (0, 1), (0, 2)] + self.player_controller.follow_path(path) + expected_positions = [(0, 0), (0, 1), (0, 2)] + self.assertEqual([(args[0], args[1]) for args in player_mock.x.call_args_list], expected_positions) + + def test_draw_path(self): + screen_mock = Mock() + self.player_controller.screen = screen_mock + path = [(0, 0), (0, 1), (1, 1)] + self.player_controller.draw_path(path) + + expected_calls = [ + ((screen_mock,), {'color': (0, 255, 0), 'rect': (0, 0, TILE_SIZE, TILE_SIZE)}), + ((screen_mock,), {'color': (0, 255, 0), 'rect': (TILE_SIZE, 0, TILE_SIZE, TILE_SIZE)}), + ((screen_mock,), {'color': (0, 255, 0), 'rect': (TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE)}) + ] + + self.assertEqual(screen_mock.mock_calls, + [unittest.mock.call.draw.rect(*args, **kwargs) for args, kwargs in expected_calls]) + + def test_find_goal_position(self): + mock_maze = Mock() + mock_maze.current_level = [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 3] + ] + + self.player_controller.maze = mock_maze + goal_position = self.player_controller.find_goal_position() + expected_goal_position = (2, 2) + self.assertEqual(goal_position, expected_goal_position) + + +if __name__ == "__main__": + unittest.main()