返回顶部
首页 > 资讯 > 后端开发 > Python >Python:游戏:五子棋之人机对战
  • 595
分享到

Python:游戏:五子棋之人机对战

人机对战五子 2023-01-30 23:01:52 595人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

本文代码基于 python3.6 和 pygame1.9.4。 五子棋比起我之前写的几款游戏来说,难度提高了不少。如果是人与人对战,那么,电脑只需要判断是否赢了就可以。如果是人机对战,那你还得让电脑知道怎么下。 我们先从简单的问题来

本文代码基于 python3.6 和 pygame1.9.4。

五子棋比起我之前写的几款游戏来说,难度提高了不少。如果是人与人对战,那么,电脑只需要判断是否赢了就可以。如果是人机对战,那你还得让电脑知道怎么下。

我们先从简单的问题来看。

开端

画棋盘

首先肯定是要画出棋盘来,用 pygame 画出一个 19 × 19 或 15 × 15 的棋盘并不是什么难事,这在之前的文章中已经多次用到,就不赘述了。

画棋子

需要说一下的是画棋子,因为没找到什么合适的棋子图片,所以只要自己来画棋子。
我们用 pygame.draw.circle 画出来的圆形是这样的:


锯齿状十分明显,pygame.draw 中有画抗锯齿直线的函数 aaline,但是并没有 aacircle 这样的函数来画一个抗锯齿的圆。

这里就需要用到 pygame.gfxdraw 啦。pygame.gfxdraw 目前还仅是实验版本,这意味着这个 API 可能会在以后的 pygame 版本中发生变化或消失。

要绘制抗锯齿和填充形状,请首先使用函数的aa *版本,然后使用填充版本。例如:

col = (255, 0, 0)
surf.fill((255, 255, 255))
pygame.gfxdraw.aacircle(surf, x, y, 30, col)
pygame.gfxdraw.filled_circle(surf, x, y, 30, col)

我们用这个方法在棋盘上画一个棋子试试看。

可以看到效果已明显改善。

落子

落子需要判断鼠标事件,当鼠标左键点击,获取鼠标点击的位置,然后根据棋盘的位置,计算出棋子落在棋盘的位置。

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            elif event.type == MOUSEBUTTONDOWN:
                pressed_array = pygame.mouse.get_pressed()
                if pressed_array[0]:  # 鼠标左键点击
                    mouse_pos = pygame.mouse.get_pos()
                    click_point = _get_clickpoint(mouse_pos)

胜利判定

当一子落下,如何判定是否胜利?

可以肯定的是,当某一子落下的时候,如果出现了 5 连,那么落下的这颗子必定在这条 5 连线上。那么这个问题就可以简化了,我们无需全盘扫描,只需要在落子位置上横竖撇捺扫描一下,判断是否出现 5 连即可。

我们定义一个棋盘类,类中实例化一个 19 × 19 的二维数组,初始值皆为 0,表示空,用 1 表示黑子,2 表示白子。这个类对外提供一个落子方法 drop,接收参数落子方和落子坐标,如果落子后胜利,则返回胜利者,否则返回 None。

CheSSMan = namedtuple('Chessman', 'Name Value Color')
Point = namedtuple('Point', 'X Y')

BLACK_CHESSMAN = Chessman('黑子', 1, (45, 45, 45))
WHITE_CHESSMAN = Chessman('白子', 2, (219, 219, 219))

offset = [(1, 0), (0, 1), (1, 1), (1, -1)]


class Checkerboard:
    def __init__(self, line_points):
        self._line_points = line_points
        self._checkerboard = [[0] * line_points for _ in range(line_points)]

    def _get_checkerboard(self):
        return self._checkerboard

    checkerboard = property(_get_checkerboard)

    # 判断是否可落子
    def can_drop(self, point):
        return self._checkerboard[point.Y][point.X] == 0

    def drop(self, chessman, point):
        """
        落子
        :param chessman: 黑子/白子
        :param point:落子位置
        :return:若该子落下之后即可获胜,则返回获胜方,否则返回 None
        """
        print(f'{chessman.Name} ({point.X}, {point.Y})')
        self._checkerboard[point.Y][point.X] = chessman.Value

        if self._win(point):
            print(f'{chessman.Name}获胜')
            return chessman

    # 判断是否赢了
    def _win(self, point):
        cur_value = self._checkerboard[point.Y][point.X]
        for os in offset:
            if self._get_count_on_direction(point, cur_value, os[0], os[1]):
                return True

    def _get_count_on_direction(self, point, value, x_offset, y_offset):
        count = 1
        for step in range(1, 5):
            x = point.X + step * x_offset
            y = point.Y + step * y_offset
            if 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:
                count += 1
            else:
                break
        for step in range(1, 5):
            x = point.X - step * x_offset
            y = point.Y - step * y_offset
            if 0 <= x < self._line_points and 0 <= y < self._line_points and self._checkerboard[y][x] == value:
                count += 1
            else:
                break

        return count >= 5

这里我定义了一个偏移量,我们一共要计算横竖撇捺 4 条线,任意一条线出现 5 连就算获胜。计算方法实际上是一样的,只是方向不同,所以定义一个偏移量数组,不同的偏移量表示不同的方向,这样就可以利用循环来实现了,节省了很多代码。

电脑落子

这就是全篇的重头戏了,要怎么教电脑下五子棋。
首先声明,我用的是相对传统的方式,不是深度学习

五子棋就是要实现 5 连,所以,一开始,我的想法是:将所有连线保存在一个数组中,落子的时候选择最长的连线落子。但这样有个问题解决不掉,如何让电脑识别“三三”呢?

后来网上看到篇文章,使用的方法是:遍历棋盘上的空位,计算每一个位置其横竖撇捺 8 个方向上是否有己方的子,有一个就加 10 分,最后选得分最高的位置落子。

这样不太严谨,写出来的电脑估计水平很菜,但是这个思路却是对的,落子就是要找到最值得的地方,那么我们干脆对每一个可落子的地方来做一个评估,选出最优解。

这里我们需要了解一下五子棋的几种基本棋形:连五,活四,冲四,活三,眠三,活二,眠二。

连五

顾名思义,五颗同色棋子连在一起,赢了。


活四

四颗同色棋子连在一起,并且左右两边都没有对方棋子阻挡,有两个连五点。


冲四

四颗同色棋子连在一起,并且一边有对方棋子阻挡,或者四颗棋子不是连的,当中有个空挡,这时只有一个连五点。


活三、跳活三

活三:三颗同色棋子连在一起。

跳活三:中间隔了一个空格的活三。


眠三

只能够形成冲四的三,无外乎两种情况,一是一边被挡住了,一是当中有 2 个空格。(其实我在代码中仅考虑了第一种情况,即便形成冲四,也不是什么危险局面。)


活二和眠二

活二,能够形成活三的二;眠二,能够形成眠三的二。这里就不放图了,参考活三眠三。

打分机制

理解了这些棋形,那么按我们之前的思路,就是如何打分了。

  • 首先,连五肯定是不存在的,出现连五胜负已分,所以只要棋局还在进行中,就不会出现连五。那么,什么优先级最高?自然就是活四了。
  • 其次是对方的“四”,对方活四,你防不防都一样输了,对方冲四,你就必须防守。
  • 再次是我方的活三或冲四,活三跟冲四其实是一个级别的,对方必须防守。
  • 再次是对方的活三或冲四。

以此类推下去。我们可以总结一点规律:

  • 相同的棋形,我方优于对方。
  • 冲四跟活三一个级别,眠三跟活二一个级别。
  • 如果中间有空格的话,肯定是要比没空格的略微低级一点,但不至于降级。

基本逻辑就是这样,这一块的代码我写得也不好,整个判断写了100多行,就不贴代码了,大家可以直接下源码看。

五子棋执黑是必赢的,代码中,玩家就是执黑先手,电脑执白后手,所以,下的好是完全可以赢电脑的,不过一个小小失误也很可能被电脑翻盘。

扫码关注我的公众号,后台回复 五子棋,获取源码。

 


 

相关博文推荐:

python:游戏:贪吃蛇

Python:游戏:扫雷(附源码)

Python:游戏:300行代码实现俄罗斯方块

--结束END--

本文标题: Python:游戏:五子棋之人机对战

本文链接: https://lsjlt.com/news/180992.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Python:游戏:五子棋之人机对战
    本文代码基于 python3.6 和 pygame1.9.4。 五子棋比起我之前写的几款游戏来说,难度提高了不少。如果是人与人对战,那么,电脑只需要判断是否赢了就可以。如果是人机对战,那你还得让电脑知道怎么下。 我们先从简单的问题来...
    99+
    2023-01-30
    人机 对战 五子
  • python实现人机对战的五子棋游戏
    本文实例为大家分享了python实现五子棋游戏的具体代码,供大家参考,具体内容如下 checkerboard.py from collections import namedtupl...
    99+
    2024-04-02
  • python实现人人对战的五子棋游戏
    python五子棋之人人对战,供大家参考,具体内容如下 checkerboard.py from collections import namedtuple Chessman = ...
    99+
    2024-04-02
  • Java实现在线五子棋对战游戏(人机对战)
    目录1. 人机对战1.1 演示1.2 评分表1.3 算法思路1.4 具体代码1. 人机对战 要增添一个人机对战的模块, 最大的难点就是如何让人机知道下在什么位置是最好的, 不仅要具备...
    99+
    2024-04-02
  • python实现单机五子棋对战游戏
    本文实例为大家分享了python实现单机五子棋对战的具体代码,供大家参考,具体内容如下  引入pygame模块  # 1、引入pygame 和 pygame.locals ...
    99+
    2024-04-02
  • python怎么实现人人对战的五子棋游戏
    这篇文章主要介绍“python怎么实现人人对战的五子棋游戏”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python怎么实现人人对战的五子棋游戏”文章能帮助大家解决问题。checkerboard.p...
    99+
    2023-06-30
  • 基于Python怎么实现人机对战五子棋游戏
    人人对战游戏规则:p1为黑子,p2为白子,黑子先手,一方达到五子相连即为获胜。动态演示源码分享cheackboard.py定义黑白子,落子位置以及获胜规则。from collections import namedtuple Chessm...
    99+
    2023-05-20
    Python
  • Python实现五子棋联机对战小游戏
    目录效果演示开发工具环境搭建主要代码修改的地方效果演示 开发工具 Python版本: 3.6.4 相关模块: pygame模块; PyQt5模块; 以及一些Python自带的模块。...
    99+
    2024-04-02
  • Python实现五子棋人机对战 和人人对战
    目录人人对战动态演示源码分享人人对战.py人机对战动态演示前言: 过完520,咱们来玩玩五子棋陶冶情操。快拿这个和你女朋友去对线。多的不说直接进入正题 人人对战 游戏规则:p1为黑子...
    99+
    2024-04-02
  • 怎么用批处理实现五子棋人机对战游戏
    这篇文章主要介绍怎么用批处理实现五子棋人机对战游戏,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!效果图:核心代码:代码如下:@echo off&setlocal enabledelayedexpansions...
    99+
    2023-06-08
  • Python如何实现五子棋人机对战和人人对战
    这篇文章主要介绍“Python如何实现五子棋人机对战和人人对战”,在日常操作中,相信很多人在Python如何实现五子棋人机对战和人人对战问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python如何实现五子棋...
    99+
    2023-06-30
  • python游戏实战项目之智能五子棋
    目录导语正文总结导语 ​ 今日游戏更新,大家好,我是木木子,每天都给大家更新最好玩的游戏!关注我,从此你再也不用去费力找游戏了! 最热门最好玩的Python游戏点击即玩!...
    99+
    2024-04-02
  • 基于Python实现五子棋-(人机对战)
    目录前言人人对战动态演示源码分享人机对战前言 快520了,咱们来玩玩五子棋陶冶情操。快拿这个和你女朋友去对线。(分了别来找我哇)。多的不说直接进入正题 人人对战 游戏规则:p1为黑子...
    99+
    2024-04-02
  • java实现双人五子棋游戏
    本文实例为大家分享了java实现双人五子棋游戏的具体代码,供大家参考,具体内容如下 通过 上下左右 控制棋盘走动  空格落子   (深度优先搜索) packag...
    99+
    2024-04-02
  • python编写五子棋游戏
    本文实例为大家分享了python编写五子棋游戏的具体代码,供大家参考,具体内容如下 游戏代码及部分注释 import pygame #导入pygame游戏模块 import time ...
    99+
    2022-06-02
    python 五子棋
  • python实现人机对战的井字棋游戏
    本文实例为大家分享了python实现人机对战井字棋的具体代码,供大家参考,具体内容如下 游戏简介:在九宫格内进行,如果一方抢先于另一方向(横、竖、斜)连成3子,则获得胜利。游戏中输入...
    99+
    2024-04-02
  • 微信小程序实战之双人五子棋游戏是实现
    目录一、项目展示二、项目核心代码三、效果展示一、项目展示 微信小程序项目实例——双人五子棋 双人五子棋是一款游戏小程序 两位选手可以在15x15的棋盘上 进行...
    99+
    2024-04-02
  • python游戏实战项目之智能五子棋简易版
    目录导语正文总结导语 前段时间不是制作了一款升级版本五子棋的嘛! 但是居然有粉丝私信我说: “准备拿到代码玩一下ok过去了!太难了准备放收藏夹落灰q@q~” 所噶,今天先放一个简...
    99+
    2024-04-02
  • Java实现五子棋对战小游戏【完整版】
     个人简介 👨🏻‍💻个人主页:陈橘又青 🏃🏻‍♂️博客记录心情,代码编写人生。 🌟如果文章对你有用,麻烦关注点赞收藏走一波,感谢支持!...
    99+
    2023-09-03
    java 开发语言
  • pythonPyGame五子棋小游戏
    目录前言五子棋小游戏1、简介2、环境准备3、初始化环境4、棋盘5、黑白棋子6、对局信息7、AI8、完善总结前言 PyGame 是一个专门设计来进行游戏开发设计的 Python 模块,...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作