diff --git a/iteration_2_voulue_par_prof.txt b/iteration_2_voulue_par_prof.txt new file mode 100644 index 0000000..d50e3a4 --- /dev/null +++ b/iteration_2_voulue_par_prof.txt @@ -0,0 +1,3 @@ +1- afficher pacman dans fenêtre +2- gérer déplacements sans sortir de la fenêtre (sans forcément être dans le labyrinthe) - + des murs autour avec notre gestion de collision diff --git a/pacmap.xcf b/pacmap.xcf new file mode 100644 index 0000000..1ae31ed Binary files /dev/null and b/pacmap.xcf differ diff --git a/pacmap_empty.png b/pacmap_empty.png new file mode 100644 index 0000000..1aa671e Binary files /dev/null and b/pacmap_empty.png differ diff --git a/pacmap_maze1.png b/pacmap_maze1.png new file mode 100644 index 0000000..503e9b9 Binary files /dev/null and b/pacmap_maze1.png differ diff --git a/pacmap_maze1.xcf b/pacmap_maze1.xcf new file mode 100644 index 0000000..f887064 Binary files /dev/null and b/pacmap_maze1.xcf differ diff --git a/pacmap_rule.txt b/pacmap_rule.txt new file mode 100644 index 0000000..c2d1f32 --- /dev/null +++ b/pacmap_rule.txt @@ -0,0 +1,9 @@ +chaque mur (sauf le mur extérieur) est d'épaisseur 2 minimum, peut être espacé par des FIT +codage RGB: +GRD 0 0 0 +GCF 255 0 255 +WAL 0 0 255 +GSD 0 255 0 +GWL 0 255 255 +TPT 255 0 0 +FIT 255 255 255 diff --git a/src/carte.py b/src/carte.py deleted file mode 100644 index ab02c40..0000000 --- a/src/carte.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python3 -from enum import IntEnum - -class DotTile(IntEnum): - NDT = 0 # no dot - SPD = 1 # small pac-dot - BPD = 2 # big pac-dot - -class PhysTile(IntEnum): - GRD = 0 # ground - WAL = 1 # wall - GSD = 2 # ghost door - TPT = 3 # teleporter tile - FIT = 4 # fully inaccessible tile - # ghost-cell ground as FIT ? verify no pac-dot here - -class Map: - """ - Pacman maps size is 28×31 - """ - - width = 28 - height = 31 - - def __init__(self, physic_map = [], dots_map = []): - """ - physic_map is the array containing elements: - 0: ground tile - 1: wall - 2: ghost door - 3: teleporter (no need to precise which to go because we assume it will - be at the opposite map tile) - 4: fully inaccessible tile (basically tiles that represent the "in-wall" - space) - - dots_map is a layer on top of the physic_map of the same dimension which contains - 0: no dot - 1: small pac-dot - 2: big pac-dot - """ - self.phys_map = phys_map # in the first part we assume phys_map is correct and no need to verify - self.dots_map = dots_map - self.intersect_map = [] # TODO - the layer which contains intersections pre-calculated - - - def verify(self, phys_map, dots_map) -> boolean: - """ - This method will verify if a given map is valid or not - Return True if correct else False - - we will assume - there are only: - - 1 ghost door - - 4 big pac-dots - - 240 pac-dots - - Each ground tile must have at least 2 ground tile neighboors because - there is no dead-end tile in pac-man - Each dot must be on a ground tile (not even a teleporter one) - """ - - if not (len(phys_map) == len(dots_map) == 31): - return False - - for i in range(len(phys_map)): - if not (len(phys_map[i]) == len(dots_map[i]) == 28): - return False - - # 1 ghost door verification - if sum(sub_arr.count(PhysTile.GSD) for sub_arr in phys_map) != 1: - return False - - # # 4 big pac dots - if sum(sub_arr.count(DotTile.BPD) for sub_arr in dots_map) != 4: - return False - - # # 240 small pac-dots - if sum(sub_arr.count(DotTile.SPD) for sub_arr in dots_map) != 240: - return False - - # dots are only in ground tile - for row in range(len(phys_map)): - for col in range(len(phys_map[0])): - if dots_map[row][col] and phys_map[row][col]: # no dot = 0; ground = 0 - return False - - # odd number of teleporter tiles - teleporter_count = sum(sub_arr.count(PhysTile.TPT) for sub_arr in phys_map) - if teleporter_count % 2: - return False - - edges = phys_map[0][1:] + phys_map[height-1][1:] + [sub[0] for sub in phys_map] + [sub[width-1] for sub in phys_map][1:-1] - - # must verify teleporters are on edges - teleporter_count -= edges.count(PhysTile.TPT) - if teleporter_count: # not all teleporters are on edges - return False - - ### ATTENTION - we need to verify teleporters are in front of the other - - # no ground tile on border - if any(PhysTile.GRD in edges): - return False - - # now we have to verify there is no dead-end ground tile - for col in range(1, width-1): - for row in range(1, height-1): - cpt = 0 - for x, y in ((0, 1), (1, 0), (-1, 0), (0, -1)): - if list[row+y][col+x] in (PhysTile.GRD, PhysTile.TPT, PhysTile.BPD, PhysTile.SPD): - cpt += 1 - if cpt == 2: - break - if cpt < 2: - return False - # we have to verify if there is only 1 connexity component of (PhysTile.GRD, PhysTile.TPT, PhysTile.BPD, PhysTile.SPD) - - return True diff --git a/src/pacman.py b/src/pacman.py old mode 100644 new mode 100755 index 900a5e3..d3dabe1 --- a/src/pacman.py +++ b/src/pacman.py @@ -13,7 +13,7 @@ class Direction(IntEnum): D = 1 R = 2 L = 3 - + class FruitType(IntEnum): A = 0 @@ -31,6 +31,7 @@ class Pacman: self.next_direction = Direction.R self.super_power = 0 # Counter of super pacdots in effect (> 0 means super power is active) self.ghost_combo = 0 + self.size = (1.8, 1.8) # size related to tile size def matrix_position(self): return (int(self.position[0]), int(self.position[1])) @@ -38,16 +39,18 @@ class Pacman: def has_super_power(self): return self.super_power > 0 - def eat_pacdot(self, map): + def eat_pacdot(self, dot_map): global score global pacdot_counter - map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT + dot_map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT pacdot_counter -= 1 score += 10 + if pacdot_counter == 0: + game_over("win") - def eat_super_pacdot(self, map): + def eat_super_pacdot(self, dot_map): global score - map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT + dot_map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT score += 50 self.super_power += 1 @@ -62,26 +65,26 @@ class Pacman: self.ghost_combo = 0 #os._exit(0) - def eat_fruit(self, fruit, map): + def eat_fruit(self, fruit, dot_map): global score - map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT + dot_map.dots_map[self.matrix_position()[0]][self.matrix_position()[1]] = pacmap.DotTile.NDT score += fruit.score def eat_ghost(self, ghost): global score ghost.despawn_and_respawn() self.ghost_combo += 1 - score += (2 ^ self.ghost_combo) * 100 + score += (2 ** self.ghost_combo) * 100 - def get_eaten(self, map): + def get_eaten(self, dot_map): global lives #TODO score loss ? - self.position = map.spawn_point #TODO + self.position = dot_map.spawn_point #TODO lives -= 1 - if lives <= 0: + if lives < 0: # à vérifier game_over() -def game_over(): +def game_over(status = "lose"): #TODO pass diff --git a/src/pacmap.py b/src/pacmap.py index 0207823..afc93f3 100755 --- a/src/pacmap.py +++ b/src/pacmap.py @@ -1,18 +1,23 @@ #!/usr/bin/env python3 from enum import IntEnum from copy import deepcopy +from PIL import Image +import os class DotTile(IntEnum): NDT = 0 # no dot SPD = 1 # small pac-dot BPD = 2 # big pac-dot + FRT = 3 # fruit class PhysTile(IntEnum): GRD = 0 # ground WAL = 1 # wall GSD = 2 # ghost door - TPT = 3 # teleporter tile - FIT = 4 # fully inaccessible tile + GWL = 3 # ghost cell wall + GCF = 4 # ghost cell floor + TPT = 5 # teleporter tile + FIT = 6 # fully inaccessible tile # ghost-cell ground as FIT ? verify no pac-dot here class Map: @@ -20,11 +25,11 @@ class Map: Pacman maps size is 28×31 """ - width = 28 - height = 31 - tile_size = 16 # tile subdivision for dynamic movement + width = 28 * 2 + 1 + height = 31 * 2 + 1 + # tile_size = 16 # tile subdivision for dynamic movement - def __init__(self, phys_map = [], dots_map = []): + def __init__(self, phys_map = [], dots_map = [], maze_img_file=""): """ physic_map is the array containing elements: 0: ground tile @@ -40,6 +45,11 @@ class Map: 1: small pac-dot 2: big pac-dot """ + if maze_img_file and os.path.isfile(maze_img_file): + try: + self.phys_map = decode_map(maze_img_file) + except Exception as e: + raise e self.phys_map = phys_map # in the first part we assume phys_map is correct and no need to verify self.dots_map = dots_map self.intersect_map = [] # TODO - the layer which contains intersections pre-calculated @@ -158,3 +168,26 @@ def connex(matrix, x=-1, y=-1): if any(tile in (PhysTile.GRD, PhysTile.TPT) for row in temp for tile in row): return False return True + +def decode_map(img_file): + img = Image.open(img_file) + dictionnary = { + (0 , 0, 0): PhysTile.GRD, + (255, 0, 255): PhysTile.GCF, + (0 , 0, 255): PhysTile.WAL, + (0 , 255, 0): PhysTile.GSD, + (0 , 255, 255): PhysTile.GWL, + (255, 0, 0): PhysTile.TPT, + (255, 255, 0): PhysTile.FIT, + } + data = list(img.getdata()) + matrix = [] + for row in range(img.height): + matrix.append([]) + for col in range(img.width): + try: + tile = dictionnary[data[col + row*img.width][:3]] # avoid alpha component + except: + raise ValueError("Pixel " + str(col) + "," + str(row) + " is invalid") + matrix[-1].append(tile) + return matrix \ No newline at end of file diff --git a/src/test_load_picture.py b/src/test_load_picture.py new file mode 100755 index 0000000..4266aef --- /dev/null +++ b/src/test_load_picture.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +from pacmap import decode_map +import sys + +if __name__ == '__main__': + if len(sys.argv) > 1: + matrix = decode_map(sys.argv[1]) + else: + matrix = decode_map("../pacmap_maze1.png") + for row in matrix: + print() + for el in row: + print(el.value, end=' ') \ No newline at end of file