相信大家在生活中肯定知道和了解五子棋的玩法,三子棋的玩法和五子棋一样,当有三个一样的“棋子”连成一条线,不管是横竖斜,谁先完成这个条件,谁就获胜。

那大家有没有想过用编码的形式怎么样简单设计一款三子棋游戏呢?会用到哪些知识呢,如果大家有一些头绪了,也不用着急,下面大家跟随我的脚步就用我们所学的C语言来设计一个简单一点的游戏 --“三子棋”。

下面我的代码会先分步骤展示出来进行讲解,最后我会把全部代码展示出来便于大家参考使用。

1.主函数块和菜单块

虽然作为一款简单的小游戏,但我们也应该有菜单界面供用户进行选择

#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3int main()
{int input=0;do{menu();printf("请选择:>");scanf("%d",&input);switch(input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入有错,请重新输入\n");break;        }      } while(input); //正好和input输入0时对应,当条件为0时跳出循环 return 0;} 
void menu()
{printf("*************************\n");printf("********井子棋游戏*******\n");printf("*****1.play   0.exit*****\n");printf("*************************\n");
}

可以看到我们先通过 switch 语句对我们进入模块进行控制,外层再通过 do-while 循环语句对 switch语句进行控制循环,while 语句的循环条件为 input 的取值,这里 while 语句和 switch 语句的判断条件形成了呼应,在 input 的输入值为0时正好时退出游戏,同时也退出了do-while循环。

2.初始化棋盘(创建棋盘)

我们是个下棋的小游戏,顾名思义是在棋盘上下棋,所以第一步我们应该创建一个空白的棋盘,这里我们创建的是一个 3 * 3 的一个棋盘。

void InitBoard(char board[ROW][COL],int row,int col)
{int i=0;int j=0;for(i=0;i<row;i++){for(j=0;j<col;j++){board[i][j]=' ';}}
}

我们通过二维数组的形式创建一个3 * 3 的棋盘,我们将数组里的每个空间都放上空格字符,这样我们就完成了对键盘的初始化了。

3.打印棋盘

上面我们初始化了一个棋盘,现在我们应该把它打印到我们的屏幕上,供我们使用

//打印键盘
void DisplayBoard(char board[ROW][COL],int row,int col)
{int i=0;for(i=0;i<row;i++){int j=0;for(j=0;j<col;j++){//打印一行数据printf(" %c ",board[i][j]);if(j<col-1)printf("|"); }printf("\n");//打印分割行 if(i<row-1){for(j=0;j<row;j++){printf("---");if(j<row-1)printf("|"); } }printf("\n");}}

我们可以将我们的棋盘看成“井”字,所以我们可以看成五行数据组成的棋盘。

分别由三行 '   |   |   ' 和两行 '---|---|---' 组成,所以我们就通过for循环对输出的结果进行控制打印后续我们下棋的棋子是字符型的数据,所以是以" %c "进行打印的。

4.玩家下棋

现在我们的棋盘也都初始化和打印好了,所以到了我们进行游戏开始下棋的步骤了。

//玩家走
void PlayerMove(char board[ROW][COL], int row, int col)
{int x=0;int y=0;printf("玩家走:\n");while(1){printf("请输入要走的坐标:>");scanf("%d%d",&x,&y);//判断输入的地址合法性if(x>=1 && x<=row && y>=1 && y<=col){if(board[x-1][y-1]==' '){board[x-1][y-1]='*';break;}else{printf("该地址被占用\n");}}else{printf("地址不合法,请重新输入\n");     }}} 

我们通过while循环对我们下棋的过程进行控制,在这之下,我们先用if语句对输入的地址进行判断是否合法,如果合法,再用if语句进行判断地址是否已经有数据了(不是空格字符),如果没有则成功落子,用break语句跳出while循环,如果不是则如此反复。

当然有细心的小伙伴可能也注意到了,我们这里对数组地址的判断是进行了减一操作的,这是因为在普通的用户中,他们可能不了解数组地址是从0开始的,很多人都认为和坐标一样,是从下标为1开始的,所以我们这里是抓住用户的思想,体现了用户友好型,方便用户进行理解。

5.电脑走

上一步玩家已经下完棋了,所以现在应该电脑下棋了

//电脑走
void ComputerMove(char board[ROW][COL],int row,int col)
{int x=0;int y=0;printf("电脑走:>\n");while(1){//通过rand函数生产随机数,通过模row,col 取的(0~row-1)的随机的数 x=rand()% row;y=rand()% col;if(board[x][y]==' '){board[x][y]='#';break;}}
}

电脑下棋的逻辑和玩家下棋的逻辑类似,但我们很多同学可能会有疑问,我们也没有输入什么来控制电脑电脑是通过什么来进行选择下在哪里的呢?我们这里用到了rand()函数,这个函数是用来产生随机数的,我们通过产生的随机数对行和列分别做取余操作,这样我们就可以得到(0~row-1)和(0~col-1)中的全部数,这些数正好符合我们二维数组的取值,所以我们产生的数可以遍历我们二维数组。(巧妙点)  然后我们和玩家一样通过if语句对数组进行判断,符合条件就落子成功,否则失败。

6.判断游戏状态

重点:我们每下的一步都有可能改变游戏的状态,所以我们应该在玩家下完棋和电脑下完棋后分别对游戏状态进行判断。

//游戏的四种状态
//玩家赢--'*'
//电脑赢--'#'
//平局--'Q'
//谁都没赢,继续--'C' //判断输赢
char IsWin(char board[ROW][COL], int row, int col)
{int i=0;//横三列 for(i=0; i<row; i++){if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] !=' ' ){return board[i][1];}}//竖三列 for(i=0; i<col; i++){if(board[0][i] == board [1][i] && board[1][i] == board[2][i] && board[1][i] !=' '){return board[1][i];}}//两个对角线  if(board[0][0] == board [1][1] && board[1][1] == board[2][2] && board[1][1] !=' ')return board[1][1];if(board[0][2] == board [1][1] && board[1][1] == board[2][0] && board[1][1] !=' ') return board[1][1];if(1==IsFull(board, ROW, COL))//通过函数判断是否平局 {return 'Q';} return 'C';
}//判断平局
int IsFull(char board[ROW][COL], int row, int col)
{int i=0;int j=0;for(i=0; i<row; i++){for(j=0; j<col; j++){if(board[i][j] ==' '){return 0;//没满 }}}return 1;//满了
}

这里我放了两个调用函数没有分开放,因为这两个函数都是用来判断游戏状态的。首先赢得条件就是当横竖斜中有三个一样的连成一条线则获胜,然后返回这三个其中的一个字符,然后通过返回的字符来判断谁获胜,最后游戏结束。当然三子棋也有平局的可能,我们通过调用IsFull函数对数组进行判断,如果数组满了(不是空格字符),返回指定字符,通过字符则判断平局,如果没满,则也返回指定字符,判断游戏继续。

这其中对应字符的对应关系我放在代码注释上了,大家自己对着进行了解

7.游戏的整个算法实现

这个是整个游戏的核心思想,整个游戏实现的逻辑和实现的算法都在这里

//游戏的整个算法实现
void game()
{char ret =0;//数组存放走出的棋盘信息 char board[ROW][COL]={0};//全部空格//初始化棋盘InitBoard(board,ROW,COL);//打印棋盘DisplayBoard(board,ROW,COL); //玩家下棋while(1){PlayerMove(board,ROW,COL);DisplayBoard(board,ROW,COL);//判断玩家是否赢ret=IsWin(board, ROW, COL);if(ret!='C'){break;} //电脑下棋  ComputerMove(board, ROW, COL);DisplayBoard(board,ROW,COL);//判断电脑输赢 ret=IsWin(board,ROW,COL);if(ret!='C'){break;}} if(ret=='*'){printf("玩家赢\n");}else if(ret=='#'){printf("电脑赢\n");}else{printf("平局\n"); }}

因为我们是通过主函数进入到这个代码块,所以在这里我们要把我后续调用函数中要用到的东西全部在这里定义好。整个游戏的思想就是通过不通转变返回的字符值,来判断游戏的状态,知道游戏结束(平局 或 玩家赢 或 电脑赢)。

虽然看着长,但是简单,步骤就是:

初始化棋盘-->打印棋盘-->玩家下棋-->判断状态-->电脑下棋-->判断状态-->反复进行直到平局,玩家赢或电脑赢的状态出现-->打印结果-->游戏结束

8.全部代码整合

#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3
#define COL 3//游戏的四种状态
//玩家赢--'*'
//电脑赢--'#'
//平局--'Q'
//谁都没赢,继续--'C' //判断输赢
char IsWin(char board[ROW][COL], int row, int col)
{int i=0;//横三列 for(i=0; i<row; i++){if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] !=' ' ){return board[i][1];}}//竖三列 for(i=0; i<col; i++){if(board[0][i] == board [1][i] && board[1][i] == board[2][i] && board[1][i] !=' '){return board[1][i];}}//两个对角线  if(board[0][0] == board [1][1] && board[1][1] == board[2][2] && board[1][1] !=' ')return board[1][1];if(board[0][2] == board [1][1] && board[1][1] == board[2][0] && board[1][1] !=' ') return board[1][1];if(1==IsFull(board, ROW, COL))//通过函数判断是否平局 {return 'Q';} return 'C';
}//判断平局
int IsFull(char board[ROW][COL], int row, int col)
{int i=0;int j=0;for(i=0; i<row; i++){for(j=0; j<col; j++){if(board[i][j] ==' '){return 0;//没满 }}}return 1;//满了
}//电脑走
void ComputerMove(char board[ROW][COL],int row,int col)
{int x=0;int y=0;printf("电脑走:>\n");while(1){//通过rand函数生产随机数,通过模row,col 取的(0~row-1)的随机的数 x=rand()% row;y=rand()% col;if(board[x][y]==' '){board[x][y]='#';break;}}
}//玩家走
void PlayerMove(char board[ROW][COL], int row, int col)
{int x=0;int y=0;printf("玩家走:\n");while(1){printf("请输入要走的坐标:>");scanf("%d%d",&x,&y);//判断输入的地址合法性if(x>=1 && x<=row && y>=1 && y<=col){if(board[x-1][y-1]==' '){board[x-1][y-1]='*';break;}else{printf("该地址被占用\n");}}else{printf("地址不合法,请重新输入\n");     }}} //打印键盘
void DisplayBoard(char board[ROW][COL],int row,int col)
{int i=0;for(i=0;i<row;i++){int j=0;for(j=0;j<col;j++){//打印一行数据printf(" %c ",board[i][j]);if(j<col-1)printf("|"); }printf("\n");//打印分割行 if(i<row-1){for(j=0;j<row;j++){printf("---");if(j<row-1)printf("|"); } }printf("\n");}}//初始化键盘
void InitBoard(char board[ROW][COL],int row,int col)
{int i=0;int j=0;for(i=0;i<row;i++){for(j=0;j<col;j++){board[i][j]=' ';}}
}//菜单界面
void menu()
{printf("*************************\n");printf("********井子棋游戏*******\n");printf("*****1.play   0.exit*****\n");printf("*************************\n");
}//游戏的整个算法实现
void game()
{char ret =0;//数组存放走出的棋盘信息 char board[ROW][COL]={0};//全部空格//初始化棋盘InitBoard(board,ROW,COL);//打印棋盘DisplayBoard(board,ROW,COL); //玩家下棋while(1){PlayerMove(board,ROW,COL);DisplayBoard(board,ROW,COL);//判断玩家是否赢ret=IsWin(board, ROW, COL);if(ret!='C'){break;} //电脑下棋  ComputerMove(board, ROW, COL);DisplayBoard(board,ROW,COL);//判断电脑输赢 ret=IsWin(board,ROW,COL);if(ret!='C'){break;}} if(ret=='*'){printf("玩家赢\n");}else if(ret=='#'){printf("电脑赢\n");}else{printf("平局\n"); }}//主函数
int main()
{int input=0;do{menu();printf("请选择:>");scanf("%d",&input);switch(input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入有错,请重新输入\n");break;        }      } while(input); //正好和input输入0时对应,当条件为0时跳出循环 return 0;} 

上面是全部代码的整合,以方便供大家使用。

三子棋游戏的核心点就是算法和逻辑的实现,加上部分函数里的巧妙点,大家需要多加的理解和掌握。如rand()生成随机数的函数,大家可能有了解过,但可能没有自己实际应用过,这里就很好的体现了,这个函数的巧妙点,大家可以通过这个小游戏对这种类型函数加深了解,以便以后自己更熟练的应用。

(初级大学软工在读小白)用来整理自己的基础知识,如果写的有什么不对的地方,还望各位大佬指出!

C语言--实现(三)井子棋小游戏(基础版)相关推荐

  1. 井字棋小游戏c语言简单编码,井字棋小游戏(C语言)

    1 #include 2 #include 3 #include 4 #include 5 #include 6 7 void drawBoard(char *board) //绘制棋盘 8 {9 p ...

  2. C语言 VS2019编译器实现简易井字棋小游戏~

    文章目录 井字棋小游戏 游戏实现 一.创建新项目及游戏文件 二.引头文件,定义符号 三.主函数 打印菜单 四.开始游戏 1.创建二维数组 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑下棋 6. ...

  3. C语言初学——井字棋小游戏

    hello呀!小伙伴们,今天小刘同学要带着大家学习的内容是--井字棋小游戏!!! 在本次学习中,我们将会运用到的主要内容是数组,函数,循环和判断. 当然,本次学习的内容并不困难,希望本次教学结束大家都 ...

  4. 用Unity3D实现简单的井字棋小游戏

    用Unity3D实现简单的井字棋小游戏 项目地址 井字棋小游戏 完成效果图 实现思路 首先定义游戏的数据部分: /* 井字棋中每一个棋格中的逻辑控制常量,代表这个棋格的状态 */ private co ...

  5. 井字棋小游戏代码(Visual Studio)

    #include<graphics.h> #include<conio.h> #include<iostream> #include "ImagePng. ...

  6. python如何在前面加井_python入门之井字棋小游戏

    引言: 刚学python好几天了,从java到python,基础学起来确实比较容易,语法掌握,基本概念上都比较容易入脑. 唯一比较郁闷的是老想着用java的语法去学python代码,这点还需要后面慢慢 ...

  7. 基于vue框架使用canvas实现井字棋小游戏

    引言:最近实现了一个图片上传压缩的功能,使用了canvas,所以学习一下canvas的语法,实现一个井字棋小游戏,这个小游戏可以人人对弈,如果大家有兴趣,可以对代码进行迭代,比如采用极大值极小值搜索法 ...

  8. python井字棋_用Python做一个井字棋小游戏

    井字棋是一个经典的小游戏,在九宫格上玩家轮流画OXO,当每列或每行或是两个对角成一线时便是获胜. 今天就用Python编写一个井字棋小游戏,与电脑对战. 程序执行画面如下图所示: 程序提供了两种人工智 ...

  9. python井字棋游戏人机对战_用Python做一个井字棋小游戏

    井字棋是一个经典的小游戏,在九宫格上玩家轮流画OXO,当每列或每行或是两个对角成一线时便是获胜. 今天就用Python编写一个井字棋小游戏,与电脑对战. 程序执行画面如下图所示: 程序提供了两种人工智 ...

最新文章

  1. Udacity机器人软件工程师课程笔记(十四)-运动学-正向运动学和反向运动学(其一)
  2. Nginx + PHP/PHP-FPM安装配置示例
  3. JAVAEE框架之SpringMVC基础
  4. edusrc0day挖掘技巧
  5. 震惊!!!CSS垂直居中竟然有这么多方法~
  6. Arcgis javascript那些事儿(十五)——影像服务的发布与使用
  7. SLAM学习------Sophus模板类的安装和使用
  8. [热门]Android系统特质 不需要太多剩余内存
  9. 对Runtime的理解
  10. CI框架入门中的简单MVC例子
  11. 弘辽科技:你吃的粽子,撑起百亿市场
  12. eve-ng 2.0.3-112懒人版安装、GNS3 2.2.32安装包、思科ASA8.42 9.42 路由器C3600 C7200、IOU镜像、思科IPS入侵防御系统
  13. “华为”和“荣耀”的关系紧密,双品牌携手驰骋手机市场
  14. R语言一般线性模型(涉及因变量是虚拟变量(哑变量))
  15. 7-66 华氏温度转换为摄氏温度
  16. mybatisPlus中getOne方法如何只取其中一条数据(Wrapper有多条数据时)
  17. EMC——辐射测试总结
  18. python 滤镜色卡
  19. 黑客新手基础扫盲贴(下) 黑客基地 黑客传说 黑客帝国 指间的黑客 黑客网站
  20. 绩效管理流程是什么?

热门文章

  1. Python——定时器
  2. 苹果电脑更改sd卡只读_sd卡反复变成只读解决办法
  3. 用C++类模板实现栈结构出现的问题以及思考
  4. 想要做”架构师“,一定要会画设计图
  5. html5都能干嘛种花,家里千万不能养的6种花
  6. 《成长是一件孤独的事》周国平 书摘
  7. 手机号码归属地API
  8. 多文件以压缩包形式下载
  9. OAuth2.0实践之foursquare客户端登录
  10. 如何调节音频音量大小?