110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
"""
|
|
Author: freezed <freezed@users.noreply.github.com> 2018-03-17
|
|
Version: 0.1
|
|
Licence: `GNU GPL v3` GNU GPL v3: http://www.gnu.org/licenses/
|
|
|
|
This file is part of [_ocp3_ project](https://github.com/freezed/ocp3)
|
|
"""
|
|
import os
|
|
import random
|
|
from conf import elmt_val, ERR_FILE, ERR_LINE, MAZE_SIZE
|
|
|
|
|
|
class Maze:
|
|
"""
|
|
Provides a usable maze from a text file
|
|
Checks the maze compatibility
|
|
Moves the player to it
|
|
"""
|
|
|
|
def __init__(self, filename):
|
|
"""
|
|
Initialise maze
|
|
|
|
The Maze object has given attributes:
|
|
|
|
:var bool status: False = End of game (file error, end of game or quit)
|
|
:var int COL_NB: column number of the maze
|
|
:var int RANGE: string range
|
|
:var int MAX_ITEMS: number of items
|
|
:var str string: contain maze without EOL in astring
|
|
|
|
|
|
:param filename: maze filename
|
|
"""
|
|
# Loading maze file
|
|
if os.path.isfile(filename) is False:
|
|
self.status = False
|
|
print(ERR_FILE.format(filename))
|
|
|
|
else:
|
|
with open(filename, "r") as maze_data:
|
|
splited_maze = maze_data.read().splitlines()
|
|
|
|
if self.check_file(splited_maze):
|
|
|
|
# Builds a square maze (end-line spaces are missing in file)
|
|
self.string = '\n'.join(
|
|
(self.check_line(line) for line in splited_maze)
|
|
)
|
|
|
|
# Place randomly 'item' on the maze
|
|
for symbol_to_place in elmt_val('symbol', 'item', True):
|
|
position = random.choice(
|
|
[idx for (idx, value) in enumerate(self.string)
|
|
if value == elmt_val('symbol', 'name', 'floor', 0)]
|
|
)
|
|
|
|
self.set_symbol(symbol_to_place, position)
|
|
|
|
self.MAX_ITEMS = sum(
|
|
1 for _ in elmt_val('name', 'item', True)
|
|
)
|
|
self.COL_NB = MAZE_SIZE + 1 # List starts to zero
|
|
self.RANGE = range(self.COL_NB * MAZE_SIZE - 1) # remove last EOL
|
|
self.status = True
|
|
|
|
else:
|
|
self.status = False
|
|
|
|
@staticmethod
|
|
def check_file(splited_maze):
|
|
"""
|
|
Checks the maze conformity before starting the game
|
|
|
|
:param list/str splited_maze: Maze splited in a list (line = index)
|
|
"""
|
|
if len(splited_maze) != MAZE_SIZE:
|
|
print(ERR_LINE.format(len(splited_maze)))
|
|
return False
|
|
|
|
# ++Add other checks here: elements inside, exit possible, etc++
|
|
else:
|
|
return True
|
|
|
|
@staticmethod
|
|
def check_line(line):
|
|
"""
|
|
Checks if a line has a good length (configured in MAZE_SIZE const).
|
|
Fill it if it's too small, truncate if it's too long.
|
|
"""
|
|
differance = MAZE_SIZE - len(str(line))
|
|
if differance < 0:
|
|
return line[:MAZE_SIZE]
|
|
elif differance > 0:
|
|
return line + (differance * elmt_val('symbol', 'name', 'floor', 0))
|
|
else:
|
|
return line
|
|
|
|
def set_symbol(self, symbol, pos):
|
|
"""
|
|
Set a symbol on the maze
|
|
|
|
Used for 'player' and 'floor' after collecting items
|
|
|
|
:param str symbol: the symbol to set
|
|
:param str pos: index in the string
|
|
"""
|
|
txt = self.string
|
|
self.string = txt[:pos] + symbol + txt[pos + 1:]
|