diff options
| author | omagdy7 <omar.professional8777@gmail.com> | 2023-05-08 14:47:07 +0300 |
|---|---|---|
| committer | omagdy7 <omar.professional8777@gmail.com> | 2023-05-08 14:47:07 +0300 |
| commit | 72aeff07de251f66c579405f0aecb0b9c4d4cfac (patch) | |
| tree | f8cd713cb9bd7df73297e110eaf8baad2236b48b /src | |
| parent | c7c473177086399a8fb97936b4c3c2b67a43fce0 (diff) | |
| download | Macpan-72aeff07de251f66c579405f0aecb0b9c4d4cfac.tar.xz Macpan-72aeff07de251f66c579405f0aecb0b9c4d4cfac.zip | |
Added scattered mode for the ghosts
Diffstat (limited to 'src')
| -rw-r--r-- | src/clyde.py | 34 | ||||
| -rw-r--r-- | src/game.py | 27 | ||||
| -rw-r--r-- | src/ghost.py | 20 | ||||
| -rw-r--r-- | src/inky.py | 25 | ||||
| -rw-r--r-- | src/map.py | 99 | ||||
| -rw-r--r-- | src/mode.py | 7 | ||||
| -rw-r--r-- | src/pinky.py | 27 | ||||
| -rw-r--r-- | src/settings.py | 2 |
8 files changed, 151 insertions, 90 deletions
diff --git a/src/clyde.py b/src/clyde.py index 95de2cb..d17a583 100644 --- a/src/clyde.py +++ b/src/clyde.py @@ -1,6 +1,7 @@ from ghost import Ghost import pygame from settings import settings +from mode import MODE from typing_extensions import override import math @@ -16,7 +17,13 @@ class Clyde(Ghost): return math.sqrt(dx * dx + dy * dy) <= tile_width * 8 @override + def get_default_tile(self): + return (27 * 30 + 15, 2 * 30 + 15) + + @override def get_next_move(self, pacman, maze, screen, blinky): + default_tile = self.get_default_tile() + dx = [1, 0, -1, 0] # right, down, left, up dy = [0, 1, 0, -1] @@ -32,23 +39,30 @@ class Clyde(Ghost): ny = self.y + dy[i] * self.speed if self.check_collision(nx, ny, 30, 30, maze): if i != forbidden: - if self.is_eight_tiles_away(pacman): + if self.mode == MODE.SCATTERED: ret[i] = self.heuristic( - (nx, ny), bottom_left_corner[0], bottom_left_corner[1]) - if settings.debug: - pygame.draw.line(screen, self.color, (bottom_left_corner), - (self.x, self.y), 1) + (nx, ny), default_tile[0], default_tile[1]) else: - ret[i] = self.heuristic( - (nx, ny), pacman.x, pacman.y) - if settings.debug: - pygame.draw.line(screen, self.color, (pacman.x, pacman.y), - (self.x, self.y), 1) + if self.is_eight_tiles_away(pacman): + ret[i] = self.heuristic( + (nx, ny), bottom_left_corner[0], bottom_left_corner[1]) + if settings.debug: + pygame.draw.line(screen, self.color, (bottom_left_corner), + (self.x, self.y), 1) + else: + ret[i] = self.heuristic( + (nx, ny), pacman.x, pacman.y) + if settings.debug: + pygame.draw.line(screen, self.color, (pacman.x, pacman.y), + (self.x, self.y), 1) min_h = min(ret) # Favour going up when there is a conflict if min_h == ret[3] and min_h != math.inf: return 3 + # Favour going down than sideways when there is a conflict + if min_h == ret[1] and min_h != math.inf: + return 1 min_idx = ret.index(min_h) return min_idx diff --git a/src/game.py b/src/game.py index c4f5597..0478b28 100644 --- a/src/game.py +++ b/src/game.py @@ -1,6 +1,7 @@ from blinky import Blinky from clyde import Clyde from direction import DIRECTION +from mode import MODE from inky import Inky from pinky import Pinky from player import Player @@ -34,6 +35,10 @@ class Game(): clyde_sprite = pygame.image.load('../assets/clyde.png').convert_alpha() inky_sprite = pygame.image.load('../assets/inky.png').convert_alpha() + # Set the timer to trigger after 10,000 milliseconds (10 seconds) + timer_event = pygame.USEREVENT + 1 + pygame.time.set_timer(timer_event, 1000 * 10, 1) + # our beautiful maze maze = Map.Map() @@ -43,10 +48,14 @@ class Game(): # Initialize the player and the ghosts player = Player(sprite_sheet) - blinky = Blinky(blinky_sprite, 75, 75) - pinky = Pinky(pinky_sprite, 27 * 30, 30 * 30 + 15) - inky = Inky(inky_sprite, 75, 30 * 30 + 15) - clyde = Clyde(clyde_sprite, 27 * 30 + 15, 75) + blinky = Blinky(blinky_sprite, 12 * TILE_WIDTH + + 15, 12 * TILE_HEIGHT + 15) + pinky = Pinky(pinky_sprite, 11 * TILE_WIDTH + + 15, 12 * TILE_HEIGHT + 15) + inky = Inky(inky_sprite, 13 * TILE_WIDTH + + 15, 12 * TILE_HEIGHT + 15) + clyde = Clyde(clyde_sprite, 14 * TILE_WIDTH + + 15, 12 * TILE_HEIGHT + 15) # Set the pacman velocity dx = 0 @@ -105,6 +114,13 @@ class Game(): player.direction = DIRECTION.RIGHT tx = player.speed ty = 0 # Necssarry to move only horizontal or vertical + # Check for the timer event + if event.type == timer_event: + print("Finished") + pinky.mode = MODE.CHASING + inky.mode = MODE.CHASING + blinky.mode = MODE.CHASING + clyde.mode = MODE.CHASING keys = pygame.key.get_pressed() @@ -126,7 +142,8 @@ class Game(): tx = player.speed ty = 0 - # if tx and ty doesn't lead to colliding change the current dx and dy to them and other wise + # if tx and ty doesn't lead to colliding change the current + # dx and dy to them and other wise # let pacman move in his previous direction if player.check_collision(maze, tx, ty, TILE_WIDTH, TILE_HEIGHT): dx = tx diff --git a/src/ghost.py b/src/ghost.py index 301645b..43c0c4a 100644 --- a/src/ghost.py +++ b/src/ghost.py @@ -2,6 +2,7 @@ import pygame import math from util import get_sprites from settings import settings +from mode import MODE import map as Map dx = [1, 0, -1, 0] # right, down, left, up @@ -19,6 +20,7 @@ class Ghost(): self.color = color self.last_move = 3 # this represents the direction based on the dx, dy arrays self.speed = 3 + self.mode = MODE.SCATTERED def in_bounds(self, pos): (x, y) = pos @@ -37,7 +39,12 @@ class Ghost(): return (is_dot or is_free or is_big_dot) return True - # checks collision with pacman and obstacles returns false if there is a collision and true otherwise + def get_default_tile(self): + return (75, 75) + + # checks collision with pacman and obstacles returns false if there is + # a collision and true otherwise + def check_collision(self, nx, ny, gx, gy, maze): direct_x = [1, 0, -1, 0, 1, 1, -1, -1] direct_y = [0, 1, 0, -1, -1, 1, -1, 1] @@ -54,6 +61,8 @@ class Ghost(): def get_next_move(self, pacman, maze, screen, blinky): + default_tile = self.get_default_tile() + ret = len(dx) * [math.inf] forbidden = inv_dir[self.last_move] @@ -63,7 +72,11 @@ class Ghost(): ny = self.y + dy[i] * self.speed if self.check_collision(nx, ny, 30, 30, maze): if i != forbidden: - ret[i] = self.heuristic((nx, ny), pacman.x, pacman.y) + if self.mode == MODE.SCATTERED: + ret[i] = self.heuristic( + (nx, ny), default_tile[0], default_tile[1]) + else: + ret[i] = self.heuristic((nx, ny), pacman.x, pacman.y) if settings.debug: pygame.draw.line(screen, self.color, (pacman.x, pacman.y), (self.x, self.y), 1) @@ -73,6 +86,9 @@ class Ghost(): # Favour going up when there is a conflict if min_h == ret[3] and min_h != math.inf: return 3 + # Favour going down than sideways when there is a conflict + if min_h == ret[1] and min_h != math.inf: + return 1 min_idx = ret.index(min_h) return min_idx diff --git a/src/inky.py b/src/inky.py index 86ac156..070faa0 100644 --- a/src/inky.py +++ b/src/inky.py @@ -1,6 +1,7 @@ import math from typing_extensions import override from direction import DIRECTION +from mode import MODE from settings import settings import pygame from ghost import Ghost @@ -36,6 +37,10 @@ class Inky(Ghost): else: return (pacman.x, pacman.y) + @override + def get_default_tile(self): + return (2 * 30 + 15, 30 * 30 + 15) + def get_target(self, inter_tile, blinky): target = (inter_tile[0] - (blinky.x - inter_tile[0]), inter_tile[1] - (blinky.y - inter_tile[1])) @@ -43,6 +48,8 @@ class Inky(Ghost): @override def get_next_move(self, target, maze, screen, blinky): + default_tile = self.get_default_tile() + dx = [1, 0, -1, 0] dy = [0, 1, 0, -1] @@ -73,8 +80,20 @@ class Inky(Ghost): nx = self.x + dx[i] * self.speed ny = self.y + dy[i] * self.speed if self.check_collision(nx, ny, 30, 30, maze): - ret[i] = self.heuristic( - (nx, ny), target[0], target[1]) + if self.mode == MODE.SCATTERED: + ret[i] = self.heuristic( + (nx, ny), default_tile[0], default_tile[1]) + else: + ret[i] = self.heuristic( + (nx, ny), target[0], target[1]) + + min_h = min(ret) - min_idx = ret.index(min(ret)) + # Favour going up when there is a conflict + if min_h == ret[3] and min_h != math.inf: + return 3 + # Favour going down than sideways when there is a conflict + if min_h == ret[1] and min_h != math.inf: + return 1 + min_idx = ret.index(min_h) return min_idx @@ -19,72 +19,39 @@ PI = math.pi class Map(): def __init__(self): self.maze = [ - [TL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, - H, H, H, H, H, H, H, H, H, H, H, H, H, TR], - [V, TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, - TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, V], - [V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V, - D, D, D, D, D, D, D, D, D, D, D, D, V, V], - [V, V, D, TL, H, H, TR, D, TL, H, H, H, TR, D, V, V, - D, TL, H, H, H, TR, D, TL, H, H, TR, D, V, V], - [V, V, BD, V, 0, 0, V, D, V, 0, 0, 0, V, D, V, V, - D, V, 0, 0, 0, V, D, V, 0, 0, V, BD, V, V], - [V, V, D, BL, H, H, BR, D, BL, H, H, H, BR, D, BL, - BR, D, BL, H, H, H, BR, D, BL, H, H, BR, D, V, V], - [V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, - D, D, D, D, D, D, D, D, D, D, D, D, V, V], - [V, V, D, TL, H, H, TR, D, TL, TR, D, TL, H, H, H, H, - H, H, TR, D, TL, TR, D, TL, H, H, TR, D, V, V], - [V, V, D, BL, H, H, BR, D, V, V, D, BL, H, H, TR, - TL, H, H, BR, D, V, V, D, BL, H, H, BR, D, V, V], - [V, V, D, D, D, D, D, D, V, V, D, D, D, D, V, V, - D, D, D, D, V, V, D, D, D, D, D, D, V, V], - [V, BL, H, H, H, H, TR, D, V, BL, H, H, TR, 0, V, V, - 0, TL, H, H, BR, V, D, TL, H, H, H, H, BR, V], - [V, 0, 0, 0, 0, 0, V, D, V, TL, H, H, BR, 0, BL, - BR, 0, BL, H, H, TR, V, D, V, 0, 0, 0, 0, 0, V], - [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], - [BR, 0, 0, 0, 0, 0, V, D, V, V, 0, TL, H, H, G, G, - H, H, TR, 0, V, V, D, V, 0, 0, 0, 0, 0, BL], - [H, H, H, H, H, H, BR, D, BL, BR, 0, V, 0, 0, 0, 0, - 0, 0, V, 0, BL, BR, D, BL, H, H, H, H, H, H], - [0, 0, 0, 0, 0, 0, 0, D, 0, 0, 0, V, 0, 0, 0, 0, - 0, 0, V, 0, 0, 0, D, 0, 0, 0, 0, 0, 0, 0], - [H, H, H, H, H, H, TR, D, TL, TR, 0, V, 0, 0, 0, 0, - 0, 0, V, 0, TL, TR, D, TL, H, H, H, H, H, H], - [TR, 0, 0, 0, 0, 0, V, D, V, V, 0, BL, H, H, H, H, - H, H, BR, 0, V, V, D, V, 0, 0, 0, 0, 0, TL], - [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], - [V, 0, 0, 0, 0, 0, V, D, V, V, 0, TL, H, H, H, H, - H, H, TR, 0, V, V, D, V, 0, 0, 0, 0, 0, V], - [V, TL, H, H, H, H, BR, D, BL, BR, 0, BL, H, H, TR, - TL, H, H, BR, 0, BL, BR, D, BL, H, H, H, H, TR, V], - [V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V, - D, D, D, D, D, D, D, D, D, D, D, D, V, V], - [V, V, D, TL, H, H, TR, D, TL, H, H, H, TR, D, V, V, - D, TL, H, H, H, TR, D, TL, H, H, TR, D, V, V], - [V, V, D, BL, H, TR, V, D, BL, H, H, H, BR, D, BL, - BR, D, BL, H, H, H, BR, D, V, TL, H, BR, D, V, V], - [V, V, BD, D, D, V, V, D, D, D, D, D, D, D, D, D, - D, D, D, D, D, D, D, V, V, D, D, BD, V, V], - [V, BL, H, TR, D, V, V, D, TL, TR, D, TL, H, H, H, H, - H, H, TR, D, TL, TR, D, V, V, D, TL, H, BR, V], - [V, TL, H, BR, D, BL, BR, D, V, V, D, BL, H, H, TR, - TL, H, H, BR, D, V, V, D, BL, BR, D, BL, H, TR, V], - [V, V, D, D, D, D, D, D, V, V, D, D, D, D, V, V, - D, D, D, D, V, V, D, D, D, D, D, D, V, V], - [V, V, D, TL, H, H, H, H, BR, BL, H, H, TR, D, V, V, - D, TL, H, H, BR, BL, H, H, H, H, TR, D, V, V], - [V, V, D, BL, H, H, H, H, H, H, H, H, BR, D, BL, - BR, D, BL, H, H, H, H, H, H, H, H, BR, D, V, V], - [V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, - D, D, D, D, D, D, D, D, D, D, D, D, V, V], - [V, BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, - H, H, H, H, H, H, H, H, H, H, H, H, BR, V], - [BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, - H, H, H, H, H, H, H, H, H, H, H, H, H, H, BR] + [TL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, TR], + [V, TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, TL, H, H, H, H, H, H, H, H, H, H, H, H, TR, V], + [V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V], + [V, V, D, TL, H, H, TR, D, TL, H, H, H, TR, D, V, V, D, TL, H, H, H, TR, D, TL, H, H, TR, D, V, V], + [V, V, BD, V, 0, 0, V, D, V, 0, 0, 0, V, D, V, V, D, V, 0, 0, 0, V, D, V, 0, 0, V, BD, V, V], + [V, V, D, BL, H, H, BR, D, BL, H, H, H, BR, D, BL, BR, D, BL, H, H, H, BR, D, BL, H, H, BR, D, V, V], + [V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, V, V], + [V, V, D, TL, H, H, TR, D, TL, TR, D, TL, H, H, H, H, H, H, TR, D, TL, TR, D, TL, H, H, TR, D, V, V], + [V, V, D, BL, H, H, BR, D, V, V, D, BL, H, H, TR, TL, H, H, BR, D, V, V, D, BL, H, H, BR, D, V, V], + [V, V, D, D, D, D, D, D, V, V, D, D, D, D, V, V, D, D, D, D, V, V, D, D, D, D, D, D, V, V], + [V, BL, H, H, H, H, TR, D, V, BL, H, H, TR, 0, V, V, 0, TL, H, H, BR, V, D, TL, H, H, H, H, BR, V], + [V, 0, 0, 0, 0, 0, V, D, V, TL, H, H, BR, 0, BL, BR, 0, BL, H, H, TR, V, D, V, 0, 0, 0, 0, 0, V], + [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], + [BR, 0, 0, 0, 0, 0, V, D, V, V, 0, TL, H, H, G, G, H, H, TR, 0, V, V, D, V, 0, 0, 0, 0, 0, BL], + [H, H, H, H, H, H, BR, D, BL, BR, 0, V, 0, 0, 0, 0, 0, 0, V, 0, BL, BR, D, BL, H, H, H, H, H, H], + [0, 0, 0, 0, 0, 0, 0, D, 0, 0, 0, V, 0, 0, 0, 0, 0, 0, V, 0, 0, 0, D, 0, 0, 0, 0, 0, 0, 0], + [H, H, H, H, H, H, TR, D, TL, TR, 0, V, 0, 0, 0, 0, 0, 0, V, 0, TL, TR, D, TL, H, H, H, H, H, H], + [TR, 0, 0, 0, 0, 0, V, D, V, V, 0, BL, H, H, H, H, H, H, BR, 0, V, V, D, V, 0, 0, 0, 0, 0, TL], + [V, 0, 0, 0, 0, 0, V, D, V, V, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, V, V, D, V, 0, 0, 0, 0, 0, V], + [V, 0, 0, 0, 0, 0, V, D, V, V, 0, TL, H, H, H, H, H, H, TR, 0, V, V, D, V, 0, 0, 0, 0, 0, V], + [V, TL, H, H, H, H, BR, D, BL, BR, 0, BL, H, H, TR, TL, H, H, BR, 0, BL, BR, D, BL, H, H, H, H, TR, V], + [V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V, D, D, D, D, D, D, D, D, D, D, D, D, V, V], + [V, V, D, TL, H, H, TR, D, TL, H, H, H, TR, D, V, V, D, TL, H, H, H, TR, D, TL, H, H, TR, D, V, V], + [V, V, D, BL, H, TR, V, D, BL, H, H, H, BR, D, BL, BR, D, BL, H, H, H, BR, D, V, TL, H, BR, D, V, V], + [V, V, BD, D, D, V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, V, V, D, D, BD, V, V], + [V, BL, H, TR, D, V, V, D, TL, TR, D, TL, H, H, H, H, H, H, TR, D, TL, TR, D, V, V, D, TL, H, BR, V], + [V, TL, H, BR, D, BL, BR, D, V, V, D, BL, H, H, TR, TL, H, H, BR, D, V, V, D, BL, BR, D, BL, H, TR, V], + [V, V, D, D, D, D, D, D, V, V, D, D, D, D, V, V, D, D, D, D, V, V, D, D, D, D, D, D, V, V], + [V, V, D, TL, H, H, H, H, BR, BL, H, H, TR, D, V, V, D, TL, H, H, BR, BL, H, H, H, H, TR, D, V, V], + [V, V, D, BL, H, H, H, H, H, H, H, H, BR, D, BL, BR, D, BL, H, H, H, H, H, H, H, H, BR, D, V, V], + [V, V, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, D, V, V], + [V, BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, BR, V], + [BL, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, BR] ] self.dot_color = (255, 255, 255) # white self.small_dot_radius = 4 diff --git a/src/mode.py b/src/mode.py new file mode 100644 index 0000000..9e7f572 --- /dev/null +++ b/src/mode.py @@ -0,0 +1,7 @@ +from enum import Enum + + +class MODE(Enum): + SCATTERED = 0 + FRIGHETENED = 1 + CHASING = 2 diff --git a/src/pinky.py b/src/pinky.py index 191ff61..688163b 100644 --- a/src/pinky.py +++ b/src/pinky.py @@ -1,6 +1,7 @@ import pygame from typing_extensions import override from direction import DIRECTION +from mode import MODE from settings import settings import math from ghost import Ghost @@ -37,7 +38,13 @@ class Pinky(Ghost): return (pacman.x, pacman.y) @override + def get_default_tile(self): + return (27 * 30 + 15, 30 * 30 + 15) + + @override def get_next_move(self, target, maze, screen, blinky): + default_tile = self.get_default_tile() + dx = [1, 0, -1, 0] dy = [0, 1, 0, -1] @@ -58,17 +65,31 @@ class Pinky(Ghost): if settings.debug: pygame.draw.circle(screen, self.color, (new_target[0], new_target[1]), 15) + pygame.draw.circle(screen, self.color, + default_tile, 15) for i in range(len(dx)): if i != forbidden: nx = self.x + dx[i] * self.speed ny = self.y + dy[i] * self.speed if self.check_collision(nx, ny, 30, 30, maze): - ret[i] = self.heuristic( - (nx, ny), new_target[0], new_target[1]) + if self.mode == MODE.SCATTERED: + ret[i] = self.heuristic( + (nx, ny), default_tile[0], default_tile[1]) + else: + ret[i] = self.heuristic( + (nx, ny), new_target[0], new_target[1]) if settings.debug: pygame.draw.line(screen, self.color, (new_target), (self.x, self.y), 1) - min_idx = ret.index(min(ret)) + min_h = min(ret) + + # Favour going up when there is a conflict + if min_h == ret[3] and min_h != math.inf: + return 3 + # Favour going down than sideways when there is a conflict + if min_h == ret[1] and min_h != math.inf: + return 1 + min_idx = ret.index(min_h) return min_idx diff --git a/src/settings.py b/src/settings.py index d1cc93c..a8dfa24 100644 --- a/src/settings.py +++ b/src/settings.py @@ -3,7 +3,7 @@ class Settings(): self.width = 900 self.height = 990 self.fps = 60 - self.debug = True + self.debug = False self.sound = False |
