何为TicTacToe?

TicTacToe也俗称井字棋或三连棋(两人轮流在一有九格方盘上划加字或圆圈, 谁先把三个同一记号排成横线、直线、斜线, 即是胜者),男女老少皆宜的入门级棋类游戏。

关于游戏的实现方式,比较简单,在这就不多说了。直接谈一谈如何写出在TicTacToe游戏中不输给人类棋手的电脑。

想要写出游戏AI,第一步是自己要会玩游戏,有自己的策略。第二部才是告诉我们的AI如何实现这样的策略。我们在玩的时候发现能尽可能占据有利的位置会帮助我们快速赢下比赛,玩游戏还能发现的一点就是一定要防住对面即将连成一条线的一路,还有很多,很多。这些特征可以说明,游戏中不同情况下,盘面的每一个位置似乎有着不同的重要性,我们完全可以利用这一点来指导我们的AI去驰骋沙场。(我一开始打算仔细判断每一种情况,比如双二单二什么的,结果不但代码量大而且效果和这样的思路没什么区别)

也就是说,给与AI一个非常重要的变量(一个3*3的数组),表示每一个位置的权值,也就是该位置的重要性的体现。比赛中第一重要的当然是自己连成一条线,这可以赋予最高的权值。而且,这个权值应该大到什么地步呢?当然应该大到无论其他什么情况发生都以此为第一要素的地步。所以我们可以在AI检查出自己能成一条线的位置时,给这个位置赋值10000,代表这个位置至高无上的地位。

第二重要的则是防止对手成一条线,此举的重要性,可谓一人之下万人之上,就在有这种情况的时候赋予这个位置1000的值吧。

其他需要赋值的三种情况是:1.某条线仅仅有己方棋子一枚;2.某条线仅仅有敌方棋子一枚;3.某条线上空空如也。如果是我们的AI先手,我认为第一条的权重大于第二条大于第三条。而AI后手则2>3>1。

因为玩过Tictactoe的朋友一定知道,这是一个先手赢不了,后手输不了的游戏。但是作为后手一旦失误就会输棋,先手若能抓住后手的失误则能赢棋。数年前中国五子棋第一人那威曾经说过“先手要攻,后手要守”。虽然是说五子棋,不过Tictactoe实际上就是三字棋,与五子棋的区别仅仅是少了很多很多的变化而已。所以我们需要给我们的AI贯彻这样的思想:先手要积极进攻,后手要小心放手。好了,AI的思路基本上就是这样了,下面贴上核心部分的代码(java)

注:游戏的地图保存在一个叫net的数组里,每一个位置值为0表示没有棋,1表示为X棋,2表示为O棋

int[][] net=new int[4][4];//0 means null;1 means X;2 means O;
       int level[][]=new int[4][4];//越大优先级越高 
       IOHelper h=new IOHelper();
       int o2=10000;//一个己方活二权值
       int x2=1000;//一个对方活二权值
       int x=10;//一个对方活一权值
       int o=6;//一个己方活一权值
       int nothing=4;//一个空行权值

for(int i=0;i<3;i++){
      for(int j=0;j<3;j++){
       if(net[i][j]!=0)level[i][j]=0;
       else{
       //横竖两条,每人都有
       //自己活二,,220
       if(((net[0][j]+net[1][j]+net[2][j])==4)&&(net[0][j]*net[1][j]*net[2][j])==0&&((net[0][j]-1)*(net[1][j]-1)*(net[2][j]-1))==-1)
        level[i][j]=level[i][j]+o2;
       if(((net[i][0]+net[i][1]+net[i][2])==4)&&(net[i][0]*net[i][1]*net[i][2])==0&&((net[i][0]-1)*(net[i][1]-1)*(net[i][2]-1))==-1)
        level[i][j]=level[i][j]+o2;
       //对方活二,110
       if(((net[0][j]+net[1][j]+net[2][j])==2)&&(net[0][j]*net[1][j]*net[2][j])==0&&((net[0][j]-1)*(net[1][j]-1)*(net[2][j]-1))==0)
        level[i][j]=level[i][j]+x2;
       if(((net[i][0]+net[i][1]+net[i][2])==2)&&(net[i][0]*net[i][1]*net[i][2])==0&&((net[i][0]-1)*(net[i][1]-1)*(net[i][2]-1))==0)
        level[i][j]=level[i][j]+x2;
       //单个X,100
       if(((net[0][j]+net[1][j]+net[2][j])==1)&&(net[0][j]*net[1][j]*net[2][j])==0&&((net[0][j]-1)*(net[1][j]-1)*(net[2][j]-1))==0)
        level[i][j]=level[i][j]+x;
       if(((net[i][0]+net[i][1]+net[i][2])==1)&&(net[i][0]*net[i][1]*net[i][2])==0&&((net[i][0]-1)*(net[i][1]-1)*(net[i][2]-1))==0)
        level[i][j]=level[i][j]+x;
       //单个O,200
       if(((net[0][j]+net[1][j]+net[2][j])==2)&&(net[0][j]*net[1][j]*net[2][j])==0&&((net[0][j]-1)*(net[1][j]-1)*(net[2][j]-1))==1)
        level[i][j]=level[i][j]+o;
       if(((net[i][0]+net[i][1]+net[i][2])==2)&&(net[i][0]*net[i][1]*net[i][2])==0&&((net[i][0]-1)*(net[i][1]-1)*(net[i][2]-1))==1)
        level[i][j]=level[i][j]+o;
       //空行,000
       if(((net[0][j]+net[1][j]+net[2][j])==0)&&(net[0][j]*net[1][j]*net[2][j])==0&&((net[0][j]-1)*(net[1][j]-1)*(net[2][j]-1))==-1)
        level[i][j]=level[i][j]+nothing;
       if(((net[i][0]+net[i][1]+net[i][2])==0)&&(net[i][0]*net[i][1]*net[i][2])==0&&((net[i][0]-1)*(net[i][1]-1)*(net[i][2]-1))==-1)
        level[i][j]=level[i][j]+nothing;
       
       //分情况
       //主对角线
       if((i==0&&j==0)||(i==2&&j==2)||(i==1&&j==1)){
        //己方活二
        if(((net[0][0]+net[1][1]+net[2][2])==4)&&(net[0][0]*net[1][1]*net[2][2])==0&&
        ((net[0][0]-1)*(net[1][1]-1)*(net[2][2]-1))==-1)
        level[i][j]=level[i][j]+o2;
        //对方活二
        if(((net[0][0]+net[1][1]+net[2][2])==2)&&(net[0][0]*net[1][1]*net[2][2])==0&&
          ((net[0][0]-1)*(net[1][1]-1)*(net[2][2]-1))==0)
          level[i][j]=level[i][j]+x2;
        //单个X
        if(((net[0][0]+net[1][1]+net[2][2])==1)&&(net[0][0]*net[1][1]*net[2][2])==0&&
          ((net[0][0]-1)*(net[1][1]-1)*(net[2][2]-1))==0)
          level[i][j]=level[i][j]+x;
        //单个O
        if(((net[0][0]+net[1][1]+net[2][2])==2)&&(net[0][0]*net[1][1]*net[2][2])==0&&
          ((net[0][0]-1)*(net[1][1]-1)*(net[2][2]-1))==1)
          level[i][j]=level[i][j]+o;
        //空行,000
        if(((net[0][0]+net[1][1]+net[2][2])==0)&&(net[0][0]*net[1][1]*net[2][2])==0&&
          ((net[0][0]-1)*(net[1][1]-1)*(net[2][2]-1))==-1)
         level[i][j]=level[i][j]+nothing;
       }
       
       //副对角线
       if((i==0&&j==2)||(i==2&&j==0)||(i==1&&j==1)){
        //己方活二
        if(((net[0][2]+net[1][1]+net[2][0])==4)&&(net[0][2]*net[1][1]*net[2][0])==0&&
        ((net[0][2]-1)*(net[1][1]-1)*(net[2][0]-1))==-1)
        level[i][j]=level[i][j]+o2;
        //对方活二
        if(((net[0][2]+net[1][1]+net[2][0])==2)&&(net[0][2]*net[1][1]*net[2][0])==0&&
          ((net[0][2]-1)*(net[1][1]-1)*(net[2][0]-1))==0)
          level[i][j]=level[i][j]+x2;
        //单个X
        if(((net[0][2]+net[1][1]+net[2][0])==1)&&(net[0][2]*net[1][1]*net[2][0])==0&&
          ((net[0][2]-1)*(net[1][1]-1)*(net[2][0]-1))==0)
          level[i][j]=level[i][j]+x;
        //单个O
        if(((net[0][2]+net[1][1]+net[2][0])==2)&&(net[0][2]*net[1][1]*net[2][0])==0&&
          ((net[0][2]-1)*(net[1][1]-1)*(net[2][0]-1))==1)
          level[i][j]=level[i][j]+o;
        //空行,000
        if(((net[0][2]+net[1][1]+net[2][0])==0)&&(net[0][2]*net[1][1]*net[2][0])==0&&
          ((net[0][2]-1)*(net[1][1]-1)*(net[2][0]-1))==-1)
         level[i][j]=level[i][j]+nothing;
       }//the end of for if
       }//the end of if
      }//the end of for j
     }//the end of for j

//寻找最大权值的位置
    int maxi = 0,maxj = 0,temp = 0;
           for(int i=0;i<3;i++){
                 for(int j=0;j<3;j++){
                      if(level[i][j]>temp)
                      {

temp=level[i][j];
                      maxi=i;
                      maxj=j;
                      }
                 System.out.println("net[i][j]="+net[i][j]);
                 System.out.println("level[i][j]="+level[i][j]);
                 }
           }

  觉得作者不容易的话请顶一个(*^__^*)  谢谢

TicTacToe(井字棋)的算法——不比人的智商低的AI相关推荐

  1. Tic-Tac-Toe井字棋多模式C++实现

    Tic-Tac-Toe井字棋多模式C++实现 根据网上的代码,利用C++实现了Tic-Tac-Toe井字棋的人机对弈.机人对弈.机机对弈.人人对弈. 关于 Tic-Tac-Toe的下法,可参考http ...

  2. Lego MindStorms NXT 井字棋机器人算法讨论

    written by flexitime 最近在搞这套Lego的玩具,大家可以看一下照片 ( 以下是一些有关这个机械人的录像: 1.最终修正版本,算法现在按正统的方式修改了,聪明了很多 http:// ...

  3. 通过简单的强化学习实现井字棋(Tic-Tac-Toe)

    一.强化学习简介 强化学习的过程可以理解为Agent与Environment的交互.学习.进步的过程,在井字棋中,可以简单的将其中的一方理解为Agent,另一方为Environment.交互的过程中主 ...

  4. python井字棋ai,python 井字棋(Tic Tac Toe)

    说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...

  5. python实现简单小游戏_python实现简单井字棋小游戏

    #Tic-Tac-Toe 井字棋游戏 #全局常量 X="X" O="O" EMPTY=" " #询问是否继续 def ask_yes_no( ...

  6. matlab实验报告井字棋,一字棋实验报告

    一. 实验目的: 1. 理解和掌握博弈树的启发式搜索过程 2. 学习极大极小搜索α –β剪枝 3. 能够用选定的编程语言设计简单的博弈游戏 二. 实验环境及工具 1. 硬件环境:网络环境中的微型计算机 ...

  7. python设计小游戏谁先走到17_python实现简单井字棋小游戏

    #Tic-Tac-Toe 井字棋游戏 #全局常量 X="X" O="O" EMPTY=" " #询问是否继续 def ask_yes_no( ...

  8. Minimax 和 Alpha-beta 剪枝算法简介,及以此实现的井字棋游戏(Tic-tac-toe)

    前段时间用 React 写了个2048 游戏来练练手,准备用来回顾下 React 相关的各种技术,以及试验一下新技术.在写这个2048的过程中,我考虑是否可以在其中加入一个 AI 算法来自动进行游戏, ...

  9. java——博弈算法实现井字棋游戏

    通过java语言开发了一个简单的井字棋游戏.主要有6个类,其中有一个是主类(Main.java),一个是抽象类(PiecesMove.java)组成. 下面对各个类简单介绍一下: TicTicToe. ...

最新文章

  1. IDEA高级用法:集成JIRA、UML类图插件、SSH、FTP、Database管理...
  2. C#中文件和byte[]互换问题
  3. 数据结构与算法 / 默克尔树
  4. Android12 Jetpack SplashScreen API总结
  5. modbus 0x06 连续写_这篇很实用,看完学会MODBUS的应用及编程
  6. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)
  7. R-CNN家族梳理:从R-CNN到Mask R-CNN
  8. 计算机网络要点,计算机网络要点
  9. linux防火墙的开启与关闭
  10. 错误解决办法:_ZNSaIcED1Ev@@GLIBCXX_3.4
  11. 包含农历、节气、节假日的前端日历
  12. 如何打造高质量的NLP数据集
  13. blender反选快捷键_【PS】常用操作及快捷键
  14. Oracle rman中restore和recover的区别
  15. 科目二 离合 要点记录
  16. 魔法少女小圆计算机音乐,求魔法少女小圆一些背景音乐的名字
  17. 游戏思考系列02:技能伤害计算流程(不涉及buff)
  18. 基于STM32的倒车雷达系统设计
  19. Service Fabric - 深入实践
  20. 如何注册宝塔面板账号?

热门文章

  1. 演绎大制作电影的“撼人心魄”——飞利浦全景声回音壁B8967分享
  2. 采集腾讯QQ国内+国际版的国家及地区库
  3. 论文投稿指南——中文核心期刊推荐(海洋学)
  4. 2021年煤矿井下电气报名考试及煤矿井下电气考试资料
  5. 晶振OSC概述、分类、工作原理及作用
  6. APISIX源码解析-启动篇【ops.lua - start】
  7. 「节能学院」苏州高新区实验中学某校区能耗管理系统的研究应用
  8. 【Recurrent Models of Visual Attention】(讲解)
  9. word表格快速插入编号
  10. 解决使用下拉组件报错:Error in callback for watcher “focusing“: “TypeError: Cannot set property className......