Skip to content

Commit 9dacbc1

Browse files
committed
enhance(Board): xml handling
1 parent 52e4ede commit 9dacbc1

File tree

6 files changed

+53
-44
lines changed

6 files changed

+53
-44
lines changed

.dev/scopes.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ sdk
2323
framework
2424
network
2525
logging
26+
2627
Game
28+
Board

plugin/src/main/kotlin/sc/plugin2023/Board.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
package sc.plugin2023
22

33
import com.thoughtworks.xstream.annotations.XStreamAlias
4+
import com.thoughtworks.xstream.annotations.XStreamImplicit
45
import sc.api.plugins.*
5-
import sc.api.plugins.Coordinates
66
import sc.framework.deepCopy
77
import kotlin.random.Random
88
import sc.plugin2023.util.PenguinConstants as Constants
99

1010
/** Spielbrett aus einem zweidimensionalen Array aus Feldern. */
1111
@XStreamAlias(value = "board")
1212
class Board(
13-
gameField: MutableTwoDBoard<Field> = generateFields()
14-
): RectangularBoard<Field>(gameField), IBoard {
13+
@XStreamImplicit(itemFieldName = "row")
14+
override val gameField: MutableTwoDBoard<Field> = generateFields()
15+
): RectangularBoard<Field>(), IBoard {
1516

1617
constructor(board: Board): this(board.gameField.deepCopy())
1718

plugin2026/src/main/kotlin/sc/plugin2026/Board.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sc.plugin2026
22

33
import com.thoughtworks.xstream.annotations.XStreamAlias
4+
import com.thoughtworks.xstream.annotations.XStreamImplicit
45
import sc.api.plugins.*
56
import sc.framework.deepCopy
67
import sc.plugin2026.util.PiranhaConstants
@@ -11,8 +12,9 @@ val line = "-".repeat(PiranhaConstants.BOARD_LENGTH * 2 + 2)
1112
/** Spielbrett für Piranhas mit [PiranhaConstants.BOARD_LENGTH]² Feldern. */
1213
@XStreamAlias(value = "board")
1314
class Board(
14-
gameField: MutableTwoDBoard<FieldState> = randomFields()
15-
): RectangularBoard<FieldState>(gameField), IBoard {
15+
@XStreamImplicit(itemFieldName = "row")
16+
override val gameField: MutableTwoDBoard<FieldState> = randomFields()
17+
): RectangularBoard<FieldState>(), IBoard {
1618

1719
override fun toString() =
1820
"Board " + gameField.withIndex().joinToString(" ", "[", "]") { row ->
@@ -34,7 +36,7 @@ class Board(
3436
}
3537

3638
override fun clone(): Board {
37-
println(gameField::class.java)
39+
//println("Cloning with ${gameField::class.java}: $this")
3840
return Board(gameField.deepCopy())
3941
}
4042

plugin2026/src/test/kotlin/sc/plugin2026/BoardTest.kt

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import io.kotest.matchers.*
55
import io.kotest.matchers.string.*
66
import io.kotest.matchers.types.*
77
import sc.helpers.shouldSerializeTo
8-
import sc.helpers.testXStream
8+
import sc.networking.XStreamProvider
9+
import sc.plugin2026.util.XStreamClasses
10+
import sc.protocol.LobbyProtocol
911

1012
class BoardTest: FunSpec({
1113
val board = Board()
@@ -14,30 +16,35 @@ class BoardTest: FunSpec({
1416
board.fieldsEmpty() shouldBe false
1517
}
1618
}
19+
val xstream = XStreamProvider.basic()
20+
LobbyProtocol.registerAdditionalMessages(xstream, XStreamClasses().classesToRegister)
1721
context("serialization") {
18-
test("board") {
19-
testXStream.toXML(board) shouldHaveLineCount 122
20-
22+
test("field") {
2123
FieldState.ONE_L shouldSerializeTo "<field>ONE_L</field>"
22-
testXStream.fromXML(testXStream.toXML(FieldState.ONE_L)) shouldBeSameInstanceAs FieldState.ONE_L
24+
xstream.fromXML(xstream.toXML(FieldState.ONE_L)) shouldBeSameInstanceAs FieldState.ONE_L
25+
}
26+
test("board") {
27+
xstream.toXML(board) shouldHaveLineCount 122
2328

24-
board.clone() shouldBe board
25-
testXStream.toXML(board.clone()) shouldHaveLineCount 122
29+
// FIXME circular reference?
30+
//val clone = board.clone()
31+
//clone shouldNotBeSameInstanceAs board
32+
//clone shouldBe board
33+
xstream.toXML(board.clone()) shouldHaveLineCount 122
2634

2735
Board(arrayOf(arrayOf(FieldState.ONE_S, FieldState.ONE_M, FieldState.ONE_L))) shouldSerializeTo """
2836
<board>
29-
<row class="field-array">
37+
<row>
3038
<field>ONE_S</field>
3139
<field>ONE_M</field>
3240
<field>ONE_L</field>
3341
</row>
3442
</board>""".trimIndent()
3543

36-
// FIXME circular reference?
37-
//val xml = testXStream.toXML(board)
38-
//val reboard = testXStream.fromXML(xml)
44+
val xml = xstream.toXML(board)
45+
val reboard = xstream.fromXML(xml)
3946

40-
//(reboard as Board).clone() shouldBe board
47+
(reboard as Board).clone() shouldBe board
4148
}
4249
}
4350
})

sdk/src/main/server-api/sc/api/plugins/RectangularBoard.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package sc.api.plugins
22

3-
import com.thoughtworks.xstream.annotations.XStreamImplicit
4-
53
/** Eine zweidimensionale Anordnung von Feldern, eine Liste von Zeilen. */
64
typealias TwoDBoard<FIELD> = Array<Array<FIELD>>
75

@@ -13,10 +11,8 @@ typealias MutableTwoDBoard<FIELD> = Array<Array<FIELD>>
1311
* Ein rechteckiges Spielfeld aus Feldern.
1412
* Intern repräsentiert durch eine Liste an Zeilen.
1513
*/
16-
open class RectangularBoard<FIELD: IField>(
17-
@XStreamImplicit(itemFieldName = "row")
18-
protected open val gameField: TwoDBoard<FIELD>
19-
): FieldMap<FIELD>() {
14+
abstract class RectangularBoard<FIELD: IField>: FieldMap<FIELD>() {
15+
protected abstract val gameField: TwoDBoard<FIELD>
2016

2117
override val size: Int
2218
get() = gameField.size * columnCount
@@ -98,12 +94,16 @@ open class RectangularBoard<FIELD: IField>(
9894
val field = RectangularBoard::class.java.getDeclaredField("gameField")
9995
field.isAccessible = true
10096
field.set(this, ArrayList<MutableList<FIELD>>())
97+
//println("Created empty gameField")
10198
}
10299
return this
103100
}
104101

105-
override fun equals(other: Any?) =
106-
other is RectangularBoard<*> && gameField.contentDeepEquals(other.gameField)
102+
override fun equals(other: Any?): Boolean {
103+
//println("Comparing ${other?.toString()}")
104+
return other is RectangularBoard<*> && gameField.contentDeepEquals(other.gameField)
105+
}
107106

108-
override fun hashCode(): Int = gameField.contentDeepHashCode()
107+
override fun hashCode(): Int =
108+
gameField.contentDeepHashCode()
109109
}
Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package sc.api
22

3-
import io.kotest.core.spec.style.FunSpec
4-
import io.kotest.matchers.*
53
import sc.api.plugins.IField
6-
import sc.api.plugins.RectangularBoard
74

85
enum class Field: IField {
96
EMPTY,
@@ -14,17 +11,17 @@ enum class Field: IField {
1411
get() = this == EMPTY
1512
}
1613

17-
class RectangularBoardTest: FunSpec({
18-
test("deep copy") {
19-
val board = RectangularBoard(arrayOf(arrayOf(Field.EMPTY, Field.ONE, Field.TWO)))
20-
board.fieldsEmpty() shouldBe false
21-
//val clone = board.clone()
22-
//clone.shouldBe(board)
23-
//clone.shouldNotBeSameInstanceAs(board)
24-
board[1, 0] = Field.EMPTY
25-
//clone.shouldNotBe(board)
26-
board[2, 0] = Field.EMPTY
27-
board.fieldsEmpty() shouldBe true
28-
//clone.fieldsEmpty() shouldBe false
29-
}
30-
})
14+
//class RectangularBoardTest: FunSpec({
15+
// test("deep copy") {
16+
// val board = RectangularBoard(arrayOf(arrayOf(Field.EMPTY, Field.ONE, Field.TWO)))
17+
// board.fieldsEmpty() shouldBe false
18+
// //val clone = board.clone()
19+
// //clone.shouldBe(board)
20+
// //clone.shouldNotBeSameInstanceAs(board)
21+
// board[1, 0] = Field.EMPTY
22+
// //clone.shouldNotBe(board)
23+
// board[2, 0] = Field.EMPTY
24+
// board.fieldsEmpty() shouldBe true
25+
// //clone.fieldsEmpty() shouldBe false
26+
// }
27+
//})

0 commit comments

Comments
 (0)