python+pygame实现五子棋人机对战之三

news2024/9/27 17:32:23

上回讲过:

python+pygame实现五子棋人机对战之一

python+pygame实现五子棋人机对战之二

界面已经有了,并且可以支持鼠标操作选择菜单和人机对战开始下棋了,那电脑是如何应手落子呢?以下内容是通用的类,全部放在utils.py中

四、

最常见的基本棋型大体有以下几种:连五,活四,冲四,活三,眠三,活二,眠二了,下面简要讲解一下:

4.1 连五:五颗同色棋子连在一起

4.2 活四:由4枚同色棋子形成的两端没有对方棋子的四枚棋子

4.3 冲四一(连四):由4枚同色棋子形成的一端有对方棋子的四枚棋子

4.4 冲四二(跳四):由4枚同色棋子形成的中间没有对方棋子的四枚棋子。

4.5 眠四:由4枚同色棋子形成的两端有对方棋子的4枚棋子。  不能成五的四连。

相对比活四来说,冲四的威胁性就小了很多,此时,防守方只要跟着防守在那个唯一的连五点上,冲四就没法形成连五。

4.6 活三一(连三):由3枚同色棋子形成连三、跳三。  再走一着可以形成活四的三。 两端都是威胁的活三。简称“连三”。

4.7 活三二(跳三):由3枚同色棋子形成的中间没有对方棋子的三枚棋子。中间夹有一个威胁的活三。简称“跳三”。

4.8 眠三:由3枚同色棋子形成的两端有对方棋子的3枚棋子。  即再走一着可以形成冲四的三。眠三的形状是很丰富的。眠三的棋型与活三的棋型相比,危险系数下降不少,因为眠三棋型即使不去防守,下一手它也只能形成冲四,而对于单纯的冲四棋型,我们是可以防守住的。

活三可以形成眠三,但也能够形成活四。眠三只能够形成冲四。

4.9 活二 :由2枚同色棋子形成的连二(由2枚同色棋子连在一起形成的两头没有对方棋子的2枚棋子。)、跳二(由2枚同色棋子形成的中间没有对方棋子的2枚棋子。)、大跳二(中间有两个空白位置的跳二)。

4.10 眠二 :由2枚同色棋子形成的两端有对方棋子的2枚棋子。是能够形成眠三的二。

               

对于棋盘上每一个交叉点,会有8个方向连成五子的可能性,那么我们就利用算法算出所有的可能性,并根据它成五的概率给它打分,这样,得分最高的就是最好的落子点。

如何去实现呢?首先我们在8个方向上将其抽象成坐标的加减,例如水平向右,那么x+1,y不变,向右上,则x+1,y+1 .按正下方开始,逆时针8个方向就形成下面的数据结构:

directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]

 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外。

from params import Params

rows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))

# 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外
def getpointpiece(_mapchess,pos, src, offset):
    # 8个方向
    directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]
    x1, y1 = pos
    x1 = x1 + directions[src - 1][0] * offset * blocksize
    y1 = y1 + directions[src - 1][1] * offset * blocksize
    if x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28:
        return 5
    else:
        return _mapchess[str(x1) + ',' + str(y1)]

再加上刚才分析的五子棋的基本棋型,可以设计出一个打分算法:

from params import Params

rows = int(Params.get('ROWS'))
blocksize = int(Params.get('blockSize'))
width = int(Params.get('WIDTH'))
height = int(Params.get('HEIGHT'))

# 判断每个点的value,用来排序该点下棋的可行性
def pointvalue(_mapchess, pos, flag1, flag2):
    value = 0    #加权值
    for i in range(1, 9):  #8个方向
        # 11111   连五
        if getpointpiece(_mapchess,pos, i, 1) == flag1 and \
                getpointpiece(_mapchess,pos, i, 2) == flag1 and \
                getpointpiece(_mapchess,pos, i, 3) == flag1 and \
                getpointpiece(_mapchess,pos, i, 4) == flag1 and \
                getpointpiece(_mapchess,pos, i, 5) == flag1:
            value += 1000000
        # *1111_ 活四
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == 0:
            value += 50000
        # *11112 冲四1,冲四指加一个点就是连五,比活四威力小得多
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == flag2:
            value += 30000
        # 1*111 冲四2
        if getpointpiece(_mapchess, pos, i, -1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1:
            value += 30000
        # 11*11 冲四3
        if getpointpiece(_mapchess, pos, i, -2) == flag1 and \
                getpointpiece(_mapchess, pos, i, -1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1:
            value += 30000
        # *111_ 活三1,活三可以形成活四的三
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == 0:
            value += 20000
        # *1_11_ 活三2
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == 0:
            value += 20000
        # *1112 眠三1  眠三是只能形成冲四的三
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == flag2:
            value += 15000
        # _1_112 眠三2
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == flag2:
            value += 15000
        # _11_12 眠三3
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == 0 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == flag2:
            value += 15000
        # 1__11 眠三4
        if getpointpiece(_mapchess, pos, i, -1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 1) == 0 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1:
            value += 15000
        # 1_1_1 眠三5
        if getpointpiece(_mapchess, pos, i, -1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1:
            value += 15000
        # 2_111_2 眠三6
        if getpointpiece(_mapchess, pos, i, -1) == flag2 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == 0 and \
                getpointpiece(_mapchess, pos, i, 5) == flag2:
            value += 15000
        # __11__ 活二1  活二能够形成活三的二
        if getpointpiece(_mapchess, pos, i, -1) == 0 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == 0 and \
                getpointpiece(_mapchess, pos, i, 4) == 0:
            value += 10000
        # _1_1_ 活二2
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == 0:
            value += 10000
        # 211__ 眠二1 ,能够形成眠三的二
        if getpointpiece(_mapchess, pos, i, -1) == flag2 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == flag1 and \
                getpointpiece(_mapchess, pos, i, 3) == 0 and \
                getpointpiece(_mapchess, pos, i, 4) == 0 and \
                getpointpiece(_mapchess, pos, i, 5) == 0:
            value += 1000
        #21_1__ 眠二2
        if getpointpiece(_mapchess, pos, i, -1) == flag2 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == flag1 and \
                getpointpiece(_mapchess, pos, i, 4) == 0 and \
                getpointpiece(_mapchess, pos, i, 5) == 0:
            value += 1000
        #21__1_ 眠二3
        if getpointpiece(_mapchess, pos, i, -1) == flag2 and \
                getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == 0 and \
                getpointpiece(_mapchess, pos, i, 4) == flag1 and \
                getpointpiece(_mapchess, pos, i, 5) == 0:
            value += 1000
        #*1___1 眠二4
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == 0 and \
                getpointpiece(_mapchess, pos, i, 4) == 0 and \
                getpointpiece(_mapchess, pos, i, 5) == flag1:
            value += 1000
        # *1__
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0 and \
                getpointpiece(_mapchess, pos, i, 3) == 0:
            value += 30
        # *1_
        if getpointpiece(_mapchess, pos, i, 1) == flag1 and \
                getpointpiece(_mapchess, pos, i, 2) == 0:
            value += 20
        # *1
        if getpointpiece(_mapchess, pos, i, 1) == flag1:
            value += 10
    return value

# 获取当前坐标的各个方向上棋子属性,返回1代表白棋,返回2代表黑棋,返回0代表没有棋,返回5表示在棋盘外
def getpointpiece(_mapchess,pos, src, offset):
    # 8个方向
    directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]
    x1, y1 = pos
    x1 = x1 + directions[src - 1][0] * offset * blocksize
    y1 = y1 + directions[src - 1][1] * offset * blocksize
    if x1 > 588 or y1 > 588 or x1 < 28 or y1 < 28:
        return 5
    else:
        return _mapchess[str(x1) + ',' + str(y1)]

这样就可以实现:当人下了棋后,电脑通过这个算法找出最有利的落子点,然后就在那里下棋。

注:本程序只是提供一个思路而已,并不是最优解。代码中value值可以自行修改,算法可以自己再设计,例如可以假如双活三之类的必须防御的应手。

如何判断胜负呢?待续。。。

python+pygame实现五子棋人机对战之四

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1920033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL优化之深分页

SQL优化之深分页 我们都知道&#xff0c;大型项目中的SQL语句&#xff0c;应该尽量避免深分页。 那么问题就来了&#xff1a; 深分页的性能差在哪&#xff1f;什么方案能避免深分页呢&#xff1f; 什么是深分页 深分页&#xff0c;即SQL查询过程中&#xff0c;使用的页数过…

无需构建工具,快速上手Vue2 + ElementUI

无需构建工具&#xff0c;快速上手Vue2 ElementUI 在前端开发的世界中&#xff0c;Vue.js以其轻量级和易用性赢得了开发者的青睐。而Element UI&#xff0c;作为一个基于Vue 2.0的桌面端组件库&#xff0c;提供了丰富的界面组件&#xff0c;使得构建美观且功能丰富的应用变得…

第6章 IT服务运营管理

第6章 IT服务运营管理 6.1 概述 大量企业的实践表明&#xff0c;IT服务运营方面的问题更多的不是来自产品或技术&#xff08;如硬件、软件、网络、电力故障等&#xff09;方面&#xff0c;而是来自管理方面。IT服务的提供者&#xff0c;无论是企业内部的IT部门&#xff0c;还…

nuPlan 是一个针对自动驾驶车辆的闭环机器学习(ML-based)规划基准测试

nuPlan: A closed-loop ML-based planning benchmark for autonomous vehicles nuPlan 是一个针对自动驾驶车辆的闭环机器学习&#xff08;ML-based&#xff09;规划基准测试 Abstract In this work, we propose the world’s first closed-loop ML-based planning benchmar…

Linux文件编程应用

目录 一、实现cp命令 二、修改程序的配置文件 三、写一个整数/结构体到文件 1.写一个整数到文件 2.写一个结构体到文件 四、写结构体数组到文件 我们学习了文件编程的常用指令以及了解文件编程的基本步骤后&#xff0c;试着来写一些程序实现某些功能。&#xff08;没有学…

Java设计模式的7个设计原则

Java设计模式的7个设计原则是面向对象设计领域中的重要指导方针&#xff0c;它们旨在提高软件系统的可维护性、可扩展性、可复用性和灵活性。以下是这7个设计原则的详细解释&#xff1a; 1. 开闭原则&#xff08;Open-Closed Principle, OCP&#xff09; 定义&#xff1a;一个…

体验一下智能指针的强大

课程总目录 文章目录 一、智能指针基础知识二、不带引用计数的智能指针auto_ptrscoped_ptrunique_ptr 三、带引用计数的智能指针模拟实现一个带引用计数的智能指针shared_ptr交叉引用问题 四、多线程访问共享对象的线程安全问题五、智能指针删除器六、建议用make_shared代替sha…

如何找工作 校招 | 社招 | 秋招 | 春招 | 提前批

马上又秋招了&#xff0c;作者想起以前读书的时候&#xff0c;秋招踩了很多坑&#xff0c;但是第一份工作其实挺重要的。这里写一篇文章&#xff0c;分享一些校招社招的心得。 现在大学的情况是&#xff0c;管就业的人&#xff0c;大都是没有就业的辅导员&#xff08;笔者见过…

JavaWeb(一:基础知识和环境搭建)

一、基本概念 1.前言 JavaWeb&#xff1a;在Java中&#xff0c;动态web资源开发网页的技术。 web应用分两种&#xff1a;静态web资源和动态web资源 Ⅰ. 静态web资源&#xff08;如html 页面&#xff09;&#xff1a; 指web页面中的数据始终是不变。 所有用户看到都是同一个…

基于YOLOV8的数粒机-农业应用辣椒种子计数计重双标质量解决方案

一:辣椒种子行业背景调查 中国辣椒年产量稳居世界第一,食辣人口超5亿。中国辣椒全球闻名,小辣椒长成大产业,带动全球食品行业腾飞。 在中国,“辣”是不少地方餐桌上的一大特色。从四川的麻辣火锅到湖南的剁椒鱼头再到陕西的油泼辣子面,由南到北,总有食客对辣有着独一份偏…

力扣-回溯法

何为回溯法&#xff1f; 在搜索到某一节点的时候&#xff0c;如果我们发现目前的节点&#xff08;及其子节点&#xff09;并不是需求目标时&#xff0c;我们回退到原来的节点继续搜索&#xff0c;并且把在目前节点修改的状态还原。 记住两个小诀窍&#xff0c;一是按引用传状态…

连接与隔离:Facebook在全球化背景下的影响力

在当今全球化的背景下&#xff0c;Facebook作为全球最大的社交网络平台&#xff0c;不仅连接了世界各地的人们&#xff0c;还在全球社会、经济和文化中发挥着深远的影响。本文将深入探讨Facebook在全球化进程中的作用&#xff0c;以及其对个体和社会之间连接与隔离的双重影响。…

【区块链农场】:农场游戏+游戏

我的酒坊是一款非常受玩家欢迎的经营手游,游戏中你需要合理经营一家酒厂,将其做大做强。通过制定合理的战略,例如新建厂房,并采用传统工艺制作,针对不同的人群研制多重口味。

Ubuntu与Windows通过WIFI与以太网口共享网络,Ubuntu与Windows相互ping通,但ping百度失败

Linux开发板&#xff08;正点原子阿尔法_IMX6U&#xff09;与Ubuntu的文件传输SCP 报错 SSH: no matching host key type found. Their offer: ssh-rsa-CSDN博客 前面的文章提到了如何将Ubuntu与Windows通过WIFI共享网络给以太网&#xff0c;从而实现Linux开发板、Ubuntu、Win…

Umi.js 项目中使用 Web Worker

1.配置 Umi.js 在 Umi.js 中&#xff0c;需要通过配置来扩展 Webpack 的功能。在项目根目录下修改 config/config.ts 文件&#xff1a; export default defineConfig({chainWebpack(config) {config.module.rule(worker).test(/\.worker\.ts$/).use(worker-loader).loader(wo…

常见网页问题解决

用edge浏览器打印功能时&#xff0c;出现瞬间或加载几秒后突然闪退情况&#xff0c;本来以为是浏览器出了问题&#xff0c;去重置设置也没有&#xff0c;后来又下载了Chrome浏览器&#xff0c;没想到还是一样&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;想着…

系统服务综合实验

实验需求&#xff1a; 现有主机 node01 和 node02&#xff0c;完成如下需求&#xff1a; 在 node01 主机上提供 DNS 和 WEB 服务dns 服务提供本实验所有主机名解析web服务提供 www.rhce.com 虚拟主机该虚拟主机的documentroot目录在 /nfs/rhce 目录该目录由 node02 主机提供的…

判断链表中是否有环(力扣141.环形链表)

这道题要用到快慢指针。 先解释一下什么是快慢指针。 快慢指针有两个指针&#xff0c;走得慢的是慢指针&#xff0c;走得快的是快指针。 在这道题&#xff0c;我们规定慢指针一次走一步&#xff0c;快指针一次走2步。 如果该链表有环&#xff0c;快慢指针最终会在环中相遇&a…

MySQL数据库基本操作-DDL和DML

1. DDL解释 DDL(Data Definition Language)&#xff0c;数据定义语言&#xff0c;该语言部分包括以下内容&#xff1a; 对数据库的常用操作对表结构的常用操作修改表结构 2. 对数据库的常用操作 功能SQL查看所有的数据库show databases&#xff1b;查看有印象的数据库show d…

02. 存储引擎

1. 前言 在校招或者社招面试中&#xff0c;无论你是 Java 后端、Cpp 后端、Python 后端&#xff0c;面试官都会详细地考察各种语法细节、框架知识&#xff0c;但是大多数候选人入职之后&#xff0c;都会体会到 "面试造火箭&#xff0c;上班拧螺丝"。面试时我们熟悉各…