C语言如何实现滑动拼图中根据用户输入交换二维数组元素的函数
4x4滑动拼图游戏实现方案
现有代码问题修正
你当前的代码有几个需要先调整的基础问题:
- 棋盘
board定义在if(a=='p')的分支内部,属于局部变量,执行移动操作的代码块无法访问,需要将其移到main函数开头定义 - C语言中二维数组作为函数参数时必须指定第二维的长度,原函数原型
int moveTile(int arry[][])、int is_move_valid(int tile)写法不合法,且合法性判断需要访问棋盘数据,需要补充棋盘参数 - 菜单循环逻辑错误,当前仅读取一次用户选项,后续不会更新输入,需要调整为每次循环都重新读取用户操作
is_move_valid函数需要传入棋盘参数才能获取空白块和目标方块的位置
核心功能实现思路
1. 移动合法性判断函数is_move_valid
实现逻辑非常直接,不需要复杂操作:
- 遍历整个棋盘,分别找到空白块
0的坐标(zero_r, zero_c)和用户要移动的目标方块的坐标(tile_r, tile_c) - 相邻判断规则:两个方块行坐标差的绝对值为1且列坐标相同,或者列坐标差的绝对值为1且行坐标相同,满足则移动合法返回1,否则返回0
- 额外补充边界判断:如果用户输入的数字小于1或大于15,直接返回0判定为无效
2. 方块移动函数moveTile
不需要额外使用指针,C语言中数组作为参数传递时默认传递的是首地址,函数内修改数组元素会直接作用于原棋盘:
- 读取用户输入的要移动的方块数字
- 调用
is_move_valid判断移动是否合法 - 合法则直接交换目标方块和空白块的数值即可完成移动
- 不合法则给用户输出错误提示
3. 胜利判断(补充功能)
每次移动完成后遍历棋盘,判断是否和目标顺序[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0]完全一致,一致则提示游戏胜利并退出程序。
完整可运行代码
#include <stdio.h> #include <stdlib.h> // 用于abs函数 const int row = 4; // 全局变量定义棋盘行列数 const int col = 4; // 修正后的函数原型 void startGame(void); void endGame(void); void displayGame(int arr[row][col]); int is_move_valid(int arr[row][col], int tile); int moveTile(int arr[row][col]); int check_win(int arr[row][col]); // 补充胜利判断函数 int main(void) { // 棋盘移到main开头定义,全局可用 int board[row][col] = { {0, 15, 14, 13}, {12, 11, 10, 9}, {8, 7, 6, 5}, {4, 3, 2, 1} }; startGame(); char op; while(1) { printf("\nMenu: [p]rint , [m]ove , [q]uit:\n"); scanf(" %c", &op); if(op == 'q') { break; } else if(op == 'p') { displayGame(board); } else if(op == 'm') { if(moveTile(board)) { // 移动成功后判断是否胜利 if(check_win(board)) { printf("\n恭喜你完成拼图!游戏胜利!\n"); break; } } } else { printf("无效选项,请重新输入!\n"); } } endGame(); return 0; } void startGame() { printf("Setting Up The Game\n"); } void displayGame(int arr[row][col]){ int i, j; for (i=0; i<row; i++) { printf("\n"); for (j=0; j<col; j++) { printf("%3d", arr[i][j]); } } } int is_move_valid(int arr[row][col], int tile) { // 边界判断:数字必须在1-15之间 if(tile < 1 || tile > 15) { printf("输入的数字无效,请输入1-15之间的数字!\n"); return 0; } int zero_r, zero_c, tile_r, tile_c; // 遍历找空白块和目标方块的坐标 for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { if(arr[i][j] == 0) { zero_r = i; zero_c = j; } if(arr[i][j] == tile) { tile_r = i; tile_c = j; } } } // 判断是否相邻 if((abs(zero_r - tile_r) == 1 && zero_c == tile_c) || (abs(zero_c - tile_c) == 1 && zero_r == tile_r)) { return 1; } else { printf("该方块和空白块不相邻,无法移动!\n"); return 0; } } int moveTile(int arr[row][col]){ int t; printf("Which tile would you like to move? :\n"); scanf("%d", &t); if(is_move_valid(arr, t)) { int zero_r, zero_c, tile_r, tile_c; // 找到两个方块的位置交换数值 for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { if(arr[i][j] == 0) { zero_r = i; zero_c = j; } if(arr[i][j] == t) { tile_r = i; tile_c = j; } } } int temp = arr[zero_r][zero_c]; arr[zero_r][zero_c] = arr[tile_r][tile_c]; arr[tile_r][tile_c] = temp; return 1; // 移动成功返回1 } return 0; // 移动失败返回0 } int check_win(int arr[row][col]) { int target[4][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}, {13,14,15,0} }; for(int i=0; i<row; i++) { for(int j=0; j<col; j++) { if(arr[i][j] != target[i][j]) { return 0; } } } return 1; } void endGame(void) { printf("Ending the game\n"); }
内容的提问来源于stack exchange,提问作者billyplantin
相关产品推荐
相关产品推荐

