makeMove函数逻辑不符预期,请求修改分配规则并讲解代码
修改后的
makeMove函数及逻辑讲解 核心问题
原代码的分配逻辑错误:清空选中坑后直接从下一个坑开始分石头,没有把第一块石头放回选中坑,导致结果不符合预期。
修改后的代码
void makeMove(int player, int move) { int i, stones, currentPit; int selectedPit = player * 6 + move; // 取出选中坑的所有石头并清空该坑 stones = board[selectedPit]; board[selectedPit] = 0; // 从选中坑本身开始分配石头 currentPit = selectedPit; for (i = 0; i < stones; i++) { // 跳过对手的Mancala坑(不往这里放石头) if (currentPit == (player ^ 1) * 6 + 6) { currentPit++; // 处理数组边界,防止越界访问 if (currentPit == BOARD_SIZE) { currentPit = 0; } } // 在当前坑放置一块石头 board[currentPit]++; // 移动到下一个坑,循环到数组开头如果超出边界 currentPit++; if (currentPit == BOARD_SIZE) { currentPit = 0; } } }
逻辑拆解
关键修改点
- 调整分配起始位置:把原代码从「选中坑的下一个坑」开始分配,改成从「选中坑本身」开始,确保第一块石头放回选中坑。
- 优化跳过逻辑:每次准备放石头前检查当前坑是否是对手的Mancala,若是直接跳坑,避免违规放置。
- 强化边界处理:跳过对手Mancala后额外检查边界,防止数组越界出错。
测试用例验证
以你给出的[4,4,4,4,4]为例,选中第一个坑(move=0):
- 先取出4块石头,
board[0]设为0。 - 循环4次分配:
- 第1次:
currentPit=0,放石头后board[0]变为1,移到坑1。 - 第2次:
currentPit=1,放石头后board[1]变为5,移到坑2。 - 第3次:
currentPit=2,放石头后board[2]变为5,移到坑3。 - 第4次:
currentPit=3,放石头后board[3]变为5,移到坑4。
- 第1次:
- 最终结果为
[1,5,5,5,4],完全符合预期。
原代码问题剖析
原代码一开始就清空选中坑,然后从下一个坑开始分配所有石头,相当于把选中坑的石头全部分给了后续坑,完全忽略了「先放回选中坑一块」的规则,所以会得到[0,5,5,5,5]的错误结果。
内容的提问来源于stack exchange,提问作者Emin Aslanbaş
相关产品推荐
相关产品推荐

