I am trying to make a tic-tac-toe game, and I currently have a 3x3 tiled board
grid to represent the game. When a user clicks a square, the program sets board[x][y]
to 1
.
board = [[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Unfortunately, whenever I click a tile, it seems to ignore whatever x
value I put; every time I click a tile, it sets the entire row instead of a single tile. So, essentially, if I set board[0][y]
to 1
, it will set board[0][y]
, board[1][y]
, and board[2][y]
all to 1
.
I tried to create a minimal reproducible example, but when I took out the drawing function game
, (and set the board
variable to a 3x3 grid of 0s manually) the program failed to change the last two rows of board
upon clicking on what would have been a tile.
# tic-tac-toe
import pygame
windowsize = (300, 300)
length = 3 # length, width of the array
width = 3
kx = windowsize[0] // length # the size of a tile
ky = windowsize[1] // length
pygame.init()
win = pygame.display.set_mode(windowsize)
win.fill((255,255,255))
inPlay = True
debug = True
board = []
firstrun = True
if debug:
width = length * 2
length = 3
# this function takes the board and draws the game.
# it's purpose is solely for visuals.
def game(flash):
# Initialize grid for first time
global board
if flash == True:
# Fill board with 0s
board = []
line = []
for i in range(length):
line.append(0)
for i in range(length):
board.append(line)
# Draw grid.
for i in range(length):
for j in range(length):
# Draw X/O tiles
r = pygame.Rect((i * kx 1, j * ky 1), (kx - 2, ky - 2))
colour = (255,255,255)
if board[i][j] == 1:
colour = (0,0,0)
#elif board[i][j] == 2:
# colour = (255,255,0)
pygame.draw.rect(win, colour, r)
#pygame.draw.line(win, (255,0,0), (i * kx, 0), (i * kx, 2 ** 20), width)
#pygame.draw.line(win, (255,0,0), (0, i * ky), (2 ** 20, i * ky), width)
while inPlay:
pygame.time.delay(10)
win.fill((5,255,255))
game(firstrun)
firstrun = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
inPlay = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
inPlay = False
if event.type == pygame.MOUSEBUTTONDOWN:
clickPos = pygame.mouse.get_pos()
# find tile coordinates by dividing by 100
x = clickPos[0] // kx
y = clickPos[1] // ky
board[0][y] = 1
if debug:
print(str(x), str(y))
print (board)
print(clickPos)
pygame.display.update()
pygame.quit()
CodePudding user response:
Actually, you don't create a grid, you create a list of references to the same line. To create a grid you need 2 nested loops:
def game(flash):
# Initialize grid for first time
global board
if flash == True:
# Fill board with 0s
board = []
for i in range(length):
line = []
for j in range(length):
line.append(0)
board.append(line)
# [...]
Or even shorter (see List Comprehensions):
def game(flash):
# Initialize grid for first time
global board
if flash == True:
# Fill board with 0s
board = [[0] * length for _ in range(length)]
# [...]
Also, there seems to be a typo in your code:
board[0][y] = 1
board[x][y] = 1