公司网站制作流程,佛山市城乡住房建设局网站首页,专业简历制作网站有哪些,镇江关键词优化1、实现三子棋 test.c //测试游戏的逻辑 game.c //游戏代码的实现 game.h //游戏代码的声明#xff08;函数声明#xff0c;符号定义#xff09; 1、
在主函数里实现#xff0c;首先有个界面#xff0c;让玩家选择是否玩游戏。上来就先打印菜单#xff0c;用do ... …1、实现三子棋 test.c //测试游戏的逻辑 game.c //游戏代码的实现 game.h //游戏代码的声明函数声明符号定义 1、
在主函数里实现首先有个界面让玩家选择是否玩游戏。上来就先打印菜单用do ... while结构。(这里menu(){ ... }menu前面要有void我忘记写了。) 2、
根据输入的选择做出相应的功能。用switch语句 3、
当选择了0时break退出这个switch到了while如果while这里放input此时intput0刚好退出循环结束游戏。如果选择了非0到了default这里break退出switch语句到了while这里刚好为真接着循环打印菜单。 4、
先测试一下
#includestdio.h
menu()
{printf(*********************************\n);printf(*********** 1、play ***********\n);printf(*********** 0、exit ***********\n);printf(*********************************\n);}
int main()
{int input 0;//接收玩家输入的选择do{menu();//菜单printf(请选择);scanf(%d, input);switch (input)//根据选择做出相应的响应{case 1:printf(三子棋\n);break;case 0:printf(退出游戏\n);break;default:printf(选择错误\n);break;}} while (input);return 0;
}
测试结果 整个当前的逻辑没有问题。开始写三子棋的逻辑。
5、三子棋逻辑
封装一个函数game()来写游戏逻辑 6、
当玩家下棋的之后电脑下棋的时候玩家下的位置得记录起来。他得存储这个数据否则我只是这次打印了下下次就没有了。当存起来的时候有9个坐标九宫格。3行3列的二维数组。
这个游戏必须有存放数据的数组。 有了这个数组这个时候就可以开始下棋
7、
但还应该打印这个棋盘而且有玩家下棋电脑下棋。这样的动作而且这个游戏在玩的过程中应该还有人会赢有人会输。应该还有判断输赢的功能。
得有这些功能打印棋盘玩家下棋电脑下棋判断输赢。
8、打印棋盘
打印棋盘这个打印的时候玩家下棋的地方打印*没下的打印空格。
所以这个游戏刚刚开始的时候这个棋盘其实就应该已经存在这个棋盘上每个位置应该对应的都是空格。这些位置应该打印的时空格而这些位置又对应的数组。也就是我刚刚传进去的数组。那数组最开始里面那应该每个元素放一个空格才对。那这样打印这个棋盘的时候这些位置上才打印空格这样才让我们这个棋盘看起来我们打印了东西但我们看起来又好像什么都没有。
那怎么做到这个数组中每个元素都是空格
那这个地方写个初始化棋盘的功能初始化棋盘本质上还是初始化这个数组。实际上就是想给我们这个数组board初始化空格进去。那这个必然要把board传进去。 数组传参传个数组名就可以了那这个时候数组几行几列最好也能够传过去。 这样就可以了当我们这样写的时候我们就要写这个函数InitBoard而这个函数其实就是棋盘初始化函数那跟这个游戏就有关系了这是初始化游戏棋盘的函数那我们就把这个InitBoard声明往game.h 这里放。 这个地方声明她的时候这个返回类型可以不要void但参数这个不能不要参数这个地方你既然给我传的是数组又传了行、列那我就要接收。
你给我传的是二维数组那我就拿二维数组来接收char board[3][3]行就是row列就是col 这三个参数就给定了。
9、
这是三个形参那我们就要拿过来实现geme.c 里面就是实现 这个地方接下来往下写肯定是没有问题的这里说个东西 这里有3那里也有3到处都有3 那我如果有一天这里不是三子棋而是五子棋呢棋盘要更大那岂不是所有涉及到这个3、3的都要改那改起来就不是一个地方了所以我建议这里不要固定的写成3、3要这样写在game.h中 ROW是行COL是列
注意这里 int row 和 int col 这里不能改这两个是形参名。不能用这个ROE和COL。
ROE和COL这是两个值row和col是形参的变量名。那相同的道理其他地方也是 但发现这个地方不行啊因为他俩来自头文件啊这是在头文件里面定义的啊你在这里怎么用这个时候很简单只要包含一下这个头文件就可以了。 这个时候就可以用了那相同的道理这两个地方也可以用了 想象一下如果我们用行和列的地方全部用ROW和COL代替那未来我要改成10行10列这两个改成10 所有地方是不是都能改这样改变起来就非常的方便用起来就非常的方便而不至于说这个地方我跟着把所有3都改一遍。
10、
注意这个game.c地方定义还没写呢那就是把这个数组的九个元素给他初始化全部空格。 这就是初始化代码。
11、
那此时我很想知道我放进去之后到底放的对不对就把棋盘打印出来看一下那这个地方一个DisplayBoard() 这个函数是必须要有的因为一会儿之后我是不是下完之后就要打印棋盘下完之后就要打印棋盘所以这个打印棋盘的功能是必须要有的。
那打印棋盘本质上打印的什么不还是这个数组吗。那这个地方再来写个打印数据。 这样一给那我们就是把board里面的行和列进行打印这就是它的功能。
11、初始化棋盘
那我们这个地方再声明。 再进行实现 注意这ROW和COL都来自头文件来自头文件的时候我们最终再包含以下这个头文件。 包含一下就可以了然后再来写这个功能
那怎么打印呢 那怎么实现呢 注意此时game.c这个文件要包含头文件 stdio.h 既然此时game.c 和 test.c 两个文件都要包含头文件 stdio.h那我直接把这个头文件 stdio.h 放到game.h 文件里然后只要game.c 和 test.c 这两个文件都包含game.h 这个头文件那game.c 和 test.c 这两个文件也就都包含了头文件 stdio.h 这样就方便些。
结果 发现不是我想要的最后一组多了一个分割行
这里打印了3行但实际上第三行不用打印。
第一个版本 那如果此时没有初始化棋盘会怎么样 就会这样子这个地方其实是不对的初始化后才是我们想要的那样。
但这个时候这个代码还是不好的如果把这里改成10行和10列。 会发现10行没有问题但列我只打印了3列。为什么只打印了3列呢 因为打印数据这里写死了所以这个地方其实不合适不方便用起来不方便。
第二个版本
让她的行和列可以动。 那他是打印这样的几组信息啊有几列是不是就打印几组这样的信息。 那打印分割信息就是这样 ---| 是一组最后一组没有 | 。 这个时候目前全代码
game.c 全代码
#includegame.hvoid InitBoard(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 DisplayBoard(char board[ROW][COL], int row, int col)
//{
// int i 0;
// for (i 0; i row; i)
// {
// //打印数据
// printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);
//
// //打印分割信息
// if (i row - 1)//-1就少打印了一组
// {
// printf(---|---|---\n);
// }
//
// }
//}void DisplayBoard(char board[ROW][COL], int row, int col)
{int i 0;for (i 0; i row; i){//打印数据//printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);int j 0;for (j 0; j col; j){printf( %c , board[i][j]);if (j col - 1){printf(|);//但这个 | 不是所以情况下都打印最后一组打印完之后就不打印了}}printf(\n);//打印分割信息//printf(---|---|---\n); if (i row - 1)//-1就少打印了一组{int j 0;for (j 0; j col; j){printf(---);if (j col - 1){printf(|);//这个 | 也是最后一组打印完之后就不打印了}}printf(\n);}}
} game.h 全代码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#includestdio.h
#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);//行就是row列就是col//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
test.c 全代码
#includegame.h
menu()
{printf(*********************************\n);printf(*********** 1、play ***********\n);printf(*********** 0、exit ***********\n);printf(*********************************\n);}
void game()
{char board[ROW][COL] { 0 };//board棋盘存*和#//初始化棋盘的功能InitBoard(board, ROW, COL);//初始化棋盘DisplayBoard(board, ROW, COL);
}
int main()
{int input 0;//接收玩家输入的选择do{menu();//菜单printf(请选择);scanf(%d, input);switch (input)//根据选择做出相应的响应{case 1:game();break;case 0:printf(退出游戏\n);break;default:printf(选择错误\n);break;}} while (input);return 0;
}
存放地 图 此时代码运行结果
10*10的 3*3的 12、开始下棋
下棋下着下着必定会有人赢有人输
玩家下完电脑下电脑下完玩家下就是一直循环用while语句先定死循环 先写玩家下棋
当玩家下棋的时候还是把数据下在棋盘上对应的就是把数据放到board这个数组里面去了。所以玩家下棋最终还是对数组进行操作玩家下棋的时候还要知道有几行几列要不然下到外面去了就把数组列行传进去。 然后在game.h 里把这个函数声明一下 接着到 game.c 文件里面实现 x和y放进去了那么问题来了这个x和y是不是合理的如果玩家输入9 9那么这个明显超出了我的棋盘范围。最后我们程序员知道这个3*3棋盘第一个元素的位置是 0 0但是玩家不知道啊他们要下在这个位置 就会输入1 1 不敢要求玩家这个左上角这个位置是0 0 要求玩家输入0 0 不现实
所以我们要求这个地方行输入的是1到3列是1到3玩家输入的时候行是1到3的值列也是1到3的值所以这个时候应该判断一下玩家输入的对不对有没有超出棋盘范围等问题 那此时是判合法了如果不和法还要提示一下重新输入那么此时要重新输入这里就要循环了用while循环。先写个while(1)死循环。 如果这里输入坐标行和列是合法的就要判断坐标范围是否合法坐标有没有被占用有没有被下过 结果 电脑下棋
前面这些参数跟玩家下棋一样。 这里电脑下棋的地方写简单的找没有下棋的地方随机下棋让电脑随机生成一个坐标。如果这个坐标没下过棋就可以把他下进去。 用rand函数生成随机值在之前写猜数字的时候学过要用rand这个之前用srand函数设计随机数起点只用设置一次就行所以把srand函数放到main函数里面调用time函数设置起点参数传空指针这样就返回一个时间戳把这个时间戳给srand就可以了这个time函数的返回类型本来应该是time_t 的所以这里强制类型转换成unsigned int 类型。 这里不管是rand还是srand都得引用头文件stdlib.h还有time函数引用time.h头文件 然后就可以生成随机数了随机数生成之后就看一下这个坐标到底有没有被占用。没有被占下棋被占不能下这。注意 这里x和y已经是0到2了是合法的所以这个地方我只要判断这个地方有没有被占用就可以了。
注这个rand产生的随机数的范围是0到32767然后这个row和col都是30到32767之间的任何一个数模上3余数都是0到2所以她的范围都是0到2所以是合法的。 入如果它没有被占用就下#被设置了就要重新下所以这里需要循环用while语句。 如果是空格就下然后跳出循环不是空格就接着循环。
此时全代码
test.c全代码
#includegame.h
menu()
{printf(*********************************\n);printf(*********** 1、play ***********\n);printf(*********** 0、exit ***********\n);printf(*********************************\n);}
void game()
{char board[ROW][COL] { 0 };//board棋盘存*和#//初始化棋盘的功能InitBoard(board, ROW, COL);//初始化棋盘DisplayBoard(board, ROW, COL);//下棋while (1){PlayerMove(board, ROW, COL);//玩家下棋DisplayBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//电脑下棋DisplayBoard(board, ROW, COL);}
}
int main()
{srand((unsigned int)time(NULL));//设置随机数的生成起点int input 0;//接收玩家输入的选择do{menu();//菜单printf(请选择);scanf(%d, input);switch (input)//根据选择做出相应的响应{case 1:game();break;case 0:printf(退出游戏\n);break;default:printf(选择错误\n);break;}} while (input);return 0;
}
game.c 全代码
#includegame.hvoid InitBoard(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 DisplayBoard(char board[ROW][COL], int row, int col)
//{
// int i 0;
// for (i 0; i row; i)
// {
// //打印数据
// printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);
//
// //打印分割信息
// if (i row - 1)//-1就少打印了一组
// {
// printf(---|---|---\n);
// }
//
// }
//}//第二个版本
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i 0;for (i 0; i row; i){//打印数据//printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);int j 0;for (j 0; j col; j){printf( %c , board[i][j]);if (j col - 1){printf(|);//但这个 | 不是所以情况下都打印最后一组打印完之后就不打印了}}printf(\n);//打印分割信息//printf(---|---|---\n); if (i row - 1)//-1就少打印了一组{int j 0;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;//横坐标int y 0;//纵坐标while (1){printf(玩家下棋\n);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] *;break;}else{printf(坐标被占用不能下棋请重新选择其他位置\n);}}else{printf(坐标非法请重新输入\n);}}
}//电脑下棋
//找没有下棋的地方随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{printf(电脑下棋\n);int x 0;int y 0;while (1){x rand() % row;//0~2y rand() % col;//0~2if (board[x][y] ){board[x][y] #;break;}}
}
game.h 全代码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#includestdio.h
#includestdlib.h
#includetime.h
#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);//行就是row列就是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); 存放 图 运行结果 到这的时候已经下满了它不管下那都不行电脑就死循环了所以这里代码肯定有问题但先不管它现在玩家下和电脑下就已经搞起来了。
13、判断输赢
1、玩家下棋之后就应该判断输赢万一玩家赢了呢。同样的道理电脑下完之后也得判断一下输赢。如果输入的时候有斜3横3竖3一样就赢了。
2、这个电脑下棋有点太笨了把它搞清楚一点。这个暂时还没实现
判断输赢写个IsWin函数。
要告诉我游戏当前是谁赢了还是平局如果玩家没有赢电脑没有赢也没有平局这个游戏就还有进行下去。这个时候约定一下玩家赢的时候返回 * 电脑赢了返回 # 平局返回 Q继续返回 C。这个IsWin函数函数就是判断斜3横3竖3三个相等。
所以这个地方判断输赢还是在判断数组参数也是数组名行和列。然后返回的值用char类型的ret来接收。 如果玩家下棋这里判断ret不等于C(就是出最终结果了)就跳出循环。电脑下棋这里也一样。 跳出循环来到这判断ret是等于哪个符号 不管是电脑赢还是玩家赢还是什么游戏的结局棋盘打印一下。 IsWin函数声明 IsWin函数定义
先判断行判断行相等且都不为空格如果这里返回* 或者 # 那这里还得判断很麻烦那我就直接返回行其中一个元素的值。 判断列一样的道理。改造一下 判断对角线 只要前面任何一个if语句返回了值说明一顶有人赢了而当我走完了所有的if语句到最后的时候说此时此刻没有人赢就要平局。
平局就是判断棋盘满了吗写个函数IsFull来判断棋盘是否满了而要判断这个棋盘是不是满了就是判断这个数组里面有没有空格空格是最开始的状态放一个字符就去掉一个空格要判断这个数组就要把行和列一次数组名传过去。 然后就要实现它
返回类型就写int然后约定一下满了就返回1没满返回0
然后就是遍历一下数组看里面有没有空格。 IsFull返回1说明满了平局返回QIsFull返回1说明没满继续最后返回C。 这里判断输赢是写死了。
如果运行发现代码出了问题但确定前面部分代码是没有问题的想直接到问题出开始调试就在想进去的语句处选中再按ctrlF9就显示一个红色断点然后再按ctrlF10进行调试这个时候调试的界面就显示断点之前的代码全部运行完成了从选中的地方就可以开始调试了。
游戏全代码
game.h 全代码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#includestdio.h
#includestdlib.h
#includetime.h
#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col);//行就是row列就是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);//判断输赢
//电脑赢 --#
//玩家赢 --*
//平局 --Q
//继续 --C
char IsWin(char board[ROW][COL], int row, int col);
game.c 全代码
#includegame.hvoid InitBoard(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 DisplayBoard(char board[ROW][COL], int row, int col)
//{
// int i 0;
// for (i 0; i row; i)
// {
// //打印数据
// printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);
//
// //打印分割信息
// if (i row - 1)//-1就少打印了一组
// {
// printf(---|---|---\n);
// }
//
// }
//}//第二个版本
void DisplayBoard(char board[ROW][COL], int row, int col)//打印棋盘
{int i 0;for (i 0; i row; i){//打印数据//printf( %c | %c | %c \n, board[i][0], board[i][1], board[i][2]);int j 0;for (j 0; j col; j){printf( %c , board[i][j]);if (j col - 1){printf(|);//但这个 | 不是所以情况下都打印最后一组打印完之后就不打印了}}printf(\n);//打印分割信息//printf(---|---|---\n); if (i row - 1)//-1就少打印了一组{int j 0;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;//横坐标int y 0;//纵坐标while (1){printf(玩家下棋\n);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] *;break;}else{printf(坐标被占用不能下棋请重新选择其他位置\n);}}else{printf(坐标非法请重新输入\n);}}
}//电脑下棋
//找没有下棋的地方随机下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{printf(电脑下棋\n);int x 0;int y 0;while (1){x rand() % row;//0~2y rand() % col;//0~2if (board[x][y] ){board[x][y] #;break;}}
}
//满了返回1没满返回0
int 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;//有元素是空格}}}//到这里都没有返回说明满了返回1return 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][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];}//没有人赢就要平局if (IsFull(board, row, col)){return Q;}//游戏继续return C;
}
test.c 全代码 #includegame.h
void menu()
{printf(*********************************\n);printf(*********** 1、play ***********\n);printf(*********** 0、exit ***********\n);printf(*********************************\n);}
void game()
{char ret 0;//接收判断输赢的返回符号char board[ROW][COL] { 0 };//board棋盘存*和#//初始化棋盘的功能InitBoard(board, ROW, COL);//初始化棋盘DisplayBoard(board, ROW, COL);//打印棋盘//下棋while (1){PlayerMove(board, ROW, COL);//玩家下棋//判断输赢retIsWin(board, ROW, COL);if (ret ! C){break;}DisplayBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//电脑下棋//判断输赢ret IsWin(board, ROW, COL);if (ret ! C){break;}DisplayBoard(board, ROW, COL);}if (ret *){printf(玩家赢\n);}else if (ret #){printf(电脑赢\n);}else{printf(平局\n);}DisplayBoard(board, ROW, COL);
}
int main()
{srand((unsigned int)time(NULL));//设置随机数的生成起点int input 0;//接收玩家输入的选择do{menu();//菜单printf(请选择);scanf(%d, input);switch (input)//根据选择做出相应的响应{case 1:game();break;case 0:printf(退出游戏\n);break;default:printf(选择错误\n);break;}} while (input);return 0;
}
结果