Skip to content

Commit 5da25f4

Browse files
committed
structure written. Efficiency required
1 parent ceb6456 commit 5da25f4

File tree

1 file changed

+80
-54
lines changed

1 file changed

+80
-54
lines changed

src/main/java/main/java/codingame/code4life/Medicine.java

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public static void main(String args[]) {
2121
for (int i = 0; i < sampleCount; i++) {
2222
final Sample sample = getSample(in);
2323
if (sample.material.cost[1] >= 0) {
24-
sample.makeVisible();
24+
sample.makeVisible(null);
2525
}
2626
if (sample.material.carriedBy == 0) {
2727
myBot.samples.put(sample.material.sampleId, sample);
@@ -35,7 +35,7 @@ public static void main(String args[]) {
3535
if (myBot.eta > 0) {
3636
System.out.println(Action.GOTO.name() + " " + myBot.target);
3737
} else if (!myBot.target.equals(Position.START_POS)) {
38-
System.out.println(new MCTS().findBestMove(new GameState(0, new Robot[]{myBot, opponentBot}, available, projects, samples), rounds));
38+
System.out.println(new MCTS().findBestMove(new GameState(0, new Robot[]{myBot, opponentBot}, available, projects, samples, rounds)));
3939
} else {
4040
System.out.println(Action.GOTO.name() + " " + Position.SAMPLES.name());
4141
}
@@ -45,7 +45,7 @@ public static void main(String args[]) {
4545
private static Sample getSample(Scanner in) {
4646
final int sampleId = in.nextInt();
4747
final int carriedBy = in.nextInt();
48-
final int rank = in.nextInt();
48+
final int rank = in.nextInt() - 1;
4949
final String expertiseGain = in.next();
5050
final int health = in.nextInt();
5151
final int cost[] = new int[]{in.nextInt(), in.nextInt(), in.nextInt(), in.nextInt(), in.nextInt()};
@@ -63,10 +63,10 @@ private static Robot getRobot(Scanner in) {
6363
}
6464

6565
class MCTS {
66-
public static long MAX_COMPUTATIONS = 100;
66+
public static long MAX_COMPUTATIONS = 2;
6767

68-
public String findBestMove(final GameState gameState, final int rounds) {
69-
final Node root = new Node(rounds, null, null, gameState);
68+
public String findBestMove(final GameState gameState) {
69+
final Node root = new Node(gameState.rounds, null, null, gameState);
7070
for (int i = 0; i < MAX_COMPUTATIONS; i++) {
7171
Node current = root;
7272
Node next = current.getNextChild();
@@ -76,22 +76,18 @@ public String findBestMove(final GameState gameState, final int rounds) {
7676
}
7777
current.expand();
7878
for (final Node child : current.children) {
79-
for (int simulate = 0; simulate < 20; simulate++) {
79+
for (int simulate = 0; simulate < 2; simulate++) {
8080
current.propagate(child.simulation());
8181
}
82+
System.err.println("ITERATION: PROPAGATED CHILD " + child + " TO PARENT: " + current);
8283
}
8384
}
84-
// return root.getRobustChild().getMove();
85-
return "GOTO SAMPLES";
85+
return root.getRobustChild().getMove();
8686
}
8787

88-
public static double evaluate(final GameState gameState, final int rounds) {
89-
// final Robot first = gameState.robots[0], second = gameState.robots[1];
90-
// return (first.score - second.score)
91-
// + (1 - (rounds / 400.0)) * ((first.totalExpertise - second.totalExpertise)
92-
// + 0.1 * (first.totalMolecules - second.totalMolecules));
88+
public static double evaluate(final GameState gameState) {
9389
final Robot first = gameState.robots[gameState.player];
94-
return first.score + (1 - (rounds / 400.0)) * (first.totalExpertise + 0.1 * first.totalMolecules);
90+
return first.score + (1 - gameState.rounds / 400.0) * (first.totalExpertise + 0.1 * first.totalMolecules);
9591
}
9692

9793
public static int flip(final int player) {
@@ -109,7 +105,7 @@ class Node {
109105
List<Node> children;
110106
private static final Random random = new Random();
111107

112-
Node(final int roundsTillNow, final Node parent, final String moveToGetHere, final GameState gameState) {
108+
public Node(final int roundsTillNow, final Node parent, final String moveToGetHere, final GameState gameState) {
113109
this.roundsTillNow = roundsTillNow;
114110
this.parent = parent;
115111
this.moveToGetHere = moveToGetHere;
@@ -139,7 +135,7 @@ public void propagate(final double score) {
139135
}
140136

141137
public void expand() {
142-
children = getPossibleMoves(gameState, roundsTillNow)
138+
children = getPossibleMoves(gameState)
143139
.entrySet()
144140
.stream()
145141
.map(entry -> new Node(roundsTillNow + 2, this, entry.getValue(), entry.getKey()))
@@ -152,9 +148,9 @@ public double simulation() {
152148
} else {
153149
double score = 0;
154150
GameState currentState = gameState;
155-
int roundsTillNow = this.roundsTillNow;
156-
while (roundsTillNow < 400) {
157-
final Map<GameState, String> possibleMoves = getPossibleMoves(currentState, roundsTillNow);
151+
int rounds = 0;
152+
while (rounds < 8 && roundsTillNow + rounds < 400) {
153+
final Map<GameState, String> possibleMoves = getPossibleMoves(currentState);
158154
int count = 0;
159155
int index = random.nextInt(possibleMoves.size());
160156
for (final GameState possible : possibleMoves.keySet()) {
@@ -164,9 +160,9 @@ public double simulation() {
164160
}
165161
count++;
166162
}
167-
roundsTillNow += 2;
163+
rounds += 2;
168164
}
169-
totalScore += MCTS.evaluate(currentState, 400);
165+
totalScore += MCTS.evaluate(currentState);
170166
plays++;
171167
return score;
172168
}
@@ -177,8 +173,8 @@ public String getMove() {
177173
}
178174

179175

180-
private Map<GameState, String> getPossibleMoves(final GameState gameState, final int rounds) {
181-
if (rounds == 400) {
176+
private Map<GameState, String> getPossibleMoves(final GameState gameState) {
177+
if (gameState.rounds == 400) {
182178
return Collections.singletonMap(gameState, Action.GOTO.name() + " " + Position.SAMPLES.name());
183179
}
184180
final Robot currentBot = gameState.robots[gameState.player];
@@ -202,14 +198,22 @@ private Map<GameState, String> getPossibleMoves(final GameState gameState, final
202198
if (currentBot.canMakeMedicine()) {
203199
gameStates.put(gameState.play(Position.LABORATORY), Action.GOTO.name() + " " + Position.LABORATORY.name());
204200
}
205-
gameStates.put(gameState.play(Position.MOLECULES), Action.GOTO.name() + " " + Position.MOLECULES.name());
206-
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
201+
if (currentBot.totalMolecules < 10) {
202+
gameStates.put(gameState.play(Position.MOLECULES), Action.GOTO.name() + " " + Position.MOLECULES.name());
203+
}
204+
if (currentBot.samples.size() < 3) {
205+
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
206+
}
207207
for (final Integer id : currentBot.samples.keySet()) {
208-
gameStates.put(gameState.play(id), Action.CONNECT.name() + " " + id);
208+
if (!currentBot.samples.get(id).isVisible() || !currentBot.isAdequate(currentBot.samples.get(id))) {
209+
gameStates.put(gameState.play(id), Action.CONNECT.name() + " " + id);
210+
}
209211
}
210212
if (currentBot.samples.size() < 3) {
211213
for (final Integer id : gameState.samples.keySet()) {
212-
gameStates.put(gameState.play(id), Action.CONNECT.name() + " " + id);
214+
if (currentBot.isPossible(gameState.samples.get(id), gameState.availableMolecules)) {
215+
gameStates.put(gameState.play(id), Action.CONNECT.name() + " " + id);
216+
}
213217
}
214218
}
215219
break;
@@ -223,11 +227,10 @@ private Map<GameState, String> getPossibleMoves(final GameState gameState, final
223227
|| currentBot.samples.values().size() == 3) {
224228
gameStates.put(gameState.play(Position.DIAGNOSIS), Action.GOTO.name() + " " + Position.DIAGNOSIS.name());
225229
}
226-
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
230+
if (currentBot.samples.size() < 3) {
231+
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
232+
}
227233
if (currentBot.totalMolecules < 10) {
228-
System.err.println(currentBot.totalMolecules);
229-
System.err.println(Arrays.toString(gameState.availableMolecules));
230-
System.err.println(Arrays.toString(currentBot.storage));
231234
for (int i = 0; i < gameState.availableMolecules.length; i++) {
232235
if (gameState.availableMolecules[i] > 0) {
233236
gameStates.put(gameState.play(i), Action.CONNECT.name() + " " + (char) ('A' + i));
@@ -242,8 +245,12 @@ private Map<GameState, String> getPossibleMoves(final GameState gameState, final
242245
|| currentBot.samples.values().size() == 3) {
243246
gameStates.put(gameState.play(Position.DIAGNOSIS), Action.GOTO.name() + " " + Position.DIAGNOSIS.name());
244247
}
245-
gameStates.put(gameState.play(Position.MOLECULES), Action.GOTO.name() + " " + Position.MOLECULES.name());
246-
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
248+
if (currentBot.totalMolecules < 10) {
249+
gameStates.put(gameState.play(Position.MOLECULES), Action.GOTO.name() + " " + Position.MOLECULES.name());
250+
}
251+
if (currentBot.samples.size() < 3) {
252+
gameStates.put(gameState.play(Position.SAMPLES), Action.GOTO.name() + " " + Position.SAMPLES.name());
253+
}
247254
currentBot.samples.values()
248255
.stream()
249256
.filter(Sample::isVisible)
@@ -258,6 +265,17 @@ private Map<GameState, String> getPossibleMoves(final GameState gameState, final
258265
}
259266
return gameStates;
260267
}
268+
269+
@Override
270+
public String toString() {
271+
return "Node{" +
272+
"roundsTillNow=" + roundsTillNow +
273+
", totalScore=" + totalScore +
274+
", plays=" + plays +
275+
", moveToGetHere='" + moveToGetHere + '\'' +
276+
", gameState=" + gameState +
277+
'}';
278+
}
261279
}
262280

263281
class SampleMaterial {
@@ -302,6 +320,7 @@ class GameState {
302320
final List<Project> projects;
303321
final Map<Integer, Sample> samples;
304322
int totalMoleculesLeft;
323+
int rounds;
305324
private final List<LinkedList<SampleMaterial>> remainingSampleMaterial = initSamplePool();
306325

307326
private List<LinkedList<SampleMaterial>> initSamplePool() {
@@ -411,13 +430,15 @@ public GameState(final int player,
411430
final Robot[] robots,
412431
final int[] availableMolecules,
413432
final List<Project> projects,
414-
final Map<Integer, Sample> samples) {
433+
final Map<Integer, Sample> samples,
434+
final int rounds) {
415435
this.player = player;
416436
this.robots = robots;
417437
this.availableMolecules = availableMolecules;
418438
this.projects = projects;
419439
this.samples = samples;
420440
this.totalMoleculesLeft = Arrays.stream(availableMolecules).sum();
441+
this.rounds = rounds;
421442
}
422443

423444
public GameState play(final Position position) {
@@ -453,7 +474,7 @@ private void updateBoard(final int id) {
453474
samples.put(id, sample);
454475
currentBot.samples.remove(id);
455476
} else {
456-
sample.makeVisible();
477+
sample.makeVisible(remainingSampleMaterial);
457478
}
458479
break;
459480
}
@@ -503,14 +524,13 @@ private void updateBoard(final int id) {
503524
throw new RuntimeException("Where is this place?");
504525
}
505526
}
527+
rounds++;
506528
// player = MCTS.flip(player);
507529
}
508530

509531
private void updateBoard(final Position position) {
510-
if (robots[player].target.equals(position)) {
511-
robots[player].eta--;
512-
} else {
513-
robots[player].eta = distances[robots[player].target.index][position.index];
532+
if (!robots[player].target.equals(position)) {
533+
rounds += distances[robots[player].target.index][position.index];
514534
robots[player].target = position;
515535
}
516536
// player = MCTS.flip(player);
@@ -528,7 +548,7 @@ public GameState clone() {
528548
}
529549
return new GameState(player, cloneBots,
530550
Arrays.copyOf(availableMolecules, availableMolecules.length),
531-
new ArrayList<>(projects), cloneSamples);
551+
new ArrayList<>(projects), cloneSamples, rounds);
532552
}
533553

534554
@Override
@@ -574,7 +594,13 @@ public Sample(final Material material) {
574594
this.material = material;
575595
}
576596

577-
public void makeVisible() {
597+
public void makeVisible(final List<LinkedList<SampleMaterial>> remainingSampleMaterial) {
598+
if (material.cost[1] < 0) {
599+
SampleMaterial pop = remainingSampleMaterial.get(material.rank).pop();
600+
material.health = pop.health;
601+
System.arraycopy(pop.cost, 0, material.cost, 0, pop.cost.length);
602+
material.expertiseGain = pop.expertise;
603+
}
578604
this.visible = true;
579605
}
580606

@@ -612,10 +638,10 @@ public int hashCode() {
612638
}
613639

614640
class Material {
615-
final int sampleId, carriedBy, rank, health;
641+
final int sampleId, carriedBy, rank;
642+
int health;
616643
final int cost[];
617-
final String expertiseGain;
618-
private static final Random random = new Random();
644+
String expertiseGain;
619645

620646
public Material(final int sampleId,
621647
final int carriedBy,
@@ -631,15 +657,6 @@ public Material(final int sampleId,
631657
this.expertiseGain = expertiseGain;
632658
}
633659

634-
public Material(final SampleMaterial material, final int rank, final int player) {
635-
this.sampleId = random.nextInt(100) + 100;
636-
this.cost = material.cost;
637-
this.health = material.health;
638-
this.expertiseGain = material.expertise;
639-
this.rank = rank;
640-
this.carriedBy = player;
641-
}
642-
643660
@Override
644661
public String toString() {
645662
return "Sample{" +
@@ -728,6 +745,15 @@ public boolean isAdequate(final Sample sample) {
728745
return true;
729746
}
730747

748+
public boolean isPossible(final Sample sample, final int available[]) {
749+
for (int i = 0; i < storage.length; i++) {
750+
if (storage[i] + expertise[i] + available[i] < sample.material.cost[i]) {
751+
return false;
752+
}
753+
}
754+
return true;
755+
}
756+
731757
@Override
732758
protected Robot clone() {
733759
final Robot robot = new Robot(target, eta, score, Arrays.copyOf(storage, storage.length), Arrays.copyOf(expertise, expertise.length));

0 commit comments

Comments
 (0)