Disclaimer: Current version of the code seems to be very weirdly indented. Some comments might be wrong because of some misinterpretation of your code.
Style
Python has a style guide called PEP 8. It is usually a good idea to try to stick to it unless you have good reasons not to. In any case, it is definitly worth the read. You'll find various tools to check compliancy. In your case, the main issues would be : naming (snake_case
is recommended for function names), spacing (whitespace around operators), indentation (4 spaces)
Design
Your function returns either a list of food or None
is there is no food. This seems to be more complicated than it should be: it could return a list of food (empty is there is no food). It makes your function easier to use, easier to explain and more concise: you can simply remove the if len(foods) == 0:
condition.
From the Zen of Python:
Special cases aren't special enough to break the rules.
In any case, your function deserves some documentation.
Tuple unpacking
One of my favorite feature of Python is iterable unpacking. You can do something like:
a, b, c = my_list_with_3_elements
and have easy access to the different elements (and an exception if the list has the wrong number of elements).
In your case, assuming location
and size
have the wrong length, you could simply write:
x, y = self.location
c_x, c_y = self.size
This is very convenient to avoid long expressions with error-prones bracket access to a particular index.
Going further, you could do the same with food[0]
and food[1]
.
Now, (assuming I haven't broken too many things) looks like:
def got_food(self, all_foods):
foods = []
x, y = self.location
c_x, c_y = self.size
for f_x, f_y in all_foods:
if f_y >= y - c_y and f_y <= y + c_y and f_x >= c_x and f_x <= x + c_x:
if f_y > y and f_y < y + c_y and f_x > x and f_x < x + c_x:
foods.append((f_x, f_y))
elif f_y < y and f_y > y - c_y and f_x > x and f_x > x - c_y:
foods.append((f_x, f_y))
if f_x >= x - c_x and f_x <= x + c_x and f_y >= y and f_y <= y + c_y:
foods.append((f_x, f_y))
return foods
Chained comparisons
From the doc:
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
In your case, many things can be rewritten:
def got_food(self, all_foods):
foods = []
x, y = self.location
c_x, c_y = self.size
for f_x, f_y in all_foods:
if y - c_y <= f_y <= y + c_y and c_x <= f_x <= x + c_x:
if y < f_y < y + c_y and x < f_x < x + c_x:
foods.append((f_x, f_y))
elif y > f_y > y - c_y and f_x > x and f_x > x - c_y:
foods.append((f_x, f_y))
if x - c_x <= f_x <= x + c_x and y <= f_y <= y + c_y:
foods.append((f_x, f_y))
return foods
I do not understand enough of the intent to go any further (also I suspect the condition f_x > x
is wrong).
food[0]x
looks pretty weird to me. \$\endgroup\$