vérification map ok, manque génération calque intersections et tout simplement les collisions

This commit is contained in:
DylanVsn 2019-11-10 18:41:05 +01:00
parent 2c4971c3fe
commit bbb2d14104
2 changed files with 205 additions and 0 deletions

160
src/pacmap.py Executable file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env python3
from enum import IntEnum
from copy import deepcopy
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
tile_size = 16 # tile subdivision for dynamic movement
def __init__(self, phys_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) -> bool:
"""
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[-1][1:] + [sub[0] for sub in phys_map] \
+ [sub[-1] for sub in phys_map][1:-1]
# no ground tile on edges
if PhysTile.GRD in edges:
return False
# teleporters are in front of the other
for col in range(1, len(phys_map[0])-1):
if phys_map[0][col] == PhysTile.TPT or phys_map[-1][col] == PhysTile.TPT:
if phys_map[0][col] == phys_map[-1][col]:
teleporter_count -= 2
else:
return False
for row in range(1, len(phys_map)-1):
if phys_map[row][0] == PhysTile.TPT or phys_map[row][-1] == PhysTile.TPT:
if phys_map[row][0] == phys_map[row][-1]:
teleporter_count -= 2
else:
return False
if teleporter_count: # not all teleporters are on edges
return False
# no teleporter on corners
if any(PhysTile.TPT in (phys_map[0][0], phys_map[0][-1],
phys_map[self.height-1][0], phys_map[-1][-1])):
return False
# now we have to verify there is no dead-end ground tile
for col in range(1, self.width-1):
for row in range(1, self.height-1):
cpt = 0
for x, y in ((0, 1), (1, 0), (-1, 0), (0, -1)):
if phys_map[row+y][col+x] in (PhysTile.GRD, PhysTile.TPT):
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)
if not connex(phys_map):
return False
return True
def explore(matrix, x=-1, y=-1):
"""explore the given matrix and change it (GRD and TPT become FIT)"""
if x < 0 and y < 0:
# searching the beginning
for row in range(len(matrix)):
for col in range(len(matrix[0])):
if matrix[row][col]:
explore(matrix, col, row)
elif matrix[y][x] in (PhysTile.TPT, PhysTile.GRD):
matrix[y][x] = PhysTile.FIT
for col, row in ((0, 1), (1, 0), (0, -1), (-1, 0)):
explore(matrix, (x+col)%len(matrix[0]), (y+row)%len(matrix))
def connex(matrix, x=-1, y=-1):
"""return True if the matrix is connex - has only one connexity part"""
temp = deepcopy(matrix)
explore(temp)
if any(tile in (PhysTile.GRD, PhysTile.TPT) for row in temp for tile in row):
return False
return True

45
src/test_connexity.py Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import pacmap
maps = [
[
[4, 1, 1, 1, 3, 1, 1, 4],
[1, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 0, 1, 0, 1],
[3, 0, 1, 0, 0, 1, 0, 3],
[1, 0, 0, 0, 1, 0, 0, 1],
[1, 1, 1, 0, 0, 0, 1, 1],
[4, 4, 1, 1, 3, 1, 1, 4],
],
[
[4, 1, 1, 1, 3, 1, 1, 4],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[4, 1, 1, 1, 3, 1, 1, 4],
],
[
[4, 1, 1, 1, 3, 1, 1, 4],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 0, 0, 1, 0, 1, 1, 1],
[1, 0, 0, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1, 1],
[4, 1, 1, 1, 3, 1, 1, 4],
],
[
[4, 1, 1, 1, 3, 1, 1, 4],
[1, 1, 1, 1, 0, 1, 1, 1],
[1, 1, 1, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 0, 1],
[3, 0, 0, 0, 0, 1, 0, 3],
[1, 1, 1, 1, 0, 1, 1, 1],
[4, 1, 1, 1, 3, 1, 1, 4],
]
]
for pac_map in maps:
is_connex = pacmap.connex(pac_map)
print(is_connex)