Reputation: 673
I've created a version of noughts and crosses in python using pygame, the finished game turned out much better than expected and I'm quite pleased with it. However, the code appears to be quite messy and I'd like to clean it up a bit. For the code to work, I create 9 objects of a sprite class that I've written. But whenever I need to apply a method to them, I have to write the same line out nine times with a difference of only one number. To fix this, I'd like to know if there is anything that I could do to run the same script for each of the nine objects. The program starts by creating the objects:
board_0 = classes.sprite.Sprite(x = 250, y = 200)
board_0.set_image('board.png')
board_1 = classes.sprite.Sprite(x = 350, y = 200)
board_1.set_image('board.png')
board_2 = classes.sprite.Sprite(x = 450, y = 200)
board_2.set_image('board.png')
board_3 = classes.sprite.Sprite(x = 250, y = 300)
board_3.set_image('board.png')
board_4 = classes.sprite.Sprite(x = 350, y = 300)
board_4.set_image('board.png')
board_5 = classes.sprite.Sprite(x = 450, y = 300)
board_5.set_image('board.png')
board_6 = classes.sprite.Sprite(x = 250, y = 400)
board_6.set_image('board.png')
board_7 = classes.sprite.Sprite(x = 350, y = 400)
board_7.set_image('board.png')
board_8 = classes.sprite.Sprite(x = 450, y = 400)
board_8.set_image('board.png')
Would it be possible to use a for loop to create these in just a few lines rather than the eighteen needed here. The same solution would hopefully work elsewhere in the code, I have these two sections that are repeated nine times for each of the objects:
if board_0.mouse_hover() and grid[0] == 0:
if turn == 0: board_0.set_image('cross.png')
elif turn == 1: board_0.set_image('nought.png')
else:
if grid[0] == 0: board_0.set_image('board.png')
if board_0.mouse_click() and grid[0] == 0:
if turn == 0:
board_0.set_image('cross.png')
grid[0] = 'X'
turn = 1
elif turn == 1:
board_0.set_image('nought.png')
grid[0] = 'O'
turn = 0
Just for those wondering I set grid
at the start of the code: grid = [0, 0, 0, 0, 0, 0, 0, 0, 0]
So what can be done to achieve the result that I'd like, I believe I've had this issue in the past but I didn't know of Stack Overflow then so I'll be updating some other programs too if there is in fact a solution to this.
Upvotes: 3
Views: 120
Reputation: 4656
So I note you said "apply methods", but really what you are doing is calling a method on an instance of a type.
You could try something like this:
def set_my_sprites(x_start, y_start)
sprites = []
for y_mx in range(1, 4):
for x_mx in range(1, 4):
board_x = classes.sprite.Sprite(x = x_start*x_mx, y = y_start*y_mx)
board_x.set_image('board.png')
sprites.append(board_x)
return sprites
then just call this function later as:
set_my_sprites(x_start=250, y_start=200)
You can probably fool around with the calling signature and whatnot to get a bit more flexibility.
In this case, I'm returning the array of sprites in case you want to do something with them later on, but I suppose you don't need to if it isn't required.
Upvotes: 3
Reputation: 1307
You can use a list comprehension and iterate over your parameters to create all the instances of Sprite.
from itertools import product
x_coords = [250, 350, 450]
y_coords = [200, 300, 400]
boards = [classes.sprite.Sprite(x=x, y=y) for x, y in product(x_coords, y_coords)]
for board in boards:
board.set_image('board.png')
board_0
thus becomes boards[0]
. Using itertools.product
is just short for writing out the x,y pairs you have in your example.
Upvotes: 5