@@ -47,18 +47,6 @@ class GameStateTest: FunSpec({
4747 gameState.currentTeam shouldBe gameState.startTeam.opponent()
4848 }
4949
50- test("reveals segment after move") {
51- val state = GameState (Board (listOf(Segment .empty(), Segment .empty(CubeCoordinates (4, 0)), Segment .empty(CubeCoordinates (8, 0)))))
52- val move = Move (Accelerate (5), Advance (6))
53- var found = false
54- state.getAllMoves().forEachRemaining { if (move == it) found = true }
55- found shouldBe true
56-
57- state.performMoveDirectly(move)
58- state.board.segmentIndex(state.otherShip.position) shouldBe 1
59- state.board.visibleSegments shouldBe 3
60- }
61-
6250 context("points calculation") {
6351 test("at start") {
6452 gameState.ships.forAll {
@@ -81,21 +69,35 @@ class GameStateTest: FunSpec({
8169 }
8270 }
8371
84- test("getPossiblePushs") {
85- gameState.getPossiblePushs().shouldBeEmpty()
86- gameState.currentShip.position = gameState.otherShip.position
87- gameState.getPossiblePushs() shouldHaveSize 4
88- gameState.currentShip.movement = 0
89- gameState.getPossiblePushs().shouldBeEmpty()
90- }
91-
92- test("getPossibleTurns") {
93- gameState.getPossibleTurns(0).shouldHaveSize(2)
94- gameState.getPossibleTurns(1).shouldHaveSize(4)
95- gameState.getPossibleTurns(2).shouldHaveSize(5)
96- }
97-
9872 context("getPossibleAdvances") {
73+ context("advanceLimit") {
74+ val ship = gameState.currentShip
75+ test("from start") {
76+ gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 1).distance shouldBe 0
77+ gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 2).distance shouldBe 1
78+ val furtherInfo = gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 3)
79+ furtherInfo.costUntil(1) shouldBe 2
80+ furtherInfo.distance shouldBe 2
81+ furtherInfo.costUntil(2) shouldBe 3
82+ }
83+ test("considers pushing and current") {
84+ ship.direction = CubeDirection .DOWN_RIGHT
85+ gameState.otherShip.position = CubeCoordinates .ORIGIN + CubeDirection .LEFT .vector
86+
87+ gameState.checkAdvanceLimit(ship).run {
88+ distance shouldBe 0
89+ problem shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
90+ }
91+
92+ ship.speed = 3
93+ ship.movement = 3
94+ gameState.checkAdvanceLimit(ship).run {
95+ distance shouldBe 1
96+ costUntil(1) shouldBe 2
97+ problem shouldBe AdvanceProblem .SHIP_ALREADY_IN_TARGET
98+ }
99+ }
100+ }
99101 test("from starting position") {
100102 gameState.getPossibleAdvances() shouldHaveSingleElement Advance (1)
101103 }
@@ -111,40 +113,24 @@ class GameStateTest: FunSpec({
111113 }
112114 }
113115
114- test("getPossibleAccelerations") {
115- gameState.getPossibleAccelerations(0).size shouldBe 1
116- gameState.getPossibleAccelerations(1).size shouldBe 2
117- }
118-
119- context("advanceLimit") {
120- val ship = gameState.currentShip
121- test("from start") {
122- gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 1).distance shouldBe 0
123- gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 2).distance shouldBe 1
124- val furtherInfo = gameState.checkAdvanceLimit(ship.position, CubeDirection .DOWN_RIGHT , 3)
125- furtherInfo.costUntil(1) shouldBe 2
126- furtherInfo.distance shouldBe 2
127- furtherInfo.costUntil(2) shouldBe 3
116+ context("getPossibleActions") {
117+ test("getPossibleAccelerations") {
118+ gameState.getPossibleAccelerations(0).size shouldBe 1
119+ gameState.getPossibleAccelerations(1).size shouldBe 2
128120 }
129- test("considers pushing and current") {
130- ship.direction = CubeDirection .DOWN_RIGHT
131- gameState.otherShip.position = CubeCoordinates .ORIGIN + CubeDirection .LEFT .vector
132-
133- gameState.checkAdvanceLimit(ship).run {
134- distance shouldBe 0
135- problem shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
136- }
137-
138- ship.speed = 3
139- ship.movement = 3
140- gameState.checkAdvanceLimit(ship).run {
141- distance shouldBe 1
142- costUntil(1) shouldBe 2
143- problem shouldBe AdvanceProblem .SHIP_ALREADY_IN_TARGET
144- }
121+ test("getPossibleTurns") {
122+ gameState.getPossibleTurns(0).shouldHaveSize(2)
123+ gameState.getPossibleTurns(1).shouldHaveSize(4)
124+ gameState.getPossibleTurns(2).shouldHaveSize(5)
145125 }
146- }
147- context("getPossibleActions") {
126+ test("getPossiblePushs") {
127+ gameState.getPossiblePushs().shouldBeEmpty()
128+ gameState.currentShip.position = gameState.otherShip.position
129+ gameState.getPossiblePushs() shouldHaveSize 4
130+ gameState.currentShip.movement = 0
131+ gameState.getPossiblePushs().shouldBeEmpty()
132+ }
133+
148134 test("from starting position") {
149135 gameState.getPossibleActions(0) shouldHaveSize 11
150136 }
@@ -199,7 +185,7 @@ class GameStateTest: FunSpec({
199185 }
200186 test("unpushable opponent") {
201187 val state = GameState (
202- Board (listOf(Segment (CubeDirection .RIGHT , CubeCoordinates .ORIGIN , arrayOf(arrayOf(Field .WATER , Field .WATER , Field .WATER ))))),
188+ Board (listOf(Segment (CubeDirection .RIGHT , CubeCoordinates .ORIGIN , arrayOf(arrayOf(Field .WATER , Field .WATER , Field .WATER ))))),
203189 ships = listOf(
204190 Ship (CubeCoordinates (-1, -2), Team .ONE ),
205191 Ship (CubeCoordinates (-1, 0), Team .TWO ),
@@ -211,29 +197,57 @@ class GameStateTest: FunSpec({
211197 }
212198 }
213199
214- context("current works when board is truncated") {
215- val commonBoard = Board (listOf(Segment .empty(),
216- Segment .empty(CubeCoordinates (4, 0)),
217- Segment (CubeDirection .UP_RIGHT , CubeCoordinates (8, -4), generateSegment(true, arrayOf()))))
218- val state = GameState (commonBoard)
219- val start = CubeCoordinates (1, -1)
220- state.currentShip.run {
221- position = start
222- speed = 2
223- movement = 2
200+ context("performing move") {
201+ val straightState = GameState (Board (listOf(Segment .empty(), Segment .empty(CubeCoordinates (4, 0)), Segment .empty(CubeCoordinates (8, 0)))))
202+ test("reveals next segment") {
203+ val move = Move (Accelerate (5), Advance (6))
204+ var found = false
205+ straightState.getAllMoves().forEachRemaining { if (move == it) found = true }
206+ found shouldBe true
207+
208+ straightState.performMoveDirectly(move)
209+ straightState.board.segmentIndex(straightState.otherShip.position) shouldBe 1
210+ straightState.board.visibleSegments shouldBe 3
224211 }
225212
226- val moves = state.getPossibleMoves(1)
227- val truncState = state.copy(Board (commonBoard.segments.subList(0, 2), nextDirection = CubeDirection .UP_RIGHT ))
228- moves shouldContainAll truncState.getPossibleMoves(1)
229- forAll<GameState >("full" to state, "truncated" to truncState) { state ->
230- state.checkAdvanceLimit(start, CubeDirection .RIGHT , 5).costUntil(4) shouldBe 5
231- state.clone().checkAdvanceLimit(start, CubeDirection .RIGHT , 5).costUntil(4) shouldBe 5
232- state.performMove(Move (Accelerate (1), Advance (3)))
233- state.performMove(Move (Accelerate (3), Advance (4)))
234- state.performMove(Move (Accelerate (4), Advance (5)))
235- shouldThrow<InvalidMoveException > { state.performMove(Move (Accelerate (2), Advance (3))) }.mistake shouldBe MoveMistake .MOVEMENT_POINTS_LEFT
236- shouldThrow<InvalidMoveException > { state.performMove(Move (Accelerate (2), Advance (4))) }.mistake shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
213+ test("merges duplicate advances") {
214+ straightState.currentShip.position = CubeCoordinates .ORIGIN
215+ val actions = arrayOf(Turn (CubeDirection .RIGHT ), Turn (CubeDirection .UP_RIGHT ), Turn (CubeDirection .RIGHT ), Advance (1))
216+ shouldThrow<InvalidMoveException > { straightState.performMove(Move (*actions)) }.mistake shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
217+ straightState.performMove(Move (Accelerate (1), *actions))
218+ shouldThrow<InvalidMoveException > { straightState.performMove(Move (*actions)) }.mistake shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
219+ straightState.performMove(Move (Accelerate (2), *actions, Advance (1)))
220+ straightState.performMoveDirectly(Move (Accelerate (2), *actions, Advance (1), Turn (CubeDirection .DOWN_RIGHT )))
221+ straightState.otherShip.run {
222+ position shouldBe CubeCoordinates (2, 0)
223+ coal shouldBe 3
224+ }
225+ }
226+
227+ context("current works when board is truncated") {
228+ val commonBoard = Board (listOf(Segment .empty(),
229+ Segment .empty(CubeCoordinates (4, 0)),
230+ Segment (CubeDirection .UP_RIGHT , CubeCoordinates (8, -4), generateSegment(true, arrayOf()))))
231+ val state = GameState (commonBoard)
232+ val start = CubeCoordinates (1, -1)
233+ state.currentShip.run {
234+ position = start
235+ speed = 2
236+ movement = 2
237+ }
238+
239+ val moves = state.getPossibleMoves(1)
240+ val truncState = state.copy(Board (commonBoard.segments.subList(0, 2), nextDirection = CubeDirection .UP_RIGHT ))
241+ moves shouldContainAll truncState.getPossibleMoves(1)
242+ forAll<GameState >("full" to state, "truncated" to truncState) { state ->
243+ state.checkAdvanceLimit(start, CubeDirection .RIGHT , 5).costUntil(4) shouldBe 5
244+ state.clone().checkAdvanceLimit(start, CubeDirection .RIGHT , 5).costUntil(4) shouldBe 5
245+ state.performMove(Move (Accelerate (1), Advance (3)))
246+ state.performMove(Move (Accelerate (3), Advance (4)))
247+ state.performMove(Move (Accelerate (4), Advance (5)))
248+ shouldThrow<InvalidMoveException > { state.performMove(Move (Accelerate (2), Advance (3))) }.mistake shouldBe MoveMistake .MOVEMENT_POINTS_LEFT
249+ shouldThrow<InvalidMoveException > { state.performMove(Move (Accelerate (2), Advance (4))) }.mistake shouldBe AdvanceProblem .NO_MOVEMENT_POINTS
250+ }
237251 }
238252 }
239253
0 commit comments