Skip to content

Commit

Permalink
fix: remove pawn moves dependency on the turn and remove capture move…
Browse files Browse the repository at this point in the history
…s with no adversaries
  • Loading branch information
maxim-derevyanchenko authored and mirko-felice committed Feb 20, 2023
1 parent ec60220 commit 28bea0d
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 37 deletions.
14 changes: 14 additions & 0 deletions chess/src/main/scala/io/github/chess/model/ChessBoard.scala
Expand Up @@ -21,6 +21,20 @@ trait ChessBoard:
*/
def pieces: Map[Position, Piece]

/**
* Gives access to all the white [[Piece]]s that are present on the board.
*
* @return the map containing only white [[Piece]]s of the board
*/
def whitePieces: Map[Position, Piece] = pieces.filter(_._2.team == Team.WHITE)

/**
* Gives access to all the black [[Piece]]s that are present on the board.
*
* @return the map containing only black [[Piece]]s of the board
*/
def blackPieces: Map[Position, Piece] = pieces.filter(_._2.team == Team.BLACK)

/**
* Updates the chess board assigning the specified piece to the specified position.
* @param position the specified position
Expand Down
29 changes: 29 additions & 0 deletions chess/src/main/scala/io/github/chess/model/moves/DoubleMove.scala
@@ -0,0 +1,29 @@
/*
* MIT License
* Copyright (c) 2023 Cesario Jahrim Gabriele & Derevyanchenko Maxim & Felice Mirko & Kentpayeva Madina
*
* Full license description available at: https://github.com/jahrim/PPS-22-chess/blob/master/LICENSE
*/
package io.github.chess.model.moves

import io.github.chess.model.Position

/** Represents the moving of a pawn by two steps forward. */
trait DoubleMove extends Move

/** Factory for [[DoubleMove]] instances. */
object DoubleMove:

/**
* Creates a double move, using the two needed positions.
*
* @param from source [[Position]]
* @param to target [[Position]]
* @return a new [[DoubleMove]]
*/
def apply(from: Position, to: Position): DoubleMove = PawnDoubleMove(from, to)

private case class PawnDoubleMove(
override val from: Position,
override val to: Position
) extends DoubleMove
@@ -0,0 +1,26 @@
/*
* MIT License
* Copyright (c) 2023 Cesario Jahrim Gabriele & Derevyanchenko Maxim & Felice Mirko & Kentpayeva Madina
*
* Full license description available at: https://github.com/jahrim/PPS-22-chess/blob/master/LICENSE
*/
package io.github.chess.model.rules.chess

import io.github.chess.model.moves.{CaptureMove, Move}
import io.github.chess.model.rules.chess.ChessRule
import io.github.chess.model.{ChessGameStatus, Position, Team}

/** Mixin that checks in which positions, among the found moves, there are enemy pieces, to perform the capture. */
trait BaseCaptureRule extends ChessRule:

abstract override def findMoves(position: Position, status: ChessGameStatus): Set[Move] =
super
.findMoves(position, status)
.filter(move =>
status.chessBoard.pieces.get(position) match
case Some(piece) =>
piece.team match
case Team.WHITE => status.chessBoard.blackPieces.contains(move.to)
case Team.BLACK => status.chessBoard.whitePieces.contains(move.to)
case None => false
)
@@ -0,0 +1,24 @@
/*
* MIT License
* Copyright (c) 2023 Cesario Jahrim Gabriele & Derevyanchenko Maxim & Felice Mirko & Kentpayeva Madina
*
* Full license description available at: https://github.com/jahrim/PPS-22-chess/blob/master/LICENSE
*/
package io.github.chess.model.rules.chess.pawn

import io.github.chess.model.moves.Move
import io.github.chess.model.rules.chess.{ChessRule, RuleShorthands}
import io.github.chess.model.rules.prolog.{BlackPawnCaptureRule, WhitePawnCaptureRule}
import io.github.chess.model.{ChessGameStatus, Position, Team, moves}

/** Finds all moves with which a pawn can capture an adversary piece. */
class PawnCaptureMoves extends ChessRule with RuleShorthands:

override def findMoves(position: Position, status: ChessGameStatus): Set[Move] =
status.chessBoard.pieces.get(position) match
case Some(piece) =>
(piece.team match
case Team.WHITE => WhitePawnCaptureRule()
case Team.BLACK => BlackPawnCaptureRule()
).findPositions(position).map(Move(position, _)).toSet
case None => Set.empty
Expand Up @@ -6,18 +6,7 @@
*/
package io.github.chess.model.rules.chess.pawn

import io.github.chess.model.moves.Move
import io.github.chess.model.rules.chess.ChessRule
import io.github.chess.model.rules.prolog.{BlackPawnCaptureRule, WhitePawnCaptureRule}
import io.github.chess.model.{ChessGameStatus, Position, Team, moves}
import io.github.chess.model.rules.chess.BaseCaptureRule

/** Finds all moves with which a pawn can capture an adversary piece. */
class PawnCaptureRule extends ChessRule:

override def findMoves(position: Position, status: ChessGameStatus): Set[Move] =
(status.currentTurn match
case Team.WHITE => WhitePawnCaptureRule()
case Team.BLACK => BlackPawnCaptureRule()
).findPositions(position).map(Move(position, _)).toSet

// TODO Add check that there is an adversary piece in the destination position
/** The rule that analyzes Pawn specific capture rules to say if it can perform them or not. */
class PawnCaptureRule extends PawnCaptureMoves with BaseCaptureRule
Expand Up @@ -20,8 +20,10 @@ class PawnMovementRule extends ChessRule:
else firstStep

private def isFirstMove(position: Position, status: ChessGameStatus): Boolean =
// TODO do not depend by current turn
position.rank == (status.currentTurn match
case Team.WHITE => Rank._2
case Team.BLACK => Rank._7
position.rank == (status.chessBoard.pieces.get(position) match
case Some(piece) =>
piece.team match
case Team.WHITE => Rank._2
case Team.BLACK => Rank._7
case None => false
)
Expand Up @@ -14,11 +14,14 @@ import io.github.chess.model.{ChessGameStatus, Position, Team, moves}
class SingleStepRule extends ChessRule:

override def findMoves(position: Position, status: ChessGameStatus): Set[Move] =
Set(
moves.Move(
position,
status.currentTurn match
case Team.WHITE => position.rankUp()
case Team.BLACK => position.rankDown()
)
)
status.chessBoard.pieces.get(position) match
case Some(piece) =>
Set(
Move(
position,
piece.team match
case Team.WHITE => position.rankUp()
case Team.BLACK => position.rankDown()
)
)
case None => Set.empty
Expand Up @@ -6,19 +6,22 @@
*/
package io.github.chess.model.rules.chess.pawn

import io.github.chess.model.moves.Move
import io.github.chess.model.moves.{DoubleMove, Move}
import io.github.chess.model.rules.chess.ChessRule
import io.github.chess.model.{ChessGameStatus, Position, Team, moves}

/** Implementation of a chess rule that makes move a piece two positions forward in the column. */
class TwoStepRule extends ChessRule:

override def findMoves(position: Position, status: ChessGameStatus): Set[Move] =
Set(
moves.Move(
position,
status.currentTurn match
case Team.WHITE => position.rankUp().rankUp()
case Team.BLACK => position.rankDown().rankDown()
)
)
status.chessBoard.pieces.get(position) match
case Some(piece) =>
Set(
DoubleMove(
position,
piece.team match
case Team.WHITE => position.rankUp().rankUp()
case Team.BLACK => position.rankDown().rankDown()
)
)
case None => Set.empty
Expand Up @@ -14,11 +14,12 @@ import org.scalatest.flatspec.AnyFlatSpec
/** Test suite for [[Pawn]]. */
class PawnSpec extends AbstractSpec:

private val position = Position(File.A, Rank._2)
private val pawn = Pawn(Team.WHITE)
private val chessBoard: ChessBoard = ChessBoard.empty
private val chessGameStatus = ChessGameStatus(chessBoard)
chessBoard.setPiece(position, pawn)

"A Pawn" should "always give a set of positions not empty, regardless of the chess board" in {
val position = Position(File.A, Rank._1)
"A Pawn" should "always give a set of positions not empty, within an empty board" in {
pawn.rule.findMoves(position, chessGameStatus) shouldNot be(empty)
}

0 comments on commit 28bea0d

Please sign in to comment.