主模块代码:
# -*- coding:utf-8 -*- import sys from tkinter import messagebox import tkinter import pygame import button SCREEN_SIDE = (400, 500) # 屏幕大小 black_color = (0, 0, 0) white_color = (255, 255, 255) yellow_color = (237, 145, 33) COUNTER = 1 # 记录每一步 EMPTY = 0 # 标记空白 BLACK = 1 # 标记黑棋 WHITE = -1 # 标记白棋 class five_chess: def __init__(self): self.color_list = [[]] * 15 # 记录棋盘每一格的状态 self.point_coord = [[]] * 15 # 记录每一步棋的坐标 self.point_color = {} # 记录每一步棋的位置 self.reset() self.resset2() def reset(self): """初始化列表""" for i in range(len(self.color_list)): self.color_list[i] = [EMPTY] * 15 # 设置初始每格的状态都是空 def resset2(self): """初始化列表""" for i in range(len(self.point_coord)): self.point_coord[i] = [EMPTY] * 15 def draw_piece(self, screen, x, y, row, col): """绘制棋子""" global COUNTER # 当计数器为奇数时,绘制黑子,并设置该子的状态为黑棋,保存该子的坐标,位置 if COUNTER % 2 == 1: pygame.draw.circle(screen, black_color, [x, y], 10, 0) self.color_list[row - 1][col - 1] = BLACK self.point_coord[row - 1][col - 1] = [x, y] self.point_color[COUNTER + 1] = [row - 1, col - 1] COUNTER += 1 else: pygame.draw.circle(screen, white_color, [x, y], 10, 0) self.color_list[row - 1][col - 1] = WHITE self.point_coord[row - 1][col - 1] = [x, y] self.point_color[COUNTER + 1] = [row - 1, col - 1] COUNTER += 1 def remv_piece(self, screen): """撤销方法""" global COUNTER # 先将上一步计数器保存的棋子状态设置为空,重新绘制空棋盘,遍历每一格的状态,将黑棋和白棋的状态绘制出来 r = self.point_color[COUNTER][0] c = self.point_color[COUNTER][1] self.color_list[r][c] = EMPTY self.draw_chessboard(screen) for i in range(15): for index, row in enumerate(self.color_list): if row[i] == BLACK: pygame.draw.circle(screen, black_color, self.point_coord[index][i], 10, 0) elif row[i] == WHITE: pygame.draw.circle(screen, white_color, self.point_coord[index][i], 10, 0) COUNTER -= 1 # 将计数器回溯到上一步的数值 def draw_chessboard(self, screen): """绘制棋盘""" pygame.draw.rect(screen, yellow_color, [60, 60, 280, 280], 0) for i in range(1, 16): # 绘制棋盘的线 pygame.draw.line(screen, black_color, [60, 40 + 20 * i], [340, 40 + 20 * i], 1) pygame.draw.line(screen, black_color, [40 + 20 * i, 60], [40 + 20 * i, 340], 1) # 绘制五个小黑点点 pygame.draw.circle(screen, black_color, [120, 120], 3, 0) pygame.draw.circle(screen, black_color, [280, 120], 3, 0) pygame.draw.circle(screen, black_color, [200, 200], 3, 0) pygame.draw.circle(screen, black_color, [120, 280], 3, 0) pygame.draw.circle(screen, black_color, [280, 280], 3, 0) def is_win(self): """判断五子胜利条件""" # 判断竖直方向的胜利条件 for col in range(15): flag = 0 for row in self.color_list: if row[col] == BLACK: flag += 1 if flag == 5: print("黑棋胜利!") return 1 else: flag = 0 for row in self.color_list: if row[col] == WHITE: flag += 1 if flag == 5: print("白棋胜利") return -1 else: flag = 0 # 判断水平方向上的胜利条件 for row in self.color_list: flag = 0 for col in range(15): if row[col] == BLACK: flag += 1 if flag == 5: print("黑棋获胜") return 1 else: flag = 0 for col in range(15): if row[col] == WHITE: flag += 1 if flag == 5: print("白棋获胜") return -1 else: flag = 0 # 判断反斜方向胜利条件 for col in range(-14, 15): for index, row in enumerate(self.color_list): if 0 <= index - col <= 14 and row[index - col] == BLACK: flag += 1 if flag == 5: print("黑棋获胜") return 1 else: flag = 0 for index, row in enumerate(self.color_list): if 0 <= index - col <= 14 and row[index - col] == WHITE: flag += 1 if flag == 5: print("白棋获胜") return -1 else: flag = 0 # 判断正斜方向胜利条件 for col in range(28, 0, -1): for index, row in enumerate(self.color_list): if 0 <= col - index <= 14 and row[col - index] == BLACK: flag += 1 if flag == 5: print("黑棋获胜") return 1 else: flag = 0 for index, row in enumerate(self.color_list): if 0 <= col - index <= 14 and row[col - index] == WHITE: flag += 1 if flag == 5: print("白棋获胜") return -1 else: flag = 0 def main(): global COUNTER root = tkinter.Tk() root.withdraw() # 将创建的窗体进行影藏 pygame.init() pygame.display.set_caption('五子棋') screen = pygame.display.set_mode(SCREEN_SIDE) screen.fill(white_color) # 设置白色背景 wuziqi = five_chess() wuziqi.draw_chessboard(screen) button1 = button.Button(screen, "重新开始", 50, 370, 150, 50) # 绘制按钮,设置坐标和大小 button2 = button.Button(screen, "悔棋", 240, 370, 150, 50) button1.draw_button() button2.draw_button() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: # 监听点击退出事件时 sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: # 当鼠标点击后,并且点的是鼠标左键时 x, y = event.pos # 拿到鼠标在当前窗口上的位置坐标 if button1.rect.collidepoint(x, y): # 当鼠标点击了该按钮的窗口位置时 COUNTER = 1 screen.fill(white_color) button1.draw_button() button2.draw_button() wuziqi.draw_chessboard(screen) wuziqi.reset() wuziqi.resset2() elif button2.rect.collidepoint(x, y): if COUNTER != 1: screen.fill(white_color) button1.draw_button() button2.draw_button() wuziqi.remv_piece(screen) for row in range(16): for col in range(16): if 37 + 20 * col <= x <= 43 + 20 * col and 37 + 20 * row <= y <= 43 + 20 * row: x = 40 + 20 * col y = 40 + 20 * row if wuziqi.color_list[row - 1][col - 1] == EMPTY: wuziqi.draw_piece(screen, x, y, row, col) if wuziqi.is_win() == 1: m = messagebox.askokcancel("恭喜", "黑子胜利\n是否再来一局?") if m: COUNTER = 1 wuziqi.draw_chessboard(screen) wuziqi.reset() else: print("退出程序") sys.exit() elif wuziqi.is_win() == -1: m = messagebox.askokcancel("恭喜", "白子胜利\n是否再来一局?") if m: COUNTER = 1 screen.fill(white_color) button1.draw_button() button2.draw_button() wuziqi.draw_chessboard(screen) wuziqi.reset() wuziqi.resset2() else: sys.exit() pygame.display.flip() pygame.quit() if __name__ == "__main__": main()`
按钮模块代码:
import pygame class Button: def __init__(self, screen, msg, x, y, width, height): # msg为要在按钮中显示的文本 """初始化按钮的属性""" self.screen = screen self.screen_rect = screen.get_rect() self.button_color = (72, 61, 139) # 设置按钮的rect对象颜色为深蓝 self.text_color = (255, 255, 255) # 设置文本的颜色为白色 self.font = pygame.font.SysFont("华文宋体", 16) # 设置文本为华文宋体,字号为16 self.rect = pygame.Rect(x, y, width, height) # self.rect.center = self.screen_rect.center # 创建按钮的rect对象,并使其居中 self.deal_msg(msg) # 渲染图像 def deal_msg(self, msg): """将msg渲染为图像,并将其在按钮上居中""" self.msg_img = self.font.render(msg, True, self.text_color, self.button_color) # render将存储在msg的文本转换为图像 self.msg_img_rect = self.msg_img.get_rect() # 根据文本图像创建一个rect self.msg_img_rect.center = self.rect.center # 将该rect的center属性设置为按钮的center属性 def draw_button(self): self.screen.fill(self.button_color, self.rect) # 填充颜色 self.screen.blit(self.msg_img, self.msg_img_rect) # 将该图像绘制到屏幕