我正在尝试建立一个游戏风险的副本猫。我有一个while循环,它告诉你在攻击还没有结束的时候做一些事情。然后,我要求用户输入'end turn‘来结束turn,或者'continue’来再次递归调用攻击函数。问题是,在用户输入攻击几次之后,然后'end turn‘这个回合并没有结束,而是从头开始或重新开始。我非常感谢专家的眼睛来看我的代码,看看我遗漏了什么,提前谢谢。
public void attackOrSkip(Player player,Player[] playerArray, int playerId) {
boolean attackFinished = false;
int numUnitsAttackWith = 0;
int defenceArmiesNumber =0;
displayString(makeLongName(player) + ": Type 'attack' to attack or 'skip' to skip your turn...");
String command = commandPanel.getCommand();
displayString(PROMPT + command);
if(command.equals("skip") ||command.equals("skip ") ||command.equals("s")) {
return;
}else if (command.equals("attack") ||command.equals("attack ")){
displayString(PROMPT + command);
//while the attack isn't finished
while(attackFinished == false) {
//get the country the user is attacking
int countryAttackingFrom=countryFromCheck(playerId,player);
//get the country to attack
int countryToAttack = countryToCheck(player);
//get the player who we are attacking
int occupierPlayer =board.getOccupier(countryToAttack);
if ((board.getNumUnits(countryAttackingFrom)) < 2) {
displayString("You dont have enough units on this country to make an attack!");
attackOrSkip(player, playerArray, playerId);
break;
}
//if the country is adjacent to another one then you can attack else no
else if(isAdjacent(countryAttackingFrom,countryToAttack)) {
//check the number of unit to attack with
numUnitsAttackWith =numUnitsCheckerAttack(player,countryAttackingFrom);
//check the number of unit to defend with
defenceArmiesNumber = numUnitsCheckerDefence(player,countryToAttack);
//roll the dice
player.rollDice(numUnitsAttackWith);
playerArray[occupierPlayer].rollDice(defenceArmiesNumber);
//display the roll results
displayString(makeLongName(player) + "Rolled: "+printDie(player));
displayString(makeLongName(playerArray[occupierPlayer]) + "Rolled: "+printDie(playerArray[occupierPlayer]));
}
displayString(makeLongName(player) + ": 'end turn' or 'continue'");
command = commandPanel.getCommand();
displayString(PROMPT + command);
if(command.equals("end turn")||command.equals("end turn ") ||command.equals("endturn")||command.equals("endturn ") ||command.equals("end")) {
attackFinished = true;
return;
}else if(command.equals("attack") ||command.equals("attack ")){
// break;
}else if(command.equals("continue") ||command.equals("continue ") ||command.equals("con")){
attackOrSkip(player,playerArray,playerId);
}else {
return;
}
}else {
displayString(makeLongName(player) + ": ERROR, not adjacent countries");
}
}
}
}发布于 2021-03-08 11:48:45
好的-就像目前写的那样-每次你在方法中调用attackOrSkip -你最终在堆栈中低了一层-有了一组新的变量-
attackFinished, numUnitsAttackWith, defenceArmiesNumber当您离开递归(即通过返回)时,您最终得到了与进入递归调用之前一样的简单变量-请记住,Java是按值调用的(即使您可以传入对对象的引用,您也会获得一个值(调用时变量引用的当前值...并且将引用更改为指向不同的对象不会更改调用者引用)。
因此,无需查看您是否完成了正确的算法--我猜测,如果您使方法返回类型为布尔值并返回状态而不是什么都不返回,您就可以更新attackFinished,并且可能会发生正确的事情。
例如,更改所有的
return;至
return attackFinished;并改变你调用的所有地方
attackOrSkip(....)根据方法返回的内容设置攻击已完成
attackFinished = attackOrSkip(....)或者-你可以在一个Holder (an example of the concept)对象中传入一个额外的参数-- attackFinished --同样,引用不能改变,但是你可以使用attackFinished.value = true (然后,当你退出递归时,它在整个堆栈中都是一样的)。
https://stackoverflow.com/questions/66521457
复制相似问题