Reputation: 47
I have a little problem with my first experience in python. I'm working on a little game, like labyrinth. I create a class Map
, when I instantiate it, works. When I tried to instantiate two times the same class I got some problems.
This is the code :
from random import randint
class Map:
"""Class that generates map"""
width = 0
height = 0
map = list()
dictLine = dict()
def __init__(self, width, height):
"""Constructor takes width and height in input"""
self.width = width
self.height = height
for i in range(0, self.width * self.height):
self.map.append('.')
self.__defineMap()
self.__defineEntrance()
def __defineMap(self):
"""Defines Map in a dict"""
index = 0
for i in range(0,self.height):
self.dictLine[index] = self.map[index:index + self.width]
index = index + self.width
def printMap(self):
"""Function that prints Wumpus World Map"""
for i in range(0, self.width * self.height):
if(i % self.width == 0):
print()
print(self.map[i], end=' ')
print()
def __defineEntrance(self):
"""Random entrance defined at game start"""
state = False
while state is False:
randomEntrance = randint(0,(self.width * self.height)-1)
self.map[-self.width:]
if randomEntrance in range(0,self.width):
#if entrance is at the first line
self.map[randomEntrance] = 'E'
return True
elif randomEntrance % self.width == 0:
#if entrance is on the left side
self.map[randomEntrance] = 'E'
return True
for key in self.dictLine.keys():
#da vedere
if key + self.width - 1 == randomEntrance:
self.map[randomEntrance] = 'E'
return True
l = list()
for key in self.dictLine.keys():
l.append(key)
l.sort()
l.reverse()
if randomEntrance in range(l[0], l[0] + self.width):
self.map[randomEntrance] = 'E'
return True
return False
def reset(self):
self.__init__(self.width, self.height)
This is the result:
>>> map = Map(6,6)
>>> map.printMap()
. . . E . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
>>> map2 = Map(7,7)
>>> map2.printMap()
. . . E . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . E . . .
How can i solve this problem? Thank you all!
Upvotes: 1
Views: 663
Reputation: 1249
Well, first things first.
As Max said, all your variables were created as class attribute instead of instance so any changes you make in one instance will affect the others (even those you will create). The solution is moving them to __init__
.
Also, try not to use "reserved" words. map
is a used as a built-in. Maybe change it to maze
.
I made some quick changes on your code. There are some room for improvements but it will serve you well:
from random import randint
class Maze(object):
"""Class that generates maze"""
def __init__(self, columns, rows):
"""Constructor takes columns and rows in input"""
self.columns = columns
self.rows = rows
self.reset()
def reset(self):
# Building maze.
self.__maze_cell_mapping = []
for i in xrange(self.columns):
for j in xrange(self.rows):
self.__maze_cell_mapping.append((i, j))
# Defining entrance.
self.__entrance = None
self.__define_entrance()
def __define_entrance(self):
"""Random entrance defined at game start"""
while self.__entrance is None:
cell_id = randint(0, len(self.__maze_cell_mapping))
if self.__is_boundary(cell_id):
self.__entrance = self.__maze_cell_mapping[cell_id]
def __is_boundary(self, cell_id):
"""
:param int cell_id:
ID of the cell to check.
:rtype: bool
:returns:
``True`` if given ``cell_id`` is at maze boundary.
"""
column, row = self.__maze_cell_mapping[cell_id]
if column == 0 or column == self.columns - 1:
return True
elif row == 0 or row == self.rows - 1:
return True
else:
return False
def print_maze(self):
"""Function that prints Wumpus World Maze"""
result = [
['.'] * self.columns
for _i in xrange(self.rows)
]
column, row = self.__entrance
result[column][row] = 'E'
for row in result:
print(' '.join(row))
Hope it helps!
Upvotes: 0
Reputation: 8910
map
is a class attribute (shared between all instances of the class), not an instance attribute.
If that's not the behavior you want, change it so that it's an instance attribute -- that is, move the map = list()
part to inside __init__
. You'll probably want to do the same to width
, height
and dictLine
.
Upvotes: 1