🌳🌳三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
大家好啊,我是小白,下面让我来和大家一起去看看怎么去实现它的吧!!
最后!!!创作不易,请各位小伙伴们点点赞,你们的支持,是我继续学习的动力哦
目录
一、主函数部分
int main() {
test(); //该游戏整体又一个test()函数完成
return 0;
}
主函数仅仅由一个test函数完成,当我们程序启动时,进入test函数,此时正式开始。为什么我们要这样写呢?因为这样写的目的是为了让我们习惯分块来写一个程序,这样会使程序简洁,容易修改,并且看得更加清晰哦,希望大家要有这个好习惯哦
test(函数部分)
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do //循环可以重复游戏
{
menu(); //进入菜单,选择是否游戏的选项
scanf("%d", &input);
if (input == 1) //当选择1时进入游戏
{
printf("游戏开始\n");
game();
}
else if (input ==0)
{
printf("游戏结束");
}
else printf("输入错误,请重新输入\n");
} while (input);
}
void menu()
{
printf("-----------------------------------\n");
printf("-----1、开始游戏 0、退出游戏-----\n");
printf("-----------------------------------\n");
}
进入test函数,首先我们要思考站在玩家的视角,我们要思考应该怎么玩游戏呢?所以我们要设计一个菜单让玩家做出选择,也就是menu。当玩家选择1时,进入游戏,选择0时退出游戏,当然我们玩游戏也不止会玩一次,所以要进入循环。游戏开始后进入游戏game的部分。
二、游戏设计部分
棋盘的初始化
void InitBoard(char board[max_row][max_col],int row,int col) //形参的名字不能和define定义的相同,不然会报错
{
for (int i = 0; i < row; i++) //让所有的行列上位置为空格
{
for(int j=0;j< col;j++)
{
board[i][j] =' ';
}
}
}
游戏开始之前我们要进行初始化,先建立一个空的棋盘雏形,这里我们用二维数组来替代棋盘上的位置,空格符号来代表此时棋盘上没有棋子落子。此时就是一个空棋盘,每次开始之前都要置空。
棋盘的打印
void DisplayBoard(char board[max_row][max_col], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++) //打印列分割线
{
if (j < col - 1)
{
printf(" %c |",board[i][j]);
}
else printf(" %c \n", board[i][j]); //打印一行跳到下一行
}
if (i < row - 1)
{
for (int j = 0; j < col; j++)//打印行分割线
{
if (j < col - 1)
{
printf("---|");
}
else printf("---\n");
}
}
}
}
打印效果如图
游戏的开始如果只有棋子,整体会看起来比较单一 ,所以我们通过两横两竖来打印一个简单的棋盘,棋盘的参数可以用define(宏)来定义,修改参数很方便,如果要做更大的棋盘,只需要修改参数,打印棋盘的细节很少,需要注意的是每打印一行注意跳行,且打印的时候要把之前棋盘定义的“空格”打印上,这样之后才能落子。
玩家落子
void Player_move(char board[max_row][max_col], int row, int col)
{
int x, y;
printf("轮到您了\n");
do
{
printf("请输入坐标>");
scanf("%d %d", &x, &y);
if ((x < 1 && x > 3) || (y < 1 && y > 3)) printf("输入错误,请重新输入\n");
else if(board[x-1][y-1]!=' ') printf("输入位置已被占用,请重新输入\n");
} while (x<1&&x > 3 || y<1&&y > 3|| board[x - 1][y - 1] != ' ');
board[x - 1][y - 1]='x'; //玩家所占位置用‘x’表示
}
看到玩家落子,此时我们又要站到玩家的角度思考,我怎么知道轮到我落子了呢?所以要打印一段文字来提示,并且玩家不会知道你的数组是从0开始,这点非常需要注意,所以我们对棋盘做出响应时都要进行—1处理
电脑落子
void Computer_move(char board[max_row][max_col], int row, int col)
{
int x, y = 0;
printf("电脑出手\n");
do
{
x = rand() % row;
y = rand() % col;
} while (board[x][y] != ' ');
board[x][y] = 'o'; //电脑用‘o’表示所占位置
}
电脑落子相对没有那么多的限制,当玩家落子后,电脑根据随机的函数落子即可,这里的处理时通过取余的方式来保证落在规定的行列里面。当然这个随机性会导致电脑玩家比较笨拙,我们可以想办法让他聪明点,比如让他一定落在玩家落子的旁边,这样会让玩家难赢一点,也比较好实现,这个就交给聪明的观众完成啦
判断输赢
char isWin(char board[max_row][max_col], int row, int col)
{
for (int i = 0; i < row; i++)
{
if (board[i][0]== board[i][1]&& board[i][1]==board[i][2]) //行相等时
{
return board[i][0];
}
}
for (int j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j]) //列相等时
{
return board[0][j];
}
}
if(board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
return board[1][1];
}
else if (board[2][0] == board[1][1] && board[1][1] == board[0][2])
{
return board[1][1];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < row; j++)
{
if (board[i][j] == ' ') return 'c'; //有空的返回c,表示继续
}
}
return 'q'; //经过判断无三子相连且没有空了的返回q,表示结束
}
判断输赢是最重要的一步,程序要结束,就得有输有赢,或者平局,对于三子棋,横三竖三斜三我们要考虑到,此时判断条件需要注意,条件判断不能连等,否则是错误的,且我们只是一个函数,不能直接判断输赢,需要通过他传递的信息来判断,所以他是一个有返回值的函数,当有三个相同棋子相连,则返回次棋子的字符,平局和继续分别对应q和c。
game游戏部分整体组成
void game()
{
char board[max_row][max_col] = { 0 };
InitBoard(board,max_row,max_col); //首先要建立空棋盘
DisplayBoard(board,max_row,max_col);//打印棋盘
while (1)
{
char ret = 0;
Player_move(board, max_row, max_col);
DisplayBoard(board, max_row, max_col);
ret = isWin(board, max_row, max_col);
if (ret == 'x')
{
printf("恭喜您获胜!\n"); //由玩家出手局数时获胜的只能是玩家
break;
}
else if (ret == 'q')
{
printf("你和人工智障打成平局了!\n"); //最后一颗由先手玩家落子,所以这里判断是否满了
break;
}
Computer_move(board, max_row, max_col);
DisplayBoard(board, max_row, max_col);
ret = isWin(board, max_row, max_col);
if(ret =='o')
{
printf("恭喜您输给人工智障了!\n"); //由电脑出手局数时获胜的只能是玩家
break;
}
}
}
🍇🍇game函数整体部分是由循环构成,能够一直落子,除非有一方获胜或者和局,在这个游戏的顺序和方式都由此函数控制,也可以通过两个玩家移动的函数来达到玩家对战玩家的目的,小伙伴们可以自己试一下哦!
三、完整代码
//实现三子棋
#define _CRT_SECURE_NO_WARNINGS 1
#define max_row 3 //定义行数 修改的时候只改变参数就行了
#define max_col 3 //定义列数
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void InitBoard(char board[max_row][max_col],int row,int col) //形参的名字不能和define定义的相同,不然会报错
{
for (int i = 0; i < row; i++) //让所有的行列上位置为空格
{
for(int j=0;j< col;j++)
{
board[i][j] =' ';
}
}
}
void DisplayBoard(char board[max_row][max_col], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++) //打印列分割线
{
if (j < col - 1)
{
printf(" %c |",board[i][j]);
}
else printf(" %c \n", board[i][j]); //打印一行跳到下一行
}
if (i < row - 1)
{
for (int j = 0; j < col; j++)//打印行分割线
{
if (j < col - 1)
{
printf("---|");
}
else printf("---\n");
}
}
}
}
void Player_move(char board[max_row][max_col], int row, int col)
{
int x, y;
printf("轮到您了\n");
do
{
printf("请输入坐标>");
scanf("%d %d", &x, &y);
if ((x < 1 && x > 3) || (y < 1 && y > 3)) printf("输入错误,请重新输入\n");
else if(board[x-1][y-1]!=' ') printf("输入位置已被占用,请重新输入\n");
} while (x<1&&x > 3 || y<1&&y > 3|| board[x - 1][y - 1] != ' ');
board[x - 1][y - 1]='x'; //玩家所占位置用‘x’表示
}
void Computer_move(char board[max_row][max_col], int row, int col)
{
int x, y = 0;
printf("电脑出手\n");
do
{
x = rand() % row;
y = rand() % col;
} while (board[x][y] != ' ');
board[x][y] = 'o'; //电脑用‘o’表示所占位置
}
char isWin(char board[max_row][max_col], int row, int col)
{
for (int i = 0; i < row; i++)
{
if (board[i][0]== board[i][1]&& board[i][1]==board[i][2]) //行相等时
{
return board[i][0];
}
}
for (int j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j]) //列相等时
{
return board[0][j];
}
}
if(board[0][0] == board[1][1] && board[1][1] == board[2][2])
{
return board[1][1];
}
else if (board[2][0] == board[1][1] && board[1][1] == board[0][2])
{
return board[1][1];
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < row; j++)
{
if (board[i][j] == ' ') return 'c'; //有空的返回c,表示继续
}
}
return 'q'; //经过判断无三子相连且没有空了的返回q,表示结束
}
void menu()
{
printf("-----------------------------------\n");
printf("-----1、开始游戏 0、退出游戏-----\n");
printf("-----------------------------------\n");
}
void game()
{
char board[max_row][max_col] = { 0 };
InitBoard(board,max_row,max_col); //首先要建立空棋盘
DisplayBoard(board,max_row,max_col);//打印棋盘
while (1)
{
char ret = 0;
Player_move(board, max_row, max_col);
DisplayBoard(board, max_row, max_col);
ret = isWin(board, max_row, max_col);
if (ret == 'x')
{
printf("恭喜您获胜!\n"); //由玩家出手局数时获胜的只能是玩家
break;
}
else if (ret == 'q')
{
printf("你和人工智障打成平局了!\n"); //最后一颗由先手玩家落子,所以这里判断是否满了
break;
}
Computer_move(board, max_row, max_col);
DisplayBoard(board, max_row, max_col);
ret = isWin(board, max_row, max_col);
if(ret =='o')
{
printf("恭喜您输给人工智障了!\n"); //由电脑出手局数时获胜的只能是玩家
break;
}
}
}
void test()
{
int input = 0;
srand((unsigned int)time(NULL));
do //循环可以重复游戏
{
menu(); //进入菜单,选择是否游戏的选项
scanf("%d", &input);
if (input == 1) //当选择1时进入游戏
{
printf("游戏开始\n");
game();
}
else if (input ==0)
{
printf("游戏结束");
}
else printf("输入错误,请重新输入\n");
} while (input);
}
int main() {
test(); //该游戏整体又一个test()函数完成
return 0;
}
另外,大家看完三子棋,可以试一试五子棋哦,五子棋的难度次数增加哦!
四、结语
这样一个简单的小游戏,推荐大家做一下哦。
读万卷书,不如行万里路,我们在尝试中不断地改变自己,不断地进步,发现自己的错误,最终会获得巨大的成就感。不放弃,就是我们编程路上的加油站,大家加油,我相信你们能编出更好程序。🌹🌹🌹