From 04ae354fe8e0d1f6ff5e855efef64837b7890fa8 Mon Sep 17 00:00:00 2001 From: Ferdinand Saurenbach Date: Tue, 19 Mar 2024 17:38:15 +0100 Subject: [PATCH] #16 And first check implementation --- src/commonMain/kotlin/Main.kt | 76 +++++++++++++------ src/commonMain/kotlin/Piece.kt | 131 ++++++++++++++++++++++++--------- 2 files changed, 150 insertions(+), 57 deletions(-) diff --git a/src/commonMain/kotlin/Main.kt b/src/commonMain/kotlin/Main.kt index 0255c1b..9e6337c 100644 --- a/src/commonMain/kotlin/Main.kt +++ b/src/commonMain/kotlin/Main.kt @@ -28,8 +28,8 @@ var blackKing: Bitmap? = null var pieces = ArrayList() var whiteTurn = true var markedCells = ArrayList() -/**Initial position of the white king */ -var kingPosition = Pair(3, 4) +/** Initial position of the white king */ +var kingPosition = Pair(4, 3) /** Entry point of the application. Initializes the game window and sets up the game scene. */ suspend fun main() = Korge(windowSize = Size(512, 512), backgroundColor = Colors["#2b2b2b"]) { @@ -70,7 +70,6 @@ class GameScene(private val cont: SceneContainer) : PixelatedScene(512, 512) { initializeBoard() initializePieces() handlePieceMovement() - } private fun initializeBoard() { @@ -107,10 +106,10 @@ class GameScene(private val cont: SceneContainer) : PixelatedScene(512, 512) { val blackBishop1 = Piece(PieceKind.BlackBishop, Colors.BLACK, 2, 7, cont = cont) val blackBishop2 = Piece(PieceKind.BlackBishop, Colors.BLACK, 5, 7, cont = cont) // Set up the kings and queens - val whiteQueen = Piece(PieceKind.WhiteQueen, Colors.WHITE, 3, 0, cont = cont) + //val whiteQueen = Piece(PieceKind.WhiteQueen, Colors.WHITE, 3, 0, cont = cont) val whiteKing = Piece(PieceKind.WhiteKing, Colors.WHITE, 4, 3, cont = cont) - val blackQueen = Piece(PieceKind.BlackQueen, Colors.BLACK, 3, 7, cont = cont) - val blackKing = Piece(PieceKind.BlackKing, Colors.BLACK, 4, 7, cont = cont) + //val blackQueen = Piece(PieceKind.BlackQueen, Colors.BLACK, 3, 7, cont = cont) + //val blackKing = Piece(PieceKind.BlackKing, Colors.BLACK, 4, 7, cont = cont) pieces.addAll( whitePawns + @@ -128,10 +127,7 @@ class GameScene(private val cont: SceneContainer) : PixelatedScene(512, 512) { whiteBishop2, blackBishop1, blackBishop2, - whiteQueen, - whiteKing, - blackQueen, - blackKing)) + whiteKing)) } private fun SContainer.handlePieceMovement() { @@ -166,13 +162,15 @@ class GameScene(private val cont: SceneContainer) : PixelatedScene(512, 512) { "Found Cell where piece is located: ${cell.cx}, ${cell.cy}") } if (selectedPiece!!.moveChecker( - newPosition!!, Pair(cell.cx, cell.cy), false)) { - //println("Can move to: ${cell.cx}, ${cell.cy}") + newPosition!!, Pair(cell.cx, cell.cy), false, false)) { + // println("Can move to: ${cell.cx}, ${cell.cy}") changeColor(cell.cy, cell.cx, false) markedCells.add(cell) } } + } + } // When dragging ends @@ -194,38 +192,74 @@ class GameScene(private val cont: SceneContainer) : PixelatedScene(512, 512) { // Perform the move if no error if (!error) { - if (selectedPiece!!.moveChecker(currentPos!!, newPosition!!, true)) { + if (selectedPiece!!.moveChecker(currentPos!!, newPosition!!, true, false)) { selectedPiece!!.moveTo(newPosition!!.first, newPosition!!.second) selectedPiece = null } else { selectedPiece!!.moveTo(currentPos!!.first, currentPos!!.second) selectedPiece = null } + kingInCheck() selectedPiece = null newPosition = null currentPos = null } - for (piece in pieces) { - if (piece.color == Colors.BLACK && piece.kind == PieceKind.BlackPawn) { - val piecePos = decodePosition(piece.position) - if (piece.moveChecker(piecePos, kingPosition, false)) { - println("KING IN CHECK!") - } - } - } // Reset colors and variables for (cell in markedCells) { changeColor(cell.cy, cell.cx, true) } markedCells.clear() error = false + } } } } } +var checkedCells = ArrayList() + +/** + * Checks if the king is in check. + * + * The function performs the following steps: + * 1. Resets the colors of previously checked cells. + * 2. Clears the list of checked cells. + * 3. Checks each black piece to see if it can move to the king's position. + * 4. If a piece can move to the king's position, the king is in check. The cell of the threatening piece is marked red and added to the list of checked cells. + */ +fun kingInCheck() { + // Iterate over all checked cells + for (cell in checkedCells) { + // Decode the position of the cell to get the x and y coordinates + val cx = decodePosition(cell.pos).first + val cy = decodePosition(cell.pos).second + // Change the color of the cell based on the sum of the x and y coordinates + cell.color = if ((cx + cy).isEven) Colors.WHITE else Colors.BLACK + } + // Clear the list of checked cells + checkedCells.clear() + println("cleared checkedCells...") + // Iterate over all pieces + for (piece in pieces) { + // Decode the position of the piece + val piecePos = decodePosition(piece.position) + // If the piece is black + if (piece.color == Colors.BLACK) { + println("Piece: $piecePos, King: $kingPosition") + // Check if the piece can move to the position of the king + if (piece.moveChecker(piecePos, kingPosition, false, true)) { + println("KING IN CHECK! kingPosition: $kingPosition") + // If the piece can move to the position of the king, change the color of the cell the piece is on to red + val b = board[piecePos.second][piecePos.first] + checkedCells.add(b) + b.color = Colors.RED + } + } + } +} + /** * Changes the color of a cell on the game board. * diff --git a/src/commonMain/kotlin/Piece.kt b/src/commonMain/kotlin/Piece.kt index 104f159..80ad3b0 100644 --- a/src/commonMain/kotlin/Piece.kt +++ b/src/commonMain/kotlin/Piece.kt @@ -44,14 +44,14 @@ fun decodePosition(cxy: Point): Pair { * @property cont The scene container. */ class Piece( - var kind: PieceKind, + private var kind: PieceKind, val color: RGBA, private val cx: Int, private val cy: Int, private val cont: SceneContainer, ) : View() { - var pieceKind: PieceKind = kind + private var pieceKind: PieceKind = kind private lateinit var piece: Image var position = board[cx][cy].pos @@ -113,36 +113,98 @@ class Piece( * @param performMove Indicates whether to perform the move or just check its validity. * @return true if the move is valid, false otherwise. */ - fun moveChecker(oldPos: Pair, newPos: Pair, performMove: Boolean): Boolean { + fun moveChecker( + oldPos: Pair, + newPos: Pair, + performMove: Boolean, + king: Boolean + ): Boolean { val pieceOnNewPos = pieces.find { it.position == board[newPos.second][newPos.first].pos } if (pieceOnNewPos != null && pieceOnNewPos.color == color) { // Prevent moving to a cell occupied by a piece of the same color during the check for // valid moves return false } - return if (whiteTurn) { - when (pieceKind) { - PieceKind.WhitePawn -> moveWhitePawn(oldPos, newPos, pieceOnNewPos, performMove) - PieceKind.WhiteRook -> moveRook(oldPos, newPos, pieceOnNewPos, performMove, true) - PieceKind.WhiteKnight -> moveWhiteKnight(oldPos, newPos, pieceOnNewPos, performMove) - PieceKind.WhiteBishop -> - moveBishop(oldPos, newPos, pieceOnNewPos, performMove, true) - PieceKind.WhiteQueen -> TODO() - PieceKind.WhiteKing -> moveWhiteKing(oldPos, newPos, pieceOnNewPos, performMove) - else -> false + if (!king) { + return if (whiteTurn) { + when (pieceKind) { + PieceKind.WhitePawn -> moveWhitePawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteKnight -> + moveWhiteKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteQueen -> TODO() + PieceKind.WhiteKing -> moveWhiteKing(oldPos, newPos, pieceOnNewPos, performMove) + else -> false + } + } else { + when (pieceKind) { + PieceKind.BlackPawn -> moveBlackPawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackKnight -> + moveBlackKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackQueen -> TODO() + PieceKind.BlackKing -> TODO() + else -> false + } } - } else { - when (pieceKind) { - PieceKind.BlackPawn -> moveBlackPawn(oldPos, newPos, pieceOnNewPos, performMove) - PieceKind.BlackRook -> moveRook(oldPos, newPos, pieceOnNewPos, performMove, false) - PieceKind.BlackKnight -> moveBlackKnight(oldPos, newPos, pieceOnNewPos, performMove) - PieceKind.BlackBishop -> - moveBishop(oldPos, newPos, pieceOnNewPos, performMove, false) - PieceKind.BlackQueen -> TODO() - PieceKind.BlackKing -> TODO() - else -> false + } + + if (king) { + return if (whiteTurn) { + when (pieceKind) { + PieceKind.WhitePawn -> moveWhitePawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteKnight -> + moveWhiteKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteQueen -> TODO() + PieceKind.WhiteKing -> moveWhiteKing(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackPawn -> moveBlackPawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackKnight -> + moveBlackKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackQueen -> TODO() + PieceKind.BlackKing -> TODO() + } + } else { + when (pieceKind) { + PieceKind.WhitePawn -> moveWhitePawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteKnight -> + moveWhiteKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.WhiteBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, true) + PieceKind.WhiteQueen -> TODO() + PieceKind.WhiteKing -> moveWhiteKing(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackPawn -> moveBlackPawn(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackRook -> + moveRook(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackKnight -> + moveBlackKnight(oldPos, newPos, pieceOnNewPos, performMove) + PieceKind.BlackBishop -> + moveBishop(oldPos, newPos, pieceOnNewPos, performMove, false) + PieceKind.BlackQueen -> TODO() + PieceKind.BlackKing -> TODO() + } } } + + return false + + + } private fun moveWhiteKing( @@ -154,11 +216,8 @@ class Piece( val rowDiff = abs(newPos.first - oldPos.first) val colDiff = abs(newPos.second - oldPos.second) - - // Check if the king is in check by iterating through all the pieces and checking if any of them can move to the kings position - - - + // Check if the king is in check by iterating through all the pieces and checking if any of + // them can move to the kings position if (rowDiff <= 1 && colDiff <= 1) { if (pieceOnNewPos == null) { @@ -188,7 +247,7 @@ class Piece( if (isPawnMoveForward || isInitialPawnMove) { if (pieceOnNewPos == null) { if (performMove) whiteTurn = false - //println("legal") + // println("legal") return true } } else if (newPos.second - oldPos.second == 1 && @@ -198,11 +257,11 @@ class Piece( removePiece(pieceOnNewPos) whiteTurn = false } - //println("legal") + // println("legal") return true } } - //println("illegal") + // println("illegal") return false } @@ -364,12 +423,12 @@ class Piece( val p = if (p1 == p2) p1 else null val color = if (isWhite) Colors.WHITE else Colors.BLACK - println("Old position: $oldPos") - println("New position: $newPos") - println("All pieces:") + // println("Old position: $oldPos") + // println("New position: $newPos") + // println("All pieces:") for (piece in pieces) { - val piecePos = decodePosition(piece.position) - println("Piece at position: $piecePos") + decodePosition(piece.position) + // println("Piece at position: $piecePos") } if (p != null) {