如何用C++实现五子棋小游戏呢?

五子棋可谓是家喻户晓了,在科技如此发达的今天,我们能不能用电脑实现五子棋人机对弈呢?
答案当然是可以的

首先,思考一下我们需要完成哪些步骤

1、打印棋盘(使用二维数组即可)
2、判断胜负(可以考虑深搜,但是暴力似乎能让代码更简洁)
3、思考下一部棋该怎么走

先从最简单的一部开始:打印棋盘

void out(){for(int i=0;i<=24;i++){for(int j=0;j<=24;j++){if(a[i][j]!=0){ //a数组即为这个棋盘,用来存储棋子位置if(a[i][j]==1&&i!=0&&j!=0) printf(" O");else if(a[i][j]==2&&i!=0&&j!=0) printf(" X");else cout<<setw(2)<<a[i][j];} else printf(" -");}printf("\n");}
}

构建的棋盘大概是这个样子:
(O是对手,X是电脑)

 - 1 2 3 4 5 6 7 8 91011121314151617181920212223241 - - - - - - - - - - - - - - - - - - - - - - - -2 - - - - - - - - - - - - - - - - - - - - - - - -3 - - - - - - - - - - - - - - - - - - - - - - - -4 - - - - - - - - - - - - - - - - - - - - - - - -5 - - - - - - - - - - - - - - - - - - - - - - - -6 - - - - - - - - - - - - - - - - - - - - - - - -7 - - - - - - - - - - - - - - - - - - - - - - - -8 - - - - - - - - - - - - - - - - - - - - - - - -9 - - - - - - - - - - - - - - - - - - - - - - - -
10 - - - - - - - - - - - - - - - - - - - - - - - -
11 - - - - - - - - - - - - - - - - - - - - - - - -
12 - - - - - - - - - - - - - - - - - - - - - - - -
13 - - - - - - - - - - - - - - - - - - - - - - - -
14 - - - - - - - - - - - - - - - - - - - - - - - -
15 - - - - - - - - - - - - - - - - - - - - - - - -
16 - - - - - - - - - - - - - - - - - - - - - - - -
17 - - - - - - - - - - - - - - - - - - - - - - - -
18 - - - - - - - - - - - - - - - - - - - - - - - -
19 - - - - - - - - - - - - - - - - - - - - - - - -
20 - - - - - - - - - - - - - - - - - - - - - - - -
21 - - - - - - - - - - - - - - - - - - - - - - - -
22 - - - - - - - - - - - - - - - - - - - - - - - -
23 - - - - - - - - - - - - - - - - - - - - - - - -
24 - - - - - - - - - - - - - - - - - - - - - - - -

这一步很简单,自己思考一下吧

第二部,判断输赢

这一步我比较推荐用暴力搜索,反正又不是NOIP,不差这点时间复杂度 /doge

思路就是搜索每一个位置,看这个位置下、右、斜是否有连续的五个子,搜就完了

int judgewin(){for(int i=1;i<=25;i++){for(int j=1;j<=25;j++){if(a[i][j]==0) continue;int numwin=0;for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j]!=a[i][j]) break;}if(numwin==5) {return a[i][j];}numwin==0;for(numwin=1;numwin<=4;numwin++){if(a[i][j+numwin]!=a[i][j]) break;}if(numwin==5) {return a[i][j];}numwin==0;for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j+numwin]!=a[i][j])break;}if(numwin==5) {return a[i][j];}numwin==0;if(j>5){for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j-numwin]!=a[i][j])break;}if(numwin==5) {return a[i][j];}}}}return 0;
}

这部也还不算困难,自己看看吧

最关键的一步

现在,终于到了这篇算法的精髓
在写代码之前,先把程序的计算原理理解一下:

1、构建一个能和a数组对应的数组dp(虽然不是dp,但是类似dp)
2、dp里面存储着这个位置下子是否合理的数字,数字越大,越应该下在这里
3、枚举每一个点,将dp数组填满

但是说来简单,究竟怎么填这个数字呢?

1、发现四周有敌人的半活4就+1000
2、发现四周有敌人的活3就+500
3、发现四周有敌人的双活2就+400
(这些算致命的,是防守,同理,自己的子也是如此,但数值要再+100,因为下一步就是我们进攻了)

(后面就极为复杂了,是经过半个月研究才弄清楚的,详见代码)

void checksit(int n,int m){for(int i=0;i<8;i++){int num=0;for(int j=1;j<5;j++){if(a[n+j*dx[i]][m+j*dy[i]]==1) num++;if(a[n+j*dx[i]][m+j*dy[i]]==2) break;}for(int j=1;j<5;j++){if(a[n-j*dx[i]][m-j*dy[i]]==1) num++;if(a[n-j*dx[i]][m-j*dy[i]]==2) break;}if(num==4) {dp[n][m]+=1000; flag[n][m]==3;}if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==2) dp[n][m]+=10;if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==0) {dp[n][m]+=500; flag[n][m]==1;}if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==2) dp[n][m]+=1;if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==0) dp[n][m]+=3;}for(int i=0;i<8;i++){int num=0;for(int j=1;j<5;j++){if(a[n+j*dx[i]][m+j*dy[i]]==2) num++;else break;}for(int j=1;j<5;j++){if(a[n-j*dx[i]][m-j*dy[i]]==2) num++;else break;}if(num==4) {dp[n][m]+=1000; flag[n][m]==2;}if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==1) dp[n][m]+=20;if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==0) {dp[n][m]+=500; flag[n][m]==2;}if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==1) dp[n][m]+=2;if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==0) dp[n][m]+=10;}for(int i=0;i<8;i++){for(int j=0;j<8;j++){if(j==i) continue;int num=0;for(int k=1;k<3;k++){if(a[n+k*dx[j]][m+k*dy[j]]==1) num++;if(a[n+k*dx[i]][m+k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[j]][m-k*dy[j]]==1) num++;if(a[n-k*dx[i]][m-k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n+k*dx[i]][m+k*dy[i]]==1) num++;if(a[n+k*dx[i]][m+k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[i]][m-k*dy[i]]==1) num++;if(a[n-k*dx[i]][m-k*dy[i]]==2) {num-=2;break;}}if(num>=4) dp[n][m]+=80;else if(num==3) dp[n][m]+=20;}} for(int i=0;i<8;i++){for(int j=0;j<8;j++){if(j==i) continue;int num=0;for(int k=1;k<3;k++){if(a[n+k*dx[j]][m+k*dy[j]]==2) num++;if(a[n+k*dx[i]][m+k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[j]][m-k*dy[j]]==2) num++;if(a[n-k*dx[i]][m-k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n+k*dx[i]][m+k*dy[i]]==2) num++;if(a[n+k*dx[i]][m+k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[i]][m-k*dy[i]]==2) num++;if(a[n-k*dx[i]][m-k*dy[i]]==1) {num-=2;break;}}if(num>=4) dp[n][m]+=50;else if(num==3) dp[n][m]+=10;}}for(int i=0;i<8;i++){int seti=0,setj=0;for(int j=1;j<5;j++)if(a[n+j*dx[i]][m+j*dy[i]]==1) seti=j;for(int j=1;j<5;j++)if(a[n-j*dx[i]][m-j*dy[i]]==1) setj=j;if(abs(seti-setj)<=4) dp[n][m]-=30;} int num=0;for(int k=0;k<8;k++){if(a[n+dx[k]][m+dy[k]]==2){dp[n][m]+=10;num++;} if(a[n+dx[k]][m+dy[k]]==1) dp[n][m]+=2;}if(num==0)for(int i=0;i<8;i++){if(a[n+rx[i]][m+rx[i]]==2) dp[n][m]-=20;}
}

整合起来,大概长这样:

#include <bits/stdc++.h>
//可替换成<iostream>和<algorithm>
using namespace std;
int a[30][30],dp[30][30];
int flag[30][30];
int dx[9]={-1,-1,-1,0,0,1,1,1};
int dy[9]={-1,0,1,-1,1,-1,0,1};
int rx[9]={-2,-2,-1,1,2,2,1,-1};
int ry[9]={-1,1,2,2,1,-1,-2,-2};
int step,check;
void checksit(int n,int m){for(int i=0;i<8;i++){int num=0;for(int j=1;j<5;j++){if(a[n+j*dx[i]][m+j*dy[i]]==1) num++;if(a[n+j*dx[i]][m+j*dy[i]]==2) break;}for(int j=1;j<5;j++){if(a[n-j*dx[i]][m-j*dy[i]]==1) num++;if(a[n-j*dx[i]][m-j*dy[i]]==2) break;}if(num==4) {dp[n][m]+=1000; flag[n][m]==3;}if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==2) dp[n][m]+=10;if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==0) {dp[n][m]+=500; flag[n][m]==1;}if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==2) dp[n][m]+=1;if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==0) dp[n][m]+=3;}for(int i=0;i<8;i++){int num=0;for(int j=1;j<5;j++){if(a[n+j*dx[i]][m+j*dy[i]]==2) num++;else break;}for(int j=1;j<5;j++){if(a[n-j*dx[i]][m-j*dy[i]]==2) num++;else break;}if(num==4) {dp[n][m]+=1000; flag[n][m]==2;}if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==1) dp[n][m]+=20;if(num==3&&a[n+4*dx[i]][m+4*dy[i]]==0) {dp[n][m]+=500; flag[n][m]==2;}if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==1) dp[n][m]+=2;if(num==2&&a[n+3*dx[i]][m+3*dy[i]]==0) dp[n][m]+=10;}for(int i=0;i<8;i++){for(int j=0;j<8;j++){if(j==i) continue;int num=0;for(int k=1;k<3;k++){if(a[n+k*dx[j]][m+k*dy[j]]==1) num++;if(a[n+k*dx[i]][m+k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[j]][m-k*dy[j]]==1) num++;if(a[n-k*dx[i]][m-k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n+k*dx[i]][m+k*dy[i]]==1) num++;if(a[n+k*dx[i]][m+k*dy[i]]==2) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[i]][m-k*dy[i]]==1) num++;if(a[n-k*dx[i]][m-k*dy[i]]==2) {num-=2;break;}}if(num>=4) dp[n][m]+=80;else if(num==3) dp[n][m]+=20;}} for(int i=0;i<8;i++){for(int j=0;j<8;j++){if(j==i) continue;int num=0;for(int k=1;k<3;k++){if(a[n+k*dx[j]][m+k*dy[j]]==2) num++;if(a[n+k*dx[i]][m+k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[j]][m-k*dy[j]]==2) num++;if(a[n-k*dx[i]][m-k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n+k*dx[i]][m+k*dy[i]]==2) num++;if(a[n+k*dx[i]][m+k*dy[i]]==1) {num-=2;break;}}for(int k=1;k<3;k++){if(a[n-k*dx[i]][m-k*dy[i]]==2) num++;if(a[n-k*dx[i]][m-k*dy[i]]==1) {num-=2;break;}}if(num>=4) dp[n][m]+=50;else if(num==3) dp[n][m]+=10;}}for(int i=0;i<8;i++){int seti=0,setj=0;for(int j=1;j<5;j++)if(a[n+j*dx[i]][m+j*dy[i]]==1) seti=j;for(int j=1;j<5;j++)if(a[n-j*dx[i]][m-j*dy[i]]==1) setj=j;if(abs(seti-setj)<=4) dp[n][m]-=30;} int num=0;for(int k=0;k<8;k++){if(a[n+dx[k]][m+dy[k]]==2){dp[n][m]+=10;num++;} if(a[n+dx[k]][m+dy[k]]==1) dp[n][m]+=2;}if(num==0)for(int i=0;i<8;i++){if(a[n+rx[i]][m+rx[i]]==2) dp[n][m]-=20;}
}
int judgewin(){for(int i=1;i<=25;i++){for(int j=1;j<=25;j++){if(a[i][j]==0) continue;int numwin=0;for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j]!=a[i][j]) break;}if(numwin==5) {return a[i][j];}numwin==0;for(numwin=1;numwin<=4;numwin++){if(a[i][j+numwin]!=a[i][j]) break;}if(numwin==5) {return a[i][j];}numwin==0;for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j+numwin]!=a[i][j])break;}if(numwin==5) {return a[i][j];}numwin==0;if(j>5){for(numwin=1;numwin<=4;numwin++){if(a[i+numwin][j-numwin]!=a[i][j])break;}if(numwin==5) {return a[i][j];}}}}return 0;
}
void out(){for(int i=0;i<=24;i++){for(int j=0;j<=24;j++){if(a[i][j]!=0){if(a[i][j]==1&&i!=0&&j!=0) printf(" O");else if(a[i][j]==2&&i!=0&&j!=0) printf(" X");else cout<<setw(2)<<a[i][j];} else printf(" -");}printf("\n");}
}
int main(){int tempi,tempj;for(int i=3;i<=24;i++) a[0][i]=i;for(int i=3;i<=24;i++) a[i][0]=i;out();while(1){step++;memset(dp,0,sizeof(dp));memset(flag,0,sizeof(flag));int n,m;scanf("%d%d",&n,&m);if(a[n][m]!=0||n>24||m>24){printf("Useless place!Try again!");scanf("%d%d",&n,&m);} a[n][m]=1;dp[n][m]=0;out();int ans=judgewin();if(ans==2) {printf("Computer win!\n"); break;} if(ans==1) {printf("Player win!\n"); break;}if(step>=100) {printf("Good game!\n");break;}if(step==1){dp[n+1][m+2]=100;tempi=n+1;tempj=m+2;}else if(step==2){if(a[tempi+1][tempj-1]==0) dp[tempi+1][tempj-1]=100;else dp[tempi-1][tempj-1]=100;}else for(int i=1;i<=25;i++){for(int j=1;j<=25;j++){if(a[i][j]!=0) continue; checksit(i,j);}}int max=0,maxn=0,maxm=0;for(int i=1;i<=25;i++){for(int j=1;j<=25;j++){if(max<dp[i][j]){max=dp[i][j];maxn=i;maxm=j;} }}int mfl=0,mfln=0,mflm=0;for(int i=1;i<=25;i++){for(int j=1;j<=25;j++){if(mfl<flag[i][j]){mfl=flag[i][j];mfln=i;mflm=j;} if(mfl==flag[i][j]&&mfl!=0){if(dp[mfln][mflm]<dp[i][j]){mfln=i;mfln=j;}}}}if(mfl==0) printf("%d %d\n",maxn,maxm);else printf("%d %d\n",mfln,mflm);a[maxn][maxm]=2;out();ans=judgewin();if(ans==2) {printf("Computer win!\n"); break;} if(ans==1) {printf("Player win!\n"); break;}if(step>=100) {printf("Good game!\n");break;}}system("pause"); return 0;
}

(代码如有任何错误与不理解,欢迎评论!)

码字辛苦,给个赞吧!

用C++实现五子棋人机对战小游戏相关推荐

  1. Python编写人机对战小游戏(抓狐狸)(2)

    封面图片:<中学生可以这样学Python>,董付国.应根球著,清华大学出版社 =========== 很久很久以前,在公众号里推送过一个抓狐狸游戏,详见Python编写人机对战小游戏(抓小 ...

  2. python自学 适合新手的 python人机对战小游戏

    目录 前言 一,游戏规则 二,游戏拆解: 版本1.0(自定属性,人工PK) 版本2.0(随机属性,自动PK) 版本3.0(打印结果,三局两胜) 前言 有很多人问,怎样学python可以进步最快,我回顾 ...

  3. Python编写人机对战小游戏(抓小狐狸)

    本文内容来源:本来是在微信群里国防科技大学刘万伟老师发了一个算法题目大家玩,然后和中国传媒大学胡凤国老师一起交流了好几天,后来我突发灵感,改写了个小游戏.微信公众号发文时作者最多只能是8个字,刘万伟老 ...

  4. python人机对战小游戏

    Nice!自己写的第一个小游戏,wanderful!!! 事前没有参照任何代码,只通过前两天学习的循环语句实现,感觉满满的成就感.以下是源代码,可能在大神们看来很稚嫩,但对于小白的我来说却是学习进程中 ...

  5. python人机对战_Python实现的人机对战小游戏——剪刀、石头、布

    各版本程序工程叙述:获取双方对战人员名单 实现一次对战 根据对战结果评输赢 实现多次对战 实现最终结果的评判 版获取双方对战人员名单 涉及知识点:print()向控制台输出信息 input()从键盘录 ...

  6. C#实现五子棋人机对战的思路与源码分享

    前言 业余闲暇时,基于.netframework使用C#语言开发了一个五子棋人机对战的游戏,在此做些整理和分享,先上图. winform版 UI虽然很简洁,却花了些功夫,图形元素全动态生成,毕竟不是美 ...

  7. C语言 AI智能,五子棋 人机对战,人人对战

    C语言五子棋,人机对战,人人对战 chunli@Linux:~$ cat main.c # include<stdio.h> # include<string.h> # inc ...

  8. java五子棋人机对战_实现简单的人机对战五子棋(实践)

    五子棋人机对战实践项目 总的任务和目标 完成一个人机对战的五子棋项目,基本效果如下: 第一部分 Java绘图原理 1.   基本概念 像素,坐标 2.   组件自定义绘图原理 3.   Graphic ...

  9. 五子棋人机对战_10.带人机对战的五子棋程序

    今天我们带来一个带人机对战功能的五子棋程序.程序基于前面文章中的框架搭建,新增人机对战的策略.程序基于规则进行决策,不考虑禁手,玩家执黑子先行.棋盘规模采用15乘15,棋盘规模容易扩展,程序棋力中等, ...

最新文章

  1. 阿里首次开源深度学习框架X-Deep Learning
  2. Android/Ophone中的悬浮对话框和即点即关对话框
  3. 深入理解ajax系列第一篇——XHR对象
  4. 编译py-faster-rcnn的问题汇总及解决方法
  5. vue循环渲染本地图片不显示?
  6. 数据结构上机实践第九周项目3 - 利用二叉树遍历思想解决问题
  7. 微信小游戏 - 理论介绍 - 账号注册 - 开发前准备
  8. 山海经电子书古文/翻译白话文版发布,免费电子书。
  9. 什么是seo?seo是什么意思,如何理解?
  10. 不删除磁盘内容,如何给C盘扩容
  11. Error running' xxxxxx': Command line is too long. Shorten command line for xxxxxxxxx
  12. 通用Excel数据导入功能模板
  13. C语言中关于四舍五入的计算方法
  14. python爬取手机app图片_python 手机app数据爬取
  15. 视频直播APP开发的主要功能
  16. kubernetes continually evict pod when node's inode exhausted
  17. 记录Windows 的一些基础知识(包括基础命令,文件系统,注册表项)
  18. flash and .net
  19. 用命令行重启/关闭电脑
  20. 高并发系统设计40问 - 学习/实践

热门文章

  1. http://you.video.sina.com.cn/b/9405481-1342156411.html
  2. 游戏建模师行业很难吗?十年建模师来告诉你
  3. 各大公司办公电脑,无权限拷贝文件的解决办法
  4. 这些岗位要注意啦,不想被迫离职,要早做打算!
  5. SQL Server OFFSET 分页存储过程
  6. 饥荒联机服务器修改冬天时间,饥荒联机版永冬永夜世界设置技巧_饥荒联机版世界怎么设置_牛游戏网...
  7. MOD17A3HGF数据下载
  8. python使用opencv对图像添加(高斯/椒盐/泊松/斑点)噪声
  9. 快播死了:各大门户视频网站能否得意的笑
  10. java加减_Java位运算实现加减乘除