C语言学习笔记-二维数组之五子棋
游戏逻辑
游戏规则:横竖线或者斜线连续五个棋子在一起即为赢,若棋盘满则为平局。
游戏需要实现难点:电脑的操作步骤,防止棋盘溢出,需要制作可调节的棋盘和棋子数量
游戏利用C语言的知识:二维数组
游戏组成
1.main.c
主要进行了定义一些变量,初始化参数,并进行菜单选择操作
do{tem = scanf("%d", &input);ch = getchar(); //'\n';if (tem == 1 && ch == '\n' && (input == 1 || input == 2)){switch (input){case 1:printf("游戏开始:)\n");game(board, ROW, COL, len);input = 2;break;case 2:printf("游戏结束:)\n");break;default:error_1:printf("输入错误,请重新输入\n");break;}}else{while ((ch = getchar()) != '\n'){;}//清空缓存区goto error_1;}} while (input != 2);
2.game.c
主要定义了函数的主体部分,下面主要加入函数名及部分重点函数
/*"动态画面"*/
void DynamicMenu()/*游戏菜单*/
void menu()/*棋盘数组初始化*/
void Initboard(char board[ROW][COL], int len)/*惩罚*/
void punish(void)/*奖励*/
void award(void)/*打印棋盘*/
void printboard(char board[ROW][COL], int row, int col)/*傻瓜操作*/
void computer1(char board[ROW][COL], int row, int col, int len)/*简单操作(保守型)*/
void computer2(char board[ROW][COL], int row, int col, int len)/*中等操作*/
//还未创建/*玩家操作*/
int player(char board[ROW][COL], int row, int col, int len)/*检查棋已满*/
int screenboard(char board[ROW][COL], int row, int col)/*判断情况*/
char judge(char board[ROW][COL], int row, int col, int len)/*结果操作*/
int judge1(char board[ROW][COL], int row, int col, int len)/*冒泡排序*/
void bubble(int* a)/*游戏逻辑*/
void game(char board[ROW][COL], int row, int col, int len)
棋盘打印
void printboard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i <= col; ++i){printf(" %d ", i);if (i <= col - 1)printf("|");}printf("\n");for (i = 0; i <= col; ++i){printf("---");if (i <= col - 1)printf("|");}printf("\n");for (j = 0; j < row; ++j){printf(" %d |", j + 1);for (i = 0; i < col; ++i){printf(" %c ", board[j][i]);if (i < col - 1)printf("|");}printf("\n");if (j < row - 1){for (i = 0; i <= col; ++i){printf("---");if (i <= col - 1)printf("|");}printf("\n");}}printf("\n");
}
游戏实现逻辑
void game(char board[ROW][COL], int row, int col, int len)
{srand((unsigned int)time(NULL));printboard(board, row, col);//打印棋盘while (1){printf("玩家下棋\n");player(board, row, col, len);printboard(board, row, col);if (judge1(board, row, col, len) != 0){break;}printf("电脑下棋\n");
#if SIMPLEcomputer2(board, row, col, len);
#endif
#if EASY computer1(board, row, col, len);
#endifprintboard(board, row, col);if (judge1(board, row, col, len) != 0){break;}}
}
游戏判断逻辑
//逻辑判断函数
char judge(char board[ROW][COL], int row, int col, int len)//判断输赢
{int a = 0;int i = 0;int j = 0;int times = 0;//判断横列赢for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (((j + 1) < COL) && (board[i][j] == board[i][j + 1]) && board[i][j] != ' '){times++;//printf("A%d\n", times);if (times == QNUM - 1){times = 0;return board[i][j];}}else{times = 0;}}times = 0;}times = 0;//判断竖列赢(省略)//判断左斜对角线赢(省略)//判断右斜对角线赢(省略)//判断平局(棋盘已满)a = screenboard(board, row, col);if (a == 1){printf("无处可下了,平局哦\n");//平局操作return '2';}
}//棋盘空位扫描
int screenboard(char board[ROW][COL], int row, int col)//检查棋盘是否已满
{int i = 0;int j = 0;int k = 0;for (j = 0; j < row; ++j){for (i = 0; i < col; ++i){if (board[j][i] == ' ')return 0;}}return 1;
}//结果操作
int judge1(char board[ROW][COL], int row, int col, int len)
{char res = '0';res = judge(board, row, col, len);if (res == '0'){printf("电脑赢了");return 1;}else if (res == '*'){printf("玩家赢了");return 2;}else if (res == '2'){printf("平局");return 3;}elsereturn 0;
}
玩家操作
int player(char board[ROW][COL], int row, int col, int len)
{int r = 0;int c = 0;char ch = '0';printf("请输入落子位置(行(空格)列):");do{scanf("%d %d", &r, &c);while ((ch = getchar()) != '\n'){;}//清空缓存区if (r <= row && c <= col){if (board[r - 1][c - 1] == ' '){board[r - 1][c - 1] = '*';play[play1] = (r - 1) * COL + c;//存入玩家棋子数组(最后一位开始存入)bubble(play);play1--;//玩家棋子数组下标志break;}else if (board[r - 1][c - 1] == '*' || board[r - 1][c - 1] == '0'){printf("该坐标被占用,请重新输入!\n");}}else{printf("非法输入!请重新输入\n");}} while (1);
}
电脑操作
先判断电脑自己是都块赢了//决胜代码
再判断是否需要对玩家进行堵截//防守代码
再判断是否为第一步//抢占中心代码
再对代码进行聚拢//距集代码
再判断是否为错误操作//随记下棋补漏代码
*此处代码逻辑并不够精细,但是大体操作思路如上*
void computer2(char board[ROW][COL], int row, int col, int len)//简单操作
{int times = 0;int i = 0;int j = 0;int flag1 = 0;//决胜代码if (flag1 == 0){int i = 0;int j = 0;int x = 0;int y = 0;int times = 1;int log = 0;for (j = 0; j < row; j++){x = i;y = j;int flag = 0;for (i = 0; i < col; i++){//横线判断while (log == 0){if (((x) < row) && ((y + 1) < col)){if ((board[x][y] == board[x][y + 1]) && (board[x][y] == '0')){times++;if (times == QNUM - 1){if (board[x][y + 2] == ' '){board[x][y + 2] = '0';flag1 = 0;times = 0;return board[x][y];}else if (board[x][y - 1] == ' '){board[x][y - 1] = '0';flag1 = 0;times = 0;return board[x][y];}}else if (times == QNUM - 2){if (board[x][y + 2] == ' '){board[x][y + 2] = '0';flag1 = 0;times = 0;return board[x][y];}else if (board[x][y - 1] == ' '){board[x][y - 1] = '0';flag1 = 0;times = 0;return board[x][y];}}else if (times == QNUM - 3){if ((board[x][y + 2] == ' ') && (board[x][y + 3] == '0')){board[x][y + 2] = '0';flag1 = 0;times = 0;return board[x][y];}else if ((board[x][y - 1] == ' ') && (board[x][y - 2] == '0')){board[x][y - 1] = '0';flag1 = 0;times = 0;return board[x][y];}}}else{times = 0;}y++;}else{log = 1;}}//竖线//左斜对角线//右斜对角线}}}//判断横列if (flag1 == 0){for (j = 0; j < col; j++){int x = 0;int y = 0;for (i = 0; i < row; i++){x = i;y = j;int flag = 0;while (flag == 0){if (((y + 1) < col) && (x < row)){if ((board[x][y] != ' ') && (board[x][y] == board[x][y + 1])){times++;printf("A%d\n", times);if (times >= QNUM - 4){if (((y + 2) < ROW) && (board[x][y + 2] == ' ')){board[x][y + 2] = '0';times = 0;flag1 = 1;return board[x][y];}else if (((y - 1) >= 0) && (board[x][y - 1] == ' ')){board[x][y - 1] = '0';flag1 = 1;times = 0;return board[x][y];}}else if (times == QNUM - 5){if (((y + 3) < ROW) && (board[x][y + 3] == board[x][y]) && (board[x][y + 2] == ' ')){board[x][y + 2] = '0';times = 0;flag1 = 1;return board[x][y];}else if (((y - 2) >= 0) && (board[x][y - 2] == board[x][y]) && (board[x][y - 1] == ' ')){board[x][y - 1] = '0';times = 0;flag1 = 1;return board[x][y];}}//暂时只能手动添加代码 可能需要用到递归取优化代码}else{times = 0;}y++;}elseflag = 1;}}times = 0;}times = 0;}//判断竖列//判断左对角线//判断右对角线//第一步操作 定点在期盼中心if (board[row / 2][col / 2] == ' '){board[row / 2][col / 2] = '0';flag1 = 1;return board[i][j];}//此处电脑进攻if (flag1 == 0){for (j = 0; j < col; j++){int x = 0;int y = 0;for (i = 0; i < row; i++){x = i;y = j;int flag = 0;while (flag == 0){if (((y + 1) < col) && (x < row)){if ((board[x][y] == '0') && (board[x][y] == board[x][y + 1])){times++;printf("A%d\n", times);if (times == QNUM - 2){if (((y + 2) < ROW) && (board[x][y + 2] == ' ')){board[x][y + 2] = '0';times = 0;flag1 = 1;return board[x][y];}else if (((y - 1) >= 0) && (board[x][y - 1] == ' ')){board[x][y - 1] = '0';flag1 = 1;times = 0;return board[x][y];}}else if (times >= QNUM - 3){if (((y + 3) < ROW) && (board[x][y + 3] == board[x][y]) && (board[x][y + 2] == ' ')){board[x][y + 2] = '0';times = 0;flag1 = 1;return board[x][y];}else if (((y - 2) >= 0) && (board[x][y - 2] == board[x][y]) && (board[x][y - 1] == ' ')){board[x][y - 1] = '0';times = 0;flag1 = 1;return board[x][y];}}//暂时只能手动添加代码 可能需要用到递归取优化代码}else{times = 0;}y++;}elseflag = 1;}}times = 0;}times = 0;}//判断竖线赢//判断左斜对角线赢//判断右斜对角线赢//棋子聚集if (flag1 == 0){for (j = 0; j < row; j++){for (i = 0; i < col; i++){if (board[i][j] == '0'){if (board[i][j + 1] == ' ') {board[i][j + 1] = '0';flag1 = 1;return board[i][j];}//else if周边八个位置循环判断 }}}}}//最后防止出错,随机下一个棋子if (flag1 == 0){computer1(board, row, col, len);}
}
3.game.h
游戏截图
备注
二维数组的外部调用
1.直接定义数组
int arr[2][3];
void fac(int arr[2][3])
{;
}
\\OR
void fac(int arr[][3])
{;
}
2.定义一个指针数组
#define COL 3
int arr[2][COL];
void fac (char(*arr)[COL])
{int x,y;arr[x][y];
}
3.定义一个指向指针的指针
int arr[2][3];
int *p[3];
p[0]=arr[0];
p[1]=arr[1];
p[2]=arr[2];void fac(int **arr)
{int x,y;arr[x][y];
}
存在问题:
1.电脑操作需要使用极大极小算法等操作,暂无时间精力去掌握,所以电脑的操作逻辑简单,
2.不能实现可移植化,博弈算法逻辑还存在问题
3.代码结构还不够精简、层次还不够清晰。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
