C语言游戏跟电脑battle三子棋
Posted Do
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言游戏跟电脑battle三子棋相关的知识,希望对你有一定的参考价值。
目录
三子棋
三子棋算法有很多,这里仅是我个人的介绍,这种方法简单实现易于理解,特别适合新手实操。
三子棋规则介绍
三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
如何用c语言实现三子棋
对于游戏实现的代码,我们最好分三个板块来写,而不是在一个源文件里面写。这里应该分类创建三个文件,test.c:游戏整体的逻辑。game.h:关于游戏相关函数的声明,头文件的包含。game.c:游戏相关函数的实现。
基本思路
-
创建游戏菜单,供用户选择玩游戏,还是退出游戏。
-
创建一个棋盘数组,并将它初始化。
-
打印一个棋盘。
-
玩家下棋(通过用户输入的坐标落子)
-
判定胜负关系。
-
电脑下棋(通过随机函数让它落子)
-
判定胜负关系。
-
游戏结束。
分部代码实现
游戏菜单
void menu()
printf("********************\\n");
printf("****** 1.play ******\\n");
printf("****** 0.exit ******\\n");
printf("********************\\n");
int main()
int input = 0;
printf("请选择:");
srand((unsigned int)time(NULL)); //使用rand函数要调用srand
do
menu();
scanf_s("%d", &input);
switch (input)
case 1:
game();
break;
case 0:
printf("退出游戏\\n");
break;
default :
printf("输入错误,请重新选择!\\n");
break;
while (input);
return 0;
这里涉及到用户的选择,所以需要把主函数部分展现给大家看,利用do while语句实现游戏的重复,使用switch语句接收用户的选择,选择1则进入game()函数开始玩游戏,选择0则退出游戏,如果未按要求输入就重新选择,这里的条件设置为input非常巧妙,只有输入0才会退出循环。
初始化棋盘
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] = ' '; //初始化棋盘为空格
棋盘可以看成一个数组,将棋盘初始化即利用for循环将棋盘数组每个元素初始化为空格。
打印棋盘
void Displayboard(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++)
//打印一行
printf(" %c ",board[i][j]); //将字符加竖线作为一个整体,分开打印
if (j < col-1)
printf("|"); //最后一列不用打印竖线
printf("\\n");//记得每打印一行就换行
//打印多行
if (i < row-1) //最后一行不打印下划线,不是最后一行都要打印
int j = 0;
for (j = 0; j < col; j++)
printf("___");
if (j < col-1)
printf("|");
printf("\\n");
下面我们来看看打印出来的棋盘:
这里有什么不懂得可以看我代码里的注释,解释的非常详细,我就不另外解释了。
玩家下棋
void Playerboard(char board[ROW][COL], int row, int col) //玩家下棋
int x = 0;
int y = 0;
while (1)
//每次输入坐标下棋是一个循环,所以用while
printf("玩家下棋,请输入坐标:\\n");
scanf_s("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) //判断坐标合法性
if (board[x - 1][y - 1] == ' ') //如果坐标没被占用,玩家输入的坐标与数组元素下标相差1
board[x - 1][y - 1] = '*';
break; //玩家每下完一次要退出循环
else
printf("坐标被占用请重新输入!\\n"); //输入错误,没有break,就返回循环
else
printf("坐标不合法请重新输入!\\n");
这里有两个关键点:
(1)确定坐标的合法性,用户输入的坐标不能超过数组下标。
(2)判断坐标有没有被占用,如果没有被占用则玩家下棋,我把这里玩家下的棋为'*'号。
电脑下棋
void Computerboard(char board[ROW][COL], int row, int col) //电脑下棋
printf("电脑下棋:\\n");
while (1)
//要使电脑下棋合法即让随机数模坐标,其范围肯定不超过行和列
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') //这里x和y不用减1,因为x和y的值不会等于行和列的数值
board[x][y] = '#';
break; //电脑下完棋要退出循环,让玩家下棋
让电脑下棋则比较简单,使用rand随机函数即可,但这里要注意的是使用rand函数必须在主函数调用srand。
判定胜负关系
如果玩家赢则返回‘*’号,如果电脑赢则返回‘#’号,平局返回‘Q’。
判定是否平局:
int Isfull(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++)
if (board[i][j] == ' ')
return 0; //没满,返回0,与后面的字符ret对应,字符ret就返回c;
return 1; //当所有棋盘都遍历完之后没有空格则表示满了,返回1;与后面Iswin函数里面的ret返回值对应
判定胜负:
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[2][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[2][0] != ' ')
return board[1][1];
//Isfull函数判断平局,这里设计整型ret返回值与game()里的字符ret(用于接收iswin字符返回值判断输赢)对应
int ret = Isfull(board, ROW, COL); //这里的ret用来判断是否平局,如果返回1则返回Q,与前面的char ret对应,表示平局,不是返回1则返回c,游戏继续;
if (ret == 1)
return 'Q';
return 'C';
game()函数
void game()
char board[ROW][COL];
Initboard(board, ROW, COL);
Displayboard(board, ROW, COL);
char ret = 0; //接收游戏返回的值
while (1)
Playerboard(board, ROW, COL);//玩家下棋
Displayboard(board, ROW, COL); //打印棋盘
ret = Iswin(board, ROW, COL); //判断是否赢
if (ret != 'C')
break; //不是c则退出循环
Computerboard(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");
Displayboard(board, ROW, COL);
game()函数是游戏的整体模型,包含了菜单打印,棋盘初始化,打印棋盘,玩家下棋,电脑下棋以及判定胜负这些函数的调用,这些函数一步一步实现以保证整个游戏的进行。这里要注意的是玩家和电脑下完棋后都要一一判定胜负。
总代码实现
这里写在一起的话不便于理解和修改,所以我分了三个部分:
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void Initboard(char board[ROW][COL], int row, int col);
void Displayboard(char board[ROW][COL], int row, int col);
void Playerboard(char board[ROW][COL], int row, int col);
void Computerboard(char board[ROW][COL], int row, int col);
char Iswin(char board[ROW][COL], int row, int col);
game.c
#include"game.h"
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 Displayboard(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++)
//打印一行
printf(" %c ",board[i][j]); //将字符加竖线作为一个整体,分开打印
if (j < col-1)
printf("|"); //最后一列不用打印竖线
printf("\\n");//记得每打印一行就换行
//打印多行
if (i < row-1) //最后一行不打印下划线,不是最后一行都要打印
int j = 0;
for (j = 0; j < col; j++)
printf("___");
if (j < col-1)
printf("|");
printf("\\n");
void Playerboard(char board[ROW][COL], int row, int col) //玩家下棋
int x = 0;
int y = 0;
while (1)
//每次输入坐标下棋是一个循环,所以用while
printf("玩家下棋,请输入坐标:\\n");
scanf_s("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) //判断坐标合法性
if (board[x - 1][y - 1] == ' ') //如果坐标没被占用,玩家输入的坐标与数组元素下标相差1
board[x - 1][y - 1] = '*';
break; //玩家每下完一次要退出循环
else
printf("坐标被占用请重新输入!\\n"); //输入错误,没有break,就返回循环
else
printf("坐标不合法请重新输入!\\n");
void Computerboard(char board[ROW][COL], int row, int col) //电脑下棋
printf("电脑下棋:\\n");
while (1)
//要使电脑下棋合法即让随机数模坐标,其范围肯定不超过行和列
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ') //这里x和y不用减1,因为x和y的值不会等于行和列的数值
board[x][y] = '#';
break; //电脑下完棋要退出循环,让玩家下棋
int Isfull(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++)
if (board[i][j] == ' ')
return 0; //没满,返回0,与后面的字符ret对应,字符ret就返回c;
return 1; //当所有棋盘都遍历完之后没有空格则表示满了,返回1;与后面Iswin函数里面的ret返回值对应
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[2][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[2][0] != ' ')
return board[1][1];
//Isfull函数判断平局,这里设计整型ret返回值与game()里的字符ret(用于接收iswin字符返回值判断输赢)对应
int ret = Isfull(board, ROW, COL); //这里的ret用来判断是否平局,如果返回1则返回Q,与前面的char ret对应,表示平局,不是返回1则返回c,游戏继续;
if (ret == 1)
return 'Q';
return 'C';
test.c
#include<stdio.h>
#include"game.h"
void menu()
printf("********************\\n");
printf("****** 1.play ******\\n");
printf("****** 0.exit ******\\n");
printf("********************\\n");
void game()
char board[ROW][COL];
Initboard(board, ROW, COL);
Displayboard(board, ROW, COL);
char ret = 0; //接收游戏返回的值
while (1)
Playerboard(board, ROW, COL);//玩家下棋
Displayboard(board, ROW, COL); //打印棋盘
ret = Iswin(board, ROW, COL); //判断是否赢
if (ret != 'C')
break; //不是c则退出循环
Computerboard(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");
Displayboard(board, ROW, COL);
int main()
int input = 0;
printf("请选择:\\n");
srand((unsigned int)time(NULL)); //使用rand函数要调用srand
do
menu();
scanf_s("%d", &input);
switch (input)
case 1:
game();
break;
case 0:
printf("退出游戏\\n");
break;
default :
printf("输入错误,请重新选择!\\n");
break;
while (input);
return 0;
玩游戏
让代码跑起来,我来跟电脑交交手:
轻而易举战胜电脑,哈哈。还挺好玩的,大家有兴趣的话可以玩玩,或者你来告诉我怎么让电脑永远赢不了,嘻嘻。
总结
三子棋游戏考验了我们对数组的理解和运用,对循环分支语句的运用,关键是要理清思路,一步一步实现,像这种这么长的代码,我们最好是写完一部分就去运行一下,以防到最后出现错误很难去找。
本期文章就到这,希望能给大家带来帮助,那怕是一点点也好,我都非常高兴能帮助到大家,你们的认可是对我最大的帮助,你们的一键三连是我的动力。最后感谢大家的阅读,如有不足敬请谅解,欢迎大家批评指正!
以上是关于C语言游戏跟电脑battle三子棋的主要内容,如果未能解决你的问题,请参考以下文章