1+ package sc.plugin2022
2+
3+ import io.kotest.assertions.throwables.shouldThrow
4+ import io.kotest.core.spec.style.FunSpec
5+ import io.kotest.inspectors.forAll
6+ import io.kotest.matchers.collections.shouldBeOneOf
7+ import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder
8+ import io.kotest.matchers.maps.shouldBeEmpty
9+ import io.kotest.matchers.maps.shouldHaveSize
10+ import io.kotest.matchers.maps.shouldNotBeEmpty
11+ import io.kotest.matchers.shouldBe
12+ import io.kotest.matchers.string.shouldHaveLineCount
13+ import io.kotest.matchers.string.shouldNotContain
14+ import sc.api.plugins.Team
15+ import sc.plugin2022.PieceType.*
16+ import sc.plugin2022.util.Constants
17+ import sc.plugin2022.util.MoveMistake
18+ import sc.shared.InvalidMoveException
19+
20+ class BoardTest : FunSpec ({
21+ context("Board generation") {
22+ val board = Board ()
23+ test("does not misplace pieces") {
24+ board shouldHaveSize Constants .BOARD_SIZE * 2
25+ board.keys.forAll {
26+ it.y shouldBeOneOf listOf(0, Constants .BOARD_SIZE - 1)
27+ }
28+ board.values shouldContainExactlyInAnyOrder values().flatMap { type ->
29+ Team .values().map { team ->
30+ Piece (type, team)
31+ }
32+ }.let { it + it }
33+ }
34+ test("is stringified apropriately") {
35+ val string = board.toString()
36+ println(string)
37+ string shouldHaveLineCount 8
38+ val lines = string.lines()
39+ lines.first() shouldNotContain " -"
40+ lines.last() shouldNotContain " -"
41+ lines.first().reversed().toLowerCase() shouldBe lines.last()
42+ lines.subList(1, 7).forAll {
43+ it shouldBe " ----------------"
44+ }
45+ }
46+ }
47+ context("Board performs Moves ") {
48+ context("refuses invalid moves") {
49+ test("can't move backwards or off the fields") {
50+ val board = Board (arrayOf(Seestern , Herzmuschel ).flatMap { it.teamPieces() }.mapIndexed { index, piece -> Coordinates (index, 4) to piece }.toMap(HashMap ()))
51+ board.entries.forAll {
52+ shouldThrow<InvalidMoveException > {
53+ board.movePiece(Move (it.key, it.key.copy(y = if(it.value.team == Team .ONE ) 3 else 5)))
54+ }.mistake shouldBe MoveMistake .INVALID_MOVEMENT
55+ }
56+ }
57+ test("can't move onto own piece") {
58+ val board = makeBoard(0 y 0 to "R ", 1 y 2 to "R ")
59+ shouldThrow<InvalidMoveException > {
60+ board.movePiece(Move (0 y 0, 1 y 2))
61+ }.mistake shouldBe MoveMistake .DESTINATION_BLOCKED
62+ }
63+ }
64+ context("amber") {
65+ val coords = Coordinates (0, 6)
66+ test("not for other team") {
67+ val moewe = Piece (Moewe , Team .TWO )
68+ val board = Board (mutableMapOf(coords to moewe))
69+ board.movePiece(Move (coords, coords.copy(y = 7))) shouldBe moewe
70+ board.shouldNotBeEmpty()
71+ }
72+ test("from position") {
73+ val moewe = Piece (Moewe , Team .ONE )
74+ val board = Board (mutableMapOf(coords to moewe))
75+ board.movePiece(Move (coords, coords.copy(y = 7))) shouldBe null
76+ board.shouldBeEmpty()
77+ }
78+ test("not from Robbe in position") {
79+ val robbe = Piece (Robbe , Team .ONE )
80+ val board = Board (mutableMapOf(coords to robbe))
81+ board.movePiece(Move (coords, Coordinates (2, 7))) shouldBe robbe
82+ board.shouldNotBeEmpty()
83+ }
84+ test("from tower") {
85+ val tower = Piece (Herzmuschel , Team .ONE , 2)
86+ val board = Board (mutableMapOf())
87+ }
88+ }
89+ }
90+ })
91+
92+ infix fun String.at (pos : Coordinates ) = Pair (pos, Piece .fromString(this ))
93+
94+ infix fun Int.y (other : Int ) = Coordinates (this , other)
95+
96+ fun makeBoard (vararg list : Pair <Coordinates , String >) =
97+ Board (list.associateTo(HashMap ()) { it.first to Piece .fromString(it.second) })
0 commit comments