You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:23:09