Reputation: 936
I am coding a simple maze game. I've created a Player class with a move method -- but whenever I want to check if the move is in the available paths list, it does run the move method and changes my character position.
class Player :
def __init__ (self, position):
self.position = position
def move (self, direction):
if direction == "right": self.position[0] += 1
elif direction == "left": self.position[0] -= 1
elif direction == "up": self.position[1] -= 1
elif direction == "down": self.position[1] += 1
return self.position
maze_paths = [[0,0], [1,0]]
mac = Player([0,0])
direction = 'left'
if mac.move(direction) in maze_paths:
print('ok')
else:
print('No way!')
print('Final position is: %r' % (mac.position))
The output I expect is:
No way!
Final position is: [0, 0]
...because the move left shouldn't be allowed with the maze as it's defined. However, what we have instead is:
No way!
Final position is: [-1, 0]
...with the move happening even though it shouldn't be allowed.
Upvotes: 0
Views: 153
Reputation: 296049
As @TimRichardson suggested in the comments, the act of calculating state should be split out from the act of changing state. Functional programming languages are built to make this easy, but Python isn't one -- so you need to jump through some hoops.
Consider splitting move
into two methods, like the calculate_move
and do_move
shown below:
class Player:
def calculate_move(self, direction):
"""Calculate where we would be if we moved in a direction"""
emulated_position = self.position[:] # make a copy
if direction == "right": emulated_position[0] += 1
elif direction == "left": emulated_position[0] -= 1
elif direction == "up": emulated_position[1] -= 1
elif direction == "down": emulated_position[1] += 1
return emulated_position
def do_move(self, direction):
"""Actually move in the given direction"""
self.position = self.calculate_move(direction)
maze_paths = [[0,0], [1,0]]
mac = Player([0,0])
direction = 'left'
if mac.calculate_move(direction) in maze_paths:
mac.do_move(direction)
print('ok')
else:
print('No way!')
print('Final position is: %r' % mac.position)
...which properly emits as output:
No way!
Final position is: [0, 0]
Upvotes: 3
Reputation: 169
Create a meningful separate validate function like. Did this on my phone.
def validateMove(direction):
if direction == "right":
return self.position[0] + 1 in self.maze_paths
if direction == "down":
return self.position[1] + 1 in self.maze_paths
if direction == "left":
return self.position[0] - 1 in self.maze_paths
if direction =="up":
return self.position[1] - 1 in self.maze_paths
return false
Upvotes: 0