Skip to content

Commit 2a43311

Browse files
authored
Zombies run at a higher speed (#27)
1 parent 16311cd commit 2a43311

7 files changed

Lines changed: 84 additions & 29 deletions

File tree

src/main/java/il/co/codeguru/corewars8086/cli/Options.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class Options extends OptionsBase {
2020
name = "comboSize",
2121
abbrev = 'c',
2222
help = "The size of each group combination",
23-
category = "Headless",
23+
category = "Gameplay",
2424
defaultValue = "4"
2525
)
2626
public int combinationSize;
@@ -29,7 +29,7 @@ public class Options extends OptionsBase {
2929
name = "battlesPerCombo",
3030
abbrev = 'b',
3131
help = "Battles per group combination",
32-
category = "Headless",
32+
category = "Gameplay",
3333
defaultValue = "100"
3434
)
3535
public int battlesPerCombo;
@@ -38,16 +38,24 @@ public class Options extends OptionsBase {
3838
name = "seed",
3939
abbrev = 's',
4040
help = "Starting seed for the game",
41-
category = "Headless",
41+
category = "Gameplay",
4242
defaultValue = "guru"
4343
)
4444
public String seed;
45+
46+
@Option(
47+
name = "zombieSpeed",
48+
help = "Number of turns zombies play per round",
49+
category = "Gameplay",
50+
defaultValue = "5"
51+
)
52+
public int zombieSpeed;
4553

4654
@Option(
4755
name = "parallel",
4856
abbrev = 'p',
4957
help = "Run multiple battles concurrently - cancel for (pre-)cgx2022 result emulation",
50-
category = "Headless",
58+
category = "Concurrency",
5159
defaultValue = "true"
5260
)
5361
public boolean parallel;
@@ -56,7 +64,7 @@ public class Options extends OptionsBase {
5664
name = "threads",
5765
abbrev = 't',
5866
help = "Number of threads for parallel mode",
59-
category = "Headless",
67+
category = "Concurrency",
6068
defaultValue = "4"
6169
)
6270
public int threads;

src/main/java/il/co/codeguru/corewars8086/war/Competition.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public int getTotalNumberOfWars() {
114114
}
115115

116116
public void runWar(WarriorGroup[] warriorGroups,boolean startPaused) throws Exception {
117-
currentWar = new War(memoryEventListener, competitionEventListener, startPaused);
117+
currentWar = new War(memoryEventListener, competitionEventListener, startPaused, options);
118118
currentWar.setSeed(this.seed);
119119
competitionEventListener.onWarStart(seed);
120120
currentWar.loadWarriorGroups(warriorGroups);
@@ -171,7 +171,7 @@ public void runWar(WarriorGroup[] warriorGroups,boolean startPaused) throws Exce
171171
}
172172

173173
public void runWarInParallel(WarriorGroup[] warriorGroups, long seed, int id) throws Exception {
174-
War war = new War(memoryEventListener, competitionEventListener, false);
174+
War war = new War(memoryEventListener, competitionEventListener, false, options);
175175
war.setSeed(seed);
176176
boolean selectedAsCurrent = false;
177177

src/main/java/il/co/codeguru/corewars8086/war/War.java

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package il.co.codeguru.corewars8086.war;
22

3+
import il.co.codeguru.corewars8086.cli.Options;
34
import il.co.codeguru.corewars8086.cpu.CpuException;
45
import il.co.codeguru.corewars8086.memory.MemoryEventListener;
56
import il.co.codeguru.corewars8086.memory.MemoryException;
@@ -56,11 +57,17 @@ public class War {
5657
/** The listener for war events */
5758
private CompetitionEventListener m_warListener;
5859

60+
private final Options options;
61+
5962
/**
6063
* Constructor.
6164
* Fills the Arena with its initial data.
6265
*/
63-
public War(MemoryEventListener memoryListener, CompetitionEventListener warListener, boolean startPaused) {
66+
public War(MemoryEventListener memoryListener,
67+
CompetitionEventListener warListener,
68+
boolean startPaused,
69+
Options options) {
70+
this.options = options;
6471
isPaused = startPaused;
6572
m_warListener = warListener;
6673
m_warriors = new Warrior[MAX_WARRIORS];
@@ -114,10 +121,19 @@ public void nextRound(int round) {
114121
// run first opcode
115122
warrior.nextOpcode();
116123

117-
// run one extra opcode, if warrior deserves it :)
118-
updateWarriorEnergy(warrior, round);
119-
if (shouldRunExtraOpcode(warrior)) {
120-
warrior.nextOpcode();
124+
if (warrior.isZombie()) {
125+
// Zombie H runs at double speed
126+
int remainingRounds =
127+
(options.zombieSpeed * ((warrior.getType() == WarriorType.ZOMBIE_H) ? 2 : 1)) - 1;
128+
129+
for (int j = 0; j < remainingRounds; j++) {
130+
warrior.nextOpcode();
131+
}
132+
} else { // run one extra opcode, if warrior deserves it :)
133+
updateWarriorEnergy(warrior, round);
134+
if (shouldRunExtraOpcode(warrior)) {
135+
warrior.nextOpcode();
136+
}
121137
}
122138
} catch (CpuException e) {
123139
m_warListener.onWarriorDeath(warrior.getName(), "CPU exception");
@@ -230,7 +246,9 @@ private void loadWarriorGroup(WarriorGroup warriorGroup) throws Exception {
230246
loadAddress,
231247
initialStack,
232248
groupSharedMemory,
233-
GROUP_SHARED_MEMORY_SIZE);
249+
GROUP_SHARED_MEMORY_SIZE,
250+
warrior.getType()
251+
);
234252

235253
// load warrior to arena
236254
for (int offset = 0; offset < warriorData.length; ++offset) {

src/main/java/il/co/codeguru/corewars8086/war/Warrior.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ public Warrior(
3535
RealModeAddress loadAddress,
3636
RealModeAddress initialStack,
3737
RealModeAddress groupSharedMemory,
38-
short groupSharedMemorySize) {
38+
short groupSharedMemorySize,
39+
WarriorType type) {
3940

41+
this.type = type;
4042
m_name = name;
4143
m_codeSize = codeSize;
4244
m_loadAddress = loadAddress;
@@ -96,7 +98,15 @@ public boolean isAlive() {
9698
*/
9799
public void kill() {
98100
m_isAlive = false;
99-
}
101+
}
102+
103+
public boolean isZombie() {
104+
return type == WarriorType.ZOMBIE || type == WarriorType.ZOMBIE_H;
105+
}
106+
107+
public WarriorType getType() {
108+
return type;
109+
}
100110

101111
/**
102112
* @return the warrior's name.
@@ -201,4 +211,6 @@ public CpuState getCpuState(){
201211
private Cpu m_cpu;
202212
/** Whether or not the warrior is still alive */
203213
private boolean m_isAlive;
214+
215+
private final WarriorType type;
204216
}

src/main/java/il/co/codeguru/corewars8086/war/WarriorData.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ public class WarriorData {
1111
* Constructor.
1212
* @param name Warrior's name.
1313
* @param code Warrior's code.
14+
* @param type Warrior's type (
1415
*/
15-
public WarriorData(String name, byte[] code) {
16+
public WarriorData(String name, byte[] code, WarriorType type) {
1617
m_name = name;
17-
m_code = code;
18+
m_code = code;
19+
this.type = type;
1820
}
1921

2022
/** @return the warrior's name. */
@@ -27,12 +29,18 @@ public byte[] getCode() {
2729
return m_code;
2830
}
2931

32+
public WarriorType getType() {
33+
return type;
34+
}
35+
3036
/** Holds warrior's name */
3137
private final String m_name;
3238

3339
/** Holds warrior's code */
3440
private final byte[] m_code;
3541

42+
private final WarriorType type;
43+
3644

3745
@Override
3846
public String toString() {

src/main/java/il/co/codeguru/corewars8086/war/WarriorRepository.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void readZombiesFileFromPath(String path) throws IOException {
9292
continue;
9393
}
9494

95-
WarriorData data = readWarriorFile(file);
95+
WarriorData data = readWarriorFile(file, WarriorType.ZOMBIE);
9696
zombieGroup.addWarrior(data);
9797
}
9898
}
@@ -105,8 +105,7 @@ public void readWarriorsFileFromPath(String path) throws IOException {
105105
File[] warriorFiles = warriorsDirectory.listFiles();
106106
if (warriorFiles == null) {
107107
JOptionPane.showMessageDialog(null,
108-
"Error - survivors directory (\"" +
109-
options.warriorsDir + "\") not found");
108+
"Error - survivors directory (\"" + path + "\") not found");
110109
System.exit(1);
111110
}
112111

@@ -120,20 +119,20 @@ public void readWarriorsFileFromPath(String path) throws IOException {
120119
}
121120

122121
String name = file.getName();
123-
WarriorData data = readWarriorFile(file);
122+
124123
if (name.endsWith("1")) {
125124
// start a new group!
126125
currentGroup = new WarriorGroup(name.substring(0, name.length() - 1));
127-
currentGroup.addWarrior(data);
126+
currentGroup.addWarrior(readWarriorFile(file, WarriorType.SURVIVOR_1));
128127
warriorNameToGroup.put(name, warriorGroups.size());
129128
} else if (name.endsWith("2")) {
130-
currentGroup.addWarrior(data);
129+
currentGroup.addWarrior(readWarriorFile(file, WarriorType.SURVIVOR_2));
131130
warriorNameToGroup.put(name, warriorGroups.size());
132131
warriorGroups.add(currentGroup);
133132
currentGroup = null;
134133
} else {
135134
currentGroup = new WarriorGroup(name);
136-
currentGroup.addWarrior(data);
135+
currentGroup.addWarrior(readWarriorFile(file, WarriorType.SURVIVOR));
137136
warriorNameToGroup.put(name, warriorGroups.size());
138137
warriorGroups.add(currentGroup);
139138
currentGroup = null;
@@ -161,24 +160,29 @@ private void fixFiles(File warriorsDirectory) {
161160
}
162161
}
163162

164-
private static WarriorData readWarriorFile(File filename) throws IOException {
165-
String warriorName = filename.getName();
163+
private static WarriorData readWarriorFile(File file, WarriorType type) throws IOException {
164+
String warriorName = file.getName();
166165

167-
int warriorSize = (int) filename.length();
166+
int warriorSize = (int) file.length();
168167
if (warriorSize > MAX_WARRIOR_SIZE) {
169168
warriorSize = MAX_WARRIOR_SIZE;
170169
}
171170

172171
byte[] warriorData = new byte[warriorSize];
173-
FileInputStream fis = new FileInputStream(filename);
172+
FileInputStream fis = new FileInputStream(file);
174173
int size = fis.read(warriorData);
175174
fis.close();
176175

177176
if (size != warriorSize) {
178177
throw new IOException();
179178
}
180179

181-
return new WarriorData(warriorName, warriorData);
180+
// Zombie H - runs at double speed
181+
if (type == WarriorType.ZOMBIE && warriorName.toLowerCase().endsWith("h")) {
182+
type = WarriorType.ZOMBIE_H;
183+
}
184+
185+
return new WarriorData(warriorName, warriorData, type);
182186
}
183187

184188
/**
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package il.co.codeguru.corewars8086.war;
2+
3+
public enum WarriorType {
4+
SURVIVOR, SURVIVOR_1, SURVIVOR_2, ZOMBIE, ZOMBIE_H
5+
}

0 commit comments

Comments
 (0)