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

C++实现6x4无旋转类俄罗斯方块拼图随机块最优放置最小替换方案

形状映射到二维棋盘的实现

你当前使用的扁平化piecesSlots数组本质就是压缩存储的棋盘,6列4行的结构对应索引计算规则为:

// 扁平索引 <-> 二维坐标转换
#define GET_ROW(slot_idx) (slot_idx / 6)
#define GET_COL(slot_idx) (slot_idx % 6)
#define GET_SLOT_IDX(row, col) ((row) * 6 + (col))

如果需要显式的puzzleBoard二维数组,直接遍历24个槽位赋值即可:

bool puzzleBoard[4][6] = {0};
for (int i = 0; i < MAX_SLOTS_NR; i++) {
    puzzleBoard[GET_ROW(i)][GET_COL(i)] = piecesSlots[i].isPosBusy;
}

你现有代码里的形状偏移规则已经完全适配该映射逻辑,无需额外调整。


最优放置搜索方案

第一步:遍历所有合法位置

你已经实现了IsValidPosition接口,直接遍历当前形状的所有可能起始位置即可,不同形状的最大起始位置可以直接从你定义的posList数组中读取。

第二步:放置评分逻辑

核心目标是最小化丢弃次数,所以评分规则按优先级从高到低排序:

  1. 无无效空白区域:放置后所有连通的空白区域的大小,可被现有形状的占格数(1/3/4/6)组合填充,不符合直接排除该位置
  2. 剩余空白数最少:相同条件下优先选填完后剩余空格更少的位置
  3. 空白区域数最少:相同剩余空格数下,优先选空白区域更集中的位置

第三步:模拟放置实现

新增三个辅助函数即可完成搜索:

// 临时缓存模拟放置前的槽位状态
StructSlotsInfo tempSlots[MAX_SLOTS_NR];

void SimulatePlace(BYTE shapePos, BYTE shapeType) {
    // 先备份当前槽位状态
    memcpy(tempSlots, piecesSlots, sizeof(tempSlots));
    // 调用现有放置逻辑
    PlaceShape(shapePos, shapeType);
}

void RollbackPlace() {
    // 回滚到备份状态
    memcpy(piecesSlots, tempSlots, sizeof(tempSlots));
}

int CalcCurrentScore() {
    int score = 0;
    // 已填充格子数加分,填充越多分越高
    for (int i = 0; i < MAX_SLOTS_NR; i++) {
        if (piecesSlots[i].shapeIndex != 0) score += 1;
    }
    // 连通空白区域检查,有无效区域扣1000分直接排除
    int blankRegions = CheckBlankRegions();
    if (blankRegions < 0) score -= 1000;
    return score;
}

其中CheckBlankRegions用简单的DFS/BFS遍历所有空白格子,计算每个连通区域的大小,只要存在小于1或者无法被1/3/4/6组合的大小,直接返回负数即可。

第四步:搜索逻辑

int GetBestPlacePosition(BYTE currentShape) {
    int bestPos = -1;
    int maxScore = -10000;
    BYTE maxPos = 0;
    // 读取当前形状的最大起始位置
    for (int i = 0; i < 7; i++) {
        if (posList[i][0] == currentShape) {
            maxPos = posList[i][1];
            break;
        }
    }
    // 遍历所有可能位置
    for (int pos = 0; pos < maxPos; pos++) {
        if (!IsValidPosition(pos, currentShape)) continue;
        SimulatePlace(pos, currentShape);
        int currentScore = CalcCurrentScore();
        RollbackPlace();
        if (currentScore > maxScore) {
            maxScore = currentScore;
            bestPos = pos;
        }
    }
    return bestPos;
}

调用该函数后如果返回值>=0,直接放置即可;如果返回-1,直接丢弃当前块。


现有代码修复提示

你当前PlaceShape函数中,非0偏移位置的isPosBusy赋值写反了,应该统一设置为true,否则会导致后续合法位置判断错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:30:05