Skip to content

Instantly share code, notes, and snippets.

@krisives
Created June 29, 2014 00:52
Show Gist options
  • Save krisives/b5872471d0f92d98c6ac to your computer and use it in GitHub Desktop.
Save krisives/b5872471d0f92d98c6ac to your computer and use it in GitHub Desktop.
public class Ability {
protected String name;
protected int level;
public Ability(String name) {
this.name = name;
}
public void levelUp() {
this.level++;
}
public static interface Critical {
public int adjustDamage(int damageDealt);
}
public static interface Stun {
public int adjustStun();
}
public static class Bash extends Ability implements Stun {
public Bash() {
super("Bash");
}
public int adjustStun() {
int dice = War3.RANDOM.nextInt(100);
int extra = 0;
if (dice > (10 + 5 * level)) {
// Miss stun
return 0;
}
if (level > 0) {
extra = War3.RANDOM.nextInt(level);
}
return 1 + extra;
}
}
public static class CriticalStrike extends Ability implements Critical {
public CriticalStrike() {
super("Critical Strike");
}
public int adjustDamage(int damageDealt) {
int dice = War3.RANDOM.nextInt(100);
if (dice > (10 + level * 5)) {
// Dice roll failed do normal damage
return damageDealt;
}
return (int)Math.round(damageDealt * (1.5 + 0.25 * level));
}
}
}
public class Archer extends Unit {
public Archer() {
this.armor = Armor.LIGHT;
this.weaponType = "pierce";
this.hp = 350;
this.minDamage = 8;
this.maxDamage = 13;
}
}
import java.util.HashMap;
import java.util.Map;
public class Armor {
private String name;
private Map<String, Double> factors;
public Armor(String name) {
this.name = name;
this.factors = new HashMap<>();
}
public double getFactor(String weaponType) {
if (factors.containsKey(weaponType)) {
return factors.get(weaponType);
}
// Default damage is 100%
return 1.0;
}
public void setFactor(String weaponType, double factor) {
factors.put(weaponType, factor);
}
public final static Armor LIGHT;
public final static Armor HEAVY;
public final static Armor MEDIUM;
public final static Armor UNARMORED;
public final static Armor FORTIFIED;
static {
LIGHT = new Armor("Light");
LIGHT.setFactor("normal", 0.90);
LIGHT.setFactor("pierce", 1.30);
LIGHT.setFactor("magic", 1.30);
LIGHT.setFactor("seige", 2.0);
HEAVY = new Armor("Heavy");
HEAVY.setFactor("normal", 0.90);
HEAVY.setFactor("pierce", 0.90);
HEAVY.setFactor("magic", 2.0);
HEAVY.setFactor("seige", 0.80);
MEDIUM = new Armor("Medium");
MEDIUM.setFactor("normal", 1.50);
MEDIUM.setFactor("pierce", 0.50);
MEDIUM.setFactor("magic", 0.70);
MEDIUM.setFactor("seige", 0.70);
UNARMORED = new Armor("Unarmored");
UNARMORED.setFactor("normal", 0.90);
UNARMORED.setFactor("pierce", 1.50);
UNARMORED.setFactor("magic", 1.50);
UNARMORED.setFactor("seige", 2.0);
FORTIFIED = new Armor("Fortified");
FORTIFIED.setFactor("normal", 0.70);
FORTIFIED.setFactor("pierce", 0.50);
FORTIFIED.setFactor("magic", 0.50);
FORTIFIED.setFactor("seige", 2.0);
}
}
public class Buff {
}
public class Grunt extends Unit {
public Grunt() {
this.armor = Armor.HEAVY;
this.weaponType = "normal";
this.hp = 700;
this.minDamage = 7;
this.maxDamage = 12;
}
public static class Berzerk extends Upgrade {
// TODO implement absurd +100 making tier 1
// unit 800 fucking HP
}
}
public class Item {
private String name;
public Item(String name) {
this.name = name;
}
public static interface LifeSteal {
public int leech(int damageDealt);
}
public static interface AddDamage {
public int adjustDamage(int damage);
}
public static class LifeStealItem extends Item implements LifeSteal {
protected double leechPercent;
public LifeStealItem(String name, double percent) {
super(name);
this.leechPercent = percent;
}
public int leech(int damageDealt) {
return (int)Math.round(damageDealt * leechPercent);
}
}
public static class MaskOfDeath extends LifeStealItem {
public MaskOfDeath() {
super("Mask of Death", 0.50);
}
}
public static class BoneChimes extends LifeStealItem {
public BoneChimes() {
super("Scourge Bone Chimes", 0.15);
}
}
public static class ClawsOfAttack extends Item implements AddDamage {
public ClawsOfAttack() {
super("Claws of Attack");
}
public int adjustDamage(int damage) {
return damage + 6;
}
}
}
import java.util.ArrayList;
import java.util.List;
public class Unit {
protected int x, y;
protected int hp;
protected int minDamage, maxDamage;
protected Armor armor;
protected String weaponType;
protected List<Item> inventory;
protected List<Buff> buffs;
protected List<Ability> skills;
protected int stun;
public Unit() {
this.inventory = new ArrayList<>();
this.buffs = new ArrayList<>();
this.skills = new ArrayList<>();
}
public void learn(Ability ability) {
skills.add(ability);
}
public boolean isStunned() {
return stun > 0;
}
public int getHP() {
return hp;
}
public boolean isAlive() {
return hp > 0;
}
public int attack(Unit another) {
double f;
int damageDealt;
if (isStunned()) {
this.stun--;
return 0;
}
f = another.armor.getFactor(weaponType);
damageDealt = (int)(rollDamage() * f);
// Apply add damage from items, etc.
damageDealt = adjustDamage(damageDealt);
// Apply life steal
this.hp += stealLife(damageDealt);
// Deal the damage
another.hp -= damageDealt;
// Stun the target that was just hit
stunTarget(another);
return damageDealt;
}
public void stunTarget(Unit target) {
Ability.Stun stunner;
int stunAdded = 0;
for (Ability ability : skills) {
if (ability instanceof Ability.Stun) {
stunner = (Ability.Stun)ability;
stunAdded += stunner.adjustStun();
}
}
if (stunAdded > 0) {
target.stun += stunAdded;
System.out.printf("Stunned! (%d)\n", stunAdded);
}
}
public int stealLife(int damage) {
Item.LifeSteal itemWithLeech;
int hpLeeched = 0;
// Go through all the items adding damage
for (Item item : inventory) {
if (item instanceof Item.LifeSteal) {
itemWithLeech = (Item.LifeSteal)item;
hpLeeched += itemWithLeech.leech(damage);
}
}
if (hpLeeched > 0) {
System.out.printf("Leeched +%d (%d)\n", hpLeeched, hp);
}
return hpLeeched;
}
public int adjustDamage(int damage) {
Item.AddDamage itemWithAdd;
// Go through all the items adding damage
for (Item item : inventory) {
if (item instanceof Item.AddDamage) {
itemWithAdd = (Item.AddDamage)item;
// Let the item adjust the damage
damage = itemWithAdd.adjustDamage(damage);
}
}
return damage;
}
/**
* Roll damage between min and max
* @return the damage
*/
protected int rollDamage() {
int span = maxDamage - minDamage;
double percent = War3.RANDOM.nextDouble();
double damage = minDamage + span * percent;
return (int)Math.round(damage);
}
public void equipItem(Item item) {
inventory.add(item);
}
}
public class Upgrade {
}
import java.util.Random;
public class War3 {
public static Random RANDOM = new Random(0xBADBEEF);
public static void main(String[] args) {
Random roller = new Random(0x1234568);
int attempts = 0;
while (!test(roller.nextLong())) {
attempts++;
if ((attempts % 1000) == 0) {
// Every 1000 attempts show progress
System.out.printf("%d attempts\n", attempts);
}
}
}
private static Item mask = new Item.MaskOfDeath();
private static Item claws = new Item.ClawsOfAttack();
private static Item boneChimes = new Item.BoneChimes();
private static Ability bash = new Ability.Bash();
static {
bash.levelUp();
bash.levelUp();
}
public static boolean test(long seed) {
Unit grunt = new Grunt();
Unit archer = new Archer();
int dice;
int combatRounds = 0;
//grunt.equipItem(mask);
//archer.equipItem(claws);
//archer.equipItem(claws);
archer.learn(bash);
///System.out.println("Fight!");
while (grunt.isAlive() && archer.isAlive()) {
combatRounds++;
// Roll a six sided die
dice = 1 + RANDOM.nextInt(5);
if (dice <= 3) {
// 1, 2, 3
System.out.printf("Grunt hits Archer for %d\n", grunt.attack(archer));
System.out.printf("Archer hits Grunt for %d\n", archer.attack(grunt));
//grunt.attack(archer);
//archer.attack(grunt);
} else {
// 4, 5, 6
System.out.printf("Archer hits Grunt for %d\n", archer.attack(grunt));
System.out.printf("Grunt hits Archer for %d\n", grunt.attack(archer));
//archer.attack(grunt);
//grunt.attack(archer);
}
}
System.out.printf("Fight was %d rounds (%d)\n", combatRounds, grunt.getHP());
if (grunt.isAlive()) {
System.out.printf("Grunt wins (%d)!\n", grunt.getHP());
}
if (archer.isAlive()) {
System.out.printf("Archer wins (%d)!\n", archer.getHP());
return true;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment