Skip to content

Commit d98dbea

Browse files
committed
upload original code
0 parents  commit d98dbea

11 files changed

+558
-0
lines changed

ActionPointDecider.java

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package clanmelee;
2+
3+
/**
4+
* Classes that implement ActionPointDecider can be used to define a ClanMember's strategy
5+
*/
6+
public interface ActionPointDecider {
7+
/**
8+
*
9+
* @param me the ClanMember doing the deciding
10+
* @param other the ClanMember that me is engaging with
11+
* @return the number of points to attack or heal with. 0 to run away.
12+
*/
13+
public int decideActionPoints(ClanMember me, ClanMember other);
14+
}

Clan.java

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package clanmelee;
2+
3+
import java.util.Collection;
4+
5+
/**
6+
* A factory that produces ClanMember objects for one particular clan
7+
*/
8+
public abstract class Clan {
9+
private final String clanName;
10+
private final int clanID;
11+
12+
/**
13+
* Constructor
14+
*
15+
* @param clanName name of the clan
16+
* @param clanID the clan's unique ID
17+
*/
18+
public Clan(String clanName, int clanID) {
19+
this.clanName = clanName;
20+
this.clanID = clanID;
21+
}
22+
23+
/**
24+
* get the ID passed to the constructor
25+
*/
26+
public int getClanID() {
27+
return clanID;
28+
}
29+
30+
/**
31+
* get the name passed to the constructor
32+
*/
33+
public String getClanName() {
34+
return clanName;
35+
}
36+
37+
/**
38+
* Concrete clans implement this factory method to produce clan members
39+
*
40+
* @param hitPoints the number of hit points to be distributed amongst all the clan members
41+
* @return the clan's members
42+
*/
43+
public abstract Collection<ClanMember> getClanMembers(int hitPoints);
44+
}

ClanFactory.java

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package clanmelee;
2+
3+
import clanmelee.Clan1.Clan1;
4+
import clanmelee.Clan2.Clan2;
5+
6+
import java.util.ArrayList;
7+
import java.util.Collection;
8+
9+
public class ClanFactory {
10+
public Collection<Clan> getClans() {
11+
ArrayList<Clan> clans = new ArrayList<>();
12+
13+
int clanID = 0;
14+
15+
clans.add(new Clan1(clanID++));
16+
clans.add(new Clan2(clanID++));
17+
18+
19+
return clans;
20+
}
21+
}

ClanMelee.java

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
2+
package clanmelee;
3+
4+
import static clanmelee.ClanMember.ClanMemberType.HEALER;
5+
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
import java.util.Collection;
9+
import java.util.Collections;
10+
11+
public class ClanMelee {
12+
ClansWins clansWins = new ClansWins();
13+
14+
public void runMelee(Collection<Clan> clans, int hitPoints) {
15+
ArrayList<ClanMember> participants = new ArrayList<>();
16+
int totalClanCount = clans.size();
17+
String[] clanNames = new String[totalClanCount];
18+
ClanStats clanStats = new ClanStats(totalClanCount);
19+
20+
for (Clan clan : clans) {
21+
int clanID = clan.getClanID();
22+
String clanName = clan.getClanName();
23+
if (clansWins.clanCount() < clans.size())
24+
clansWins.addClan(clanID, clanName);
25+
Collection<ClanMember> members = clan.getClanMembers(hitPoints);
26+
if (!validateClan(members, hitPoints, clanID, clan.getClanName()))
27+
continue;
28+
clanNames[clanID] = clan.getClanName();
29+
participants.addAll(members);
30+
for (ClanMember member : members)
31+
clanStats.addPlayer(member);
32+
}
33+
34+
35+
int clanCount = totalClanCount;
36+
37+
boolean[] previouslyAlive = new boolean[totalClanCount];
38+
Arrays.fill(previouslyAlive, true);
39+
int roundCount = 0;
40+
41+
while (clanCount > 1) {
42+
Collections.shuffle(participants);
43+
clanStats = new ClanStats(totalClanCount);
44+
boolean[] currentlyAlive = new boolean[totalClanCount];
45+
Arrays.fill(currentlyAlive, false);
46+
ArrayList<ClanMember> remaining = new ArrayList<>(participants.size());
47+
for (int i = 0; i < participants.size() - 1; i += 2) {
48+
ClanMember p1 = participants.get(i);
49+
ClanMember p2 = participants.get(i + 1);
50+
51+
runInteraction(p1, p2);
52+
53+
if (p1.isAlive()) {
54+
clanStats.addPlayer(p1);
55+
currentlyAlive[p1.getClanID()] = true;
56+
remaining.add(p1);
57+
}
58+
if (p2.isAlive()) {
59+
clanStats.addPlayer(p2);
60+
currentlyAlive[p2.getClanID()] = true;
61+
remaining.add(p2);
62+
}
63+
}
64+
65+
if (participants.size() % 2 == 1) {
66+
ClanMember lastPlayer = participants.get(participants.size() - 1);
67+
int lastID = lastPlayer.getClanID();
68+
lastPlayer.dealIterationDamage(0);
69+
if (lastPlayer.isAlive()) {
70+
clanStats.addPlayer(lastPlayer);
71+
currentlyAlive[lastID] = true;
72+
remaining.add(lastPlayer);
73+
}
74+
}
75+
76+
clanCount = clanStats.getClanCount();
77+
78+
roundCount += 1;
79+
80+
for (int i = 0; i < totalClanCount; i++) {
81+
if (!currentlyAlive[i] && previouslyAlive[i]) {
82+
if (clanNames[i] == null)
83+
continue;
84+
System.out.println(clanNames[i] + " eliminated after " +
85+
roundCount + " interactions");
86+
}
87+
}
88+
89+
previouslyAlive = currentlyAlive;
90+
91+
participants = remaining;
92+
}
93+
94+
if (clanCount == 0) {
95+
System.out.println("All were slain after " + roundCount
96+
+ " interactions!");
97+
} else {
98+
int victorID = clanStats.getWinner();
99+
System.out.println(clanNames[victorID] + " emerged victorious after " +
100+
roundCount + " interactions!");
101+
clansWins.addWin(victorID);
102+
}
103+
}
104+
105+
private void runInteraction(ClanMember p1, ClanMember p2) {
106+
int p1Action = p1.getActionPoints(p2);
107+
int p2Action = p2.getActionPoints(p1);
108+
109+
applyAction(p1, p1Action, p2, p2Action);
110+
applyAction(p2, p2Action, p1, p1Action);
111+
}
112+
113+
private void applyAction(ClanMember p1, int p1Action,
114+
ClanMember p2, int p2Action) {
115+
if (p1.getType() == HEALER)
116+
p2.heal(p1Action);
117+
else {
118+
if (p2Action > 0 || Math.random() < 0.5)
119+
p2.dealDamage(p1Action);
120+
}
121+
}
122+
123+
void printStats() {
124+
clansWins.print();
125+
}
126+
127+
private boolean validateClan(Collection<ClanMember> members, int hitPoints,
128+
int clanID, String clanName) {
129+
int hitPointSum = 0;
130+
for (ClanMember cm : members) {
131+
if (cm.getClanID() != clanID) {
132+
System.out.println(clanName + " does not have consistent clan IDs!!");
133+
System.out.println(clanName + " DISQUALIFIED!!");
134+
return false;
135+
}
136+
hitPointSum += cm.getMaxHitPoints();
137+
}
138+
if (hitPointSum > hitPoints) {
139+
System.out.println(clanName + " has " + hitPointSum +
140+
" hit points when only " + hitPoints + " are allowed!!");
141+
System.out.println(clanName + " DISQUALIFIED!!");
142+
return false;
143+
}
144+
return true;
145+
}
146+
}
147+

ClanMeleeConstants.java

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package clanmelee;
2+
3+
public class ClanMeleeConstants {
4+
// maximum possible hit points
5+
public static final int HIT_POINT_CAP = 1000;
6+
// number of action points that do not cost additional iteration damage
7+
public static final int FREE_ACTION_POINTS = 10;
8+
// number of extra action points which cost a single iteration damage point
9+
public static final int ACTION_POINTS_PER_ITERATION_DAMAGE_POINT = 2;
10+
11+
private ClanMeleeConstants() {
12+
}
13+
}

ClanMember.java

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package clanmelee;
2+
3+
import static clanmelee.ClanMeleeConstants.*;
4+
5+
/**
6+
* All clan members are of this class. Each clan member's strategy is defined
7+
* by its ActionPointDecider
8+
*/
9+
public class ClanMember {
10+
// Each clan member must be either a warrior or a healer
11+
public enum ClanMemberType {WARRIOR, HEALER};
12+
13+
private final int clanID;
14+
private final ClanMemberType type;
15+
16+
// Each clan mamber starts off with hitPoints == maxHitPoints. Attack
17+
// damage decreases hitPoints. Iteration damage decreases both hitPoints
18+
// and maxHitPoints.
19+
private int maxHitPoints;
20+
private int hitPoints;
21+
22+
// The decider decides whether to act or to run away, and how many points
23+
// to attack or heal with.
24+
private ActionPointDecider decider;
25+
26+
/**
27+
* Constructor
28+
*
29+
* @param clanID the member's clan's unique clan ID
30+
* @param type ClanMemberType.WARRIOR or ClanMemberType.HEALER
31+
* @param hitPoints initial number of hit points
32+
* @param decider implements the clan member's strategy
33+
*/
34+
public ClanMember(int clanID, ClanMemberType type, int hitPoints,
35+
ActionPointDecider decider) {
36+
this.clanID = clanID;
37+
this.type = type;
38+
this.decider = decider;
39+
40+
// Respect the limit on an individual clan member's hit points
41+
if (hitPoints > HIT_POINT_CAP)
42+
this.maxHitPoints = HIT_POINT_CAP;
43+
else
44+
this.maxHitPoints = hitPoints;
45+
46+
this.hitPoints = this.maxHitPoints;
47+
}
48+
49+
/** Get the clan ID passed to the constructor */
50+
public int getClanID() {
51+
return clanID;
52+
}
53+
54+
/** Get the clan member type passed to the contructor */
55+
public ClanMemberType getType() {
56+
return type;
57+
}
58+
59+
/** Get the clan member's current number of hit points */
60+
public int getHitPoints() {
61+
return hitPoints;
62+
}
63+
64+
/** Get the clan member's maximum number of hit points */
65+
public int getMaxHitPoints() {
66+
return maxHitPoints;
67+
}
68+
69+
/**
70+
* Public way to get action points. Ensures no more than the max allowed
71+
* action points are returned.
72+
*
73+
* @param other the clan member that this clan member is up against
74+
* @return the number of points to attack or heal with. 0 to run away.
75+
*/
76+
public int getActionPoints(ClanMember other) { // Don't call this
77+
int actionPoints = decider.decideActionPoints(this, other);
78+
79+
// the most action points this clan member can afford in hit points
80+
int maxActionPoints = hitPoints * ACTION_POINTS_PER_ITERATION_DAMAGE_POINT
81+
+ FREE_ACTION_POINTS;
82+
83+
if (actionPoints > maxActionPoints)
84+
actionPoints = maxActionPoints;
85+
86+
dealIterationDamage(actionPoints);
87+
88+
return actionPoints;
89+
}
90+
91+
/**
92+
* Self-inflict the action point damage and decrease max hit points by 1
93+
*
94+
* @param actionPoints number of action points dealt this iteration
95+
*/
96+
public void dealIterationDamage(int actionPoints) {
97+
if (actionPoints > FREE_ACTION_POINTS) {
98+
int damage = (actionPoints - FREE_ACTION_POINTS - 1)
99+
/ ACTION_POINTS_PER_ITERATION_DAMAGE_POINT + 1;
100+
dealDamage(damage);
101+
}
102+
103+
maxHitPoints -= 1;
104+
if (hitPoints > maxHitPoints)
105+
hitPoints = maxHitPoints;
106+
}
107+
108+
/**
109+
* Heal the clan member by a certain number of points. The clan member's
110+
* hit points will not exceed the maximum hit point limit
111+
*
112+
* @param healPoints number of points to heal by
113+
*/
114+
public void heal(int healPoints) {
115+
hitPoints += healPoints;
116+
if (hitPoints > maxHitPoints)
117+
hitPoints = maxHitPoints;
118+
}
119+
120+
/**
121+
* Decrease the clan member's hit points by a certain number of points. Will
122+
* not decrease the number of hit points below 0
123+
*
124+
* @param damagePoints number of points of damage
125+
*/
126+
public void dealDamage(int damagePoints) {
127+
hitPoints -= damagePoints;
128+
if (hitPoints < 0)
129+
hitPoints = 0;
130+
}
131+
132+
/**
133+
* @return true if the clan member has more than 0 hit points, false otherwise
134+
*/
135+
public boolean isAlive() {
136+
return hitPoints != 0;
137+
}
138+
}

0 commit comments

Comments
 (0)