/// <summary> /// Tells if the moved piece on the cell changed the hit state of the blocked /// </summary> /// <param name="from">Where the piece stands right now</param> /// <param name="to">Where the piece is moved</param> /// <param name="blocked">Hit tests this piece</param> /// <returns>If blocked is hittable after moving the from</returns> public bool IsBlockedIfMove(ChessBoard.Cell from, ChessBoard.Cell to, ChessBoard.Cell blocked) { if (possibleMoves.Contains(blocked) && !possibleMoves.Contains(to)) { //The blocked is hittable to begin with and we don't block it with a new blocker //To may still equal blocked but direction should not care about that return(false); } else if (possibleMoves.Contains(from)) { int toIndex = possibleMoves.IndexOf(to); if (0 <= toIndex && toIndex < possibleMoves.Count - 1) { return(true); //The blocker closer to the piece } else { //If we moved further foreach (ChessBoard.Cell move in from.OpenLineOfSight(X, Y, DesiredCount - possibleMoves.Count)) { if (move == to) //The blocker moved into the new path { return(true); } if (move == blocked) //The blocked is hittable { return(false); } } } } //Happens when the blocker was not cotained and the blocked was not contained a perfect combination for nothing happening return(true); }
/// <summary> /// Called when the turn is passed to the other player /// </summary> private void turnOver() { board.Move(holdedNode, moveTo, promoteOption); holdedNode = null; moveTo = null; playerState = PlayerState.Idle; currentPlayer = currentPlayer == PlayerColor.White ? PlayerColor.Black : PlayerColor.White; turnStart(); }
/// <summary> /// Happens when the user presses the enter key /// </summary> private void interact() { switch (playerState) { case PlayerState.Idle: holdedNode = board.GetCell(cursorX, cursorY); if (holdedNode.Piece == null || holdedNode.Piece.Color != currentPlayer || holdedNode.Piece.LegalMoves.Count == 0) { holdedNode = null; return; } else { playerState = PlayerState.Holding; } break; case PlayerState.Holding: playerState = PlayerState.Holding; moveTo = board.GetCell(cursorX, cursorY); if (!holdedNode.Piece.LegalMoves.Contains(moveTo)) { moveTo = null; return; } if (board.IsPromotable(holdedNode, moveTo)) { showPromote(); } else { turnOver(); } break; case PlayerState.AwaitPromote: turnOver(); break; case PlayerState.GameOver: Running = false; break; } }
protected virtual bool canHit(ChessBoard.Cell cell) { return(cell != null && cell.Piece != null && cell.Piece.Color != Color); }
/// <summary> /// Tells if the moved piece on the cell changed the hit state of the blocked /// </summary> /// <param name="from">Where the piece stands right now</param> /// <param name="to">Where the piece is moved</param> /// <param name="blocked">Hit tests this piece</param> /// <returns>If blocked is hittable after moving the from</returns> public abstract bool IsBlockedIfMove(ChessBoard.Cell from, ChessBoard.Cell to, ChessBoard.Cell blocked);
/// <summary> /// Called when the piece is moved. /// Does not recalculate just yet, you have to call <see cref="Recalculate"/> for that. /// </summary> public void OnMove(ChessBoard.Cell cell) { Parent = cell; Moved = true; }
/// <summary> /// Called when the piece is first placed or when the piece is replaced after promotion. /// Does not recalculate just yet, you have to call <see cref="Recalculate"/> for that. /// </summary> public void OnPlace(ChessBoard.Cell cell) { Parent = cell; }
/// <summary> /// Happens when the user presses the escape key /// </summary> private void cancel() { playerState = PlayerState.Idle; holdedNode = null; }
/// <summary> /// Draws the game /// </summary> /// <param name="g">ConsoleGraphics object to draw with/to</param> public void Draw(ConsoleGraphics g) { g.FillArea(new CChar(' ', ConsoleColor.Black, ConsoleColor.DarkGray), 10, 5, 8, 8); //7-j everywhere cuz it's reversed in chess for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { //Draw the symbol ChessBoard.Cell cell = board.GetCell(i, j); if (cell.Piece != null) { g.DrawTransparent(cell.Piece.Char, (cell.Piece.Color == PlayerColor.White) ? ConsoleColor.White : ConsoleColor.Black, 10 + i, 5 + (7 - j)); if (cell.Piece.LegalMoves.Count == 0) { g.SetBackground(ConsoleColor.DarkRed, 10 + i, 5 + (7 - j)); } } if (cell.HitBy.Contains(debugPiece)) { g.SetBackground(ConsoleColor.DarkMagenta, 10 + i, 5 + (7 - j)); } } } if (holdedNode != null && playerState == PlayerState.Holding) { //Highlight legal moves foreach (ChessBoard.Cell move in holdedNode.Piece.LegalMoves) { g.SetBackground(ConsoleColor.DarkGreen, 10 + move.X, 5 + (7 - move.Y)); } } //Sets the cursor color -> yellow g.SetBackground(ConsoleColor.DarkYellow, 10 + cursorX, 5 + (7 - cursorY)); //TODO: Remove en passant testing /*if (board.EnPassant != null) * g.SetBackground(ConsoleColor.DarkCyan, 10 + board.EnPassant.X, 5 + (7 - board.EnPassant.Y)); * * if (board.EnPassantCapture != null) * g.SetBackground(ConsoleColor.DarkMagenta, 10 + board.EnPassantCapture.X, 5 + (7 - board.EnPassantCapture.Y));*/ //Lighten for checkerboard pattern for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if ((i + j) % 2 == 1) { g.LightenBackground(10 + i, 5 + j); } } } //Promotion option menu if (playerState == PlayerState.AwaitPromote) { g.DrawTextTrasparent("Queen", promoteOption == PromoteOptions.Queen ? ConsoleColor.Yellow : ConsoleColor.White, 22, 7); g.DrawTextTrasparent("Rook", promoteOption == PromoteOptions.Rook ? ConsoleColor.Yellow : ConsoleColor.White, 22, 9); g.DrawTextTrasparent("Bishop", promoteOption == PromoteOptions.Bishop ? ConsoleColor.Yellow : ConsoleColor.White, 22, 11); g.DrawTextTrasparent("Knight", promoteOption == PromoteOptions.Knight ? ConsoleColor.Yellow : ConsoleColor.White, 22, 13); } else { g.ClearArea(22, 7, 6, 7); } }