@@ -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
6565class 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
263281class 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
614640class 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