900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 三子棋小游戏————如何用C语言实现(含完整代码)

三子棋小游戏————如何用C语言实现(含完整代码)

时间:2023-06-29 12:50:00

相关推荐

三子棋小游戏————如何用C语言实现(含完整代码)

过程

整体思路(后面有思维导图,理清思维逻辑)实现过程完整代码测试源文件里的:用来放函数定义的源文件:头文件

QQ录屏0925175438

整体思路(后面有思维导图,理清思维逻辑)

如何实现用C语言编写以上代码呢?其实并不难写,只是看起来比较繁琐罢了,但只要静下心来,把逻辑理顺,就能写出来,这对于新手小白来说是一个挑战,同时也是一个锻炼,那么如何能具体实现呢?

首先,我们为了能使自己的代码条理清晰,也方便自己以及他人日后查看,我们不能只写在一个源文件里,这样显得很繁琐。所以我们必须再创建一个源文件,用来存放被调用函数定义,同时,为了更加方便,我们再创建一个头文件,用来存放函数声明以及使用库函数时头文件的包含。然后在用来测试的源文件里着手写代码,首先要有一个菜单吧,供玩家选择,开始游戏,退出游戏等,然后我们要知道,我们最终的目的是在一个棋盘上进行游戏,既然是在棋盘上进行,就得有棋盘吧,所以我们要把一个棋盘用C语言写出来,写出来之后,我们还必须要有玩家和电脑来落子,否则怎么玩,既然落子,就会出现几种可能:1、玩家获胜。2、电脑获胜。3、平局(棋子满盘)。4、继续游戏(棋子未满盘)。

同时,我们可以把一个三子棋的棋盘看成是一个33的九宫格演变过来的,再仔细看,其实本质上是在一个二维数组里输入与#演变来的。知道这些,我们心里就有谱了,可以着手去写,完善细节。

实现过程

整理好之后开始入手:

#include"game.h"//我们把函数声明,库函数头文件的包含都放在头文件game.h里,然后在测//试源文件以及函数定义源文件里都包含一下,就可以实现跨文件使用void menu(){printf("************************************\n");printf("************************************\n");printf("*********1、play**********\n");printf("*********0、exit**********\n");printf("************************************\n");printf("************************************\n");}int main(){int input = 0;//这是为了让电脑生成随机数使用的srand((unsigned int)time(NULL));do{//菜单menu();printf("请选择:>");scanf("%d", &input);//清理屏幕system("cls");switch (input){case 1:game();break;case 0:break;default:printf("输入错误,请重新输入“:>\n");break;}} while (input);return 0;}

这里实现了我们菜单栏的打印,以及整体的一个轮廓,到这里,我们已经把退出游戏,以及错误返回给写好了,下面就着重入手游戏环节,game()的实现。

void game(){char ret = 0;//二维数组的创建char board[ROW][COL] = {0};//初始化棋盘init_board(board, ROW, COL);//打印棋盘display_board(board, ROW, COL);//玩游戏环节while (1){//玩家下棋player_move(board, ROW, COL);//判断局面ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//打印棋盘display_board(board, ROW, COL);//电脑下棋computer_move(board, ROW, COL);//判断局面ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//打印棋盘display_board(board, ROW, COL);}//我们自己规定,假如函数is_win(board, ROW, COL)返回值为*,表示玩家获胜//假如函数is_win(board, ROW, COL)返回值为#,表示电脑获胜//假如函数is_win(board, ROW, COL)返回值为C,表示继续游戏//假如函数is_win(board, ROW, COL)返回值为Q,表示平局if (ret == '*'){printf("-----------------------------------------------\n");printf("------------ !!! VICTORY !!! --------------\n");printf("-----------------------------------------------\n");printf("----------- !!! 玩家获胜 !!! -----------\n");printf("-----------------------------------------------\n");}else if (ret == '#'){printf("-----------------------------------------------\n");printf("------------- !!! DEFEAT !!! --------------\n");printf("-----------------------------------------------\n");printf("----------- !!! 电脑获胜 !!! ----------\n");printf("-----------------------------------------------\n");}else if (ret == 'Q'){printf("--------------------------------------------\n");printf("--------------- !!!DRAW!!! ---------------\n");printf("--------------------------------------------\n");printf("----------- !!! 平局 !!! -----------\n");printf("--------------------------------------------\n");}}

注意,这里我用的是ROW与COL来表示数组的行与列,这是为了以后万一我们要调整棋盘行列数,只需要在头文件修改数据就可以了,避免了把程序写死(只能是33棋盘)

大家注意看我头文件的内容:

很清晰明了的就可以看到里面的内容,用#define定义常量,这里就是三行三列,假如想要55的棋盘,只需要在这里修改ROW与COL的值就可以,很灵活。就像这样:避免了写死程序。

接下来就是这些函数的具体内容了,跟着思维导图,先看一下游戏前的准备:

void init_board(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 display_board(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)//第col-1列不打印|{printf("|");}}//换行printf("\n");//最后一行不打印---|---|---if (i < row - 1){for (j = 0; j < col; j++){printf("---");//最后的|不打印if (j < col - 1){printf("|");}}printf("\n");}}}

这两个是使我们的棋盘最终定型所用的函数,由于我们要在数组里输入数据落子,同时为了保证美观性,所以我们必须保证二维数组里的所有数据都是空格,然后打印棋盘的时候不打印|与—|—|—我们进行了如上所改。最终才打印这种我们想要的棋盘:

有了棋盘接下来我们进行落子:

void player_move(char board[ROW][COL], int row, int col){int x = 0;int y = 0;printf("玩家请落子:>\n");while (1){printf("请输入落子坐标:");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] = '*';//清理屏幕,每输出完后都清理历史痕迹system("cls");break;}else{printf("该位置已落子,请重新输入!\n");}}else{printf("已超出棋盘范围,请重新落子!\n");}}}//电脑下棋void computer_move(char board[ROW][COL], int row, int col){printf("电脑落子\n");while (1){int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';system("cls");//清理屏幕break;}}}

为了保证我们与电脑之间的下棋始终都在一个不变的棋盘上,我们使用了system()函数,每次落子都清理历史屏幕,这就使得我们像视频里那样,屏幕里始终只有一个棋盘。

落完子最后一步便是胜负的判定了:

int is_full(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;}}}return 1;}//胜负可能,列举char is_win(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][2] != ' '){return board[i][2];}}//列获胜的可能for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' '){return board[2][i];}}//斜着获胜的可能if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' '){return board[2][2];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] != ' '){return board[2][0];}//平局可能if (is_full(board,row,col) == 1){return 'Q';}//继续游戏return 'C';}

上面,我们把所有取胜的结果全罗列了出来,那一行一列要么是*要么是#,所以我们直接返回它落的棋子,假如返回#,说明那一行或一列或斜着都是#。同时在这里我们又调用了一个函数,is_full()用来判断假如棋盘落子已满,将是平局。最后假如都不满足,就说明胜负未分,棋盘未满,游戏继续。

我们跟着逻辑走,把所有可能性想全,就可以保证我们写出来的代码又条理清楚,又可以完美运行。

到这里的时候,我们再进行调试,就发现可以很完美的进行游戏了。我们就可以奖励自己一顿大餐!再接再厉!!!

完整代码

测试源文件里的:

#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"void menu(){printf("************************************\n");printf("************************************\n");printf("*********1、play**********\n");printf("*********0、exit**********\n");printf("************************************\n");printf("************************************\n");}void game(){char ret = 0;//二维数组的创建char board[ROW][COL] = {0};//初始化棋盘init_board(board, ROW, COL);//打印棋盘display_board(board, ROW, COL);//玩游戏环节while (1){//玩家下棋player_move(board, ROW, COL);//判断局面ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//打印棋盘display_board(board, ROW, COL);//电脑下棋computer_move(board, ROW, COL);//判断局面ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//打印棋盘display_board(board, ROW, COL);}//我们自己规定,假如函数is_win(board, ROW, COL)返回值为*,表示玩家获胜//假如函数is_win(board, ROW, COL)返回值为#,表示电脑获胜//假如函数is_win(board, ROW, COL)返回值为C,表示继续游戏//假如函数is_win(board, ROW, COL)返回值为Q,表示平局if (ret == '*'){printf("-----------------------------------------------\n");printf("------------ !!! VICTORY !!! --------------\n");printf("-----------------------------------------------\n");printf("----------- !!! 玩家获胜 !!! -----------\n");printf("-----------------------------------------------\n");}else if (ret == '#'){printf("-----------------------------------------------\n");printf("------------- !!! DEFEAT !!! --------------\n");printf("-----------------------------------------------\n");printf("----------- !!! 电脑获胜 !!! ----------\n");printf("-----------------------------------------------\n");}else if (ret == 'Q'){printf("--------------------------------------------\n");printf("--------------- !!!DRAW!!! ---------------\n");printf("--------------------------------------------\n");printf("----------- !!! 平局 !!! -----------\n");printf("--------------------------------------------\n");}}int main(){int input = 0;srand((unsigned int)time(NULL));do{//菜单menu();printf("请选择:>");scanf("%d", &input);//清理屏幕system("cls");switch (input){case 1:game();break;case 0:break;default:printf("输入错误,请重新输入“:>\n");break;}} while (input);return 0;}

用来放函数定义的源文件:

#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"//棋盘初始化void init_board(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 display_board(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)//第col-1列不打印|{printf("|");}}//换行printf("\n");//最后一行不打印---|---|---if (i < row - 1){for (j = 0; j < col; j++){printf("---");//最后的|不打印if (j < col - 1){printf("|");}}printf("\n");}}}//玩家下棋void player_move(char board[ROW][COL], int row, int col){int x = 0;int y = 0;printf("玩家请落子:>\n");while (1){printf("请输入落子坐标:");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] = '*';//清理屏幕,每输出完后都清理历史痕迹system("cls");break;}else{printf("该位置已落子,请重新输入!\n");}}else{printf("已超出棋盘范围,请重新落子!\n");}}}//电脑下棋void computer_move(char board[ROW][COL], int row, int col){printf("电脑落子\n");while (1){int x = rand() % row;int y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';system("cls");//清理屏幕break;}}}//满了返回1//没满返回0int is_full(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;}}}return 1;}//胜负可能,列举char is_win(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][2] != ' '){return board[i][2];}}//列获胜的可能for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' '){return board[2][i];}}//斜着获胜的可能if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' '){return board[2][2];}if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] != ' '){return board[2][0];}//平局可能if (is_full(board,row,col) == 1){return 'Q';}//继续游戏return 'C';}

头文件

#pragma once//printf函数所包含头文件#include<stdio.h>//rand函数所包含的头文件#include<stdlib.h>//时间戳,生成随机数使用#include<time.h>//清理屏幕,system()使用#include<Windows.h>#define ROW 3#define COL 3//棋盘初始化void init_board(char board[ROW][COL], int row, int col);//打印棋盘void display_board(char board[ROW][COL], int row, int col);//玩家下棋void player_move(char board[ROW][COL], int row, int col);//电脑下棋void computer_move(char board[ROW][COL], int row, int col);//判断局面char is_win(char board[ROW][COL], int row, int col);

望诸君加油!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。