1
+
1
2
import hlt .*;
3
+ //import hlt.Victory;
2
4
3
5
import java .util .*;
6
+ import java .util .stream .Collectors ;
4
7
5
8
public class MyBot {
6
9
7
- /**
8
- * Returneaza cea mai buna directie in care sa mearga nava - adancime 1
9
- * @param ship nava pentru care se aplica greedy
10
- * @param gameMap harta jocului
11
- * @return pozitia pe care urmeaza sa mearga
12
- */
13
- public static Position Greedy (final Ship ship , final GameMap gameMap ) {
14
- Position initial = ship .position ;
15
-
16
- Position [] positions =
17
- {
18
- new Position (initial .x - 1 , initial .y ), // sus
19
- new Position (initial .x , initial .y + 1 ), // dreapta
20
- new Position (initial .x + 1 , initial .y ), // jos
21
- new Position (initial .x , initial .y - 1 ) // stanga
22
- };
23
-
24
- Arrays .sort (positions , new Comparator <Position >() {
25
- @ Override
26
- public int compare (Position o1 , Position o2 ) {
27
- return gameMap .at (o1 ).halite - gameMap .at (o2 ).halite ;
28
- }
29
- });
30
- return positions [0 ];
31
- }
32
-
33
- /**
34
- * Functie care returneaza comenzi in legatura cu jocul in general
35
- * @param game referinta la joc
36
- * @return comanda
37
- */
38
- public static Command DecisionGame (final Game game ) {
39
-
40
- // TODO daca playerul are mai mult de 3k halite (ales arbitrar) si runda e sub 200
41
- // TODO sa se faca o nava
42
- if (game .me .halite > 3000 && game .turnNumber < Constants .MAX_TURNS / 2 ) {
43
- return null ;
44
- }
45
-
46
- // TODO daca conditia e adevarata sa se creeze un drop-off + conditia daca o nava a ajuns
47
- // TODo la mai mult de ~8 pozitii departare
48
- if (game .me .halite > 8000 && game .turnNumber < Constants .MAX_TURNS * 3 / 4 ) {
49
- return null ;
50
- }
51
-
52
- return null ;
53
- }
54
-
55
- /**
56
- * Functie care returneaza comenzi in legatura cu o singura nava
57
- * @param ship nava
58
- * @param gameMap harta jocului
59
- * @return comanda
60
- */
61
- public static Command DecisionShip (final Ship ship , final GameMap gameMap ) {
62
-
63
- // TODO daca are mai mult de 750 halite - sa mearga la dropoff
64
- if (ship .halite > (Constants .MAX_HALITE * 3 / 4 )) {
65
-
66
- return null ;
67
- }
68
-
69
- // TODO daca pozitia actuala nu mai are destule resurse sa mearga in alta pozitie
70
- // TODO altfel ramane pe pozitia actuala
71
- if (gameMap .cells [ship .position .x ][ship .position .y ].halite < (Constants .MAX_HALITE / 4 )) {
72
-
73
- // TODO daca pozitia actuala are mai putine resurse decat cea mai buna alta
74
- // TODO pozitie sa ramana aici (ca pe else)
75
- int result = 0 ;
76
- if (gameMap .cells [ship .position .x ][ship .position .y ].halite > result ) {
77
-
78
- return null ;
79
- }
80
-
81
- return null ;
82
- } else {
83
-
84
- return null ;
85
- }
86
- }
87
-
88
10
public static void main (final String [] args ) {
11
+ Victory victory = new Victory ();
89
12
final long rngSeed ;
90
13
if (args .length > 1 ) {
91
14
rngSeed = Integer .parseInt (args [1 ]);
92
15
} else {
93
- rngSeed = System .nanoTime ();
16
+ // constant seed number for constant results and a deterministic solution over all
17
+ rngSeed = 42 ;
94
18
}
95
- final Random rng = new Random (rngSeed );
19
+ victory . rnd . setSeed (rngSeed );
96
20
97
- Game game = new Game ();
98
21
// At this point "game" variable is populated with initial map data.
99
22
// This is a good place to do computationally expensive start-up pre-processing.
100
23
// As soon as you call "ready" function below, the 2 second per turn timer will start.
24
+ victory .game .ready ("QuantumGreedy" );
25
+ // maximum number of ships to be created
26
+ final int maxShips = (int ) Math .sqrt (victory .game .gameMap .height * victory .game .gameMap .width ) / 2 ;
101
27
102
- game .ready ("MyJavaBot" );
28
+ Log .log ("Successfully created bot! My Player ID is " + victory .game .myId
29
+ + ". Bot rng seed is " + rngSeed + "." );
103
30
104
- Log .log ("Successfully created bot! My Player ID is " + game .myId +
105
- ". Bot rng seed is " + rngSeed + "." );
106
31
for (;;) {
107
- game .updateFrame ();
108
- final Player me = game .me ;
109
- final GameMap gameMap = game .gameMap ;
32
+ victory . game .updateFrame ();
33
+ final Player me = victory . game .me ;
34
+ final GameMap gameMap = victory . game .gameMap ;
110
35
111
36
final ArrayList <Command > commandQueue = new ArrayList <>();
37
+ // processes a vip list with the top% positions with halite on the
38
+ // map
39
+ victory .scanVipPositions ();
40
+ // variable for knowing if we have queued a ship spawn command in
41
+ // this round
42
+ boolean willSpawn = false ;
43
+ // checks whether we hit the maximum limit of ships to build
44
+ if (me .ships .size () < maxShips
45
+ // and we have enough halite to build a new ship
46
+ && me .halite >= Constants .SHIP_COST
47
+ // and the position of the shipyard is not occupied
48
+ && !gameMap .at (me .shipyard ).isOccupied ()
49
+ // and there is no reason to avoid building a ship (for
50
+ // better scoring)
51
+ && !victory .shouldAvoidBuildingShips (maxShips )) {
52
+ me .halite -= Constants .SHIP_COST ;
53
+ commandQueue .add (me .shipyard .spawn ());
54
+ willSpawn = true ;
55
+ }
112
56
113
- Command command = DecisionGame (game ); //
114
-
115
- // TODO schimbat cu logica noua
57
+ // attempt to compute the action of each ship
116
58
for (final Ship ship : me .ships .values ()) {
117
- if (gameMap .at (ship ).halite < Constants .MAX_HALITE / 10 || ship .isFull ()) {
118
- final Direction randomDirection = Direction .ALL_CARDINALS .get (rng .nextInt (4 ));
119
- commandQueue .add (ship .move (randomDirection ));
120
- } else {
59
+ // checks if the ship should be turned into a drop off
60
+ if (victory .shouldTurnIntoDropOff (ship )
61
+ // and whether we have enough halite for transformation
62
+ && me .halite > Constants .DROPOFF_COST ) {
63
+ me .halite -= Constants .DROPOFF_COST ;
64
+ commandQueue .add (ship .makeDropoff ());
65
+ continue ;
66
+ }
67
+
68
+ // the direction which does not lead to a crash, initially nil
69
+ Direction goodDir = null ;
70
+ // findDirections returns a "personalized" list, for every ship,
71
+ // of close positions from the vips list
72
+ for (Direction dir : victory .findDirections (ship )) {
73
+ // avoid going into a direction that could lead to a crash
74
+ if (!victory .canCrash (ship , dir )) {
75
+ goodDir = dir ;
76
+ break ;
77
+ }
78
+ }
79
+
80
+ // if no good direction was found, stay still
81
+ if (goodDir == null ) {
121
82
commandQueue .add (ship .stayStill ());
83
+
84
+ continue ;
122
85
}
123
- }
124
86
125
- if (
126
- game .turnNumber <= 200 &&
127
- me .halite >= Constants .SHIP_COST &&
128
- !gameMap .at (me .shipyard ).isOccupied ())
129
- {
130
- commandQueue .add (me .shipyard .spawn ());
87
+ final Position pos = ship .position .directionalOffset (goodDir );
88
+ // the ship will stay still if there is halite to collect on
89
+ // this position and it is not full
90
+ if (gameMap .at (ship .position ).halite > 64 && !ship .isFull ()
91
+ // or if there will be a new spawned ship and there
92
+ // could be a collision
93
+ || me .shipyard .position .equals (pos ) && willSpawn
94
+ // or if it hasn't got enough halite to move
95
+ || ship .halite - gameMap .at (ship ).halite / 10 < 0 ) {
96
+ commandQueue .add (ship .stayStill ());
97
+ } else {
98
+ // otherwise move in the `best` direction
99
+ commandQueue .add (ship .move (gameMap .naiveNavigate (ship , pos )));
100
+ }
131
101
}
132
102
133
- game .endTurn (commandQueue );
103
+ victory . game .endTurn (commandQueue );
134
104
}
135
105
}
136
- }
106
+ }
0 commit comments