import java.util.Random;

public class Player {

int att;
int str;
int def;
int hp;
int attackRoll;
int defenceRoll;
int maxHit;

//A player has variable attack, strength, defence, and hp stats
//attack = determines accuracy, strength = determines damage, defence = determines ability to block hits
public Player(int attack, int strength, int defence, int hitpoints)
{
    attack = att;
    strength = str;
    defence = def;
    hitpoints = hp;
    /*
        attackRoll and defenceRoll are used by the 2 players to determine probability
        of successfully scoring a hit, in m sample testing attRoll will always be
        higher than defRoll; they are integer numbers used in below method
    */
    attackRoll = (this.att + 3)*(90+64);
    defenceRoll = (this.def + 3)*(0+64);
    maxHit = (int) ((0.5) + ((this.str + 0 + 8.0)*(86.0+64.0))/(640.0));
    //maxHit determines the maximum number player can deal each attack
}

//this determines if p1 successfully lands a hit on p2, true if so, false if not
//accuracy is calculated as a probability, ie  .7 probability of hitting
//in which case there is .7 probability of being true and .3 of being false
public static boolean hit(Player p1, Player p2)
{
    double accuracy;
    if (p1.attackRoll > p2.defenceRoll)
    {
        accuracy = 1.0 - ((double)(p2.defenceRoll+2.0)/(2*(p1.attackRoll+1.0)));
    }
    else
    {
        accuracy = (double) (p1.attackRoll/(2*(p2.defenceRoll+1.0)));
    }
    Random r = new Random();
    System.out.println("Accuracy: " + accuracy);
    return r.nextDouble() <= accuracy;
    //idea is that if accuracy is .7 for example, nextDouble() generates
    //between 0-1.0 so the probability that nextDouble() is <= .7 is .7, what we want
}

//calculates damage p1 does to p2, if hit returns true
public static void attack(Player attacker, Player defender)
{
    int damage = 0;
    if(!hit(attacker, defender)) return; //if the attacker missed, damage is 0, defender doesn't lose hp

    //if p1 successfully landed a hit on p2 as determined in previous method
    else if(hit(attacker, defender))
    {
        Random r = new Random();
        damage = r.nextInt(attacker.maxHit+1); //p1 deals (0 to maxHit) damage on p2 from that attack
        defender.hp -= damage; //p2 loses that much hp
    }
}

public static void main(String[] args) {
    int p1wins = 0; //counts number of times p1 won
    int p2wins = 0; //counts number of times p2 won
    int firstCounter = 0; //counts the number of times p1 went first, should be near 50% as its randomly decided
    int secondCounter = 0; //couonts the number of times p2 went first, should be near 50%
    for (int i = 1; i <= 10000; i++) //10000 trials of p1 and p2 battling
    {
        Player p1 = new Player(99, 99, 99, 99); //set p1's attack, strength, defence, hp to 99
        Player p2 = new Player(99, 99, 99, 40); //p2 only has 40 hp, therefore p2 should lose most of the time
        Random r = new Random();
        int first = r.nextInt(2); //determines which player attacks first
        if(first == 0) firstCounter++;
        if(first == 1) secondCounter++;
        while((p1.hp>0) && (p2.hp>0)) //the fight goes on until one player dies (hp is <= 0)
        {

            if(first == 0) //if player 1 attacks first
            {

                attack(p1, p2); //player 1 attacks player 2
                if(p2.hp <= 0) break; //if player 2's hp goes 0 or below from that attack, he dies and there's no more fighting
                attack(p2, p1); //then p2 attacks p1, and repeat
                if(p1.hp <= 0) break;
            }
            else if (first == 1) //if player  2 attacks first
            {

                attack(p2, p1); //player 2 attacks player 1
                if(p1.hp <= 0) break;
                attack(p1, p2);
                if(p2.hp <= 0) break;
            }

        }
          if(p1.hp <= 0) p2wins++;
        else if(p2.hp <= 0) p1wins++;
    }
    System.out.println("p1 won " + p1wins + " times."); //prints number of times p1 wins
    System.out.println("p2 won " + p2wins + " times.");
    System.out.println(firstCounter); //prints number of times p1 went first, should be near 50% with large sample size
    System.out.println(secondCounter);
}


}

上面的代码是一个模拟2个玩家战斗的程序。
主要思想是了解一个玩家具有4个属性(攻击,力量,防御,生命值),并且如果两个玩家使用相同的属性进行战斗(即,两个属性分别为99,99,99,99),那么任何人获胜的概率自然是大约50%。

我遇到的问题是该程序使p2在每场比赛中均获胜,即使统计数据明显差于其他游戏

(例如,具有99 at,99 str,99 def,99 hp的p1具有99 at,99 str,99 def但20 hp的p2),因此在大多数测试中p2会更快地死亡,但是10000次打斗显示p2获胜全部10000个,这显然是错误的,不是故意的。我不知道为什么p2赢得100%的时间。

最佳答案

Player构造函数的开头出现错误。

分配顺序错误。正确的方法是:

att = attack;
str = strength;
def = defence;
hp = hitpoints;


否则,p1.hp和p2.hp始终为0。

09-10 01:00
查看更多