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

玩家企鹅移动逻辑Bug修复与游戏结束判定方案咨询

企鹅移动逻辑修复及游戏结束判定方案

问题背景

移动判定规则:目标位置需满足无企鹅、非0号水域tile、未超出棋盘范围,违反则需重新输入方向。当前实现的移动逻辑存在无规律错误移动、误判无法移动的问题,同时缺少所有玩家无企鹅可移动时的游戏结束判定。

现存代码问题分析

1. 企鹅定位函数逻辑错误

getPengPos仅返回玩家的第一只企鹅位置,但循环中按企鹅编号遍历,导致所有编号对应的操作都修改同一只企鹅,这是错误移动的核心原因。

2. 边界判定完全混乱

  • 行边界与board_width对比、列边界与board_height对比,维度完全搞反;
  • 边界条件错误(如向上移动判断playerRow-1 > 0,遗漏了第0行的合法位置)。

3. 缺少核心判定条件

未检查目标位置是否有企鹅、是否为0号水域tile,仅判断边界,不符合规则要求。

4. 移动循环逻辑不合理

当前循环强制所有玩家的第N只企鹅必须移动,未考虑企鹅是否可移动,也没有全局检查所有企鹅的可移动状态。


修复方案及代码实现

1. 修复企鹅定位函数

新增penguinIndex参数,按顺序查找玩家的第N只企鹅:

void getPengPos(struct board *gameBoard, int playerIndex, int penguinIndex, int *row, int *column) {
    int count = 0;
    for (int i = 0; i < gameBoard->rows; i++) {
        for (int j = 0; j < gameBoard->columns; j++) {
            if (gameBoard->penguins[i * gameBoard->columns + j] == 'A' + playerIndex) {
                if (count == penguinIndex) {
                    *row = i;
                    *column = j;
                    return;
                }
                count++;
            }
        }
    }
    *row = -1;
    *column = -1; // 未找到对应编号的企鹅
}

2. 新增辅助函数

单只企鹅可移动检查

bool canPenguinMove(struct board *gameBoard, int row, int col) {
    // 检查四个方向是否符合移动条件
    // 向上
    if (row - 1 >= 0) {
        int idx = (row-1)*gameBoard->columns + col;
        if (gameBoard->penguins[idx] == ' ' && gameBoard->tiles[idx] != 0) {
            return true;
        }
    }
    // 向下
    if (row + 1 < gameBoard->rows) {
        int idx = (row+1)*gameBoard->columns + col;
        if (gameBoard->penguins[idx] == ' ' && gameBoard->tiles[idx] != 0) {
            return true;
        }
    }
    // 向左
    if (col - 1 >= 0) {
        int idx = row*gameBoard->columns + (col-1);
        if (gameBoard->penguins[idx] == ' ' && gameBoard->tiles[idx] != 0) {
            return true;
        }
    }
    // 向右
    if (col + 1 < gameBoard->columns) {
        int idx = row*gameBoard->columns + (col+1);
        if (gameBoard->penguins[idx] == ' ' && gameBoard->tiles[idx] != 0) {
            return true;
        }
    }
    return false;
}

全局可移动状态检查

bool allPenguinsTrapped(struct board *gameBoard, int num_players, int num_pengwings) {
    for (int i = 0; i < num_players; i++) {
        for (int x = 0; x < num_pengwings; x++) {
            int row, col;
            getPengPos(gameBoard, i, x, &row, &col);
            if (row != -1 && canPenguinMove(gameBoard, row, col)) {
                return false; // 存在可移动企鹅,游戏继续
            }
        }
    }
    return true; // 所有企鹅无法移动,游戏结束
}

3. 重写移动阶段函数

修正循环逻辑、边界判断,补充核心规则检查,添加游戏结束判定:

void movementPhase(struct board *gameBoard, Player players[], int num_players, int num_pengwings, int board_height, int board_width) {
    char direction;
    bool validInput;

    // 先检查全局状态,若所有企鹅无法移动直接结束
    if (allPenguinsTrapped(gameBoard, num_players, num_pengwings)) {
        printf("所有企鹅都无法移动,游戏结束!\n");
        return;
    }

    // 玩家轮流操作自己的所有企鹅
    for (int i = 0; i < num_players; i++) {
        for (int x = 0; x < num_pengwings; x++) {
            int playerRow, playerCol;
            getPengPos(gameBoard, i, x, &playerRow, &playerCol);
            
            // 企鹅不存在或无法移动则跳过
            if (playerRow == -1 || !canPenguinMove(gameBoard, playerRow, playerCol)) {
                printf("玩家%d的第%d只企鹅无法移动,跳过操作。\n", i+1, x+1);
                continue;
            }

            validInput = false;
            while (!validInput) {
                printf("玩家%d,输入第%d只企鹅的移动方向(u, d, r, l): ", i+1, x+1);
                scanf(" %c", &direction);

                int targetRow = playerRow;
                int targetCol = playerCol;
                bool boundaryValid = true;

                // 计算目标坐标并校验边界
                switch(direction) {
                    case 'u':
                        targetRow = playerRow - 1;
                        boundaryValid = (targetRow >= 0);
                        break;
                    case 'd':
                        targetRow = playerRow + 1;
                        boundaryValid = (targetRow < gameBoard->rows);
                        break;
                    case 'r':
                        targetCol = playerCol + 1;
                        boundaryValid = (targetCol < gameBoard->columns);
                        break;
                    case 'l':
                        targetCol = playerCol - 1;
                        boundaryValid = (targetCol >= 0);
                        break;
                    default:
                        printf("无效输入,请输入u、d、r或l。\n");
                        boundaryValid = false;
                        break;
                }

                if (!boundaryValid) {
                    printf("移动方向超出棋盘范围,请重新输入。\n");
                    continue;
                }

                // 校验目标位置的核心规则
                int targetIdx = targetRow * gameBoard->columns + targetCol;
                if (gameBoard->penguins[targetIdx] != ' ') {
                    printf("目标位置已有企鹅,无法移动,请重新输入。\n");
                    continue;
                }
                if (gameBoard->tiles[targetIdx] == 0) {
                    printf("目标位置是水域tile,无法移动,请重新输入。\n");
                    continue;
                }

                // 执行移动
                validInput = true;
                gameBoard->penguins[playerRow * gameBoard->columns + playerCol] = ' ';
                gameBoard->penguins[targetIdx] = 'A' + i;
                printBoard(gameBoard);

                // 移动后再次检查全局状态,若所有企鹅无法移动则提前结束
                if (allPenguinsTrapped(gameBoard, num_players, num_pengwings)) {
                    printf("所有企鹅都无法移动,游戏结束!\n");
                    return;
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Merrichu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:34:53