You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

实现逻辑非常直接,不需要复杂操作:

  1. 遍历整个棋盘,分别找到空白块0的坐标(zero_r, zero_c)和用户要移动的目标方块的坐标(tile_r, tile_c)
  2. 相邻判断规则:两个方块行坐标差的绝对值为1且列坐标相同,或者列坐标差的绝对值为1且行坐标相同,满足则移动合法返回1,否则返回0
  3. 额外补充边界判断:如果用户输入的数字小于1或大于15,直接返回0判定为无效

2. 方块移动函数moveTile

不需要额外使用指针,C语言中数组作为参数传递时默认传递的是首地址,函数内修改数组元素会直接作用于原棋盘:

  1. 读取用户输入的要移动的方块数字
  2. 调用is_move_valid判断移动是否合法
  3. 合法则直接交换目标方块和空白块的数值即可完成移动
  4. 不合法则给用户输出错误提示

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 04:45:00