Reputation: 13
I have a for loop that is supposed to iterate a number of times equal to the length of an array. The loop runs the correct number of times, but the index does not properly increment.
I tried manually incrementing i with i = i + 1, but that did not seem to change anything.
room = [['x','x','x','x','x'],['x','.','.','.','x'],['x','.','.','.','x'],['x','.','.','.','x'],['x','x','x','x','x']]
entities = []
class Entity:
def __init__(self, x_pos, y_pos):
self.x_pos = x_pos
self.y_pos = y_pos
self.new_x_pos = x_pos
self.new_y_pos = y_pos
def Move(self, x_move, y_move):
self.new_y_pos = self.y_pos + y_move
self.new_x_pos = self.x_pos + x_move
if self.CheckCollision(self) is True:
print("collision")
if self.CheckCollision(self) is False:
self.new_x_pos = self.x_pos
self.new_y_pos = self.y_pos
def CheckCollision(self, entity1):
for i in range(len(entities)-1):
#this loop here. It runs twice, but the value of i is zero for both iterations
entity = entities[i]
print(i)
if entity1.new_y_pos == entity.y_pos:
if entity1.new_x_pos == entity.x_pos:
return True
break
else:
return False
calipso = Entity(1, 1)
entities.append(calipso)
joseph = Entity(3,2)
entities.append(joseph)
print(entities)
calipso.Move(1,1)
print(calipso.x_pos, calipso.y_pos, sep=' ')
I want i to increment each iteration of the for loop, thus i === 0 for the first iteration and i === 1 for the second iteration. Currently, i === 0 for both iterations and I don't know why.
Upvotes: 0
Views: 150
Reputation: 2359
There's a couple things wrong with your for
loop. First of all, if the y
positions match but the x
values don't, nothing will happen. Barring this case, however, the for
loop will always exit after the first iteration because if the positions coincide, return True
is called (and by the way, because of the return True
, you don't need break
after it). And otherwise, it returns False
.
So inside Move
, CheckCollision
is called twice, once for each if
statement, which is why i
is printed twice, 0
both times.
To fix it, you would have to have CheckCollision
return False
outside the for
loop, so that it checks ALL the entities to make sure it doesn't collide with anything.
The last thing to consider is that you never check that entity1
and entity
don't refer to the same object. There are some cases that would result in an entity colliding with itself! Without completely revising the method itself to be like the other answer, the only option to fix that would be some sort of unique id
attached to each entity
, but revising the method (as in the other answer) is DEFINITELY the better option.
Also, stylistically, method names for classes should always start with a lower case letter (so your methods should be move
, checkCollision
, etc.).
EDIT: In this specific case, i
will never go to 1
anyway. This is because len(entities)
is 2
, so the for
loop will go from 0
to 1
, NOT including the end, so no matter what it will stop after the first iteration. But if you had more entities, you would run into the problem described above.
Upvotes: 1
Reputation: 1279
I've refactored your code so that the checkCollision method works the way I think you meant it. See comments within the code. I changed the name of the methods to start with lower case.
class Entity:
def __init__(self, x_pos, y_pos):
self.x_pos = x_pos
self.y_pos = y_pos
self.new_x_pos = x_pos
self.new_y_pos = y_pos
def move(self, x_move, y_move):
self.new_x_pos = self.x_pos + x_move
self.new_y_pos = self.y_pos + y_move
if self.checkCollision() is True:
# We don't update x_pos and y_pos here since collision means entity shouldn't move
print("collision")
return False
else: # You need to use ELSE here so that you don't end up calling checkCollision twice
# if checkCollision returned a False, then we can update the position of entity
self.x_pos = self.new_x_pos
self.y_pos = self.new_y_pos
return True
def checkCollision(self):
for entity in entities:
# Iterate through every entity other than self and see if their position is the same as self's possible new position
if entity != self and entity.x_pos == self.new_x_pos and entity.y_pos == self.new_y_pos:
return True
# Return false if no collision occurs after checking through every entity
return False
calipso = Entity(1, 1)
entities.append(calipso)
joseph = Entity(3,2)
entities.append(joseph)
calipso.move(1,1) # successful move
print(calipso.x_pos, calipso.y_pos, sep=' ') # prints 2 2 after succesful move
calipso.move(1,0) # collision with joseph, fails
print(calipso.x_pos, calipso.y_pos, sep=' ') # prints 2 2, calipso did not move
Upvotes: 1