我穿着睡衣做了一个简单的 TicTacToe,但我 运行 犯了一些错误
Im making a simple TicTacToe in pyjama but I am running into some errors
绘图板函数有一个 if 语句来查看它应该绘制哪个色圈。但是当单击鼠标按钮时,它会在右侧 x 坐标但在相反的 y 坐标中绘制圆。此外,结尾有点奇怪我想显示获胜者然后使用 time.wait
等待但它等待然后打印语句一秒钟。如果你能 运行 它,你就会明白。我也在寻找我可以做出的一般改进。
import pygame, sys
import numpy as np
import math
pygame.init()
clock = pygame.time.Clock()
# Colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ROW_COUNT = 3
COLUMN_COUNT = 3
SQUARE_SIZE = 100
RADIUS = int(SQUARE_SIZE/2 - 5)
WIDTH = COLUMN_COUNT * SQUARE_SIZE
HEIGHT = ROW_COUNT * SQUARE_SIZE
myfont = pygame.font.SysFont("monospace", 20)
PLAYER_COUNT = 2
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
class Player:
def __init__(self, number):
self.number = number
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
class Board:
def __init__(self):
self.board_body = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
self.remaining_spaces = 9
self.print_board()
self.draw_board()
def print_board(self):
print(np.flip(self.board_body, 0))
def draw_board(self):
one_x, one_y, one_end_x, one_end_y, two_x, two_y, two_end_x, two_end_y = 100, 0, 100, 300, 0, 100, 300, 100
for r in range(ROW_COUNT):
for c in range(COLUMN_COUNT):
pygame.draw.line(screen, BLACK, (one_x, one_y), (one_end_x, one_end_y), 3)
one_x += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x, two_y), (two_end_x, two_end_y), 3)
two_y += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), HEIGHT - int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), HEIGHT - int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
pygame.display.update()
def check_empty_space_and_place(self, row, column, number):
if self.board_body[row][column] == 0:
self.board_body[row][column] = number
self.remaining_spaces -= 1
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT - 1):
for r in range(ROW_COUNT - 1):
if board[r - 1][c] == piece and board[r][c] == piece and board[r + 1][c] == piece:
return True
# Vertical
for c in range(0, COLUMN_COUNT - 1):
for r in range(0, ROW_COUNT - 1):
if board[r][c - 1] == piece and board[r][c] == piece and board[r][c + 1] == piece:
return True
# Positively sloped diagonals
for c in range(0, COLUMN_COUNT - 1):
for r in range(0, ROW_COUNT - 1):
if board[r][c] == piece and board[r + 1][c + 1] == piece and board[r + 2][c + 2] == piece:
return True
# Negatively sloped diagonals
for c in range(COLUMN_COUNT - 1):
for r in range(ROW_COUNT - 1):
if board[r + 1][c + 1] == piece and board[r][c] == piece and board[r - 1][c - 1] == piece:
return True
def next_player():
while True:
for player in players:
yield player
player_generator = next_player()
board = Board()
run = True
while run:
if board.remaining_spaces == 0:
run = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos_of_mouse = pygame.mouse.get_pos()
posx = pos_of_mouse[0]
posy = pos_of_mouse[1]
column = int(posx // SQUARE_SIZE)
row = int(posy // SQUARE_SIZE)
p = player_generator.__next__()
board.check_empty_space_and_place(row, column, p.number)
board.draw_board()
if board.check_winning_move(board.board_body, p.number):
label = myfont.render("Player {} wins!!!!".format(p.number), False, WHITE)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.time.wait(3000)
run = False
board.print_board()
pygame.display.update()
clock.tick(60)```
在PyGame坐标系中左上角为(0, 0)。您不必翻转 y 轴或从高度中减去 y 坐标。在 class Board
:
的方法 draw_board
中删除术语 HEIGHT -
class Board:
# [...]
def draw_board(self):
# [...]
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
# [...]
如果只是等待一段时间,可以使用pygame.time.wait
or pygame.time.delay
. However, if you want to display a message and then wait some time, you need to update the display beforehand. The display is updated only if either pygame.display.update()
or pygame.display.flip()
叫做。此外,在显示更新在 window:
中可见之前,您必须通过 pygame.event.pump()
处理事件
(参见 How to wait some time in pygame?)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.display.flip()
pygame.event.pump()
pygame.time.wait(3000)
此外,在寻找获胜者时也存在一些错误。你根本不需要嵌套循环。只有 2 条对角线。所以你不需要对角线的任何循环:
class Board:
# [...]
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT):
if board[0][c] == piece and board[1][c] == piece and board[2][c] == piece:
return True
# Vertical
for r in range(ROW_COUNT):
if board[r][0] == piece and board[r][1] == piece and board[r][2] == piece:
return True
# Positively sloped diagonals
if board[0][0] == piece and board[1][1] == piece and board[2][2] == piece:
return True
# Negatively sloped diagonals
if board[0][2] == piece and board[1][1] == piece and board[2][0] == piece:
return True
另见 。
完整代码:
import pygame, sys
import numpy as np
import math
pygame.init()
clock = pygame.time.Clock()
# Colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ROW_COUNT = 3
COLUMN_COUNT = 3
SQUARE_SIZE = 100
RADIUS = int(SQUARE_SIZE/2 - 5)
WIDTH = COLUMN_COUNT * SQUARE_SIZE
HEIGHT = ROW_COUNT * SQUARE_SIZE
myfont = pygame.font.SysFont("monospace", 20)
PLAYER_COUNT = 2
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
class Player:
def __init__(self, number):
self.number = number
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
class Board:
def __init__(self):
self.board_body = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
self.remaining_spaces = 9
self.print_board()
self.draw_board()
def print_board(self):
print(np.flip(self.board_body, 0))
def draw_board(self):
one_x, one_y, one_end_x, one_end_y, two_x, two_y, two_end_x, two_end_y = 100, 0, 100, 300, 0, 100, 300, 100
for r in range(ROW_COUNT):
for c in range(COLUMN_COUNT):
pygame.draw.line(screen, BLACK, (one_x, one_y), (one_end_x, one_end_y), 3)
one_x += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x, two_y), (two_end_x, two_end_y), 3)
two_y += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
pygame.display.update()
def check_empty_space_and_place(self, row, column, number):
if self.board_body[row][column] == 0:
self.board_body[row][column] = number
self.remaining_spaces -= 1
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT):
if board[0][c] == piece and board[1][c] == piece and board[2][c] == piece:
return True
# Vertical
for r in range(ROW_COUNT):
if board[r][0] == piece and board[r][1] == piece and board[r][2] == piece:
return True
# Positively sloped diagonals
if board[0][0] == piece and board[1][1] == piece and board[2][2] == piece:
return True
# Negatively sloped diagonals
if board[0][2] == piece and board[1][1] == piece and board[2][0] == piece:
return True
def next_player():
while True:
for player in players:
yield player
player_generator = next_player()
board = Board()
run = True
while run:
if board.remaining_spaces == 0:
run = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos_of_mouse = pygame.mouse.get_pos()
posx = pos_of_mouse[0]
posy = pos_of_mouse[1]
column = int(posx // SQUARE_SIZE)
row = int(posy // SQUARE_SIZE)
p = player_generator.__next__()
board.check_empty_space_and_place(row, column, p.number)
board.draw_board()
if board.check_winning_move(board.board_body, p.number):
label = myfont.render("Player {} wins!!!!".format(p.number), False, WHITE)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.display.flip()
pygame.event.pump()
pygame.time.wait(3000)
run = False
board.print_board()
pygame.display.update()
clock.tick(60)
绘图板函数有一个 if 语句来查看它应该绘制哪个色圈。但是当单击鼠标按钮时,它会在右侧 x 坐标但在相反的 y 坐标中绘制圆。此外,结尾有点奇怪我想显示获胜者然后使用 time.wait
等待但它等待然后打印语句一秒钟。如果你能 运行 它,你就会明白。我也在寻找我可以做出的一般改进。
import pygame, sys
import numpy as np
import math
pygame.init()
clock = pygame.time.Clock()
# Colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ROW_COUNT = 3
COLUMN_COUNT = 3
SQUARE_SIZE = 100
RADIUS = int(SQUARE_SIZE/2 - 5)
WIDTH = COLUMN_COUNT * SQUARE_SIZE
HEIGHT = ROW_COUNT * SQUARE_SIZE
myfont = pygame.font.SysFont("monospace", 20)
PLAYER_COUNT = 2
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
class Player:
def __init__(self, number):
self.number = number
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
class Board:
def __init__(self):
self.board_body = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
self.remaining_spaces = 9
self.print_board()
self.draw_board()
def print_board(self):
print(np.flip(self.board_body, 0))
def draw_board(self):
one_x, one_y, one_end_x, one_end_y, two_x, two_y, two_end_x, two_end_y = 100, 0, 100, 300, 0, 100, 300, 100
for r in range(ROW_COUNT):
for c in range(COLUMN_COUNT):
pygame.draw.line(screen, BLACK, (one_x, one_y), (one_end_x, one_end_y), 3)
one_x += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x, two_y), (two_end_x, two_end_y), 3)
two_y += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), HEIGHT - int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), HEIGHT - int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
pygame.display.update()
def check_empty_space_and_place(self, row, column, number):
if self.board_body[row][column] == 0:
self.board_body[row][column] = number
self.remaining_spaces -= 1
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT - 1):
for r in range(ROW_COUNT - 1):
if board[r - 1][c] == piece and board[r][c] == piece and board[r + 1][c] == piece:
return True
# Vertical
for c in range(0, COLUMN_COUNT - 1):
for r in range(0, ROW_COUNT - 1):
if board[r][c - 1] == piece and board[r][c] == piece and board[r][c + 1] == piece:
return True
# Positively sloped diagonals
for c in range(0, COLUMN_COUNT - 1):
for r in range(0, ROW_COUNT - 1):
if board[r][c] == piece and board[r + 1][c + 1] == piece and board[r + 2][c + 2] == piece:
return True
# Negatively sloped diagonals
for c in range(COLUMN_COUNT - 1):
for r in range(ROW_COUNT - 1):
if board[r + 1][c + 1] == piece and board[r][c] == piece and board[r - 1][c - 1] == piece:
return True
def next_player():
while True:
for player in players:
yield player
player_generator = next_player()
board = Board()
run = True
while run:
if board.remaining_spaces == 0:
run = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos_of_mouse = pygame.mouse.get_pos()
posx = pos_of_mouse[0]
posy = pos_of_mouse[1]
column = int(posx // SQUARE_SIZE)
row = int(posy // SQUARE_SIZE)
p = player_generator.__next__()
board.check_empty_space_and_place(row, column, p.number)
board.draw_board()
if board.check_winning_move(board.board_body, p.number):
label = myfont.render("Player {} wins!!!!".format(p.number), False, WHITE)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.time.wait(3000)
run = False
board.print_board()
pygame.display.update()
clock.tick(60)```
在PyGame坐标系中左上角为(0, 0)。您不必翻转 y 轴或从高度中减去 y 坐标。在 class Board
:
draw_board
中删除术语 HEIGHT -
class Board:
# [...]
def draw_board(self):
# [...]
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
# [...]
如果只是等待一段时间,可以使用pygame.time.wait
or pygame.time.delay
. However, if you want to display a message and then wait some time, you need to update the display beforehand. The display is updated only if either pygame.display.update()
or pygame.display.flip()
叫做。此外,在显示更新在 window:
中可见之前,您必须通过 pygame.event.pump()
处理事件
(参见 How to wait some time in pygame?)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.display.flip()
pygame.event.pump()
pygame.time.wait(3000)
此外,在寻找获胜者时也存在一些错误。你根本不需要嵌套循环。只有 2 条对角线。所以你不需要对角线的任何循环:
class Board:
# [...]
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT):
if board[0][c] == piece and board[1][c] == piece and board[2][c] == piece:
return True
# Vertical
for r in range(ROW_COUNT):
if board[r][0] == piece and board[r][1] == piece and board[r][2] == piece:
return True
# Positively sloped diagonals
if board[0][0] == piece and board[1][1] == piece and board[2][2] == piece:
return True
# Negatively sloped diagonals
if board[0][2] == piece and board[1][1] == piece and board[2][0] == piece:
return True
另见
完整代码:
import pygame, sys
import numpy as np
import math
pygame.init()
clock = pygame.time.Clock()
# Colours
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
ROW_COUNT = 3
COLUMN_COUNT = 3
SQUARE_SIZE = 100
RADIUS = int(SQUARE_SIZE/2 - 5)
WIDTH = COLUMN_COUNT * SQUARE_SIZE
HEIGHT = ROW_COUNT * SQUARE_SIZE
myfont = pygame.font.SysFont("monospace", 20)
PLAYER_COUNT = 2
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
class Player:
def __init__(self, number):
self.number = number
players = [Player(i) for i in range(1, PLAYER_COUNT + 1)]
class Board:
def __init__(self):
self.board_body = np.zeros((ROW_COUNT, COLUMN_COUNT), dtype=np.uint8)
self.remaining_spaces = 9
self.print_board()
self.draw_board()
def print_board(self):
print(np.flip(self.board_body, 0))
def draw_board(self):
one_x, one_y, one_end_x, one_end_y, two_x, two_y, two_end_x, two_end_y = 100, 0, 100, 300, 0, 100, 300, 100
for r in range(ROW_COUNT):
for c in range(COLUMN_COUNT):
pygame.draw.line(screen, BLACK, (one_x, one_y), (one_end_x, one_end_y), 3)
one_x += 100
one_end_x += 100
pygame.draw.line(screen, BLACK, (two_x, two_y), (two_end_x, two_end_y), 3)
two_y += 100
two_end_y += 100
for c in range(COLUMN_COUNT):
for r in range(ROW_COUNT):
if self.board_body[r][c] == 1:
pygame.draw.circle(screen, RED, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
elif self.board_body[r][c] == 2:
pygame.draw.circle(screen, GREEN, (int(c * SQUARE_SIZE + SQUARE_SIZE / 2), int(r * SQUARE_SIZE + SQUARE_SIZE / 2)), RADIUS)
pygame.display.update()
def check_empty_space_and_place(self, row, column, number):
if self.board_body[row][column] == 0:
self.board_body[row][column] = number
self.remaining_spaces -= 1
def check_winning_move(self, board, piece):
# Horizontal
for c in range(COLUMN_COUNT):
if board[0][c] == piece and board[1][c] == piece and board[2][c] == piece:
return True
# Vertical
for r in range(ROW_COUNT):
if board[r][0] == piece and board[r][1] == piece and board[r][2] == piece:
return True
# Positively sloped diagonals
if board[0][0] == piece and board[1][1] == piece and board[2][2] == piece:
return True
# Negatively sloped diagonals
if board[0][2] == piece and board[1][1] == piece and board[2][0] == piece:
return True
def next_player():
while True:
for player in players:
yield player
player_generator = next_player()
board = Board()
run = True
while run:
if board.remaining_spaces == 0:
run = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
pos_of_mouse = pygame.mouse.get_pos()
posx = pos_of_mouse[0]
posy = pos_of_mouse[1]
column = int(posx // SQUARE_SIZE)
row = int(posy // SQUARE_SIZE)
p = player_generator.__next__()
board.check_empty_space_and_place(row, column, p.number)
board.draw_board()
if board.check_winning_move(board.board_body, p.number):
label = myfont.render("Player {} wins!!!!".format(p.number), False, WHITE)
screen.fill(BLACK)
screen.blit(label, (20, 50))
pygame.display.flip()
pygame.event.pump()
pygame.time.wait(3000)
run = False
board.print_board()
pygame.display.update()
clock.tick(60)