苏州市城乡建设局网站,微官网和微网站,常熟市网页设计公司,自己做购物网站魔王的介绍#xff1a;#x1f636;#x1f32b;️一名双非本科大一小白。魔王的目标#xff1a;#x1f92f;努力赶上周围卷王的脚步。魔王的主页#xff1a;#x1f525;#x1f525;#x1f525;大魔王.#x1f525;#x1f525;#x1f525; ❤️#x1… 魔王的介绍️一名双非本科大一小白。魔王的目标努力赶上周围卷王的脚步。魔王的主页大魔王. ❤️大魔王与你分享罗曼罗兰说过:这个世上只有一种真正的英雄主义那就是认清生活的真相并且任然热爱他。 文章目录一、前言二、文件介绍三、代码实现1.完成test.c文件模板2.创建棋盘并进行初始化3.打印棋盘4.玩家下棋5.电脑下棋6.判断输赢7.判断是否满了8.电脑智能下棋四、对于初学者较陌生的知识1.休眠函数2.清屏函数3.随机数函数五、总代码game.h2.game.c3.test.c4.效果展示图六、总结一、前言 相信大家都玩过三子棋或者五子棋游戏但你会通过编程完美实现吗本篇将带领你真正学会三子棋并与你自己编译出来的程序分出胜负。 二、文件介绍
test.c测试文件 game.c源文件,进行函数的定义 game.h头文件只进行声明 我们用测试文件调用game.h声明、game.c文件中实现的函数这就是三个文件的关系。 为了使三者联系起来我们需要让两个源文件.c文件都包含头文件这样他们中的函数就可以一起使用了。 三、代码实现
1.完成test.c文件模板 模板介绍我们在玩游戏时首先肯定需要看到菜单然后菜单中有选线供玩家选择等玩家选择完成后就要根据玩家的选择展开不同的路线来执行程序。为了使游戏可以重复完我们还需要让程序能够玩完一次继续玩直到玩家不想玩选择退出程序程序再结束。 #include game.hvoid menu()
{printf(********************\n);printf(****** 1.play ******\n);printf(****** 0.exit ******\n);printf(********************\n);
}
void test()
{int input 0;do{menu();printf(请选择: );scanf(%d, input);switch (input){case 1:printf(开始游戏\n);game();break;default:printf(输入错误请重新输入\n);break;case 0:printf(退出游戏\n);}} while (input);
}
int main()
{test();return 0;
}2.创建棋盘并进行初始化 因为我们是要把符号输入到二维数组中结合我们构造出来的图案形成三子棋的模样所以我们需要创建一个二维数组并进行初始化因为棋盘最开始为空白的所以二维数组初始化的内容为空格。 我们先在test.c文件中创建一个棋盘然后再调用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] ;}}
}3.打印棋盘 我们创建并初始化棋盘后需要打印出三子棋图供玩家进行观察和下棋如果玩家想玩不只3*3格的三子棋或者想把三子棋改为五子棋也就是说当规模较大时为了方便玩家我们给每行每列开头都给定标号便利玩家。 //打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col)
{int k 0;printf( );printf( );for (k 0; k col; k){printf( );printf(%d, k 1);printf( );printf( );}printf(\n);int i 0;for (i 0; i row; i)//打印row行{int j 0;printf(%-2d, i 1);//打印每行开头的行数for (j 0; j col; j)//第一种行中的那一小段空格、数组、空格{printf( );printf(%c, board[i][j]);printf( );if (j col - 1)printf(|);//打印一个|}printf(\n);if (i row - 1)//第二种行中的那一小段-、-、-{printf( );printf( );//对应补齐每行开头的行数不然棋盘会错一位for (j 0; j col; j){printf(-);printf(-);printf(-);if (j col - 1)printf(|);//打印一个|}printf(\n);}}
}4.玩家下棋 游戏是由程序员编译的但是玩家可能是个小白玩家并不知道数组下标是从0开始的所以我们需要让玩家输入的两个值都减去1才是玩家真实想填入的地方。但是我们在填入时首先需要判断输入的坐标是否合法也就是说是否为坐标范围之外的值如果是需要重新输入判断完这个我们还需要判断这个坐标是否已经被使用只有这两个条件都满足我们才可以将棋子落入玩家想下的地方。 //玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int i 0;int j 0;while (1){printf(玩家下棋,请输入坐标: );scanf(%d %d, i, j);if ((i 0 i row) (j 0 j col)){if (board[i - 1][j - 1] ){board[i - 1][j - 1] *;break;}elseprintf(输入坐标已经使用请重新输入\n);}elseprintf(输入坐标不在范围内请重新输入\n);}
}5.电脑下棋 电脑下棋需要用到随机数rand()最后会统一讲对初学者比较陌生的库函数。和玩家下棋很相似不过不用减一了因为这是电脑操作的。但是还需要判断是否已被占用若已被占用就重新给定一组值直到电脑成功下一个棋。 //电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{while (1){int i rand() % row;int j rand() % col;if (board[i][j] ){board[i][j] #;break;}}
}6.判断输赢 三子棋的胜利分为四种形式一种是横向三个一种是纵向三个一种是右下倾斜\一种是左下倾斜/这四种方式我们都会采用遍历法实现。 //判断输赢
char JudgeGame(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 - 2; j){if (board[i][j] board[i][j 1] board[i][j] board[i][j 2] board[i][j] ! )return board[i][j];}}//竖for (j 0; j col; j){for (i 0; i row - 2; i){if (board[i][j] board[i1][j] board[i][j] board[i2][j] board[i][j] ! )return board[i][j];}}//右下方向(\)for (i 0; i row - 2; i){for (j 0; j col - 2; j){if (board[i][j] board[i1][j 1] board[i][j] board[i2][j 2] board[i][j] ! ){return board[i][j];}}}//左下方向(/)for (i 0; i row; i){for (j col - 1; j 1; j--){if (board[i][j] board[i1][j - 1] board[i][j] board[i2][j - 2] board[i][j] ! )return board[i][j];}}return 0;
}7.判断是否满了 每次判断完是否胜利后如果没有胜利我们不能直接让另一个下棋我们还要判断是否已经满了如果满了还没分出胜负因为是先判断输赢再判断是否满的所以这一点不用用管就是这样那就是平局。 //判断是否棋盘已经下满
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;
}8.电脑智能下棋 我们如果不给电脑赋一点智商他真的好笨让他赢都赢不了难受啊但又没办法给他说话那么就让我们的思想赋给电脑这样就是两个你在对比输赢了哈哈哈哈。 说实话让电脑智能一点其实自己想的时候没有思路于是看了安 度 因点击安度因可以跳转到他的文章大佬的智能三子棋但是真的就瞄一眼思路瞬间就出来了我们只要想到从获胜那里提取思路真的一下就出来了,无非就是那四种情况下有两个棋子所谓的两个棋子又分为三种情况比如说###获胜那么情况就有三个##空、#空#、空##都是这三种情况代码如下 //电脑智能下棋
int intelligent_move(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 - 2; j){if (board[i][j] board[i][j 1] board[i][j] ! board[i][j 2] ){board[i][j2] #;return 1;}if (board[i][j] board[i][j 2] board[i][j] ! board[i][j 1] ){board[i][j1] #;return 1;}if (board[i][j 1] board[i][j 2] board[i][j 1] ! board[i][j] ){board[i][j] #;return 1;}}}//纵行拦截/下棋for (j 0; j col; j){for (i 0; i row - 2; i){if (board[i][j] board[i1][j] board[i][j] ! board[i2][j] ){board[i2][j] #;return 1;}if (board[i][j] board[i2][j] board[i][j] ! board[i1][j] ){board[i1][j] #;return 1;}if (board[i1][j] board[i2][j] board[i1][j] ! board[i][j] ){board[i][j] #;return 1;}}}//右下方向拦截/下棋for (i 0; i row - 2; i){for (j 0; j col - 2; j){if (board[i][j] board[i 1][j 1] board[i][j] ! board[i 2][j 2] ){board[i 2][j 2] #;return 1;}if (board[i][j] board[i 2][j 2] board[i][j] ! board[i 1][j 1] ){board[i 1][j 1] #;return 1;}if (board[i2][j2] board[i 1][j 1] board[i2][j2] ! board[i][j] ){board[i][j] #;return 1;}}}//左下方向拦截/下棋for (i 0; i row - 2; i){for (j col-1; j 1; j--){if (board[i][j] board[i 1][j - 1] board[i][j] ! board[i 2][j - 2] ){board[i 2][j - 2] #;return 1;}if (board[i][j] board[i 2][j - 2] board[i][j] ! board[i 1][j - 1] ){board[i 1][j - 1] #;return 1;}if (board[i2][j-2] board[i 1][j - 1] board[i2][j-2] ! board[i][j] ){board[i][j] #;return 1;}}}return 0;
}四、对于初学者较陌生的知识
1.休眠函数 睡眠函数我们在玩时是不是觉得电脑反应好快我们明明已经给他赋上智慧了他却还那么快这不就比我们都聪明了为了让他笨一点我们让他下的时候反应一秒这就引入了睡眠函数C语言库里是小写sleep但是VS必须开头大写也就是Sleep我们按小写说那就是sleepunsigned int里面的无符号整型单位是ms毫秒所以我们写1000实际就是每次走到这个程序停顿1秒。对应的头文件是windows.h 2.清屏函数 清屏函数每次棋盘被修改我们都要打印一次但是这次打印出来上次的不就没用了吗让他们一直留着好麻烦所以我们引入一个清屏函数system“cls”;对应的头文件是windows.h 3.随机数函数
随机数函数rand rand函数原型 一、#include stdlib.h; 二、int rand(void); rand函数调用: 一、rand()函数每次调用前会查询是否调用过srandseed是否给seed设定了一个值如果有那么它会自动调用srandseed一次来初始化它的起始值。 二、若之前没有调用srand(seed)那么系统会自动给seed赋初始值即srand(1)自动调用它一次。
srand函数 一、srand函数是随机数发生器的初始化函数原型 void srand(unsigned int seed); 二、这个函数需要提供一个种子如srand(1),用1来初始化种子。 三、rand函数产生随机数时如果srand(seed)播下种子之后一旦种子相同产生的随机数将是相同的。但是我们很多时候都是要让rand产生一个随机数那么这就意味着我们需要让种子值时刻发生变化所以就可以这样赋值srand(time(NULL)),那么我们就又引入了时间函数详细如下
time函数 我们常常使用系统时间来初始化使用time函数来获取系统时间得到的值是一个时间戳即从1970年1月1日到现在时间的秒数然后将得到的time_t类型数据转化为(unsigned int)的数然后再传给srand函数用法如下 一、srand(unsigned int)timeNULL对应的头文件time.h,我们在使用rand和srand时主要使用的就是这一种初始化方法。 二、如果感觉时间间隔太小可以让这个整体乘上一个数srandunsignedtimeNULL*10 三、time的参数传NULL表示不需要经过参数获得的time_t数据。 四、time函数原型如下: time_t time(time_t * tloc); time_t类型被定义为一个长整型 五、详细的rand讲解可以点击这里进入该文章
五、总代码
game.h
#pragma once#include stdio.h
#include windows.h
#include time.h
#include stdlib.h#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void PrintBoard(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 JudgeGame(char board[ROW][COL], int row, int col);//判断是否棋盘已经下满
int is_full(char board[ROW][COL], int row, int col);//电脑智能下棋
int intelligent_move(char board[ROW][COL], int row, int col);2.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 PrintBoard(char board[ROW][COL], int row, int col)
{int k 0;printf( );printf( );for (k 0; k col; k){printf( );printf(%d, k 1);printf( );printf( );}printf(\n);int i 0;for (i 0; i row; i)//打印row行{int j 0;printf(%-2d, i 1);//打印每行开头的行数for (j 0; j col; j)//第一种行中的那一小段空格、数组、空格{printf( );printf(%c, board[i][j]);printf( );if (j col - 1)printf(|);//打印一个|}printf(\n);if (i row - 1)//第二种行中的那一小段-、-、-{printf( );printf( );//对应补齐每行开头的行数不然棋盘会错一位for (j 0; j col; j){printf(-);printf(-);printf(-);if (j col - 1)printf(|);//打印一个|}printf(\n);}}
}//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int i 0;int j 0;while (1){printf(玩家下棋,请输入坐标: );scanf(%d %d, i, j);if ((i 0 i row) (j 0 j col)){if (board[i - 1][j - 1] ){board[i - 1][j - 1] *;break;}elseprintf(输入坐标已经使用请重新输入\n);}elseprintf(输入坐标不在范围内请重新输入\n);}
}//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{while (1){int i rand() % row;int j rand() % col;if (board[i][j] ){board[i][j] #;break;}}
}//判断输赢
char JudgeGame(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 - 2; j){if (board[i][j] board[i][j 1] board[i][j] board[i][j 2] board[i][j] ! )return board[i][j];}}//竖for (j 0; j col; j){for (i 0; i row - 2; i){if (board[i][j] board[i1][j] board[i][j] board[i2][j] board[i][j] ! )return board[i][j];}}//右下方向(\)for (i 0; i row - 2; i){for (j 0; j col - 2; j){if (board[i][j] board[i1][j 1] board[i][j] board[i2][j 2] board[i][j] ! ){return board[i][j];}}}//左下方向(/)for (i 0; i row; i){for (j col - 1; j 1; j--){if (board[i][j] board[i1][j - 1] board[i][j] board[i2][j - 2] board[i][j] ! )return board[i][j];}}return 0;
}//判断是否棋盘已经下满
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;
}//电脑智能下棋
int intelligent_move(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 - 2; j){if (board[i][j] board[i][j 1] board[i][j] ! board[i][j 2] ){board[i][j2] #;return 1;}if (board[i][j] board[i][j 2] board[i][j] ! board[i][j 1] ){board[i][j1] #;return 1;}if (board[i][j 1] board[i][j 2] board[i][j 1] ! board[i][j] ){board[i][j] #;return 1;}}}//纵行拦截/下棋for (j 0; j col; j){for (i 0; i row - 2; i){if (board[i][j] board[i1][j] board[i][j] ! board[i2][j] ){board[i2][j] #;return 1;}if (board[i][j] board[i2][j] board[i][j] ! board[i1][j] ){board[i1][j] #;return 1;}if (board[i1][j] board[i2][j] board[i1][j] ! board[i][j] ){board[i][j] #;return 1;}}}//右下方向拦截\下棋for (i 0; i row - 2; i){for (j 0; j col - 2; j){if (board[i][j] board[i 1][j 1] board[i][j] ! board[i 2][j 2] ){board[i 2][j 2] #;return 1;}if (board[i][j] board[i 2][j 2] board[i][j] ! board[i 1][j 1] ){board[i 1][j 1] #;return 1;}if (board[i2][j2] board[i 1][j 1] board[i2][j2] ! board[i][j] ){board[i][j] #;return 1;}}}//左下方向拦截/下棋for (i 0; i row - 2; i){for (j col-1; j 1; j--){if (board[i][j] board[i 1][j - 1] board[i][j] ! board[i 2][j - 2] ){board[i 2][j - 2] #;return 1;}if (board[i][j] board[i 2][j - 2] board[i][j] ! board[i 1][j - 1] ){board[i 1][j - 1] #;return 1;}if (board[i2][j-2] board[i 1][j - 1] board[i2][j-2] ! board[i][j] ){board[i][j] #;return 1;}}}return 0;
}3.test.c
#define _CRT_SECURE_NO_WARNINGS 1#include game.hvoid 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);//打印棋盘char ret 0;while (1){PlayerMove(board, ROW, COL);//玩家下棋,玩家为*system(cls);//清屏PrintBoard(board, ROW, COL);//打印棋盘ret JudgeGame(board, ROW, COL);//判断输赢if (ret ! 0)break;if (ret is_full(board, ROW, COL) 1)break;int flag intelligent_move(board, ROW, COL);//如果这一步电脑智能下棋确实下了那么flag为1否则为0if(flag0)//flag为0说明没有智能下棋那么就进行随机下棋ComputerMove(board, ROW, COL);//电脑下棋电脑为#Sleep(1000);//休眠一秒(让电脑思考一会哈哈哈哈哈)system(cls);//清屏PrintBoard(board, ROW, COL);//打印棋盘ret JudgeGame(board, ROW, COL);//判断输赢if (ret ! 0)break;if (ret is_full(board, ROW, COL) 1)break;}if (ret *)printf(恭喜你赢啦\n);else if (ret #)printf(好遗憾你连自己设置的电脑都玩不赢\n);elseprintf(棋盘下满了未分出胜负电脑表示不服\n);
}
void test()
{int input 0;do{menu();printf(请选择: );scanf(%d, input);switch (input){case 1:printf(开始游戏\n);game();break;default:printf(输入错误请重新输入\n);break;case 0:printf(退出游戏\n);}} while (input);
}int main()
{srand((unsigned int)time(NULL));test();return 0;
}4.效果展示图 六、总结 原创不易还希望各位佬佬支持一下\textcolor{colourful}{原创不易还希望各位佬佬支持一下}原创不易还希望各位佬佬支持一下 点赞你的认可是我创作的动力\textcolor{red}{点赞你的认可是我创作的动力}点赞你的认可是我创作的动力 收藏你的青睐是我努力的方向\textcolor{orange}{收藏你的青睐是我努力的方向}收藏你的青睐是我努力的方向 评论你的意见是我进步的财富\textcolor{aqua}{评论你的意见是我进步的财富}评论你的意见是我进步的财富 ✨请点击下面进入主页关注大魔王 如果感觉对你有用的话就点我进入主页关注我吧