我一直在用C语言开发一个非洲棋盘游戏Oware的实现项目,并且正在为捕获特性而挣扎,因为种子被取出的坑没有像它应该的那样被清空。
#include <stdio.h>
#include <stdlib.h>
#define num_players 2
#define num_pits_player 6
#define num_seeds 4
struct gameState{
int pits[num_players][num_pits_player]; //pits for the seeds
int deposit[num_players]; //deposit for the pits
int playerTurn; //keeping track of whose turn it is
};
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 capture(struct gameState *game, int player, int pitToSow){
int currentPit = (pitToSow + 1) % num_pits_player; //variable for the current pit
int seedsInCurrentPit = game->pits[(player + currentPit / num_pits_player) % num_players][currentPit % num_pits_player]; //getting the seeds in the current pit
int opponent = (player + 1) % num_players;
if(seedsInCurrentPit == 2 || seedsInCurrentPit == 3) { //checking for conditions to sow
game->deposit[player] += seedsInCurrentPit; //adding to deposit
game->pits[opponent][seedsInCurrentPit] = 0; //dont work
printf("player %d sowed %d seeds from \nplayer %d's pit number %d", player, seedsInCurrentPit, opponent, game->pits[opponent][seedsInCurrentPit]);
//check suplementary rules
}
}
void makeMove(struct gameState *game){
int player = game->playerTurn;
printf("Player %d's turn.\nPick a pit to sow(1-6): ", player);
int pitToSow;
if(scanf("%d", &pitToSow) != 1 || pitToSow < 1 || pitToSow > 6) { //validating if the pit is valid
fprintf(stderr, "scanf failed\n");
exit(1);
}
pitToSow--; // adjusting for zero-based indexing
// Get the seeds from the selected pit
int seedsToSow = game->pits[player][pitToSow];
int lastPitSown = -1; // Initialize the variable to track the last pit sown
int lastPlayer = player; // Initialize the variable to track the player of the last pit sown
//zero out the pit
game->pits[player][pitToSow] = 0;
for(int currentPit = pitToSow + 1; seedsToSow > 0; currentPit++, seedsToSow--) {
// Distribute one seed to the current pit - moving mechanic
game->pits[(player + currentPit / num_pits_player) % num_players][currentPit % num_pits_player]++;
lastPitSown = currentPit % num_pits_player; // Update the last pit sown
lastPlayer = (player + currentPit / num_pits_player) % num_players; // Update the player of the last pit sown
}
if(lastPitSown >= 0 && lastPitSown < num_pits_player){ //if the last pit sown is in the scope of the array
capture(game, player, pitToSow); //call capture function
}
//update turns
game->playerTurn = (game->playerTurn + 1) % num_players;
}
void startGame(struct gameState *game){
for(int player=0; player < num_players; player++){ //rotating the players
for(int pit=0; pit < num_pits_player; pit++){ //populating each player's pits
game->pits[player][pit] = num_seeds;
}
game->deposit[player] = 0; //init of deposits/score
}
game->playerTurn=0;
}
int main() {
struct gameState game;
//picking the game mode to play
//game start - populate each pit w/ 4, deposit w/ 0
startGame(&game);
//display game
displayGame(&game);
while(game.deposit[0] <= 25 || game.deposit[1] <= 25){
makeMove(&game);
displayGame(&game);
}
return 0;
}
字符串
我试过使用game->pits[opponent][seedsInCurrentPit] = 0;
,但即使我相信索引是正确的,代码也不能按预期运行。我还添加了printf("player %d sowed %d seeds from \nplayer %d's pit number %d", player, seedsInCurrentPit, opponent, game->pits[opponent][seedsInCurrentPit]);
作为调试语句,它似乎返回得很好,但我需要清零的值(保存seedsInCurrentPit的pit)却没有。最后,我试过使用game->pits[(player + currentPit / num_pits_player) % num_players][currentPit % num_pits_player] = 0;
,但没有用。
运行当前代码实现时返回的一个示例是
可以看出,debug语句返回得很好,因为要清空的坑应该是player 1
中的第一个(坑0),并且正确数量的种子被添加到player 0's deposit
,但是从中取出种子的坑没有像它应该的那样被清空,并且表现得像正常的坑。
对于这个场景,我提供了以下输入:
球员0:3
1:1
球员0:4
一比三
球员0:2
在这里,捕获发生
此外,我注意到,即使条件满足,参与人1也不会从参与人0那里获得任何种子,如下面的图片
所示
这应该促使玩家1捕获2个种子,但它没有。
1条答案
按热度按时间3xiyfsfu1#
正如在一些评论中所指出的,你似乎混淆了布尔AND和OR的效果。(我最喜欢的盲点是混淆了整数除法(
a/b
)和模(a%b
)的效果。我知道我想要什么,但我的手指键入了 other 运算符。)建议复习。很久以前就看到过这个游戏的参考资料,你的代码很有趣。然而,实现给我的印象是一堆 * 难以辨别 * 的操作,涉及 * 太多 * 变量,每个变量的名字都 * 太长 。C不是COBOL,这个应用程序不需要长变量名。(当目的和范围受到限制时,我建议选择简洁而不是冗长。)
下面是原始代码的精华。值得注意的属性:
1.内部表示可以是任何最好的服务目的。一个单一的数组(12 pits)简化了种子分布的模 Package 。
1.将代码分解为函数是值得称赞的,但有时会使操作变得模糊,而不是帮助读者理解。
1.注解应该只解释不寻常的,而不是明显的(对熟悉语言的读者)。
1.下面使用单字节
unsigned char
表示 * 种子 * 的数量和分数(数据范围为0
到48
)。这允许memset()
(库函数)初始化每个 * 坑 * 中的种子数量。1.在阅读了这个游戏的Wikipedia页面之后,下面的代码似乎完全实现了得分(我希望是正确的)。
1.这个游戏是逆时针进行的。
您的代码
printf()
中的用户反馈给人的印象是,您花费了大量时间来实现特定的布局。建议首先集中精力让程序逻辑按照需要工作。格言中有很多智慧,“ 证据在布丁中,”和“ 外表可能是欺骗性的。”
出于教育目的:
字符串
编辑:
在对OP代码的修改中,我没有停下来意识到主循环条件是错误的!
应该是
score[0] < 25 && score[1] < 25
根据维基百科,
draw
是可能的。当一个玩家获得25+ * 种子 * 时,该玩家已经**赢得了比赛。修订版本:
这是一个棘手的游戏玩独奏,因为董事会的方向是“固定的”。思考左向右的一些动作,然后右向左的其他人。减缓测试时,错误。
下面是大致相同的代码修改,以便当前玩家从他们的Angular 看到棋盘“从左到右”。这个修改是为了演示扩展 * 紧凑 * 代码的灵活性。
型
玩得开心点!