黑白棋(人人对战)——C语言实现方法之一

黑白棋,又叫翻转棋(Reversi)、奥赛罗棋(Othello)、苹果棋或正反棋(Anti reversi)。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。

棋规

  1. 棋局开始时黑棋位于E4和D5,白棋位于D4和E5。
  2. 黑方先行,双方交替下棋。
  3. 一步合法的棋步包括:在一个空格新落下一个棋子,并且翻转对手一个或多个棋子。
  4. 新落下的棋子与棋盘上已有的同色棋子间,对方被夹住的所有棋子都要翻转过来。可以是横着夹,竖着夹,或是斜着夹。夹住的位置上必须全部是对手的棋子,不能有空格。
  5. 一步棋可以在数个方向上翻棋,任何被夹住的棋子都必须被翻转过来,棋手无权选择不去翻某个棋子。
  6. 除非至少翻转了对手的一个棋子,否则就不能落子。如果一方没有合法棋步,也就是说不管他下到哪里,都不能至少翻转对手的一个棋子,那他这一轮只能弃权,而由他的对手继续落子直到他有合法棋步可下。
  7. 如果一方至少有一步合法棋步可下,他就必须落子,不得弃权。
  8. 棋局持续下去,直到棋盘填满或者双方都无合法棋步可下。
  9. 结束时棋子多者是赢家。

(以上内容摘自百度百科)

下面是黑白棋的一种C语言实现方法:

界面:



C语言代码:

#include<stdio.h>
#include<stdlib.h>
//棋盘边界检测
#define BOUNDARY(x,y) ((x)>=1&&(x)<=8&&(y)>=1&&(y)<=8)//开局介绍
int introduce()
{ printf("       [游戏规则]\n\n");printf("[开局] 棋局开始时,黑棋位于E4和D5,白棋位于D4和E5。黑方先行,双方交替下棋。\n\n");printf("[落子] 在空位落下一枚棋子,且在该棋子的横、竖、斜八个方向有一枚己方棋子,则\n");printf("       夹在中间的全部对方棋子翻转成为己方棋子。并且,只能在可以翻转棋子的地\n");printf("       方落子。若没有可落子位置,则这一轮只能弃权。\n\n");printf("[结束] 当双方都不能落子时,游戏结束,棋子多的一方获胜。\n\n");printf("[操作] 落子时输入行字母+列数字(如:D3);在轮到对方落子时输入字母“R”悔棋;\n");printf("       输入字母“P”查看游戏规则。\n\n");system("pause");return 0;
}//重置并搜索可落子位置
int search( int * const piece , const int color )
{int exist = 0;for( int i=0 ; i<=63 ; i++ ){if( piece[i]==1 || piece[i]==-1 )  continue;//有子跳过 if( piece[i]==2*color || piece[i]==-2*color )  piece[i]=0;//重置标记 for( int dx=-1 ; dx<=1 ; dx++ )//八向搜索 for( int dy=-1 ; dy<=1 ; dy++ ){if( dx==0 && dy==0 )  continue;for( int row = i/8+1+dx, col = i%8+1+dy ; BOUNDARY(row,col) ; row+=dx, col+=dy ) if( piece[row*8+col-9] != -color )  break;//不是反色棋子就退出 else if( BOUNDARY(row+dx,col+dy) && piece[(row+dx)*8+col+dy-9]==color ){  //若反色棋子下一格是同色,则该点可落子;否则无操作 piece[i] = 2*color;exist = 1;goto finish;}}finish: ;}return exist;//存在可落子位置则返回1,不存在则返回0
} //输出棋盘界面
int gui( int * const piece )
{system("cls");int score_black = 0, score_white = 0;printf("\033[0m\n        [黑白棋]\n\n    1 2 3 4 5 6 7 8\n  ┌─────────────────┐\n");for( int i=0 ; i<=63 ; i++ ){if( i%8 == 0 )  printf(" %c│ ", i/8+'A' );switch ( piece[i] ){case  1:printf("○");      //黑棋 score_black++; break;case -1:printf("●");      //白棋 score_white++; break;case  2:case -2:printf("\033[32m┼ \033[0m"); break;   //提示位置 default:printf("┼ ");      //空位 }if( i%8 == 7 ) printf("│\n");}printf("  └─────────────────┘\n   黑棋:%2d | 白棋:%2d \n", score_black, score_white);printf("─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─\n");return score_black==score_white ? 0 : ( score_black>score_white ? 1 : -1 ) ;
}//输出信息,在gui()后
int info( int * const piece, const int sign, const int color )
{static int cnt[3] = {0};for(int i=0;i<3;i++)if(cnt[i]>10){printf("再玩就坏了\n");cnt[i]=0;return 0;}switch( sign>=64 ? sign-80 : sign ){case -1:printf("%s方悔棋!\n", color==1 ? "黑" : "白" ); break;case -2:printf("无效操作!\n"); cnt[0]++; break;case -3:printf("该位置已有棋子!\n"); cnt[1]++; break;case -4:printf("该位置不可落子!\n"); cnt[1]++; break;case -5:printf("开局不能悔棋哦!\n"); cnt[0]++; break;case -6:introduce(); gui(piece); cnt[2]++; break;default: //sign>=0 if( sign < 64 ) printf("%s方在[%c%c]落子\n", color==1 ? "白" : "黑" , sign/8+'A' , sign%8+'1' );else printf("%s方在[%c%c]落子\n%s方无可落子位置!\n", color==1 ? "黑":"白" , sign/8-10+'A' , sign%8+'1', color==1 ? "白":"黑" );cnt[0]=cnt[1]=cnt[2]=0;}return 0;
}//复制棋盘,用于悔棋
int retract( int * const piece, int * const piece_last )
{int sign = -2;for( int i=0 ; i<64 ; i++ ){if( piece[i] != piece_last[i] ) sign = -1;piece[i] = piece_last[i];}return sign;
}//落子操作,落子前备份棋盘
int place( int * const piece, int * const piece_last, const int color )//棋盘,备份棋盘,颜色
{int row = 0, col = 0; char ch;printf("请%s方落子:\n", color==1 ? "黑" : "白" );fflush(stdin);while( ( ch=getchar() ) == '\n' || ch == ' ' );//第一次输入 if( ch=='R' || ch=='r' ) return -1;//悔棋 if( ch=='P' || ch=='p' ) return -6;//游戏规则if( ch>='A' && ch<='H' )   row = ch+1-'A';else if( ch>='a' && ch<='h' ) row = ch+1-'a';else if( ch>='1' && ch<='8' ) row = ch-'0';while( ( ch=getchar() ) == '\n' || ch == ' ' );//第二次输入 if( ch>='A' && ch<='H' )      col = ch+1-'A';else if( ch>='a' && ch<='h' ) col = ch+1-'a';else if( ch>='1' && ch<='8' ) col = ch-'0';if( !BOUNDARY(row,col) ) return -2;//无效操作 int loc = row*8+col-9;//数组格式位置 loc=0~63 if( piece[loc]==1 || piece[loc]==-1 ) return -3;//已有棋子 if( piece[loc]==0 || piece[loc]==-2*color ) return -4;//不可落子 retract(piece_last, piece);piece[loc] = color;//落子操作 for( int dx=-1 ; dx<=1 ; dx++ )//八向搜索,翻转棋子  for( int dy=-1 ; dy<=1 ; dy++ ){if( dx==0 && dy==0 )  continue;for( int rowp = row+dx, colp = col+dy ; BOUNDARY(rowp,colp) ; rowp+=dx, colp+=dy ) if( piece[rowp*8+colp-9] != -color )  break;//不是反色就退出 else if( BOUNDARY(rowp+dx,colp+dy) && piece[(rowp+dx)*8+colp+dy-9]==color )for( ; rowp!=row || colp!=col ; rowp-=dx, colp-=dy )piece[rowp*8+colp-9] = color;//存在反色棋子则搜寻同色,并翻转中间的所有反色棋子 }return loc;//返回落子位置
}int main()
{int piece[64] = {0}, piece_last[64], color=1, sign=-1;piece[27]=piece[36]=-1; piece[28]=piece[35]=1;//预设棋子位置 gui(piece); introduce();start: piece[64] = {0};piece[28]=piece[35]=color=1; piece[27]=piece[36]=sign=-1;search(piece,color);//首次落子 do{gui(piece);if( sign <= -2 ) info(piece, sign, color);sign = place(piece, piece_last, color);if( sign == -1 ) sign = -5;}while( sign <= -1 );//直到落子成功,sign为位置,才退出 while(1)//后续落子 if( search(piece, color *= -1) || ( sign+=80, search(piece, color *= -1) ) )//判断是否可落子 do{gui(piece);info(piece, sign, color);sign = place(piece, piece_last, color);if( sign == -1 ) sign = retract(piece, piece_last);}while( sign <= -2 );else break;//双方都不可落子则结束;若一方无棋子,同样满足双方都不可落子 int outcome = gui(piece);printf("%s方在[%c%c]落子\n",color==1 ? "黑" : "白" , sign/8+'A' , sign%8+'1' );//黑白要颠倒一下 printf("游戏结束, %s\n再来一局吗? (Y|N 或 1|0)\n", outcome==0 ? "平局!" : ( outcome==1 ? "黑方胜!" : "白方胜!" ) );char ch;for( fflush(stdin) ; (ch=getchar())!='0' && ch!='n' && ch!='N' ; )if( ch=='1' || ch=='y' || ch=='Y' ) goto start;system("pause");return 0;
}

水平有限,若有不当之处,还请指出。

2021/4/17

黑白棋(人人对战)——C语言实现方法之一相关推荐

  1. 基于DevCloud进行黑白棋实时对战游戏开发实践【华为云至简致远】

    [摘要] 本次实践让我体验到了全程在云上创建弹性云服务器ECS,配置云服务器环境,在DevCloud平台上一站式进行项目管理.代码托管.代码检查.流水线.编译.构建.部署.测试.发布的流程.基本做到了 ...

  2. 黑白棋代码Linux程序,C语言编写的黑白棋游戏源代码.doc

    PAGE PAGE 1 C语言编写的黑白棋游戏源代码 /*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x ...

  3. 手把手教你实战开发黑白棋实时对战游戏

    摘要:本次实践可以体验到全程在云上创建弹性云服务器ECS,配置云服务器环境,在DevCloud平台上一站式进行项目管理.代码托管.代码检查.流水线.编译.构建.部署.测试.发布的流程. 本文分享自华为 ...

  4. c语言大作业黑白棋,C语言编写黑白棋游戏源代码.doc

    C语言编写的黑白棋游戏源代码 /*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值 ...

  5. Linux下黑白棋c语言程序,黑白棋(C语言源程序)

    <黑白棋(C语言源程序)>由会员分享,可在线阅读,更多相关<黑白棋(C语言源程序)(8页珍藏版)>请在人人文库网上搜索. 1.黑白棋C语言程序编辑#includegraphic ...

  6. c语言课程设计之黑白棋游戏,c语言课程设计黑白棋游戏.doc

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp学术论文&nbsp>&nbsp大学论文 c语言课程设计黑白棋游戏.doc26页 本文档一共被 ...

  7. c语言写的黑白棋游戏代码,C语言编写的黑白棋游戏源代码..doc

    C语言编写的黑白棋游戏源代码. C语言编写的黑白棋游戏/*3.3.4 源程序*/ #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x ...

  8. c语言程序设计黑白棋游戏,C语言课程设计_黑白棋游戏

    C语言课程设计_黑白棋游戏 C语言课程设计_黑白棋游戏 #include "graphics.h" /*图形系统头文件*/ #define LEFT 0x4b00 /*光标左键值* ...

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

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

最新文章

  1. 为什么Android教程中的大多数字段(类成员)都以`m`开头?
  2. chrome 技巧篇-如何查看web元素绑定的监听事件
  3. 机器人运动学(a simple car)
  4. namespace mismatch错误处理方法
  5. 一次“内存泄露”引发的血案
  6. NET问答:如何理解 IEnumerableT 和 IQueryableT
  7. 算法题目——被围绕的区域(dfs,bfs)
  8. spring aop示例_Spring JpaRepository示例(内存中)
  9. weblogic创建域后启动不了_摩托车淋雨后启动不了什么原因?如何解决?
  10. mysql 集群分区_mysql 集群与分区
  11. 案例:使用正则表达式的爬虫
  12. java加载js_Java加载js
  13. 【补丁分析】CVE-2016-8610:对导致拒绝服务的“SSL Death Alert”漏洞补丁分析
  14. mysql横纵分组统计_MySQL中如何实现分组统计
  15. 良好的树结构设计会让开发更舒爽
  16. Windows+Linux 双系统安装教程
  17. vue-video-player 实现广告视频轮播和播放直播
  18. 数据库性能优化面试题,全网最新
  19. python爬虫爬取网页图片存储本地_Python爬虫抓取糗百的图片,并存储在本地文件夹...
  20. Spring全家桶--Spring5

热门文章

  1. 2022 CSP-J1 CSP-S1 第1轮 初赛 攻略 总结 心得体会 注意事项 游记
  2. css3 的filer 功能
  3. #{}和¥{}的区别
  4. 李子柒:不希望年轻人当网红...
  5. 呀!原来这就是前端监控系统
  6. 【UOS】如何用Ventoy工具制作UOS启动盘操作
  7. windows密钥查看器ProduKey1.82汉化
  8. word2003,使用修订模式
  9. 怎么用python编写个apk_【android】如何利用python做Android项目自动化构建,并一键实现构建结果发送到钉钉通知以及通过二维码下载apk或者其他处理等功能...
  10. IMPERVA-WAF 硬盘更换