119 lines
3.9 KiB
Python
119 lines
3.9 KiB
Python
#!/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
|