基于python pyqt的围棋游戏制作

这篇具有很好参考价值的文章主要介绍了基于python pyqt的围棋游戏制作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


本文使用python中的pygame库设计制作了一个围棋游戏。
参考项目资料: https://github.com/HapHac/weiqi

1、初始化棋盘

# 绘制棋盘
    def draw_chessboard(self):
        # 画棋盘,填充颜色
        pygame.draw.rect(self.screen, (204, 85, 17), [0 * self.size, 0 * self.size, 400 * self.size, 400 * self.size])
        pygame.draw.rect(self.screen, (51, 102, 153),
                         [400 * self.size, 0 * self.size, 200 * self.size, 400 * self.size])
        # 画外框
        outer_frame_color = (60, 20, 0)
        pygame.draw.rect(self.screen, outer_frame_color,
                         [20 * self.size, 20 * self.size, 360 * self.size, 360 * self.size],
                         5)
        # 棋盘上的九个定位点,以中点为模型,移动位置,以作出其余八个点
        for m in [-1, 0, 1]:
            for n in [-1, 0, 1]:
                rect = pygame.Rect([200 * self.size - self.size * 2,
                                    200 * self.size - self.size * 2,
                                    self.size * 4, self.size * 4])
                pygame.draw.ellipse(self.screen, (0, 0, 0), rect, width=0)
                rect = rect.move(m * self.interval * (2 if self.mode_num == 9 else (3 if self.mode_num == 13 else 6)),
                                 n * self.interval * (2 if self.mode_num == 9 else (3 if self.mode_num == 13 else 6)))
                pygame.draw.ellipse(self.screen, (0, 0, 0), rect, width=0)
        # 画中间的线条
        for i in range(1, self.mode_num - 1):
            pygame.draw.line(self.screen, (0, 0, 0), (20 * self.size, 20 * self.size + i * self.interval),
                             (380 * self.size, 20 * self.size + i * self.interval), width=2)
            pygame.draw.line(self.screen, (0, 0, 0), (20 * self.size + i * self.interval, 20 * self.size),
                             (20 * self.size + i * self.interval, 380 * self.size), width=2)

        # 放置右侧初始图片
        if self.stop:
            self.screen.blit(self.photoW, (480 * self.size, 65 * self.size))
            self.screen.blit(self.photoB, (480 * self.size - 45, 65 * self.size))
        elif self.present == 1:
            self.screen.blit(self.photoB, (480 * self.size - 45, 65 * self.size))
        else:
            self.screen.blit(self.photoW, (480 * self.size, 65 * self.size))
        # # 几个功能按钮
        button_color = (255, 255, 255)

        self.start_button = Button('开始游戏', button_color, 'msyh.ttc', 23)
        self.start_button.draw(self.screen, 480 * self.size, 200 * self.size)
        self.pass_me_button = Button('弃一子', button_color, 'msyh.ttc', 23)
        self.pass_me_button.draw(self.screen, 480 * self.size, 225 * self.size)
        self.regert_button = Button('悔棋', button_color, 'msyh.ttc', 23)
        self.regert_button.draw(self.screen, 480 * self.size, 250 * self.size)
        self.restsrt_button = Button('重新开始', button_color, 'msyh.ttc', 23)
        self.restsrt_button.draw(self.screen, 480 * self.size, 275 * self.size)
        self.thirteen_way_button = Button('十三路棋', button_color, 'msyh.ttc', 23)
        self.thirteen_way_button.draw(self.screen, 480 * self.size, 300 * self.size)
        self.nineteenth_way_button = Button('十九路棋', button_color, 'msyh.ttc', 23)
        self.nineteenth_way_button.draw(self.screen, 480 * self.size, 325 * self.size)
        self.exit_button = Button('退出游戏', button_color, 'msyh.ttc', 23)
        self.exit_button.draw(self.screen, 480 * self.size, 350 * self.size)

在上述代码中,首先绘制棋盘的框架,使用pygame中的pygame.draw.rect,然后通过pygame.draw.line绘制线条,形成完整的棋盘。除此之外,在棋盘的一旁,添加了一个太极图用以表示当前的棋手,以及一些按钮用于控制游戏的进程(按钮使用自定义类完成)。

class Text:
    def __init__(self, text: str, text_color, font_type: str, font_size: int):
        """
        text: 文本内容,注意是字符串形式
        text_color: 字体颜色
        font_type: 字体文件
        font_size: 字体大小
        """
        self.text = text
        self.text_color = text_color
        self.font_type = font_type
        self.font_size = font_size

        font = pygame.font.Font(os.path.join('font', (self.font_type)), self.font_size)
        self.text_image = font.render(self.text, True, self.text_color).convert_alpha()

        self.text_width = self.text_image.get_width()
        self.text_height = self.text_image.get_height()

    def draw(self, surface: pygame.Surface, center_x, center_y):
        """
        surface: 文本放置的表面
        center_x, center_y: 文本放置在表面的<中心坐标>
        """
        upperleft_x = center_x - self.text_width / 2
        upperleft_y = center_y - self.text_height / 2
        surface.blit(self.text_image, (upperleft_x, upperleft_y))


class Button(Text):
    def __init__(self, text: str, text_color, font_type: str, font_size: int):
        super().__init__(text, text_color, font_type, font_size)
        self.rect = self.text_image.get_rect()
        self.enable = True

    def draw(self, surface: pygame.Surface, center_x, center_y):
        super().draw(surface, center_x, center_y)
        self.rect.center = center_x, center_y

    def handle_event(self, command):
        self.hovered = self.rect.collidepoint(pygame.mouse.get_pos())
        if self.hovered:
            if self.enable:
                command()
            else:
                pass

2、初始化棋子

    # 绘制棋子
    def draw_chess(self):
        # 遍历棋盘二维数组,绘制出棋盘中所有已下子
        for i in range(self.mode_num):
            for j in range(self.mode_num):
                pos = i * self.interval + 20 * self.size - 30 * self.p, j * self.interval + 20 * self.size - 30 * self.p
                if self.positions[i][j] == 0:
                    continue
                elif self.positions[i][j] == 1:
                    self.screen.blit(self.photoBD, pos)
                elif self.positions[i][j] == -1:
                    self.screen.blit(self.photoWD, pos)

定义一个数组:self.positions用以存储棋盘中棋子的状态。

3、开始游戏

点击开始游戏按钮,正式开始游戏,删除白色太极图,表示黑棋先行。

    # 开始游戏函数,点击“开始游戏”时调用
    def start(self):
        # 删除右侧太极图
        self.screen.blit(self.bg_rect, (400 * self.size, 65 * self.size))
        # 利用右侧图案提示开始时谁先落子
        if self.present == 1:
            self.screen.blit(self.photoB, (480 * self.size - 45, 65 * self.size))
        else:
            self.screen.blit(self.photoW, (480 * self.size, 65 * self.size))
        # 开始标志,解除stop
        self.stop = None

4、落子设置

首先定义一个函数,用以获取当前鼠标的位置。

    # 获取鼠标当前位置
    def get_mouse_current_position(self, x, y):
        self.mouse_x = x
        self.mouse_y = y

然后设置棋子跟随鼠标移动。

    # 棋子跟随鼠标移动
    def chess_follow(self):
        if 20 * self.size < self.mouse_x < 380 * self.size and 20 * self.size < self.mouse_y < 380 * self.size:
            pos = self.mouse_x - 30 * self.p, self.mouse_y - 35 * self.p
            if self.present == 1:
                self.screen.blit(self.photoBD, pos)
            else:
                self.screen.blit(self.photoWD, pos)

最后定义一个函数,在鼠标左键点击时,落下棋子。

 # 落子,并驱动玩家的轮流下棋行为
    def getDown(self):
        # 拷贝三份棋盘“快照”,悔棋和判断“打劫”时需要作参考
        self.last_3_positions = copy.deepcopy(self.last_2_positions)
        self.last_2_positions = copy.deepcopy(self.last_1_positions)
        self.last_1_positions = copy.deepcopy(self.positions)
        dx = (self.mouse_x - 20 * self.size) % self.interval
        dy = (self.mouse_y - 20 * self.size) % self.interval
        if not self.stop:
            row = int((self.mouse_x - 20 * self.size) / self.interval) + round(dx / self.interval)
            col = int((self.mouse_y - 20 * self.size) / self.interval) + round(dy / self.interval)
            if self.positions[row][col] == 0:
                self.positions[row][col] = self.present
                deadlist = self.get_deadlist()
                self.kill(deadlist)
                # 自杀判定
                # 对方无“气”棋子全部提走后,对己方棋子进行有无“气”的判断,若己方仍存在无“气”棋子,则判定为自杀行为,自杀标志置1(因只需检测到一个无“气”子即说明是自杀,故无需继续检测,跳出循环)
                for i in range(9):
                    for j in range(9):
                        if self.positions[i][j] == self.present:
                            if self.if_dead(i, j) == True:
                                win32api.MessageBox(0, "禁止自杀", "警告", win32con.MB_ICONWARNING)
                                self.positions[i][j] = 0
                                self.present = - self.present
            else:
                # 警告信息框
                win32api.MessageBox(0, "此处以存在棋子", "警告", win32con.MB_ICONWARNING)

5、吃子判断

在每次落子之后,遍历整个棋盘,并返回死棋列表位置

    # 落子后,依次判断四周是否有棋子被杀死,并返回死棋位置列表
    def get_deadlist(self):
        deadlist = []
        for i in range(self.mode_num):
            for j in range(self.mode_num):
                if self.positions[i][j] == 0:
                    continue
                elif self.positions[i][j] == -self.present and self.if_dead(i, j) == True:
                    # continue
                    self.visit_positions = [[0 for k in range(self.mode_num + 2)] for k in range(self.mode_num + 2)]
                    deadlist.append([i, j])
        # print(deadlist)
        return deadlist

判断棋子是否有气函数if_dead

    # 判断棋子是否无气(死亡),有气则返回False,无气则返回无气棋子的列表
    def if_dead(self, x, y):
        # 为避免重复搜索,走过的位置记为1
        self.visit_positions[x][y] = 1
        directions = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]]
        # 左,右,上,下四个方向
        for dx, dy in directions:
            # 左边是墙 或 右边是墙 或 上边是墙 或 下边是墙,即死路,则跳过此方向
            if dx < 0 or dx > 8 or dy < 0 or dy > 8:
                continue
            # 若此方向没有搜索过,则开始搜索
            elif self.visit_positions[dx][dy] == 0:
                # 此方向没有棋子,可看做迷宫的出口,于是该棋子有“气”,停止搜索
                if self.positions[dx][dy] == 0:
                    return False
                # 此方向是对方棋子,是死路,跳过此方向
                elif self.positions[dx][dy] == - self.positions[x][y]:
                    continue
                # 此方向是己方棋子,即通路,继续递归执行DFS
                elif self.positions[dx][dy] == self.positions[x][y]:
                    self.if_dead(dx, dy)
        # 以上条件都不满足,即所有路径都为死路,该棋子无“气”,停止搜索
        return True

杀死死棋

    # 杀死位置列表killList中的棋子,即删除图片,位置值置0
    def kill(self, killList):
        if len(killList) > 0:
            for i, j in killList:
                self.positions[i][j] = 0

6 悔棋和弃一子

    # 放弃一子
    def passme(self):
        self.present = -self.present

    # 悔棋函数
    def regret(self):
        self.positions = self.last_2_positions

7 重新开始、推出与切换棋盘

# 重新开始游戏
    def reload(self):
        self.present = 1
        self.draw_chessboard()
        # 定义棋盘阵列,无子:0,黑棋:1,白棋:-1
        self.positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.visit_positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.draw_chess()

    # 退出游戏
    def exit(self):
        pygame.quit()
        sys.exit()

    # 更改游戏棋盘
    def newgame1(self):
        self.mode_num = 13
        # 棋盘每格的边长
        self.interval = 360 * self.size / (self.mode_num - 1)
        # 相对九路棋盘的矫正比例
        self.p = 1 if self.mode_num == 9 else (2 / 3 if self.mode_num == 13 else 4 / 9)
        # 定义棋盘阵列,无子:0,黑棋:1,白棋:-1
        self.positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.visit_positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.photoBD = pygame.image.load("./Pictures/" + "BD" + "-" + str(self.mode_num) + ".png")  # .convert()
        self.photoWD = pygame.image.load("./Pictures/" + "WD" + "-" + str(self.mode_num) + ".png")  # .convert()

    # 更改游戏棋盘
    def newgame2(self):
        self.mode_num = 19
        # 棋盘每格的边长
        self.interval = 360 * self.size / (self.mode_num - 1)
        # 相对九路棋盘的矫正比例
        self.p = 1 if self.mode_num == 9 else (2 / 3 if self.mode_num == 13 else 4 / 9)
        # 定义棋盘阵列,无子:0,黑棋:1,白棋:-1
        self.positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.visit_positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.photoBD = pygame.image.load("./Pictures/" + "BD" + "-" + str(self.mode_num) + ".png")  # .convert()
        self.photoWD = pygame.image.load("./Pictures/" + "WD" + "-" + str(self.mode_num) + ".png")  # .convert()

8 显示

    def show(self):
        while True:
            pygame.display.flip()
            self.clock = pygame.time.Clock()
            # 绘制棋盘
            self.draw_chessboard()
            # 绘制棋子
            self.draw_chess()
            if not self.stop:
                # 棋子跟随鼠标移动
                self.chess_follow()
            # 监听所有事件
            for event in pygame.event.get():
                # 点击x则关闭窗口
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                # 点击窗口里面类容则完成相应指令
                elif event.type == MOUSEMOTION:
                    x, y = event.pos
                    self.get_mouse_current_position(x, y)
                elif event.type == MOUSEBUTTONDOWN:
                    # 鼠标点击按钮函数
                    self.start_button.handle_event(self.start)
                    self.pass_me_button.handle_event(self.passme)
                    self.regert_button.handle_event(self.regret)
                    self.restsrt_button.handle_event(self.reload)
                    self.thirteen_way_button.handle_event(self.newgame1)
                    self.nineteenth_way_button.handle_event(self.newgame2)
                    self.exit_button.handle_event(self.exit)
                    # 如果鼠标左键在棋盘内按下
                    if 20 * self.size < self.mouse_x < 380 * self.size and 20 * self.size < self.mouse_y < 380 * self.size:
                        self.getDown()
                        self.present = - self.present

9 初始化

class weiqi():
    def __init__(self):
        # 模式,九路棋:9,十三路棋:13,十九路棋:19
        self.mode_num = 9
        # 窗口尺寸设置,默认:1.8
        self.size = 1.8
        # 棋盘每格的边长
        self.interval = 360 * self.size / (self.mode_num - 1)
        # 相对九路棋盘的矫正比例
        self.p = 1 if self.mode_num == 9 else (2 / 3 if self.mode_num == 13 else 4 / 9)
        # 定义棋盘阵列,无子:0,黑棋:1,白棋:-1
        self.positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        self.visit_positions = [[0 for i in range(self.mode_num + 2)] for i in range(self.mode_num + 2)]
        # 当前轮到的玩家,黑:1,白:-1,执黑先行
        self.present = 1
        # 初始停止运行,点击“开始游戏”运行游戏
        self.stop = True
        # 悔棋次数,次数大于0才可悔棋,初始置0(初始不能悔棋),悔棋后置0,下棋或弃手时恢复为1,以禁止连续悔棋
        self.regretchance = 0
        self.mouse_x = -100
        self.mouse_y = -100
        self.last_1_positions = copy.deepcopy(self.positions)
        self.last_2_positions = copy.deepcopy(self.positions)
        self.last_3_positions = copy.deepcopy(self.positions)

        pygame.init()
        # 创建一个窗口
        self.screen = pygame.display.set_mode([600 * self.size, 400 * self.size])
        # 设置窗口标题
        pygame.display.set_caption("围棋")

        self.photoW = pygame.image.load("./Pictures/W.png")  # .convert()
        self.photoB = pygame.image.load("./Pictures/B.png")  # .convert()
        self.photoBD = pygame.image.load("./Pictures/" + "BD" + "-" + str(self.mode_num) + ".png")  # .convert()
        self.photoWD = pygame.image.load("./Pictures/" + "WD" + "-" + str(self.mode_num) + ".png")  # .convert()
        self.bg_rect = pygame.Surface((200 * self.size, 100 * self.size), flags=pygame.HWSURFACE)
        self.bg_rect.fill((51, 102, 153))

完整代码
https://download.csdn.net/download/m0_55818687/87698112文章来源地址https://www.toymoban.com/news/detail-594489.html

到了这里,关于基于python pyqt的围棋游戏制作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 强化学习Agent系列(一)——PyGame游戏编程,Python 贪吃蛇制作实战教学

    大家好,未来的开发者们请上座 随着人工智能的发展,强化学习基本会再次来到人们眼前,遂想制作一下相关的教程。强化学习第一步基本离不开虚拟环境的搭建,下面用大家耳熟能详的贪吃蛇游戏为基础,制作一个Agent,完成对这个游戏的绝杀。 万里长城第一步:用pytho

    2024年01月21日
    浏览(65)
  • Python 程序员过中秋Python+pygame 制作拼图小游戏(附源码:5源码)

    Python 程序员过中秋Python+pygame 制作拼图小游戏(附源码:5源码) 又是一年中秋至一花好月 圆夜,佳文当共鉴。Python+ pygame制作拼图小游戏; 制作一个自己的拼图小游戏,看看几步可以观赏到月亮。 官方活动入口 ​ 本文档是对Python语言制作拼图小游戏界面功能需求进行分析归

    2023年04月09日
    浏览(48)
  • 基于Python的pygame库的五子棋游戏

    2024年04月09日
    浏览(44)
  • 【pygame】01 pygame制作游戏的最小系统

    这次使用sublime+python进行pygame的游戏开发,目的是学习使用python的基本操作和常用模块 添加一个文件夹到工程 1.导入使用的模块 2.初始化:pygame.init函数包含了各个子模块的初始化,可以重复调用 3.pygame.display.set_mode返回一个特殊的Surface,之后所有的操作都体现在这个Surface

    2024年02月09日
    浏览(69)
  • 基于Python的PyGame的俄罗斯方块游戏设计与实现

    近年来,随着游戏产业的突飞猛进,游戏玩家的技术也是与日俱增,当你看见游戏高手完美的表演时,你是否想过我也能达到那种水平,本程序用Python语言编写俄罗斯方块,左侧显示正在运行的游戏,右边显示下一个出现的形状、等级和积分等。游戏运行时随着等级的提高而

    2024年02月04日
    浏览(57)
  • 用Python编写的超级马里奥小游戏(基于Pygame)

    在本文中,我将向您展示如何使用Python编写一个简单的超级马里奥小游戏,使用Pygame库来处理游戏的图形和输入。 首先,我们需要确保已安装Pygame库。您可以使用以下命令在终端或命令提示符中安装Pygame: 一旦安装完成,我们就可以开始编写代码了。下面是完整的Python代码

    2024年01月16日
    浏览(50)
  • 基于Python+Pygame实现一个俄罗斯方块小游戏【完整代码】

    俄罗斯方块,一款起源于上世纪80年代的经典电子游戏,凭借简单的规则和独特的魅力,一跃成为全球家喻户晓的经典。你知道其实只需要一些基础的编程知识,就可以自己实现它吗?今天,我们将使用Python的Pygame库,一步步带你构建属于自己的俄罗斯方块小游戏! 游戏初始

    2024年02月04日
    浏览(50)
  • 基于Python pygame简易版斗兽棋小游戏源代码

    基于Python pygame简易版斗兽棋小游戏源代码 游戏规则如下: 胜利条件: 1.吃掉对方全部棋子 2.走入对方兽穴(不可进入自己洞穴) 吃法: 1.象狮虎豹狼狗猫鼠象 2.同类棋子先行者吃掉对方 3.老鼠可以进河,老鼠在河里时,岸上的动物不能捕食他,他也不能捕食岸上的动物 4.狮虎在河中没

    2023年04月09日
    浏览(120)
  • pygame制作rpg类游戏或者模拟经营类游戏的思路

    Pygame 能够支持开发 RPG 类或者模拟经营类游戏。Pygame 提供了图形界面、事件处理、音频处理等基础功能,开发者可以利用这些功能实现自己的游戏逻辑。 例如,开发者可以利用 Pygame 实现以下功能: 地图绘制和移动:通过 Pygame 提供的绘图函数和事件处理函数,实现地图的绘

    2024年02月05日
    浏览(47)
  • Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

    Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk 程序依赖:pygame 2.0.1, pymunk 5.5.0 直接运行main.py 完整代码下载地址:Python版经典小游戏愤怒的小鸟源代码 tool.py 完整代码下载地址:Python版经典小游戏愤怒的小鸟源代码

    2024年02月16日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包