Java中Math.random()重复生成相同随机数问题求助
问题根源:不是Math.random()的问题,是你的play方法逻辑错了!
别怀疑Math.random(),它每次调用都会生成新的随机数——真正的问题出在你写的play方法里,有两个致命逻辑错误:
错误1:play方法内部的while循环一直在重复使用同一个随机值
你在main方法里调用play()时,确实生成了一对随机数,但play方法内部的while循环会把这两个随机值重复用4次。看这段代码:
public void play(int player1, int player2){ consecutiveWins = 0; lastWinner = 0; while (consecutiveWins<4){ int p1Choice = player1; // 每次循环都用传入的同一个值! int p2Choice = player2; // 同上,不会生成新随机数 // ... 后面的对战逻辑 } }
也就是说,你每次调用play,其实是把同一组玩家选择重复执行了4次,自然每次结果都一样。
错误2:play方法开头重置了连续获胜计数
你在play方法第一行就把consecutiveWins = 0;和lastWinner = 0;,这直接导致main方法里的while循环完全失效——不管之前连续赢了几次,只要调用play,计数就被清0,真正控制循环的是play内部的while,而不是main里的逻辑。
修复方案:拆分逻辑,让play只处理单局对战
正确的做法是让play()只负责一次对战,连续获胜的判断交给main方法来处理。具体修改步骤:
1. 重构play方法,去掉内部while循环,删除计数重置
修改后的play方法应该只执行一局对战,更新全局的consecutiveWins和lastWinner,而不是重置它们:
public void play(int player1, int player2){ // 删掉这两行:consecutiveWins = 0; lastWinner = 0; int p1Choice = player1; int p2Choice = player2; int pWinner = 0; // --- 修复switch里的胜负判断逻辑(原来的逻辑全错了!)--- switch (p1Choice) { case 1://Player 1 rock System.out.println("Player 1 Chooses Rock"); if (p2Choice == 1){ pWinner = 0; } else if (p2Choice == 2){ pWinner = 2; }//P2 paper wins else if (p2Choice == 3){ pWinner = 1; }//P2 Scissors, P1 wins else if (p2Choice == 4){ pWinner = 1; }//P2 Lizard, P1 wins else { pWinner = 2; }//p2 spock wins break; case 2: //P1 paper System.out.println("Player 1 Chooses Paper"); if (p2Choice == 1){ pWinner = 1; }//Paper beats Rock, P1 wins else if (p2Choice == 2){ pWinner = 0; }//tie else if (p2Choice == 3){ pWinner = 2; }//Scissors cut Paper, P2 wins else if (p2Choice == 4){ pWinner = 2; }//Lizard eats Paper, P2 wins else { pWinner = 1; }//Spock is disproven by Paper, P1 wins break; case 3: //P1 scissors System.out.println("Player 1 Chooses Scissors"); if (p2Choice == 1){ pWinner = 2; }//Rock crushes Scissors, P2 wins else if (p2Choice == 2){ pWinner = 1; }//Scissors cut Paper, P1 wins else if (p2Choice == 3){ pWinner = 0; }//tie else if (p2Choice == 4){ pWinner = 1; }//Scissors decapitate Lizard, P1 wins else { pWinner = 2; }//Spock smashes Scissors, P2 wins break; case 4: //P1 lizard System.out.println("Player 1 Chooses Lizard"); if (p2Choice == 1){ pWinner = 2; }//Rock crushes Lizard, P2 wins else if (p2Choice == 2){ pWinner = 1; }//Lizard eats Paper, P1 wins else if (p2Choice == 3){ pWinner = 2; }//Scissors decapitate Lizard, P2 wins else if (p2Choice == 4){ pWinner = 0; }//tie else { pWinner = 1; }//Lizard poisons Spock, P1 wins break; case 5: //P1 Spock System.out.println("Player 1 Chooses Spock"); if (p2Choice == 1){ pWinner = 1; }//Spock vaporizes Rock, P1 wins else if (p2Choice == 2){ pWinner = 2; }//Paper disproves Spock, P2 wins else if (p2Choice == 3){ pWinner = 1; }//Spock smashes Scissors, P1 wins else if (p2Choice == 4){ pWinner = 2; }//Lizard poisons Spock, P2 wins else { pWinner = 0; }//tie break; } // --- 保留胜负后的计数更新逻辑 --- if(pWinner==1){ System.out.println("Player 2 chooses " + convert(p2Choice)); System.out.println(convert(p1Choice) + " beats " + convert(p2Choice) + ". Player 1 wins" + System.lineSeparator()); if(lastWinner == 1){ consecutiveWins +=1; }else{ lastWinner = 1; consecutiveWins = 1; } } else if (pWinner==2){ System.out.println("Player 2 chooses " + convert(p2Choice)); System.out.println(convert(p2Choice) + " beats " + convert(p1Choice) + ". Player 2 wins" + System.lineSeparator()); if(lastWinner == 2){ consecutiveWins +=1; }else{ lastWinner = 2; consecutiveWins = 1; } } else { System.out.println("Player 2 also chooses " + convert(p2Choice)); System.out.println("It's a tie!" + System.lineSeparator()); // 平局时连续获胜计数重置 consecutiveWins = 0; } }
2. 保留main方法的逻辑(它是对的)
main方法里每次调用play时都会生成新的随机数,只要play方法不再重复使用同一组值,就能每次得到不同的对战结果:
public static void main(String[] args) { RockPaperScissorsLizardSpock game = new RockPaperScissorsLizardSpock(); while(game.getConsecutiveWins()<4){ // 每次调用都生成新的随机数,没问题 game.play(((int)(Math.random()*5)+1),((int)(Math.random()*5)+1)); } if (game.getLastWinner()==1){ System.out.println(System.lineSeparator() + "Player 1 Wins!"); } else{ System.out.println(System.lineSeparator() + "Player 2 Wins!"); } }
额外提醒:修复convert方法和常量定义
确保你的convert(int choice)方法能正确把数字转成对应的字符串(比如1→Rock,2→Paper等),还有PLAYER1、PLAYER2常量要和你用的1、2对应上,避免出现逻辑混乱。
内容的提问来源于stack exchange,提问作者nodeg
相关产品推荐
相关产品推荐

