商城网站开发技术可行性分析,衡水seo,淘宝客网站api,网站权重接口Tic-Tac-Toe 1 游戏介绍和随机数1.1 游戏介绍1.2 随机数的生成1.3 棋盘大小和符号 2 设计游戏2.1 初始化棋盘2.2 打印棋盘2.3 玩家下棋2.4 电脑下棋2.5 判断输赢2.6 game()函数2.7 main()函数 3 完整三子棋代码3.1 Tic_Tac_Toe.h3.2 Tic_Tac_Toe.c3.3 Test.c 4 游戏代码的缺陷 … Tic-Tac-Toe 1 游戏介绍和随机数1.1 游戏介绍1.2 随机数的生成1.3 棋盘大小和符号 2 设计游戏2.1 初始化棋盘2.2 打印棋盘2.3 玩家下棋2.4 电脑下棋2.5 判断输赢2.6 game()函数2.7 main()函数 3 完整三子棋代码3.1 Tic_Tac_Toe.h3.2 Tic_Tac_Toe.c3.3 Test.c 4 游戏代码的缺陷 1 游戏介绍和随机数
1.1 游戏介绍 井字棋英文名叫Tic-Tac-Toe是一种在3*3格子上进行的连珠游戏由于棋盘一般不画边框格线排成井字故得名。游戏需要的工具仅为纸和笔然后由分别代表O和X的两个游戏者轮流在格子里留下标记一般来说先手者为X任意三个标记形成一条直线则为获胜。 点此进入井字棋链接 1.2 随机数的生成
1 rand()函数int rand(void)
生成随机数 返回0到RAND_MAX之间的伪随机整数。RAND_MAX是32767二进制原码最大为0111111111111111215-132767 这个数字是由一个算法生成的该算法每次被调用时都会返回一个明显不相关的数字序列。该算法使用种子来生成序列该序列应使用函数srand初始化为某个独特的值。 RAND_MAX是中定义的常数。 使用rand在确定的范围内生成平凡伪随机数的典型方法是使用返回值乘以范围跨度的模并添加范围的初始值
v1 rand() % 100; // v1 范围 0 to 99
v2 rand() % 100 1; // v2 范围 1 to 100
v3 rand() % 30 1985; // v3 范围 1985-2014请注意这种取模运算并不会在跨度中生成均匀分布的随机数。
2 sand函数是用来初始化随机数生成器的void srand(unsigned int seed);在调用rand前调用srand,修改seed参数生成随机数种子
int main()
{void srand(unsigned int seed);return 0;
}3 time() time函数可以获得时间,需要引用头文件time.h
time_t time(time_t* timer);生成真的随机数
#define _CRT_SECURE_NO_WARNINGS
#includestdio.h
#includetime.h
#includestdlib.h
int main()
{srand((unsigned int)time(NULL));//srand 的参数是unsigned int 类型,强制转换,//time(NULL)返回一段时间戳printf(%d\n, rand());printf(%d\n, rand());printf(%d\n, rand());printf(%d\n, rand());printf(%d\n, rand());return 0;
} 1.3 棋盘大小和符号 在Tic-Tac-Toe.h中定义棋盘行列大小玩家和电脑的符号方便后续修改 #define ROW 3
#define COL 3#define Player_Choice X
#define Computer_Choice O
//#define Player_Choice √
//#define Computer_Choice ×2 设计游戏
2.1 初始化棋盘 将二维数组的所有元素定义为“空”等待后续放入Player_Choice和Computer_Choice void 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] ;}}
}2.2 打印棋盘 我们朝向这个%c | %c | %c \n和 ---|---|---\n打印设计棋盘形状。 后续改变棋盘大小可以通过更改ROW和COL快速更改。 我们以%c |为一组在最后一组是没有|的---|也是同理。需要单独判断 //2 打印棋盘
void DispalyBoard(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){printf( %c , board[i][j]);if (j col - 1)printf(|);}printf(\n);//打印分割信息if (i row - 1){int j 0;for (j 0; j col; j){printf(---);if (j col - 1)printf(|);}printf(\n);}}
} 2.3 玩家下棋 有以下3点要注意 1 输入的坐标格式 2 输入的坐标是否被占用 3 输入的坐标范围是否正确 void PlayerMove(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] Player_Choice;break;}else{printf(坐标被占用不能下棋请选择其他位置\n);}}else{printf(坐标非法请重新输入\n);}}
}2.4 电脑下棋 为了让电脑生产真正的随机数我们前面已经讲了如何做。 void ComputerMove(char board[ROW][COL], int row, int col)
{printf(电脑下棋:\n);int x 0;int y 0;while (1){x rand() % row;y rand() % col;if (board[x][y] ){board[x][y] Computer_Choice;break;}}
}2.5 判断输赢 判断输赢要从三方面行列对角线。分三种情况判定。 先判断棋盘是否填满。 棋盘满了返回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;}}}return 1;
}我们规定 玩家赢的时候IsWin函数返回符号 * 电脑赢的时候IsWin函数返回符号 # 平局的时候IsWin函数返回符号 Q 没结果还要继续时候IsWin函数返回符号 C 因此规定IsWin 函数返回类型是char。 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;
}2.6 game()函数 game()函数放在Test.c中。一旦选择了1 开始游戏启动game()函数。 一定注意下棋的逻辑顺序。 初始化棋盘后放置“空”元素进去。 开始下棋后我们规定玩家先走电脑后走。 玩家走一步判断输赢展示棋盘电脑再走再判断输赢。 第一回合是没必要输赢。但是不妨碍游戏逻辑。 玩家赢 - IsWin函数返回 - Player_Choice 电脑赢 - IsWin函数返回 - Computer_Choice 平局 - IsWin函数返回 - Q void game()
{char result 0;char board[ROW][COL] { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);DispalyBoard(board, ROW, COL);//下棋while (1){PlayerMove(board, ROW, COL);//判断输赢result IsWin(board, ROW, COL);if (result ! C){break;}DispalyBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//判断输赢result IsWin(board, ROW, COL);if (result ! C){break;}DispalyBoard(board, ROW, COL);}if (result Player_Choice){printf(你赢了\n);}else if (result Computer_Choice){printf(电脑赢了\n);}else{printf(你和电脑打成平局\n);}DispalyBoard(board, ROW, COL);
}2.7 main()函数 其实main()函数一开始就写了笔者最后以是修改main()结尾的就把它放最后了。 设置随机数的生成起点的。srand((unsigned int)time(NULL));我忘了这个逻辑。电脑生产伪随机数。 每次进行游戏时电脑都是固定位置没有意义。 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;
}3 完整三子棋代码
主要利用二维数组实现井字棋主要分以下三个模块。 Test.c负责测试游戏的逻辑 Tic_Tac_Toe.c 负责游戏代码的实现 Tic_Tac_Toe.h 负责游戏代码的声明
3.1 Tic_Tac_Toe.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1#include stdio.h
#include stdlib.h
#include time.h#define ROW 3
#define COL 3#define Player_Choice X
#define Computer_Choice O//#define Player_Choice √
//#define Computer_Choice ×//1 初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//2 打印棋盘
void DispalyBoard(char board[ROW][COL], int row, int col);//3 玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);//4 电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);//5 判断输赢
char IsWin(char board[ROW][COL], int row, int col);3.2 Tic_Tac_Toe.c
#include Tic_Tac_Toe.h//1 初始化棋盘
void 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 DispalyBoard(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(irow-1)
// printf(---|---|---\n);
// }
//}//2 打印棋盘
void DispalyBoard(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){int j 0;for (j 0; j col; j){printf(---);if (j col - 1)printf(|);}printf(\n);}}
}//3 玩家下棋
void PlayerMove(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] Player_Choice;break;}else{printf(坐标被占用不能下棋请选择其他位置\n);}}else{printf(坐标非法请重新输入\n);}}
}//4 电脑下棋
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] Computer_Choice;break;}}
}//5 判断输赢
//棋盘满了就返回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;}}}return 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;
}//返回 Player_Choice 玩家赢
//返回 Computer_Choice 玩家赢
//返回 Q 平局
//返回 C 继续
3.3 Test.c
#include Tic_Tac_Toe.hvoid menu()
{printf(*****************************\n);printf(***********1 开始游戏*********\n);printf(***********0 退出游戏*********\n);printf(*****************************\n);
}void game()
{char result 0;char board[ROW][COL] { 0 };//初始化棋盘的函数InitBoard(board, ROW, COL);DispalyBoard(board, ROW, COL);//下棋while (1){PlayerMove(board, ROW, COL);//判断输赢result IsWin(board, ROW, COL);if (result ! C){break;}DispalyBoard(board, ROW, COL);ComputerMove(board, ROW, COL);//判断输赢result IsWin(board, ROW, COL);if (result ! C){break;}DispalyBoard(board, ROW, COL);}if (result Player_Choice){printf(----------你赢了----------\n);}else if (result Computer_Choice){printf(----------电脑赢了----------\n);}else{printf(----------平局----------\n);}DispalyBoard(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;
}
4 游戏代码的缺陷
这个电脑是随便下棋的它没有动脑子每次生产随机的坐标不把我们放心上。不追求矢量直线。 你说如果棋盘再大一带你的电脑也知道适量原则。人下棋的胜率会低多少呢? 不过想要和电脑下平局还是很难的。因为我总要电脑让着我。