摘要:因为每个格子在游戏开始的时候都是空着的状态,而在玩家与电脑进行游戏中是要输入符号的,所以我们还要定义一个型的二维数组,并初始化为。函数声明打印棋盘初始化数组玩家下棋二维数组进行函数传参时可以不用写行数电脑下棋判断是否胜利定义一个二维数组。
三子棋是大家小时候和同桌在纸上都玩过的简单小游戏,这个游戏我们在c语言中就可以实现。
在这篇文章我推荐大家使用vs2013,vs2019,vs2022等的编译器。部分学校使用的vc6.0以及Devc++。前者是1998年推出的c语言编译器,在现在的win10或者win11的系统中并不兼容,可能会出现一些问题,后者也在2015年停更,这两款祖传c语言编译器并不推荐使用,但是如果你们学校考试需要使用或者有明确要求,那当我没说。
首先,我们要先创建一个项目,常见三个文件分别是头文件game.h,源文件game.c,text.c。在这个game.h的头文件中我们放入函数的声明,定义常量以及头文件的引用,在text.c文件中我们写入游戏进行的程序,在game.c文件中我们写入实现游戏的函数。
因为我们玩一把游戏肯定不过瘾,我们要多玩几把游戏,我们在text.c文件中的main函数里写入一个do while循环语句,实现多次进行游戏。然后我们在循环语句中写入一个menu函数用来打印菜单。然后我们要在键盘上输入一个值去判断是否进行游戏,这里使用一个switch分支。当使用者输入正确的输入值时开始进行游戏。这里使用一个game函数实现游戏流程。
int main(){ int n = 0; srand((size_t)time(NULL)); do { menu();//打印菜单 printf("请输入 "); scanf("%d", &n); switch (n) { case 1:game(); break; case 0:printf("游戏结束/n"); break; default:printf("输入错误,请重新输入!/n"); break; } } while (n != 0); }
main函数部分
void menu(){ printf("******************************************/n"); printf("******** 1.play *********/n"); printf("******** 0.exit *********/n"); printf("******************************************/n");}
menu函数部分
2、game函数部分
在game函数中我们要实现游戏的主要流程,首先我们要打印一个3*3的棋盘,大概是这样的。
(在这里我们先把游戏的流程捋清楚,至于实现那些游戏步骤的函数我们放在后面game源文件部分去细说。)
因为每个格子在游戏开始的时候都是空着的状态,而在玩家与电脑进行游戏中是要输入符号的,所以我们还要定义一个char型的二维数组,并初始化为‘ ’。然后就是下棋阶段,我们要连续下很多次棋所以说这里使用一个while循环语句实现,这里可以写成一个死循环,当后面的函数判断到有玩家已经胜出或者平局的时候使用break跳出循环,因为不论是电脑还是玩家下棋后,我们要看到下到了哪里,所以说我们要在玩家和电脑下棋后面再打印一次棋盘。每个人在下完棋之后,我们要判断是否已经胜利所以我们使用条件语句来判断是否胜利,失败或是平局。在配合循环我们基本游戏流程已经写完了。
void game(){ char board[ROW][COL];//定义一个二维数组。 initboard(board, ROW, COL);//初始化数组。 printboard(board, ROW, COL);//打印棋盘。 while (1) { //玩家下棋 playerboard(board, ROW, COL); //打印棋盘 printboard(board, ROW, COL); //判断是否胜利 if (iswinboard(board, ROW, COL) == "*") { printf("玩家胜利/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "#") { printf("电脑获胜/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "Q") { printf("平局/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } //电脑下棋 computermove(board, ROW, COL); //打印棋盘 printboard(board, ROW, COL); //判断是否胜利 if (iswinboard(board, ROW, COL) == "*") { printf("玩家胜利/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "#") { printf("电脑获胜/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "Q") { printf("平局/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } }}
game函数部分
在头文件中我们需要对函数进行声明,定义常量。具体怎么实现可以看下面代码的注释。
在这里我们棋盘的行列在头文件使用ROW和COL来定义是为了方便我们以后在更改棋盘大小时,更加容易,只用在头文件中更改,在下面我们也能看到有很多地方使用这两个常量。
#pragma once//在game头文件里面去声明函数,定义常量。#include#include#include//定义常量#define ROW 3//这里通过更改ROW,COL的值来改变棋盘的大小#define COL 3//可以更改成为n*n的棋盘。//函数声明//打印棋盘void printboard(char board[ROW][COL], int row, int col);//初始化数组void initboard(char board[ROW][COL], int row, int col);//玩家下棋//二维数组进行函数传参时可以不用写行数void playerboard(char board[][COL], int row, int col); //电脑下棋void computermove(char board[ROW][COL], int row, int col);//判断是否胜利char iswinboard(char board[ROW][COL], int row, int col);
game.h部分
还记得我们在text.c中使用了哪些函数吗?
1、我们先要初始化二维数组
2、打印棋盘
3、玩家下棋
4、电脑下棋
5、判断胜利
接下来的game.c文件就是要写入实现这几个步骤的函数。
首先,初始化数组非常容易,两个for循环即可。
//初始化数组元素void initboard(char board[ROW][COL], int row, int col){ int i = 0, j = 0; //先对数组进行赋值,因为是n*n的数组所以要赋值n*n次 //这里使用两个for循环来实现。 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = " "; } }}
初始化数组元素函数
然后是打印棋盘函数。
在打印棋盘中我们要注意,需要打印一行数组,一行“---”符号。在每一行的最后“|”不打印。在最下面一行“---|---|---”不打印,在这里我们只需要去控制for循环条件即可实现,并不困难。
//打印棋盘void printboard(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++) { 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"); }}
然后是玩家下棋函数
也就是对数组进行赋值,因为玩家不一定学过c语言,也不一定知道c语言中数组的下标是从0开始的,所以我们要对输入的坐标-1之后在进行数组的相关操作。这里可以写上一个死循环,当玩家下出非法坐标时提醒玩家重新下,当玩家下出正确时再break跳出。
//玩家下棋函数void playerboard(char board[][COL], int row, int col){ int x = 0, y = 0; printf("请玩家下棋/n"); while (1)//这里可以写上一个死循环,当玩家下出非法坐标时提醒玩家重新下。 //当玩家下出正确时再break跳出。 { 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; } else { printf("坐标已被占用,请重新输入!"); } } else { printf("坐标非法,请重新输入!"); } }}
再然后是电脑下棋
相较于玩家下棋电脑下棋就比较容易了,只用使用rand()%3随机生成0-2之间的值,再判断是否已被占用即可。
//电脑下棋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; } }}
最后是判断是否胜利的函数
这个比较长,但是基本就是if条件语句进行判断,分别判断行、列、对角线以及平局。如果胜利成立则返回已连成线的其中一个格中的符号即可,这样就不用再麻烦这判断到底是电脑赢还是玩家赢了。返回到text.c中再进行相应的输出。
//判断是否胜利char iswinboard(char board[ROW][COL], int row, int col){ int i = 0, j = 0, count = 0; //判断行是否胜利 for (i=0;i|
这样我们的一个三子棋游戏就写好了。你就可以发给朋友,或是自己私藏了。(steam是上不了了,自己玩玩算了。)
最后全部代码放在这里
game.h
#pragma once//在game头文件里面去声明函数,定义常量。#include#include#include//定义常量#define ROW 3//这里通过更改ROW,COL的值来改变棋盘的大小#define COL 3//可以更改成为n*n的棋盘。//函数声明//打印棋盘void printboard(char board[ROW][COL], int row, int col);//初始化数组void initboard(char board[ROW][COL], int row, int col);//玩家下棋//二维数组进行函数传参时可以不用写行数void playerboard(char board[][COL], int row, int col); //电脑下棋void computermove(char board[ROW][COL], int row, int col);//判断是否胜利char iswinboard(char board[ROW][COL], int row, int col);
text.c
#define _CRT_SECURE_NO_WARNINGS 1#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);//初始化数组。 printboard(board, ROW, COL);//打印棋盘。 while (1) { //玩家下棋 playerboard(board, ROW, COL); //打印棋盘 printboard(board, ROW, COL); //判断是否胜利 if (iswinboard(board, ROW, COL) == "*") { printf("玩家胜利/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "#") { printf("电脑获胜/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "Q") { printf("平局/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } //电脑下棋 computermove(board, ROW, COL); //打印棋盘 printboard(board, ROW, COL); //判断是否胜利 if (iswinboard(board, ROW, COL) == "*") { printf("玩家胜利/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "#") { printf("电脑获胜/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } else if (iswinboard(board, ROW, COL) == "Q") { printf("平局/n"); printf("********** 是否进行下一局 **********/n"); printf("/n"); break; } }}int main(){ int n = 0; srand((size_t)time(NULL)); do { menu();//打印菜单 printf("请输入 "); scanf("%d", &n); switch (n) { case 1:game(); break; case 0:printf("游戏结束/n"); break; default:printf("输入错误,请重新输入!/n"); break; } } while (n != 0); }
game.c
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"//初始化数组元素void initboard(char board[ROW][COL], int row, int col){ int i = 0, j = 0; //先对数组进行赋值,因为是n*n的数组所以要赋值n*n次 //这里使用两个for循环来实现。 for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = " "; } }}//打印棋盘void printboard(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++) { 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 playerboard(char board[][COL], int row, int col){ int x = 0, y = 0; printf("请玩家下棋/n"); while (1)//这里可以写上一个死循环,当玩家下出非法坐标时提醒玩家重新下。 //当玩家下出正确时再break跳出。 { 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; } else { printf("坐标已被占用,请重新输入!"); } } 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; } }}//判断是否胜利char iswinboard(char board[ROW][COL], int row, int col){ int i = 0, j = 0, count = 0; //判断行是否胜利 for (i=0;i|
借用鹏哥的头像(狗头保命)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/125073.html
摘要:三子棋代码耗时三天,本人很菜,疯狂不细心写代码真的很累本代码使用编译所以使用了懂得都懂如果使用别的编译器请注意将起改为宏定义行数为为行,为列不会列的英文宏定义列数为也可以改为大棋盘,但要更改游戏机制初始 ...
摘要:三子棋目录一问题介绍三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的井字,多称为井字棋。 三子棋 目录 一、问题介绍 三子棋,在民间又叫井字棋。因为人们在游玩时常常不画棋盘的边框,正如汉字中的井字,多称为井字棋。 三子棋的游戏规则十分的简单: ...
摘要:简单介绍了三子棋原理后接下来为大家讲解分步目标及代码如何实现。电脑下棋我们实现了玩家和电脑的下棋后,我们需要编写一个函数来判断双方的输赢。我们使用函数来实现这一目标。 目录 1.三子棋原理 2.分块代码实现 3.总结 1.首先向大家介绍一下三子棋的原理 首先我们需要有一个棋盘,初始时棋...
摘要:今天博主将为大家带来语言入门级小游戏三子棋井字棋的详细介绍,希望这篇文章对大家能有帮助。在这里,我们使用函数来实现这一功能。 今天博主将为大家带来C语言入门级小游戏——三子棋(井字棋)的详细介绍,希望这篇文章对大家能有帮助 。 在编程的学习过程中,编写一些中这样...
阅读 2537·2023-04-26 00:57
阅读 909·2021-11-25 09:43
阅读 2219·2021-11-11 16:55
阅读 2203·2019-08-30 15:53
阅读 3592·2019-08-30 15:52
阅读 1457·2019-08-30 14:10
阅读 3378·2019-08-30 13:22
阅读 1208·2019-08-29 11:18