You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
7.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# -*- coding: utf-8 -*-
"""
Created on Fri May 24 19:55:20 2024
@author: 李庆
"""
import pygame
import Gomoku
import QMessageBox
import pygame.time
# 初始化pygame
pygame.init()
screen = pygame.display.set_mode((600, 600)) # 设置窗口长宽
pygame.display.set_caption('五子棋-EduCoder') # 设置 pygame 窗口名
space = 20 # 四周留下的边距
cell_size = 40 # 每个格子大小
cell_num = 15 #设置线条数
chess_arr = [] #创建列表记录落子位置
#加入背景音乐
file=r"D:\python课\轻松时光乐团 - 心灵和鸣.mp3"
pygame.mixer.init()
track=pygame.mixer.music.load(file)
pygame.mixer.music.play(-1)
myfont = pygame.font.Font()
# 初始化Clock对象
clock = pygame.time.Clock()
remaining_time = 300 * 1000 # 300秒转换为毫秒
def get_one_dire_num(lx, ly, dx, dy, m):
#将最后的x坐标赋值给tx
tx = lx
#将最后的y坐标赋值给tx
ty = ly
#判断连子
s = 0
while True:
#判断上下左右斜方向是否有连子
tx += dx
ty += dy
#如果没有的连子的话返回当前连子数量
if tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or m[ty][tx] == 0: return s
#连子累加 1
s+=1
def check_win(chess_arr, flag):
m = [[0] * cell_num for i in range(cell_num)] # 先定义一个15*15的全0的数组,不能用[[0]*cell_num]*cell_num的方式去定义因为一位数组会被重复引用
for x, y, c in chess_arr:
if c == flag:
m[y][x] = 1 # 上面有棋则标1
lx = chess_arr[-1][0] # 最后一个子的x
ly = chess_arr[-1][1] # 最后一个子的y
dire_arr = [[(-1, 0), (1, 0)], [(0, -1), (0, 1)], [(-1, -1), (1, 1)],
[(-1, 1), (1, -1)]] # 4个方向数组,往左往右、往上往下、往左上往右下、往左下往右上4组判断方向
for dire1, dire2 in dire_arr:
# 往左,往上,往左上,往左下判断是否有连子
dx, dy = dire1
num1 = get_one_dire_num(lx, ly, dx, dy, m)
# 往右,往下,往右下、往右上判断是否有连子
dx, dy = dire2
num2 = get_one_dire_num(lx, ly, dx, dy, m)
# 不同方向加起来的连子数为5的则获胜返回True
if num1 + num2 + 1 >= 5: return True
return False
flag = 1 # 1=》黑 2=》白
game_state = 1 # 游戏状态1.表示正常进行 2.表示白胜 3.表示黑胜
while True: # 死循环确保窗口一直显示
# 控制帧率
fps = 60 # 设定帧率
dt = clock.tick(fps) # 传递你想要的帧率给tick方法
# 减去经过的时间
remaining_time -= dt
# 检查是否时间耗尽
if remaining_time <= 0:
# 设置游戏状态为平局或其他你想要的逻辑
game_state = 4 # 假设4表示平局
break # 跳出循环
for event in pygame.event.get(): # 遍历所有事件
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
pygame.quit() #关闭 pygame 程序
exit() #结束程序
if game_state == 1 and (event.type == pygame.MOUSEBUTTONUP and event.button==1): # 鼠标弹起
x, y = pygame.mouse.get_pos() # 获取鼠标位置
file=r"D:\python课\落子声音.mp3"
pygame.mixer.init()
track=pygame.mixer.music.load(file)
pygame.mixer.music.play(1)
xi = int(round((x - space) * 1.0 / cell_size)) # 获取到x方向上取整的序号
yi = int(round((y - space) * 1.0 / cell_size)) # 获取到y方向上取整的序号
if xi >= 0 and xi < cell_num and yi >= 0 and yi < cell_num and (xi, yi,1) not in chess_arr and (xi, yi,2) not in chess_arr:
chess_arr.append((xi, yi,flag))
#调用函数判断下的该子是否获胜
if check_win(chess_arr, flag):
#若状态值为 1 则表示3否则表示2
game_state = 2 if flag == 1 else 3
else:
#若状态值为 1 则表示 2 否则为 1代表转换棋子
flag = 2 if flag == 1 else 1
#悔棋
if game_state == 1 and (event.type == pygame.MOUSEBUTTONUP and event.button==3):
flag=chess_arr[-1][-1]
chess_arr.pop(-1)
screen.fill((204, 153, 102)) # 将界面设置棕色
#遍历横位置点步长为40
#pygame.draw.line(窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小 )
for x in range(0, cell_size * cell_num, cell_size):
pygame.draw.line(screen, (200, 200, 200), (x + space, 0 + space),
(x + space, cell_size * (cell_num - 1) + space), 1)
# 遍历竖位置点步长为40
# pygame.draw.line(窗口, 线条颜色, 开始坐标, 结束坐标, 线条大小 )
for y in range(0, cell_size * cell_num, cell_size):
pygame.draw.line(screen, (200, 200, 200), (0 + space, y + space),
(cell_size * (cell_num - 1) + space, y + space), 1)
#绘制棋子
for x, y,c in chess_arr:
chess_color = (30, 30, 30) if c == 1 else (225, 225, 225)
pygame.draw.circle(screen, chess_color, [x * cell_size + space, y * cell_size + space], 16, 16)
# 绘制五个点
# pygame.draw.circle(窗口,颜色,坐标,圆半径,线条大小)
lst1=[(4, 4,1),(10, 10, 1),(10, 4, 1),(4, 10, 1),(7, 7, 1)]
lst2=[(4, 4,2),(10, 10, 2),(10, 4, 2),(4, 10, 2),(7, 7, 2)]
for i in range(len(lst1)):
a=lst1[i]
b=lst2[i]
if a not in chess_arr and b not in chess_arr:
pygame.draw.circle(screen, (0, 0, 0), (cell_size * a[0] + space, cell_size * b[1] + space), 2, 1)
# 绘制剩余时间
time_text = "Time remaining: {:.2f}s".format(remaining_time / 1000)
time_image = myfont.render(time_text, True, (255,255,255))
screen.blit( (10, 10)) # 假设在屏幕左上角显示剩余时间
pygame.display.update() # 必须调用update才能看到绘图显示
if game_state != 1 and (game_state == 2 or game_state == 3):
myfont = pygame.font.Font(None, 60)
white = 210, 210, 0
win_text = "%s win" % ('black' if game_state == 2 else 'white')
textImage = myfont.render(win_text, True, white)
screen.blit(textImage, (260, 320))
else :
win_text = "Draw"
textImage = myfont.render(win_text, True, white)
screen.blit(textImage, (260, 320))
pygame.display.update() # 必须调用update才能看到绘图显示
def game_restart(game,game_state):
#显示游戏结束信息
if game_state==2:
QMessageBox.about(game,'游戏结束','白棋胜')
elif game_state==3:
QMessageBox.about(game,'游戏结束','黑棋胜')
elif game_state==4:
QMessageBox.about(game,'游戏结束','平局')
else:
raise ValueError('游戏结束的标志必须为23或4')
#重新开始游戏(再来一局)
game.g=Gomoku()
game.repaint(0,0,600,600)