C语言开发Oware棋盘游戏:跨玩家数组播种循环实现求助
Oware棋盘游戏播种逻辑修复
我正在用C语言复刻Oware棋盘游戏,需要实现种子在两名玩家的pits数组间循环播种的逻辑。现有代码中,玩家执行播种操作时,种子仅能在当前玩家的6个pits内分发,耗尽当前玩家的pits后无法循环到另一名玩家的pits中,导致游戏逻辑不符合预期。
相关代码
#include <stdio.h> #define num_players 2 #define num_pits_player 6 #define num_seeds 4 struct gameState{ int pits[num_players][num_pits_player]; // 存储种子的坑位 int deposit[num_players]; // 玩家的得分存储区 int playerTurn; // 当前回合玩家 }; void displayGame(struct gameState *game){ printf("\n"); printf("|--------|--|--player1--|--|--------|\n" "|score_p1|%2d|%2d|%2d|%2d|%2d|%2d|score_p0|\n" "| %2d |-----------------| %2d |\n" "| |%2d|%2d|%2d|%2d|%2d|%2d| |\n" "|--------|--|--player0--|--|--------|\n", game->pits[1][0], game->pits[1][1], game->pits[1][2], game->pits[1][3], game->pits[1][4], game->pits[1][5], game->deposit[1], game->deposit[0], game->pits[0][0], game->pits[0][1], game->pits[0][2], game->pits[0][3], game->pits[0][4], game->pits[0][5]); } void makeMove(struct gameState *game){ int player = game->playerTurn; int pitToSow; printf("Player %d's turn.\nPick a pit to sow(1-6): ", player); scanf("%d", &pitToSow); pitToSow--; // 转换为0-based索引 // 获取选中坑内的种子数 int seedsToSow = game->pits[player][pitToSow]; // 清空选中的坑 game->pits[player][pitToSow] = 0; // 逆时针分发种子 int currentPit = (pitToSow + 1) % num_pits_player; while (seedsToSow > 0) { // 给当前坑添加一颗种子 game->pits[player][currentPit]++; seedsToSow--; // 移动到下一个坑 currentPit = (currentPit + 1); } }
当前错误输出
|--------|--|--player1--|--|--------| /*初始状态*/ |score_p1| 4| 4| 4| 4| 4| 4|score_p0| | 0 |-----------------| 0 | | | 4| 4| 4| 4| 4| 4| | |--------|--|--player0--|--|--------| Player 0's turn. Pick a pit to sow(1-6):4 |--------|--|--player1--|--|--------| /*玩家0操作后*/ |score_p1| 5| 5| 4| 4| 4| 4|score_p0| /*此部分符合预期*/ | 0 |-----------------| 0 | | | 4| 4| 4| 0| 5| 5| | |--------|--|--player0--|--|--------| Player 1's turn. Pick a pit to sow(1-6):5 |--------|--|--player1--|--|--------| /*玩家1操作后,问题出现*/ |score_p1| 5| 5| 4| 4| 0| 5|score_p0| /*种子没有循环到玩家0的坑位*/ | 1 |-----------------| 1 | | | 4| 4| 4| 0| 5| 5| | |--------|--|--player0--|--|--------|
理想输出
|--------|--|--player1--|--|--------| /*初始状态*/ |score_p1| 4| 4| 4| 4| 4| 4|score_p0| | 0 |-----------------| 0 | | | 4| 4| 4| 4| 4| 4| | |--------|--|--player0--|--|--------| Player 0's turn. Pick a pit to sow(1-6):4 |--------|--|--player1--|--|--------| /*玩家0操作后*/ |score_p1| 5| 5| 4| 4| 4| 4|score_p0| /*此部分符合预期*/ | 0 |-----------------| 0 | | | 4| 4| 4| 0| 5| 5| | |--------|--|--player0--|--|--------| Player 1's turn. Pick a pit to sow(1-6):5 |--------|--|--player1--|--|--------| /*玩家1操作后,种子循环到玩家0的坑位*/ |score_p1| 5| 5| 4| 4| 0| 5|score_p0| | 1 |-----------------| 1 | | | 5| 5| 5| 0| 5| 5| | |--------|--|--player0--|--|--------|
问题根源与修复方案
问题根源
- 原代码始终将种子分发到当前回合玩家的pits中,没有处理跨玩家的切换逻辑
currentPit的更新仅在当前玩家的6个坑位内递增,没有考虑坑位用完后切换到对方玩家的情况
修改后的makeMove函数
void makeMove(struct gameState *game){ int player = game->playerTurn; int pitToSow; printf("Player %d's turn.\nPick a pit to sow(1-6): ", player); scanf("%d", &pitToSow); pitToSow--; // 转换为0-based索引 // 获取选中坑内的种子数 int seedsToSow = game->pits[player][pitToSow]; // 清空选中的坑 game->pits[player][pitToSow] = 0; // 初始化当前播种的玩家和坑位:从选中坑的下一个开始 int currentPlayer = player; int currentPit = (pitToSow + 1) % num_pits_player; while (seedsToSow > 0) { // 给当前坑添加一颗种子 game->pits[currentPlayer][currentPit]++; seedsToSow--; // 移动到下一个坑位 currentPit++; // 如果当前玩家的坑位已遍历完,切换到对方玩家并重置坑位索引 if (currentPit >= num_pits_player) { currentPlayer = (currentPlayer + 1) % num_players; currentPit = 0; } } }
修改说明
- 新增
currentPlayer变量,动态跟踪当前要播种的玩家,不再固定为回合玩家 - 当
currentPit超过当前玩家的坑位数量(6个)时,自动切换到另一名玩家,并将currentPit重置为0 - 这样种子会按逆时针方向在两名玩家的所有坑位间循环分发,完全符合Oware的播种规则
修改后运行,玩家1选择第5个坑(初始4颗种子)时,会先填满自己的第6个坑,然后依次给玩家0的前3个坑各加1颗种子,和理想输出完全一致。
内容的提问来源于stack exchange,提问作者ramwen0
相关产品推荐
相关产品推荐

