@@ -96,7 +96,7 @@ abstract class Variant private[variant] (
96
96
Map (pos ->
97
97
pos.neighbours.flatten
98
98
.filterNot(situation.board.pieces.contains(_))
99
- .map(landingSquare =>
99
+ .map(landingSquare =>
100
100
Move (piece, pos, landingSquare, situation, boardAfter(situation, pos, landingSquare), false )
101
101
)
102
102
)
@@ -105,26 +105,37 @@ abstract class Variant private[variant] (
105
105
def validMovesOf2And3 (situation : Situation ): Map [Pos , List [(String , Move )]] = {
106
106
val activePlayerPieces = situation.board.piecesOf(situation.player)
107
107
val opponentPieces = situation.board.piecesOf(! situation.player)
108
-
108
+
109
109
def createMove (orig : Pos , dest : Pos , category : String ): (String , Move ) =
110
110
(category, Move (Piece (situation.player, Role .defaultRole), orig, dest, situation, boardAfter(situation, orig, dest), true , if (category == " pushout" ) Some (dest) else None ))
111
111
112
112
def generateSideMoves (lineOfMarbles : List [Pos ], direction : Option [String ]): List [(String , Move )] = {
113
- // "left" is related to the direction
114
- def canLeftSideMove (pos : Pos ): Boolean =
115
- pos.sideMovesDirsFromDir(direction)._1.fold(false )(p => situation.board.isEmptySquare(Some (p)))
116
- def canRightSideMove (pos : Pos ): Boolean =
117
- pos.sideMovesDirsFromDir(direction)._2.fold(false )(p => situation.board.isEmptySquare(Some (p)))
113
+ def canMoveTowards (pos : Pos , dir : String ): Boolean = {
114
+ situation.board.isEmptySquare(pos.dir(dir))
115
+ }
116
+
117
+ val possibleSideMovesDirections = Pos .sideMovesDirsFromDir(direction)
118
+ def possibleSideMoves : List [Option [(Pos , Pos )]] = possibleSideMovesDirections.map(
119
+ dir =>
120
+ if (lineOfMarbles.flatMap(
121
+ (pos) => Some (canMoveTowards(pos, dir))
122
+ ).contains(false )) None
123
+ else List (
124
+ lineOfMarbles.headOption,
125
+ lineOfMarbles.reverse.headOption.flatMap(_.dir(dir))
126
+ ) match {
127
+ case List (Some (head), Some (tail)) => Some ( (head, tail) )
128
+ case _ => None
129
+ }
130
+ )
118
131
119
132
List (
120
133
if (lineOfMarbles.size == 3 ) generateSideMoves(lineOfMarbles.dropRight(1 ), direction)
121
134
else None ,
122
- if (! lineOfMarbles.map(canLeftSideMove).contains(false ))
123
- Some (createMove(lineOfMarbles(0 ), lineOfMarbles.last.sideMovesDirsFromDir(direction)._1.get, " side" ))
124
- else None ,
125
- if (! lineOfMarbles.map(canRightSideMove).contains(false ))
126
- Some (createMove(lineOfMarbles(0 ), lineOfMarbles.last.sideMovesDirsFromDir(direction)._2.get, " side" ))
127
- else None ,
135
+ possibleSideMoves.flatMap {
136
+ case Some ((orig, dest)) => Some (createMove(orig, dest, " side" ))
137
+ case _ => None
138
+ }
128
139
).flatten
129
140
}
130
141
@@ -183,11 +194,11 @@ abstract class Variant private[variant] (
183
194
}.flatMap {
184
195
case (pos, neighbour) =>
185
196
generateMovesForNeighbours(pos, neighbour)
186
- }
187
- ).view.toList
197
+ }).view.toList
188
198
}
189
199
}
190
200
201
+ // @TODO: would be interesting to pass the direction so we can easily differenciate a side move from a line move (orig meets dest in case of line move)
191
202
def boardAfter (situation : Situation , orig : Pos , dest : Pos ): Board = {
192
203
// 1. move pieces and get the score
193
204
val (pieces, capture) = piecesAfterAction(situation.board.pieces, situation.player, orig, dest)
@@ -210,9 +221,34 @@ abstract class Variant private[variant] (
210
221
def piecesAfterAction (pieces : PieceMap , player : Player , @ nowarn orig : Pos , dest : Pos ): (PieceMap , Boolean ) = {
211
222
var capture = false
212
223
213
- if (pieces.contains(dest)) { // push
214
- // compute direction between orig and dest to push the opponent marble
224
+ /*
225
+
226
+ * * * * *
227
+ * a A B C 1
228
+ * * * * * 2 *
229
+ How to move pieces based on orig and dest :
230
+ 1. identify the type of move :
231
+ - push : dest contains a marble (orig=C, dest=a)
232
+ - line move : orig meets dest thanks to the direction we passed as extra parameter
233
+ - side move : NOT a push or a side move
234
+
235
+ 2. play the move
236
+ - line move :
237
+ - move from orig to dest
238
+ - push :
239
+ - dest contains a marble
240
+ - we know the direction :
241
+ - apply the direction from dest until there is an empty square or being off the board
242
+ - in case of being off the board, increment the score (capture = true)
243
+ - do the line move (orig to dest)
244
+ - side move :
245
+ - apply the direction to orig and dest : but still have to find the marble in the middle in case of a move of 3 marbles ?
246
+
247
+ in case of a side move, orig=A and dest=1, how do we determine how to move A and B ?
248
+
249
+ */
215
250
251
+ if (pieces.contains(dest)) { // push
216
252
// apply that direction from orig, until we find an empty square or get out of the board (considering a max distance of 3 from dest)
217
253
218
254
// then move the 2 marbles :
0 commit comments