代码参考自:https://blog.csdn.net/weixin_43918046/article/details/119521845
新增功能:1任意棋盘大小;2.任意棋子连线
# 棋盘大小 [670, 670]
# 棋盘行列 15*15
import pygame
from pygame.locals import QUIT, KEYDOWN
import numpy as np
import time
line_space=44
screen_margin=27
row=col=17
# screen_size=(670, 670) # 27*2+44*14
screen_row=(row-1)*line_space+screen_margin*2
screen_col=(col-1)*line_space+screen_margin*2
screen_size=(screen_row,screen_col )
screen_color = [238, 154, 73]
line_color=[0,0,0]
prompt_box_color=[0, 229, 238]
stage = np.zeros((row, col))
white_color = [255, 255, 255] # 白棋颜色
black_color = [0, 0, 0] # 黑棋颜色
victory_color=[238,48,167]
line=5 # 五颗棋子
# 设置鼠标时延
flag = False
tim = 0
def find_pos(x, y):
x=int((x-screen_margin)/line_space+0.5)
y=int((y-screen_margin)/line_space+0.5)
x=x if x<=(row-1) else row-1
y=y if y<=(col-1) else col-1
return x,y
def find_line_consecutive_ones(matrix, line):
victory_list=[]
w, h = matrix.shape
# 水平方向
for row_index, row in enumerate(matrix):
for col_index in range(len(row) - (line - 1)):
if np.all(row[col_index:col_index + line] == 1):
r,c=row_index,col_index
victory_list.append([[r,c+i] for i in range(line) ])
# 垂直方向
for col_index in range(matrix.shape[1]):
for row_index in range(matrix.shape[0] - (line - 1)):
if np.all(matrix[row_index:row_index + line, col_index] == 1):
r, c = row_index, col_index
victory_list.append([[r+i, c] for i in range(line )])
# 正对角线方向
for diag in range(-(w - line), (h - line) + 1):
diagonal = np.diag(matrix, k=diag)
# print(diagonal)
if len(diagonal) >= line:
for start in range(len(diagonal) - (line - 1)):
if np.all(diagonal[start:start + line] == 1):
start_row = max(0, -diag) + start
start_col = max(0, diag) + start
end_row = start_row + line-1
end_col = start_col + line-1
rc=[]
for r in (start_row,end_row+1):
for c in (start_col,end_col+1):
rc.append([r,c])
victory_list.append(rc)
# 反对角线方向
for diag in range(-(w - line), (h - line) + 1):
diagonal = np.diag(np.fliplr(matrix), k=diag)
# print(diagonal)
if len(diagonal) >= line:
for start in range(len(diagonal) - (line - 1)):
if np.all(diagonal[start:start + line] == 1):
start_row = max(0, -diag) + start
start_col = min(h - 1, h - 1 - diag) - start
end_row = start_row + line-1
end_col = start_col - line+1
rc=[]
for r in (start_row,end_row+1):
for c in (start_col,end_col+1):
rc.append([r,c])
victory_list.append(rc)
return victory_list
def find_line_consecutive_ones_v2(matrix, line):
victory_list_v2=[]
a=find_line_consecutive_ones(matrix, line)
b=find_line_consecutive_ones(matrix*(-1), line)
victory_list_v2.extend(a)
victory_list_v2.extend(b)
return victory_list_v2
# 初始化pygame
pygame.init()
# 获取对显示系统的访问,并创建一个窗口screen
# 窗口大小为670x670
screen = pygame.display.set_mode(screen_size)
while True: # 不断训练刷新画布
for event in pygame.event.get(): # 获取事件,如果鼠标点击右上角关闭按钮,关闭
if event.type in (QUIT, KEYDOWN):
sys.exit()
screen.fill(screen_color) # 清屏
col_lines = [[[screen_margin+i*line_space, screen_margin], [screen_margin +
i*line_space, screen_margin+(col-1)*line_space]] for i in range(col)]
for i, xy_xy in enumerate(col_lines):
line_thickness = 2
if i == 0 or i == len(col_lines)-1:
line_thickness = 4
pygame.draw.line(screen, line_color,
xy_xy[0], xy_xy[1], line_thickness)
row_lines = [[[screen_margin, screen_margin+i*line_space], [screen_margin +
(row-1)*line_space, screen_margin+i*line_space]] for i in range(row)]
for i, xy_xy in enumerate(row_lines):
line_thickness = 2
if i == 0 or i == len(row_lines)-1:
line_thickness = 4
pygame.draw.line(screen, line_color,
xy_xy[0], xy_xy[1], line_thickness)
pygame.draw.circle(screen, line_color, [screen_row/2, screen_col/2], 8, 0)
for x in range(stage.shape[0]): # 外层循环遍历行
for y in range(stage.shape[1]): # 内层循环遍历列
if stage[x][y] == 0:
continue
play_color = black_color if stage[x][y] == -1 else white_color
pygame.draw.circle(screen, play_color, [
screen_margin+x*line_space, screen_margin+y*line_space], 20, 0)
res = find_line_consecutive_ones_v2(stage, line)
time.sleep(0.1)
if len(res) > 0:
for ret in res:
for x, y in ret:
pygame.draw.rect(screen, victory_color, [screen_margin + int(
(x-0.5)*line_space), screen_margin+int((y-0.5)*line_space), line_space, line_space], 2, 1)
pygame.display.update() # 刷新显示
continue # 游戏结束,停止下面的操作
# 获取鼠标坐标信息
x, y = pygame.mouse.get_pos()
x, y = find_pos(x, y)
if stage[x][y] == 0:
pygame.draw.rect(screen, prompt_box_color, [screen_margin + int(
(x-0.5)*line_space), screen_margin+int((y-0.5)*line_space), line_space, line_space], 2, 1)
if pygame.mouse.get_pressed()[0] and tim == 0:
flag = True
if stage[x][y] == 0: # 判断是否可以落子,再落子
if np.sum(stage == 0) % 2 == 0: # 黑子
stage[x][y] = -1
else:
stage[x][y] = 1
# 鼠标左键延时作用
if flag:
tim += 1
if tim % 10 == 0: # 延时200ms
flag = False
tim = 0
pygame.display.update() # 刷新显示