前言
今天向大家分享用c语言来实现三子棋,至于为啥说是小朋友的三子棋,相信大家看完后就会有答案了。
游戏说明
我们会创建三个分文件来实现该游戏:text.c && game.c &&game.h
text.c:实现游戏的整体思路
game.c:游戏内部函数的实现
game.h:游戏内部函数的定义
二 实现步骤
1.用text函数实现菜单打印
void menu() { printf("*****************************\n"); printf("*****1:玩游戏 0:退出游戏*****\n"); printf("*****************************\n");} void text() { int intput = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入:>"); scanf("%d", &intput);//scanf函数一定要放在循环语句中 switch (intput) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (intput); } int main() { text(); return 0; }
这样我们便得到了一个菜单,玩家可以选择是否玩游戏
2.初始化棋盘以及打印棋盘
char board [ROW][COL] = {0}; Initboard(board,ROW,COL);//初始化棋盘 playboard(board,ROW,COL);//打印棋盘
具体的代码实现:
void Initboard(char board[ROW][COL], int row, int col) { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } void playboard(char board[ROW][COL], int row, int col) { int i ; int j ; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) {//1 打印一行的数据 printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //2 打印分割行 if (i < row - 1) {for(j=0;j<col;j++) { printf("---"); if (j < col - 1) printf("|"); } printf("\n"); } } }
棋盘初始化是为了让board中的每一个元素都初始化为' ',打印棋盘时值得注意的是为了让棋盘更加的美观,每一行最后一个'|'不打印,最后一个分割行不打印,用的是if语句实现的,具体的可以参考我写的代码。
3 玩家和电脑下棋
//玩家下棋 playermove(board, ROW, COL); playboard(board, ROW, COL);
//电脑下棋 computermove(board, ROW, COL); playboard(board, ROW, COL);
玩家和电脑下棋后还要打印棋盘,方便玩家进行下一步
4 玩家移动和电脑移动
void playermove(char board[ROW][COL], int row, int col) { int x = 0, y = 0; printf("玩家下棋;>\n"); while (1) { printf("请输入坐标:>\n"); 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;//用break语句跳出循环,防止一直输入坐标 } else printf("该坐标被占用\n"); } else printf("输入错误,请重新输入:>"); } } void computermove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑走:>\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '$'; break; } } }
玩家落棋是用playermove函数实现的,其中玩家每一次成功落棋后都要用break跳出循环,以防一直输入坐标。电脑落棋是用computermove函数实现的,其中随机数的设计用到了时间戳,这里便不在多说。
5 判断输赢
我们可以知道三子棋只要有一方三个数连在一起时就获胜,无论是横向纵向还是斜向,那么我们该如何判断有三个数连在一起呢?
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][0] != ' ') return board[i][0]; } //判断竖三列 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') return board[0][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ') return board[0][0]; if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ') return board[2][0]; if (1 == IsFull(board, ROW, COL)) return 'Q'; return 'C'; }
上面的横三行 竖三列 斜向都很好理解,关键是后面的'Q','C'怎么理解?
我们这样来看:
游戏的结果有下面这几种情况
- 玩家赢
- 电脑赢
- 平局
- 继续游戏
IsWin函数实现后会返回一个值,为了让代码更加简单,我们不妨假设玩家赢了返回'*'.电脑赢了返回'$',平局就返回'Q',继续游戏就返回'C'
有了这个理解我们就可以写代码了
while (1) { //玩家下棋 playermove(board, ROW, COL); playboard(board, ROW, COL); //判断玩家的输赢 ret=IsWin(board,ROW,COL); if (ret != 'C') break; //电脑下棋 computermove(board, ROW, COL); playboard(board, ROW, COL); //判断电脑的输赢 ret = IsWin(board, ROW, COL); if (ret != 'C') break; } if (ret == '*') printf("玩家赢\n"); else if (ret == '$') printf("电脑赢\n"); else printf("平局\n"); }
IsWin函数函数中的IsFull函数又是什么鬼呢?
是这样的:当棋盘已经被下满了的时候IsFull函数就返回1,否则就返回0。
//返回1表示棋盘满了 //返回0表示棋盘没满 int IsFull(char board[ROW][COL],int row,int col) { int i = 0, j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') return 0;//没有满 } } return 1;//满了
这样我们就完成了这个小游戏
三 代码实现
在text.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include"game.h" void game() { char board [ROW][COL] = {0}; Initboard(board,ROW,COL);//初始化棋盘 playboard(board,ROW,COL);//打印棋盘 char ret = 0; while (1) { //玩家下棋 playermove(board, ROW, COL); playboard(board, ROW, COL); //判断玩家的输赢 ret=IsWin(board,ROW,COL); if (ret != 'C') break; //电脑下棋 computermove(board, ROW, COL); playboard(board, ROW, COL); //判断电脑的输赢 ret = IsWin(board, ROW, COL); if (ret != 'C') break; } if (ret == '*') printf("玩家赢\n"); else if (ret == '$') printf("电脑赢\n"); else printf("平局\n"); } void menu() { printf("*****************************\n"); printf("*****1:玩游戏 0:退出游戏*****\n"); printf("*****************************\n");} void text() { int intput = 0; srand((unsigned int)time(NULL)); do { menu(); printf("请输入:>"); scanf("%d", &intput);//scanf函数一定要放在循环语句中 switch (intput) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (intput); } int main() { text(); return 0; }
在game.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void Initboard(char board[ROW][COL], int row, int col) { int i, j; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } void playboard(char board[ROW][COL], int row, int col) { int i ; int j ; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) {//1 打印一行的数据 printf(" %c ", board[i][j]); if (j < col - 1) printf("|"); } printf("\n"); //2 打印分割行 if (i < row - 1) {for(j=0;j<col;j++) { printf("---"); if (j < col - 1) printf("|"); } printf("\n"); } } } void playermove(char board[ROW][COL], int row, int col) { int x = 0, y = 0; printf("玩家下棋;>\n"); while (1) { printf("请输入坐标:>\n"); 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;//用break语句跳出循环,防止一直输入坐标 } else printf("该坐标被占用\n"); } else printf("输入错误,请重新输入:>"); } } void computermove(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; printf("电脑走:>\n"); while (1) { x = rand() % row; y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '$'; break; } } } //返回1表示棋盘满了 //返回0表示棋盘没满 int IsFull(char board[ROW][COL],int row,int col) { int i = 0, j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') return 0;//没有满 } } return 1;//满了 } 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][0] != ' ') return board[i][0]; } //判断竖三列 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') return board[0][i]; } if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ') return board[0][0]; if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[2][0] != ' ') return board[2][0]; if (1 == IsFull(board, ROW, COL)) return 'Q'; return 'C'; }
在game.h:
#define ROW 3//千万不要加分号 #define COL 3 #include<stdio.h> #include<stdlib.h> #include<time.h> //声明函数 void Initboard(char board[ROW][COL], int row, int col); void playboard(char board[ROW][COL], int row, int col); void playermove(char board[ROW][COL], int row, int col); void computermove(char board[ROW][COL], int row, int col); char IsWin(char board[ROW][COL],int row,int col);
四 结果演示
当然还有其它结果,你们快去试试吧!
至于为啥这个叫做小朋友的三子棋,我相信你们一定也有了答案了吧
因为这个电脑真的有点“蠢”,可以拿去骗骗小孩子
哈哈 今天的分享就到这里了,我们下次再见
拜拜~~