Skip to content

Instantly share code, notes, and snippets.

@KevinTyrrell
Created July 22, 2017 10:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KevinTyrrell/4b439d2cc627d2ecfdc0a805672ced7d to your computer and use it in GitHub Desktop.
Save KevinTyrrell/4b439d2cc627d2ecfdc0a805672ced7d to your computer and use it in GitHub Desktop.
public class Creature implements Cloneable
{
static class Hero extends Creature
{
public Hero(final int HP, final boolean markedForDeath)
{
super(HP, markedForDeath);
}
public Hero(final int HP)
{
super(HP);
}
}
private int HP;
private final boolean markedForDeath;
public Creature(final int HP, final boolean markedForDeath)
{
assert HP > 0;
this.HP = HP;
this.markedForDeath = markedForDeath;
}
public Creature(final int HP)
{
this(HP, false);
}
public void damage(final int damage)
{
assert damage > 0;
assert HP > 0;
HP = Math.max(HP - damage, 0);
}
public void damage()
{
damage(1);
}
public boolean isDead()
{
return HP <= 0;
}
public boolean isMarkedForDeath()
{
return markedForDeath;
}
@Override protected Creature clone() throws CloneNotSupportedException
{
return new Creature(HP, markedForDeath);
}
}
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.math.RoundingMode;
public final class Fraction implements Cloneable
{
private final BigInteger numerator, denominator;
public static final Fraction ZERO = new Fraction(),
ONE = new Fraction(1);
private Fraction(final BigInteger numerator, final BigInteger denominator)
{
assert numerator != null;
assert denominator != null;
assert denominator.compareTo(BigInteger.ZERO) != 0;
final BigInteger gcd = numerator.gcd(denominator);
this.numerator = numerator.divide(gcd);
this.denominator = denominator.divide(gcd);
}
public Fraction(final int numerator, final int denominator)
{
this(BigInteger.valueOf(denominator >= 0 ? numerator : -numerator),
BigInteger.valueOf(denominator >= 0 ? denominator : -denominator));
}
public Fraction(final int numerator)
{
this(numerator, 1);
}
public Fraction()
{
this(0);
}
public Fraction add(final Fraction other)
{
assert other != null;
return new Fraction(
numerator.multiply(other.denominator).add(other.numerator.multiply(denominator)),
denominator.multiply(other.denominator)
);
}
public Fraction subtract(final Fraction other)
{
assert other != null;
return new Fraction(
numerator.multiply(other.denominator).subtract(other.numerator.multiply(denominator)),
denominator.multiply(other.denominator)
);
}
public Fraction multiply(final Fraction other)
{
assert other != null;
return new Fraction(
numerator.multiply(other.numerator),
denominator.multiply(other.denominator)
);
}
public Fraction divide(final Fraction other)
{
assert other != null;
return new Fraction(
numerator.multiply(other.denominator),
denominator.multiply(other.numerator)
);
}
public double doubleValue()
{
final MathContext context = new MathContext(6, RoundingMode.HALF_UP);
return new BigDecimal(numerator).divide(new BigDecimal(denominator), context).doubleValue();
}
@Override public String toString()
{
return String.format("%s/%s", numerator, denominator);
}
@Override protected Fraction clone() throws CloneNotSupportedException
{
return this;
}
}
import java.util.Arrays;
public class Tester
{
public static void main(String[] args)
{
final Creature[] creatures = new Creature[] {
new Creature(6, true),
new Creature(1),
new Creature(2, true),
new Creature(2),
new Creature(8),
new Creature.Hero(25)
};
final int projectiles = 8;
final Fraction STARTING_CHANCE = Fraction.ONE;
final Fraction result = calculate(creatures, projectiles, STARTING_CHANCE);
System.out.printf("There is a %.5f%% chance of the marked creature(s) dying.\n", 100 * result.doubleValue());
System.out.printf("Precisely: %s\n", result);
}
public static Fraction calculate(final Creature[] creatures, final int projectiles, final Fraction chance)
{
assert creatures != null;
assert chance != null;
if (projectiles == 0) return Fraction.ZERO;
final int targets = (int)Arrays.stream(creatures).filter(e -> !e.isDead()).count();
final Fraction nextChance = chance.divide(new Fraction(targets));
Fraction successfulOutcomes = Fraction.ZERO;
for (int i = 0; i < creatures.length; i++)
{
if (creatures[i].isDead()) continue;
final Creature[] paralellDimension = Arrays.stream(creatures)
.map(e ->
{
try
{
return e.clone();
}
catch (CloneNotSupportedException e1)
{
e1.printStackTrace();
return null;
}
})
.toArray(size -> new Creature[size]);
paralellDimension[i].damage();
if (paralellDimension[i].isDead())
{
if (paralellDimension[i].isMarkedForDeath()
&& Arrays.stream(paralellDimension)
.filter(e -> e.isMarkedForDeath())
.allMatch(e -> e.isDead()))
{
successfulOutcomes = successfulOutcomes.add(nextChance);
continue;
}
if (paralellDimension[i] instanceof Creature.Hero) continue;
}
successfulOutcomes = successfulOutcomes.add(
calculate(paralellDimension, projectiles - 1, nextChance));
}
return successfulOutcomes;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment