小游戏"/>
C语言实现小游戏
目录
一:游戏说明
二:基本流程说明
三:步骤实现
1.设置菜单函数
2.设计棋盘
3.棋盘初始化
4.打印棋盘的函数
5.玩家下棋
6.电脑下棋
7.判断胜负
8.判断棋盘是否满了
笔者最后之言(附上最终版的代码):
一:游戏说明
工程中为了多人协作,经常是每人负责一个模块!
所以我们可以养成良好习惯!在test.c文件中进行游戏的测试,在game.c文件中实现游戏函数,在game.h中声明游戏函数。
二:基本流程说明
1.首先我们要做一个菜单,让用户选择玩游戏/不玩游戏。
2.若用户选择玩游戏,我们首先要创建一个棋盘 ->可认为是二维数组
3.为了美观,我们可以先简易构思三子棋棋盘的样子。创建好之后 初始化棋盘。
4.将棋盘打印出来供玩家看着下棋
5.玩家进行操作 ->电脑操作->玩家操作.....,每执行一步都要将棋盘打印出来进行观看
6.判断胜负 以及是否和棋(棋盘满了,仍没有人胜出)
7.退出游戏 /继续游戏
三:步骤实现
1.设置菜单函数
因为至少也要把菜单函数打印出来进行选择,所以用do-while比较合适。
基本框架:
void menu() {printf("***************************************\n");printf("*********** 1. play *********\n");printf("*********** 2. exit *********\n");printf("***************************************\n");} int main() {int input = 0;do{menu();printf("请选择是否进行游戏:->\n");scanf("%d", &input);switch (input){case 1 ://进行三子棋游戏//game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);return 0; }
效果:
2.设计棋盘
因为要实现的是三子棋,所以我们创建一个3行3列的二维数组.为了方便后续的更改,我们可以将行和列进行宏定义。(game.h文件)
3.棋盘初始化
首先,数组中没有元素,我们可以将数组全部初始化为空格,当然打印出来你也看不见,因为空格是空白字符!
实现函数:void InitBoard(char board[ROW][COL], int row, int col)
//初始化数组为空格(在game.c文件中实现) void InitBoard(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++){board[i][j] = ' ';}} }
4.打印棋盘的函数
为了打印出来的棋盘更美观,我们可以进行稍微的设计!
把正方形圈起来的当成一次打印的内容
把棋盘的每一行拆分为 : 空格+字符+空格 | 空格+字符+空格 | 空格+字符+空格
每一行的下一行用分隔符进行分割,但最后一行不打印分隔行,以及每一行的最后一列不打印分隔列。
看代码实现:
//打印棋盘 void DisplayBoard(char board[ROW][COL], int row, int col) {int i = 0;for (i = 0; i < row; i++){//1.打印一行的数据int j = 0;for (j = 0; j < col; j++){printf(" %c ", board[i][j]);//每行打印两个列分隔符if (j < col - 1)printf("|");}//打印完一行之后进行换行printf("\n");//2.打印分割行 //只打印两次分割行 最后一行不打印分割行if (i < row - 1){for (j = 0; j < col; j++) //每行打印3次 --- {printf("---");if (j < col - 1) //每行只打印2次 | printf("|");}printf("\n");}} }
效果:
5.玩家下棋
玩家下棋本质上是操作数组的内容,玩家下棋和电脑下去是循环的过程,所以用while(1)控制,且下棋后要把棋盘打印出来观看。
下棋的时候注意事项:1.判断坐标的合法性 2.判断该位置是否为空(有无棋)
站在玩家的角度,认为第一行第一列的坐标为1 1 ,实际放在数组的0行0列位置 !所以判断坐标合法性时要注意!
代码实现:
void PlayerMove(char board[ROW][COL], int row, int col) {//需要坐标 ,所以定义x,y两个变量int x = 0;int 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; // 当输入合法时及时跳出循环,不然会造成死循环}elseprintf("坐标被占用\n");}elseprintf("坐标非法,请重新输入\n");} }
效果:
6.电脑下棋
电脑下棋要产生随机坐标,但也要保证坐标不会越界。电脑下棋默认下标是从0开始的。
产生随机数 ->使用rand()函数,要配套srand()函数使用,设置随机数生成起点(写在main函数内部)
-> srand((unsigned int)time(NULL)); 要引用头文件 #include<stdlib.h> 和#include<time.h>、
rand() %行或列 范围:0-行数/列数-1 刚好符合数组下标
注意事项:1.产生的坐标不越界 2.要下的位置是否被占用 电脑下了棋子也要把棋盘打印出来看 3.电脑生成的坐标若被下过,要重新生成,所以用循环 ->while(1)
代码实现:
//电脑下棋 void ComputerMove(char board[ROW][COL], int row, int col) {int x = 0l;int y = 0;printf("电脑走->\n");while (1){x = rand() % row ;y = rand() % col ;if (board[x][y] == ' '){board[x][y] = '#';break;}} }
效果:
7.判断胜负
共有4种情况产生:玩家赢,电脑赢,平局,未结束
因为我们定义玩家是拿 * 作为棋子 电脑i拿 # 作为棋子,所以:
要返回4种不同的状态:
玩家获胜—> ‘O’
电脑获胜 —> ‘X’
平局 —> ‘Q’
继续 —> ‘C’注意:
每当用户/电脑下完棋时都要进行一次判断,当棋盘未满时要继续游戏 , 因为返回的是字符,所以判断胜负的函数返回类型定义为char类型,而且判断胜负时还要保证某一个字符不是空格,否则出现bug! 接受判断胜负函数返回值的变量也要定义为char类型。
代码实现:
//判断胜负 char IsWin(char board[ROW][COL], int row, int col) {//1. 判断输赢//三行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];}}//三列int j = 0;for (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}//对角线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];}//2. 判断平局if (1 == IsFull(board, ROW, COL)){return 'Q';}//3. 游戏继续return 'C';}
8.判断棋盘是否满了
方法:遍历二维数组,看还有没有空格存在
代码实现:
//判断棋盘是否满了 //没满返回0 //满了返回1int 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; }
最终效果:
笔者最后之言(附上最终版的代码):
有需要的自取,如果感觉此文对你有收获,欢迎各位收藏,点赞,关注!
test.c 代码
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h"void menu() {printf("***************************************\n");printf("*********** 1. play *********\n");printf("*********** 2. exit *********\n");printf("***************************************\n");} void game() {//进行游戏的函数char board[ROW][COL];//初始化数组为空格InitBoard(board, ROW, COL);//打印数组DisplayBoard(board, ROW, COL);char ret = 0;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;srand((unsigned int)time(NULL));do{menu();printf("请选择是否进行游戏:->\n");scanf("%d", &input);switch (input){case 1://进行三子棋游戏game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);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 = 0;for (i = 0; i < row; i++){int j = 0;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 (j = 0; j < col; j++)//{// printf(" %d ", j+1);//}//printf("\n");for (i = 0; i < row; i++){//1.打印一行的数据int j = 0;for (j = 0; j < col; j++){printf(" %c ", board[i][j]);//每行打印两个列分隔符if (j < col - 1)printf("|");}//打印完一行之后进行换行printf("\n");//2.打印分割行 //只打印两次分割行 最后一行不打印分割行if (i < row - 1){for (j = 0; j < col; j++) //每行打印3次 --- {printf("---");if (j < col - 1) //每行只打印2次 | printf("|");}printf("\n");}} }//玩家下棋 void PlayerMove(char board[ROW][COL], int row, int col) {//需要坐标 ,所以定义x,y两个变量int x = 0;int 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; // 当输入合法时及时跳出循环,不然会造成死循环}elseprintf("坐标被占用\n");}elseprintf("坐标非法,请重新输入\n");} }//电脑下棋 void ComputerMove(char board[ROW][COL], int row, int col) {int x = 0l;int y = 0;printf("电脑走->\n");while (1){x = rand() % row ;y = rand() % col ;if (board[x][y] == ' '){board[x][y] = '#';break;}} }//判断棋盘是否满了 //没满返回0 //满了返回1int 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; } //判断胜负 char IsWin(char board[ROW][COL], int row, int col) {//1. 判断输赢//三行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];}}//三列int j = 0;for (j = 0; j < col; j++){if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}//对角线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];}//2. 判断平局if (1 == IsFull(board, ROW, COL)){return 'Q';}//3. 游戏继续return 'C';}
game.h代码
#define _CRT_SECURE_NO_WARNINGS 1 #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 PlayerMove(char board[ROW][COL], int row, int col);//电脑下棋 void ComputerMove(char board[ROW][COL], int row, int col);//判断游戏输赢 //要返回4种不同的状态 //玩家赢 - '*' //电脑赢 - '#' //平局 - ‘Q’ //继续 - 'C'char IsWin(char board[ROW][COL], int row, int col); int IsFull(char board[ROW][COL], int row, int col);
更多推荐
C语言实现小游戏
发布评论