Once upon a time in the land of Asgard there lived 3 wizards Gandalf, Merlin and Dumbledore. These 3 wizards often had an argument over which one of them was thegreatest software developer of all time. To end the argument once and for all, they agreed on a fight to the death. Gandalf was a poor shooter and only hit his target with a probability of 1/3. Merlin was a bit better and hit his target with a probability of 1/2. Dumbledore was an expert marksman andnever missed. A hit means a kill and the person hit drops out of the duel.
To compensate for the inequities in their marksmanship skills, the three decided that they would fire in turns, starting with Gandalf, followed by Merlin, and then by Dumbledore. The cycle would repeat until there was one man or creature standing, and that man or creature would be the greatest software developer of All Time.
An obvious and reasonable strategy is for each wizard to shoot at the most accurate shooter still alive, on the grounds that this shooter is the deadliest and has the best chance of hitting back.
Write a program to simulate the duel using this strategy. Your program should use random numbers and the probabilities given
in the problem to determine whether a shooter hits the target. Create a class named Fighter that contains the wizard’s name
and shooting accuracy, a Boolean indicating whether the fighter is still alive, and a method shootAtTarget(Fighter target) that sets the target to dead if the fighter hits his target (using a random number and the shooting accuracy) and does nothing otherwise.
Once you can simulate a single fight, add a loop to your program that simulates 10,000 fights. Count the number of times that each contestant wins and print the probability of winning for each contestant in a tabular format. For example:
Fighter.java
package com.zx.bean;
import com.zx.util.Util;
/**
* @author 作者
* @version 创建时间:2019年10月17日 下午9:50:55
* @email zxiao@stu.ouc.edu.cn 类说明
*/
public class Fighter {
String name;
int accuracy;
boolean weatherAlive;
public Fighter() {
super();
}
public Fighter(String name, int accuracy, boolean weatherAlive) {
super();
this.name = name;
this.accuracy = accuracy;
this.weatherAlive = weatherAlive;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAccuracy() {
return accuracy;
}
public void setAccuracy(int accuracy) {
this.accuracy = accuracy;
}
public boolean isWeatherAlive() {
return weatherAlive;
}
public void setWeatherAlive(boolean weatherAlive) {
this.weatherAlive = weatherAlive;
}
public void shootAtTarget(Fighter fighter) {
boolean flag = Util.getTargetProbability(this.getAccuracy());
if (flag) {//如果射中
fighter.setWeatherAlive(false);
}
}
}
Main.java
package com.zx.main;
/**
* @author 作者
* @version 创建时间:2019年10月18日 下午3:48:34
* @email zxiao@stu.ouc.edu.cn
* 类说明
*/
import java.text.DecimalFormat;
import com.zx.bean.Fighter;
import com.zx.util.Util;
public class Main {
public static void main(String[] args) {
Fighter[] f = new Fighter[3];
for (int i = 0; i < 3; i++) {
f[i] = new Fighter();
f[i].setWeatherAlive(true);
}
int gameTime = 10000;
int winNumOfGandalf = 0;
int winNumOfMerlin = 0;
int winNumOfDumbledore = 0;
float winRateOfGandalf = 0.0f;
float winRateOfMerlin = 0.0f;
float winRateOfDumbledore = 0.0f;
f[0].setAccuracy(33);
f[1].setAccuracy(50);
f[2].setAccuracy(100);
for (int i = 0; i < gameTime; i++) {
while (!Util.wheatherOnlyOne(f)) {//当比赛未结束时
if (f[0].isWeatherAlive()) {//如果Gandalf存活,选择M或者D进行射击,如果D存活,射击D,如果D不存活,则射击M
f[0].shootAtTarget(Util.getCurrentBestTarget(f, 0));
}
if (f[1].isWeatherAlive()) {
if(!Util.wheatherOnlyOne(f)) {
f[1].shootAtTarget(Util.getCurrentBestTarget(f, 1));
}
else {
break;
}
}
if (f[2].isWeatherAlive()&& !Util.wheatherOnlyOne(f)) {
f[2].shootAtTarget(Util.getCurrentBestTarget(f, 2));
}
}
if (Util.getWinnerNum(f) == 0) {
winNumOfGandalf++;
}else
if (Util.getWinnerNum(f) == 1) {
winNumOfMerlin++;
}else
if (Util.getWinnerNum(f) == 2) {
winNumOfDumbledore++;
}else {
System.out.println("dada");
}
Util.setAllAlive(f);
}
DecimalFormat df = new DecimalFormat("0.00%");
winRateOfGandalf = (float) winNumOfGandalf / gameTime;
winRateOfMerlin = (float) winNumOfMerlin / gameTime;
winRateOfDumbledore = (float) winNumOfDumbledore / gameTime;
System.out.println("LEADERBOARD - AFTER " + gameTime + " DUELS");
System.out.println("Contestant\t" + "Number of Wins" + "Winning Percentag");
System.out.println("Gandalf\t" + "\t" + winNumOfGandalf + "\t" + df.format(winRateOfGandalf));
System.out.println("Merlin\t" + "\t" + winNumOfMerlin + "\t" + df.format(winRateOfMerlin));
System.out.println("Dumbledore\t" + winNumOfDumbledore + "\t" + df.format(winRateOfDumbledore));
}
}
Util.java
package com.zx.util;
import java.lang.annotation.Target;
import java.util.Random;
import com.zx.bean.Fighter;
/**
* @author 作者
* @version 创建时间:2019年10月17日 下午9:53:38
* @email zxiao@stu.ouc.edu.cn 类说明
*/
public class Util {
public static boolean getTargetProbability(int total) {// 输入目标概率,判断是否命中。命中返回true,否则返回false
// System.out.println("total:" + total);
/*
* int arrCache[] = new int[100]; int cache[] = new int[100]; int arr[]= new
* int[100]; for (int i = 0; i < total; i++) {// 如果是零,则命中 arr[i] = 0; } for (int
* k = 100 - total; k < 100; k++) {// 如果是1,则不命中 arr[k] = 1; } // 打乱 Random
* random = new Random(); for (int i = 0; i < 100; i++) { int nextInt =
* random.nextInt(100); int k = 0; while (k <= i && k != 99) { if (cache[k] ==
* nextInt) { nextInt = random.nextInt(100); k = 0; } else { k++; } } cache[i] =
* nextInt; arrCache[i] = arr[i]; } for (int i = 0; i < 100; i++) { arr[i] =
* arrCache[cache[i]]; } int nextInt = random.nextInt(100); if (arr[nextInt] ==
* 0) {// 如果选中的数为零,表示命中 return true; } else { return false; }
*/
Random r = new Random();
int nextInt = r.nextInt(100);
if (nextInt < total) {
return true;
} else {
return false;
}
}
public static Fighter getCurrentBestTarget(Fighter[] f, int now) {// 得到目前存活的精确度最好的非自我射手
int k = -1;// 记录目前最好的射手的编号
switch (now) {
case 0:
if (f[2].isWeatherAlive()) {
k = 2;
} else {
k = 1;
}
break;
case 1:
if (f[2].isWeatherAlive()) {
k = 2;
} else {
k = 0;
}
break;
case 2:
if (f[1].isWeatherAlive()) {
k = 1;
} else if (f[0].isWeatherAlive()) {
k = 0;
}
break;
default:
break;
}
return f[k];
}
public static boolean wheatherOnlyOne(Fighter[] f) {
if ((f[0].isWeatherAlive() == true && f[1].isWeatherAlive() == false && f[2].isWeatherAlive() == false)
|| (f[0].isWeatherAlive() == false && f[1].isWeatherAlive() == true && f[2].isWeatherAlive() == false)
|| (f[0].isWeatherAlive() == false && f[1].isWeatherAlive() == false
&& f[2].isWeatherAlive() == true)) {
return true;
}
return false;
}
public static void setAllAlive(Fighter[] f) {
for (int i = 0; i < 3; i++) {
f[i].setWeatherAlive(true);
}
}
public static int getWinnerNum(Fighter[] f) {
for (int i = 0; i < 3; i++) {
if (f[i].isWeatherAlive()) {
return i;
}
}
return -1;
}
}