Skip to content

Commit 9b8ccba

Browse files
feat: replayMove invoke boardAfter
remove Direction from moves creation parameters list in Variant
1 parent 4d85c75 commit 9b8ccba

File tree

2 files changed

+38
-34
lines changed

2 files changed

+38
-34
lines changed

src/main/scala/abalone/Replay.scala

+14-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import strategygames.format.pgn.San
99
import strategygames.abalone.format.pgn.{ Parser, Reader }
1010
import strategygames.abalone.format.{ FEN, Forsyth, Uci }
1111
import strategygames.{ Action => StratAction, ActionStrs, Move => StratMove, Situation => StratSituation }
12-
import scala.annotation.nowarn
1312

1413
case class Replay(setup: Game, actions: List[Move], state: Game) {
1514

@@ -70,14 +69,20 @@ object Replay {
7069
case _ => sys.error("Invalid abalone move")
7170
}
7271

73-
@nowarn def replayMove(
74-
before: Game,
75-
orig: Pos,
76-
dest: Pos,
77-
endTurn: Boolean
78-
): Move = {
79-
before.situation.moves.get(orig).flatMap(_.find(m => m.dest == dest)).get // @TODO: adapt
80-
}
72+
def replayMove(before: Game, orig: Pos, dest: Pos, endTurn: Boolean): Move =
73+
Move(
74+
piece = before.situation.board.pieces(orig),
75+
orig = orig,
76+
dest = dest,
77+
situationBefore = before.situation,
78+
after = before.situation.board.variant.boardAfter(
79+
before.situation,
80+
orig,
81+
dest
82+
),
83+
autoEndTurn = endTurn,
84+
capture = before.situation.board.piecesOf(!before.situation.player).get(dest).map(_ => dest)
85+
)
8186

8287
def actionStrsWithEndTurn(actionStrs: ActionStrs): Seq[(String, Boolean)] =
8388
actionStrs.zipWithIndex.map { case (a, i) =>

src/main/scala/abalone/variant/Variant.scala

+24-25
Original file line numberDiff line numberDiff line change
@@ -104,30 +104,29 @@ abstract class Variant private[variant] (
104104
val activePlayerPieces = situation.board.piecesOf(situation.player)
105105
val opponentPieces = situation.board.piecesOf(!situation.player)
106106

107-
def createMove(category: String, orig: Pos, dest: Pos) = Move(Piece(situation.player, Role.defaultRole), orig, dest, situation, boardAfter(situation, orig, dest), true, if (category == "pushout") Some(dest) else None)
107+
def createMove(orig: Pos, dest: Pos, capture: Boolean = false) = Move(Piece(situation.player, Role.defaultRole), orig, dest, situation, boardAfter(situation, orig, dest), true, if(capture) Some(dest) else None)
108108

109109
def generateSideMoves(lineOfMarbles: List[Pos], direction: Direction): List[Move] = {
110110
def canMoveTowards(pos: Pos, direction: Direction): Boolean = situation.board.isEmptySquare(direction(pos))
111111

112-
def possibleSideMoves: List[(Pos, Pos, Direction)] = Pos.sideMovesDirsFromDir(direction).flatMap(
112+
def possibleSideMoves: List[(Pos, Pos)] = Pos.sideMovesDirsFromDir(direction).flatMap(
113113
dir =>
114114
if (lineOfMarbles.map(
115115
(pos) => canMoveTowards(pos, dir)
116116
).contains(false)) None
117117
else (
118118
lineOfMarbles.headOption,
119-
lineOfMarbles.reverse.headOption.flatMap(dir(_)),
120-
dir
119+
lineOfMarbles.reverse.headOption.flatMap(dir(_))
121120
) match {
122-
case ( (Some(head), Some(tail), dir) ) => Some( (head, tail, dir) )
121+
case ( (Some(head), Some(tail)) ) => Some( (head, tail) )
123122
case _ => None
124123
}
125124
)
126125

127126
List(
128127
if (lineOfMarbles.size == 3) generateSideMoves(lineOfMarbles.dropRight(1), direction) else List(),
129128
possibleSideMoves.flatMap {
130-
case ( (orig, dest, _) ) => Some(createMove("side", orig, dest))
129+
case ( (orig, dest) ) => Some(createMove(orig, dest))
131130
case _ => None
132131
}
133132
).flatten
@@ -139,30 +138,30 @@ abstract class Variant private[variant] (
139138
direction(neighbour).toList.flatMap {
140139
case (thirdSquareInLine) => {
141140
if (situation.board.isEmptySquare(Some(thirdSquareInLine))) // xx.
142-
Some(createMove("line", pos, thirdSquareInLine))
141+
Some(createMove(pos, thirdSquareInLine))
143142
else if (opponentPieces.contains(thirdSquareInLine)) // xxo
144143
direction(thirdSquareInLine) match { // xxo?
145-
case None => Some(createMove("pushout", pos, thirdSquareInLine)) // xxo\
144+
case None => Some(createMove(pos, thirdSquareInLine, true)) // xxo\
146145
case Some(emptySquare) if situation.board.isEmptySquare(Some(emptySquare)) => {
147-
Some(createMove("push", pos, thirdSquareInLine)) // xxo.
146+
Some(createMove(pos, thirdSquareInLine)) // xxo.
148147
}
149148
case _ => None
150149
}
151150
else if (activePlayerPieces.contains(thirdSquareInLine)) // xxx
152151
direction(thirdSquareInLine).flatMap {
153152
case (fourthSquareInLine) => // xxx_
154153
if (situation.board.isEmptySquare(Some(fourthSquareInLine))) // xxx.
155-
Some(createMove("line", pos, fourthSquareInLine))
154+
Some(createMove(pos, fourthSquareInLine))
156155
else if (opponentPieces.contains(fourthSquareInLine)) // xxxo
157156
direction(fourthSquareInLine) match { // xxxo?
158-
case None => Some(createMove("pushout", pos, fourthSquareInLine)) // xxxo\
159-
case Some(emptyPos) if (situation.board.isEmptySquare(Some(emptyPos))) => Some(createMove("push", pos, fourthSquareInLine)) // xxxo.
157+
case None => Some(createMove(pos, fourthSquareInLine, true)) // xxxo\
158+
case Some(emptyPos) if (situation.board.isEmptySquare(Some(emptyPos))) => Some(createMove(pos, fourthSquareInLine)) // xxxo.
160159
case _ => direction(fourthSquareInLine).flatMap { // xxxo?
161160
case (fifthSquareInLine) =>
162161
if (opponentPieces.contains(fifthSquareInLine)) // xxxoo
163162
direction(fifthSquareInLine) match {
164-
case None => Some(createMove("pushout", pos, fourthSquareInLine)) // xxxoo\
165-
case Some(emptySquare) if situation.board.isEmptySquare(Some(emptySquare)) => Some(createMove("push", pos, emptySquare)) // xxxoo.
163+
case None => Some(createMove(pos, fourthSquareInLine, true)) // xxxoo\
164+
case Some(emptySquare) if situation.board.isEmptySquare(Some(emptySquare)) => Some(createMove(pos, emptySquare)) // xxxoo.
166165
case _ => None
167166
}
168167
else None
@@ -197,20 +196,13 @@ abstract class Variant private[variant] (
197196
situation.board.copy(pieces = piecesAfterAction(situation.board.pieces, orig, dest))
198197
}
199198

200-
def isSideMove(orig: Pos, dest: Pos): Boolean = orig.dir(dest) match {
201-
case dirString if (dirString == "upRight" || dirString == "downLeft") =>
202-
if (orig.|<>|((square) => square.index == dest.index, Pos.dirFromString(orig.dir(dest))) == Nil) true
203-
else false
204-
case _ => orig.rank.index != dest.rank.index && orig.file.index != dest.file.index
205-
}
206-
207199
/*
208200
How to move pieces based on orig, dest :
209-
A. Find direction between orig and dest
201+
A. Find direction between orig and dest (in case of a sideMove this will always be "upY" or "downX")
210202
B. Determine the kind of move (side move or not)
211203
C. play the move
212204
- side move :
213-
Based on the 2 directions computed in A, applied to origin to land on a square,
205+
Based on the 2 directions computed in A (vertical + horizontal), applied to origin to land on a square,
214206
find out which square :
215207
- is the empty square (it's the sideMoveSideDir)
216208
- contains the marble used to do a side move (it's the sideMoveLineDir)
@@ -233,15 +225,15 @@ abstract class Variant private[variant] (
233225
case _ => None
234226
}
235227
}.headOption
236-
val sideMoveSideDir: Option[Direction] = Pos.possibleLineDirsFromSideMoveDir(origToDestDir).flatMap {
228+
val sideDir: Option[Direction] = Pos.possibleLineDirsFromSideMoveDir(origToDestDir).flatMap {
237229
direction => direction(orig) match {
238230
case (Some(squareInLine)) if(!pieces.contains(squareInLine)) => Some(direction)
239231
case _ => None
240232
}
241233
}.headOption
242234
val lineDirSecondPos: Option[Pos] = lineDir.flatMap(direction => direction(orig))
243235
val lineDirThirdPos: Option[Pos] = lineDirSecondPos.flatMap(direction => lineDir.flatMap(_(direction)))
244-
val sideMovePosFromOrig: Option[Pos] = sideMoveSideDir.flatMap(direction => direction(orig))
236+
val sideMovePosFromOrig: Option[Pos] = sideDir.flatMap(direction => direction(orig))
245237
val diagonalPosFromOrig: Option[Pos] = (lineDir, sideMovePosFromOrig) match {
246238
case ( Some(someLineDir), Some(origSideMove) ) => someLineDir(origSideMove)
247239
case _ => None
@@ -327,6 +319,13 @@ abstract class Variant private[variant] (
327319

328320
override def hashCode: Int = id
329321

322+
private def isSideMove(orig: Pos, dest: Pos): Boolean = orig.dir(dest) match {
323+
case dirString if (dirString == "upRight" || dirString == "downLeft") =>
324+
if (orig.|<>|((square) => square.index == dest.index, Pos.dirFromString(orig.dir(dest))) == Nil) true // if we can't reach dest from orig using only the same direction.
325+
else false
326+
case _ => orig.rank.index != dest.rank.index && orig.file.index != dest.file.index
327+
}
328+
330329
private def turnPieces(situation: Situation): PieceMap = situation.board.piecesOf(situation.player)
331330

332331
val kingPiece: Option[Role] = None

0 commit comments

Comments
 (0)