I have code from two companies asoft and bsoft. I cannot change either. This is a simplified version of my situation which I'm pretty sure has enough information to the find what's causing the problem.
bsoft provides IGang
, which represents a gang that can battle other gangs.
package bsoft;
public interface IGang {
/** @return negative, 0, or positive, respectively
* if this gang is weaker than, equal to, or stronger
* than the other
*/
public int compareTo(IGang g);
public int getStrength();
public String getName();
public void attack(IGang g);
public void weaken(int amount);
}
asoft provides GangWar
, which allows IGang
s to battle:
package asoft;
import java.util.*;
import bsoft.*;
/** An `IGang` ordered by identity (name) */
public interface ComparableGang extends IGang, Comparable<IGang> {}
package asoft;
import java.util.*;
public class GangWar {
public final Set<ComparableGang> gangs = new TreeSet<ComparableGang>();
public void add(ComparableGang g) {gangs.add(g);}
public void doBattle() {
while (gangs.size() > 1) {
Iterator<ComparableGang> i = gangs.iterator();
ComparableGang g1 = i.next();
ComparableGang g2 = i.next();
System.out.println(g1.getName() + " attacks " + g2.getName());
g1.attack(g2);
if (g2.getStrength() == 0) {
System.out.println(g1.getName() + " smokes " + g2.getName());
gangs.remove(g2);
}
if (g1.getStrength() == 0) {
System.out.println(g2.getName() + " repels " + g1.getName());
gangs.remove(g1);
}
}
for (ComparableGang g : gangs) {
System.out.println(g.getName() + " now controls the turf!");
}
}
}
It requires the additional constraint that the Gang
s you supply to it are Comparable
, presumably so it can sort by name or avoid duplicates. Each gang (in an arbitrary order, Set order used here for simplicity) attacks another gang, until only one gang is left (or no gangs, if the last two have a tie). I've written a simple implementation of ComparableGang
to test it out:
import asoft.*;
import bsoft.*;
import java.util.*;
class Gang implements ComparableGang {
final String name;
int strength;
public Gang(String name, int strength) {
this.name = name;
this.strength = strength;
}
public String getName() {return name;}
public int getStrength() {return strength;}
public int compareTo(IGang g) {
return strength - g.getStrength();
}
public void weaken(int amount) {
if (strength < amount) strength = 0;
else strength -= amount;
}
public void attack(IGang g) {
int tmp = strength;
weaken(g.getStrength());
g.weaken(tmp);
}
public boolean equals(Object o) {
if (!(o instanceof IGang)) return false;
return name.equals(((IGang)o).getName());
}
}
class Main {
public static void main(String[] args) {
GangWar gw = new GangWar();
gw.add(new Gang("ballas", 2));
gw.add(new Gang("grove street", 9));
gw.add(new Gang("los santos", 8));
gw.add(new Gang("triads", 9));
gw.doBattle();
}
}
Testing it out...
$ java Main
ballas attacks los santos
los santos repels ballas
los santos attacks grove street
grove street repels los santos
grove street now controls the turf!
The problem is, triads do not show up to the fight. In fact, printing gangs.size()
right at the start of doBattle()
returns 3 instead of 4. Why? How to fix it?