Giter VIP home page Giter VIP logo

tictacgame's Introduction

井字棋AI的实现

开始时间: 2019/4/29

搭建环境: Ubuntu 18.04 gcc 7.3.0

输入规范:

linux根目录下使用make编译进入井字棋界面;
开局根据提示选择先后手;
先手方执'O',后手方执'X';
输入坐标表示落子的位置,如(2,2)表示下在中心点;

游戏规则:

+---+---+---+    +---+---+---+
|   |   |   |    | O |   | X | 
|---|---|---|    |---|---|---|
|   |   |   |    | O | O | X |
|---|---|---|    |---|---|---|
|   |   |   |    | O | X |   | 
+---+---+---+    +---+---+---+
如图3*3的棋盘,先手落"O",后手落"X";若横、竖、斜方向出现三子连线,则胜出;
如右图,先手方"O"胜出:

思路分析:

1.0 代码架构(已实现部分)

#ChessBoard.h  
ChessBoard.cpp
//棋盘的存储、判定输赢、可视化打印、局面评估函数

#PlayGame.h  
PlayGame.cpp
//模拟对弈、遍历回溯所有局面

example.c  /* 输入棋盘的测试数据 */
result.c   /* 输出可视化结果 */
Makefile   /* make编译 */

1.1 先回溯遍历所有情形,摸个底

1. 暴力穷举所有局面共有9!种可能即362880种2. 考虑到产生输赢游戏就结束有些局面不用继续搜索下去解空间缩小为113416种先手胜平负的局面占比分别是49%,23%,28%,因此理论上先手占优;(通过代码遍历得出,尽管实际中这种数据没任何意义)
3. 通过对称性可以进一步缩小解空间此处省略4. 回溯法核心伪代码Go(depth){
	if (depth==9)
		return;
	do 找到空位置(i,j)并落子;
	if (胜负未分)
		Go(depth+1);
	do (i,j)上的落子还原;
}

1.2 可视化打印棋盘,方便检查局面

#include "ChessBoard.h"
void ShowBoard(); //可视化打印
char Graph[3][3]; //空则为' ',先手'O',后手'X'
//通过规范化的输出实现棋盘

1.3 尝试模拟博弈: 对于任一种局面,判断是否存在最终获胜的子节点

以下全部建立在,所有局面都可能且必然会出现,即博弈双方零智能的情况下

#include "PlayGame.h"
//给一个输入接口,用来检测判断的正确性
int WhoTurn;  //当前落子方
bool CanWin;  //落子方能否赢
int Sum();    //返回输入局面的落子数,即回合数
bool Input(); //输入一个局面,判断当前落子方是否有赢的可能

1.4 赋予一些初步智能:如遇己方二子必填、遇对方二子必堵

如以下局面其实只有唯一解:
+---+---+---+    +---+---+---+
| O | X |   |    | O | X | O | 
|---|---|---|    |---|---|---|
|   | X | O |    | O | X | O |
|---|---|---|    |---|---|---|
| X | O |   |    | X | O | X | 
+---+---+---+    +---+---+---+
左图为输入局面右图为结果局面唯一流程O必落右上角封堵接着X落右下角封堵最后O落子棋盘下满#include "ChessBoard.h"
int Check4(); //return 2:己方2子   return 1:对方2子
//修改Go():优先填己方2子,其次堵对方2子,最后才是遍历for循环

阶段1.5 设计局面评估函数:对每个位置给出相应价值,每次挑价值最高的落子

  • 一个3*3的棋盘能同时覆盖3个点位的共有8条线,横3条,竖3条,斜2条;以此作为评分的依据;
    • 评估规则1:每有一条线经过,该点位价值+1
    • 评估规则2:每有一个己方棋子同线,且无对方障碍子,该点位价值再+1
    • 评估规则3:若有一个对方棋子同线,该点价值不受影响
    • 评估规则4:各种局面处理优先级: 己方2子 > 对方2子 > 选择价值最大点位落子
下图对于空棋盘先手方O的每个点位价值如下
(因为中心点有4条线经过所有该点位价值为4)
因此先手O最佳开局位置是中心点
+---+---+---+ 
| 3 | 2 | 3 |
|---|---|---| 
| 2 | 4 | 2 | 
|---|---|---| 
| 3 | 2 | 3 |
+---+---+---+

对于左图的局面轮到先手方O落子相应的价值分布如右图
按照评估规则2只有左下角的点位不加分所以先手方O合理的落子位置是左上角或右下角(两个点位等价)
+---+---+---+
|   |   | X |
|---|---|---|
|   | O |   |
|---|---|---|
|   |   |   |
+---+---+---+ 

先根据规则1打分
+---+---+---+
| 3 | 2 | X |
|---|---|---|
| 2 | O | 2 |
|---|---|---| 
| 3 | 2 | 3 | 
+---+---+---+ 

再根据规则2打分
+---+---+---+
| 4 | 3 | X |
|---|---|---|
| 3 | O | 3 |
|---|---|---|
| 3 | 3 | 4 | 
+---+---+---+
  • 实现函数如下
#include <ChessBoard.h>
int Value[3][3]; //记录每个点位的价值
void ShowValue; //打印点位价值图
void Evaluate(); //点位的价值评估函数

阶段1.6 添加最终博弈过程,可选择先后手,设计输入和输出界面

#include <Playgame.h>
bool FirstTurn; //记录是否电脑先手
bool Overl //记录是否游戏结束
int MyStep(); //我方落子
int GoStep(); //电脑落子
/* 每次落子前先判断输赢,其次连己方2子、堵对方2子*/

总结

  • 井字棋优势开局为中心点;
  • 井字棋的特点在于:先手争胜,后手争平;
  • 井字棋先手无必胜策略,后手有必平策略;

最终结论:井字棋理想化博弈的结局永远是平局

tictacgame's People

Contributors

593413198 avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.