Reputation: 50
How can I shorten all of the if
statements in the for
loop? I am developing this for a college project. I cannot think of a way.
Basically the thing it should do is that if a certain location on a board does not equal a rock, then set it as a plant. The locations are a circle around the plant. Example:
N N N
N P N
N N N
if RainFall == 2:
print("This summer has been a perfect summer, the plants have multiplied.")
for Row in range(FIELDLENGTH):
for Column in range(FIELDWIDTH):
if Field[Row][Column] == PLANT:
if Field[Row + 1][Column] != ROCKS:
Field[Row + 1][Column] = GOODSUMMER
if Field[Row - 1][Column] != ROCKS:
Field[Row - 1][Column] = GOODSUMMER
if Field[Row + 1][Column + 1] != ROCKS:
Field[Row + 1][Column + 1] = GOODSUMMER
if Field[Row - 1][Column - 1] != ROCKS:
Field[Row - 1][Column - 1] = GOODSUMMER
if Field[Row][Column + 1] != ROCKS:
Field[Row][Column + 1] = GOODSUMMER
if Field[Row][Column - 1] != ROCKS:
Field[Row][Column - 1] = GOODSUMMER
if Field[Row + 1][Column + 1] != ROCKS:
Field[Row + 1][Column - 1] = GOODSUMMER
if Field[Row - 1][Column + 1] != ROCKS:
Field[Row - 1][Column + 1] = GOODSUMMER
break
Upvotes: 1
Views: 411
Reputation: 21991
We can only guess about the rest of your code, so included down below is a full implementation for testing purposes. To see your reworked code, check out the multiply_plants
function. Instead of a having many if
statements, it uses loops to check the area around a cell. You may also notice that is correctly checks for the bounds of each list so that IndexError
exceptions do not occur.
#! /usr/bin/env python3
import random
FIELD_ROWS = 10
FIELD_COLUMNS = 10
EMPTY = ' '
PLANT = 'P'
ROCKS = 'R'
NEW_PLANT = 'N'
def main():
field = create_field()
show_field(field)
multiply_plants(field, 2)
replace_cells(field, NEW_PLANT, PLANT)
show_field(field)
def create_field():
field = []
for _ in range(FIELD_ROWS):
row = []
for _ in range(FIELD_COLUMNS):
row.append(random.choice([EMPTY] * 3 + [ROCKS] * 2 + [PLANT] * 1))
field.append(row)
return field
def show_field(field):
width = max(map(len, field)) * 2 + 1
print(f'/{"-" * width}\\')
print('\n'.join(' '.join(['|'] + row + ['|']) for row in field))
print(f'\\{"-" * width}/')
def multiply_plants(field, rainfall):
# If there was enough rain, cause the plants to spread.
if rainfall > 1:
print('This summer has been a perfect summer;')
print('the plants have multiplied!')
# Find each space that already has a plant in it.
for y, row in enumerate(field):
for x, cell in enumerate(row):
if cell == PLANT:
# Introduce a Y-axis offset to search up & down.
for y_offset in range(-1, 2):
y_index = y_offset + y
if 0 <= y_index < len(field):
# Introduce a X-axis offset to search left & right.
for x_offset in range(-1, 2):
if y_offset or x_offset: # Skip zero offset.
x_index = x_offset + x
if 0 <= x_index < len(field[y_index]):
# Spread plant to non-rock areas.
if field[y_index][x_index] != ROCKS:
field[y_index][x_index] = NEW_PLANT
def replace_cells(field, old, new):
for y, row in enumerate(field):
for x, cell in enumerate(row):
if cell == old:
field[y][x] = new
if __name__ == '__main__':
main()
Upvotes: 1
Reputation: 696
Yeah, put your index permutations in a list and iterate over that. You can either define the list explicitely (more readable for beginners, but more error prone) or generate it with a comprehension. Explicit version first:
coord_shift = [(1, 0), (-1, 0), (1, 1), (-1, -1), (0, 1), (0, -1), (1, -1), (-1, 1)]
for Row in range(FIELDLENGTH):
for Column in range(FIELDWIDTH):
if Field[Row][Column] == PLANT:
for i, j in coord_shift:
if Field[Row + i][Column + j] != ROCKS:
Field[Row + i][Column + j] = GOODSUMMER
Some additional notes:
Recommended Python style is to use lowercase variable names for regular variables, uppercase guys are more meant for classes.
You don't need break.
The above catches your small mistake for Field[Row +1][Column -1]
.
The adventurous version I promised is:
coord_shift = [(i, j) for i in range(-1, 2) for j in range (-1, 2)]
coord_shift.drop((0, 0))
Upvotes: 2