public Board() { string startingColor; string otherColor; string currentColor; boardSpaces = new Space[boardSize, boardSize]; for(int i = 0; i < boardSize; i++) { if(i % 2 == 0) { startingColor = "Black"; otherColor = "White"; } else { startingColor = "White"; otherColor = "Black"; } for(int j = 0; j < boardSize; j++) { currentColor = (j % 2 == 0) ? startingColor : otherColor; boardSpaces[i, j] = new Space(currentColor); } } }
public Knight(Space space, string color) : base(space, color) { Name = Color.Substring(0, 1) + "Kn"; }
public Queen(Space space) : base(space) { XCoord = space.XCoord; YCoord = space.yCoord; }
/********************************************************************* * ButtonClick * Handles the button click for each space of the board *********************************************************************/ public void ButtonClick(object sender, MouseEventArgs e) { Space thisButton = ((Space)sender); //MessageBox.Show(whiteTeam[0].GetRow().ToString() + " " + whiteTeam[0].GetColumn().ToString()); if (!gameOver) { // Check if it was a right mouse click if (e.Button == MouseButtons.Right) { // if this was the selected space then we unselect it if (selected != null && thisButton.GetPiece() == selected) { selected = null; thisButton.ForeColor = thisButton.GetPiece().GetTextColor(); ClearPossible(); return; } } // left mouse click else { // if there isn't a piece selected if (selected == null) { // if the place we just clicked on has a piece there if (thisButton.GetPiece() != null) { // if the piece is on our team if (turn == thisButton.GetPiece().GetTeam()) { // set this piece as the selected one selected = thisButton.GetPiece(); if (e.Button == MouseButtons.Right) { } else { // calculate all the spots this piece could move to selected.CalcPossMoves(board); // if it can't move then we unselect it if (selected.GetPossMoves().Count == 0) { selected = null; } // we set the text color to yellow to show which piece is selected else { thisButton.ForeColor = Color.Yellow; ShowPossibleMoves(); } } } } } // if we already had a selected piece else { int row = thisButton.GetRow(); int col = thisButton.GetCol(); // if the selected piece can be moved here then we move it if (IsPossible(row, col)) { int fromRow = selected.GetRow(); int fromCol = selected.GetColumn(); MoveTo(fromRow, fromCol, row, col); ClearPossible(); gameOver = IsCheckMate(); SwitchTurn(); } } } } }
//MAIN PROGRAM static void Main(string[] args) { bool New_Game = true; string player1 = ""; string player2 = ""; string turn = ""; List <Space> Board = new List <Space>(); List <Piece> Captured_Pieces = new List <Piece>(); bool check = false; bool checkmate = false; while (true) { if (New_Game) { //Define Players Console.WriteLine("Player 1 (White), what is your name?"); player1 = Console.ReadLine(); Console.WriteLine("Player 2 (Black), what is your name?"); player2 = Console.ReadLine(); turn = "White"; //White moves first. //Construct Board Board = Starting_Board(); Captured_Pieces = new List <Piece>(); New_Game = false; } //Display board Display_Board(Board, Captured_Pieces); //Check for check (heh) check = Check(Board, turn); //Check for checkmate checkmate = Checkmate(Board, turn); //Take turn (Choose initial space and target space, check for invalid inputs along the way) if (turn == "White") { Console.Write(player1 + ", it's your turn!"); if (checkmate) { Console.Write(" Oh no, you're in checkmate! Make your final move..."); } else if (check) { Console.Write(" Careful, your king is in check!"); } Console.WriteLine(); } else if (turn == "Black") { Console.Write(player2 + ", it's your turn!"); if (checkmate) { Console.Write(" Oh no, you're in checkmate! Make your final move..."); } else if (check) { Console.Write(" Careful, your king is in check!"); } Console.WriteLine(); } else { break; } Piece selected_piece = new Piece(); Space initial_space = new Space(); Space target_space = new Space(); //Ask for initial space, check validity bool valid_initial = false; while (!valid_initial) { valid_initial = true; Console.WriteLine("Please enter the X coordinate of the piece you want to move:"); string initial_x = Console.ReadLine(); Console.WriteLine("Please enter the Y coordinate of the piece you want to move:"); string initial_y = Console.ReadLine(); Console.WriteLine(); bool x_is_number = int.TryParse(initial_x, out int x); bool y_is_number = int.TryParse(initial_y, out int y); Space space = new Space(); if (!x_is_number) { Console.WriteLine("The space you have selected is invalid."); valid_initial = false; } else if (!y_is_number) { Console.WriteLine("The space you have selected is invalid."); valid_initial = false; } else if (x < 0 || x > 7) { Console.WriteLine("The space you have selected is out of bounds."); valid_initial = false; } else if (y < 0 || y > 7) { Console.WriteLine("The space you have selected is out of bounds."); valid_initial = false; } if (valid_initial) { space = Board[x + 8 * y]; if (!space.ContainsPiece) { Console.WriteLine("The space you have selected is empty."); valid_initial = false; } else if (space.ContainsPiece && space.CurrentPiece.Side != turn) { Console.WriteLine("The space you have selected contains an opposing piece."); valid_initial = false; } } if (valid_initial) { selected_piece = space.CurrentPiece; initial_space = space; } } //Ask for target space, check validity bool valid_target = false; while (!valid_target) { valid_target = true; Console.WriteLine("Please enter the X coordinate of the space you want to move the " + selected_piece.Side + " " + selected_piece.Name + " to:"); string target_x = Console.ReadLine(); Console.WriteLine("Please enter the Y coordinate of the space you want to move the " + selected_piece.Side + " " + selected_piece.Name + " to:"); string target_y = Console.ReadLine(); Console.WriteLine(); bool x_is_number = int.TryParse(target_x, out int x); bool y_is_number = int.TryParse(target_y, out int y); Space space = new Space(); if (!x_is_number) { Console.WriteLine("The space you have selected is invalid."); valid_target = false; } else if (!y_is_number) { Console.WriteLine("The space you have selected is invalid."); valid_target = false; } else if (x < 0 || x > 7) { Console.WriteLine("The space you have selected is out of bounds."); valid_target = false; } else if (y < 0 || y > 7) { Console.WriteLine("The space you have selected is out of bounds."); valid_target = false; } if (valid_target) { space = Board[x + 8 * y]; if (space.X == initial_space.X && space.Y == initial_space.Y) { Console.WriteLine("The space you have selected is the initial location."); valid_target = false; } else if (space.ContainsPiece && space.CurrentPiece.Side == turn) { Console.WriteLine("The space you have selected contains one of your own pieces."); valid_target = false; } } //Check if the target can be reached under the movement rules for the piece if (valid_target) { if (!selected_piece.is_Valid_Move(initial_space, space)) { Console.WriteLine("The space you have selected can't be reached by a " + selected_piece.Name + "."); valid_target = false; } } //Check for collision during movement (Not necessary for the knight, who can jump over pieces, or for the king, who doesn't have valid moves that could put him past other pieces.) //Note that, by this point, we have already verified that the move is a legal move and is targeting an empty space or an opposing piece. if (valid_target) { if (selected_piece.will_Collide(Board, initial_space, space)) { Console.WriteLine("The path to the space you have selected is blocked by other pieces."); valid_target = false; } } //If target space survives all validity checks, assign it if (valid_target) { target_space = space; } else { Console.WriteLine(); Console.WriteLine("You have failed to enter a valid target space. Press any key to start your turn over."); Console.ReadKey(); //This break is required; if the target space request loops like the initial space request, the program enters an infinite loop if the piece has no valid space to move to, i.e. a king in the starting position. break; } } //Update board and captured pieces list if (valid_initial && valid_target) { int initial_index = initial_space.X + 8 * initial_space.Y; int target_index = target_space.X + 8 * target_space.Y; if (target_space.ContainsPiece) { Captured_Pieces.Add(target_space.CurrentPiece); } selected_piece.HasMoved = true; Board[target_index].CurrentPiece = selected_piece; Board[target_index].ContainsPiece = true; Board[initial_index].CurrentPiece = new Piece(); Board[initial_index].ContainsPiece = false; //Check for promotion if (selected_piece.Name == "Pawn" && turn == "White" && target_space.Y == 7) { string ans = ""; bool valid_ans = false; Console.WriteLine("Congratulations on the promotion, " + player1 + "! What will your pawn become? (Choose Bishop/Knight/Rook/Queen, please captialize.)"); while (!valid_ans) { ans = Console.ReadLine(); if (ans == "Bishop") { Board[target_index].CurrentPiece = new Piece("White", "Bishop", "WB"); valid_ans = true; } else if (ans == "Knight") { Board[target_index].CurrentPiece = new Piece("White", "Knight", "WN"); valid_ans = true; } else if (ans == "Rook") { Board[target_index].CurrentPiece = new Piece("White", "Rook", "WR"); valid_ans = true; } else if (ans == "Queen") { Board[target_index].CurrentPiece = new Piece("White", "Queen", "WQ"); valid_ans = true; } else { Console.WriteLine("Invalid piece. Choose Bishop/Knight/Rook/Queen, please captialize."); } } } else if (selected_piece.Name == "Pawn" && turn == "Black" && target_space.Y == 0) { string ans = ""; bool valid_ans = false; Console.WriteLine("Congratulations on the promotion, " + player2 + "! What will your pawn become? (Choose Bishop/Knight/Rook/Queen, please captialize.)"); while (!valid_ans) { ans = Console.ReadLine(); if (ans == "Bishop") { Board[target_index].CurrentPiece = new Piece("Black", "Bishop", "BB"); valid_ans = true; } else if (ans == "Knight") { Board[target_index].CurrentPiece = new Piece("Black", "Knight", "BN"); valid_ans = true; } else if (ans == "Rook") { Board[target_index].CurrentPiece = new Piece("Black", "Rook", "BR"); valid_ans = true; } else if (ans == "Queen") { Board[target_index].CurrentPiece = new Piece("Black", "Queen", "BQ"); valid_ans = true; } else { Console.WriteLine("Invalid piece. Choose Bishop/Knight/Rook/Queen, please captialize."); } } } //Check for winners bool win = false; for (int i = 0; i < Captured_Pieces.Count; i++) { if (Captured_Pieces[i].Name == "King") { win = true; } } if (win) { Display_Board(Board, Captured_Pieces); if (turn == "White") { Console.WriteLine("Congratulations, " + player1 + "! You win!"); } else if (turn == "Black") { Console.WriteLine("Congratulations, " + player2 + "! You win!"); } else { break; } string ans = ""; while (ans != "y" && ans != "Y" && ans != "n" && ans != "N") { Console.WriteLine("Play again? Y/N"); ans = Console.ReadLine(); } if (ans == "n" || ans == "N") { break; } else if (ans == "y" || ans == "Y") { Console.WriteLine(); New_Game = true; } } //Update turn if (turn == "White") { turn = "Black"; } else if (turn == "Black") { turn = "White"; } else { break; } } } }
//INCOMPLETE static bool Checkmate(List <Space> Board, string turn) { bool can_run = true; bool can_attack = true; bool can_block = true; List <Space> target_spaces = new List <Space>(); List <Space> threatened_spaces = new List <Space>(); List <Space> king_threateners = new List <Space>(); List <Piece> threat_pieces = new List <Piece>(); Space king_space = new Space(); king_space.ContainsPiece = false; //Locate king's space for (int i = 0; i < Board.Count; i++) { if (Board[i].ContainsPiece && Board[i].CurrentPiece.Name == "King" && Board[i].CurrentPiece.Side == turn) { king_space = Board[i]; } } //If a king is not found, return false if (!king_space.ContainsPiece) { return(false); } //Create a list of spaces the king could run to (within one tile that are empty or contain an opposing piece) for (int i = 0; i < Board.Count; i++) { if (Math.Abs(Board[i].X - king_space.X) <= 1 && Math.Abs(Board[i].Y - king_space.Y) <= 1) { if (!Board[i].ContainsPiece) { target_spaces.Add(Board[i]); } else if (Board[i].ContainsPiece && Board[i].CurrentPiece.Side != turn) { target_spaces.Add(Board[i]); } else if (Board[i] == king_space) { target_spaces.Add(Board[i]); } } } //Check to see which of the previous spaces are threatened by opposing pieces for (int i = 0; i < Board.Count; i++) { if (Board[i].ContainsPiece && Board[i].CurrentPiece.Side != turn) { Space threat_space = Board[i]; Piece threat_piece = Board[i].CurrentPiece; for (int j = 0; j < target_spaces.Count; j++) { if (threat_piece.is_Valid_Move(threat_space, target_spaces[j]) && !threat_piece.will_Collide(Board, threat_space, target_spaces[j]) && !threatened_spaces.Contains(target_spaces[j])) { threatened_spaces.Add(target_spaces[j]); if (target_spaces[j] == king_space) { king_threateners.Add(threat_space); } } } } } //Check to see if the king's space and all surrounding spaces are threatened. Note that because we did not add duplicate spaces to threatened_spaces and restricted the add loop to the size of target_spaces, the following condition holds. if (target_spaces.Count == threatened_spaces.Count) { can_run = false; //If the king cannot run, the only remaining ways out are attacking or blocking any piece that currently threatens the king. //Note that you cannot block or attack two opposing pieces with one move. So: if (king_threateners.Count > 1) { return(true); } } if (!can_run) { //Check to see if the piece that threatens the king can be attacked. Note that, if the king can't run, the only remaining possibility that doesn't return a value is that exactly one piece threatens the king. for (int i = 0; i < Board.Count; i++) { if (Board[i].ContainsPiece && Board[i].CurrentPiece.Side == turn) { Space threat_space = Board[i]; Piece threat_piece = Board[i].CurrentPiece; if (threat_piece.is_Valid_Move(threat_space, king_threateners[0]) && !threat_piece.will_Collide(Board, threat_space, king_threateners[0])) { can_attack = false; break; } } } if (!can_attack) { if (king_threateners[0].CurrentPiece.Name == "Knight") { can_block = false; return(true); } List <Space> possible_blocks = king_threateners[0].CurrentPiece.Path(Board, king_threateners[0], king_space); //Check to see if the piece that threatens the king can be blocked. for (int i = 0; i < Board.Count; i++) { if (Board[i].ContainsPiece && Board[i].CurrentPiece.Side == turn) { Space threat_space = Board[i]; Piece threat_piece = Board[i].CurrentPiece; for (int j = 0; j < possible_blocks.Count; j++) { if (threat_piece.is_Valid_Move(threat_space, possible_blocks[j]) && !threat_piece.will_Collide(Board, threat_space, possible_blocks[j])) { can_block = false; break; } } if (!can_block) { break; } } } if (!can_block) { return(true); } else { return(false); } } else { return(false); } } else { return(false); } }
public bool gameOver; //false when still; true when king killed //starts a new game of chess //intitailizes {@code rep} public Board() { gameOver = false; rep = new Space[8, 8]; for (int col = 0; col < deminsion; col++) { for (int row = 0; row < deminsion; row++) { if (row == 0 || row == 1) { Team white = Team.White; if (row == 0) { if (col == 0 || col == 7) { rep[col, row] = new Space(Value.Rook, white, false); } else if (col == 1 || col == 6) { rep[col, row] = new Space(Value.Knight, white); } else if (col == 2 || col == 5) { rep[col, row] = new Space(Value.Bishop, white); } else if (col == 4) { rep[col, row] = new Space(Value.King, white, false); } else { rep[col, row] = new Space(Value.Queen, white); } } else { rep[col, row] = new Space(Value.Pawn, white); } } else if (row == 6 || row == 7) { Team white = Team.Black; if (row == 7) { if (col == 0 || col == 7) { rep[col, row] = new Space(Value.Rook, white, false); } else if (col == 1 || col == 6) { rep[col, row] = new Space(Value.Knight, white); } else if (col == 2 || col == 5) { rep[col, row] = new Space(Value.Bishop, white); } else if (col == 4) { rep[col, row] = new Space(Value.King, white, false); } else { rep[col, row] = new Space(Value.Queen, white); } } else { rep[col, row] = new Space(Value.Pawn, white); } } else { rep[col, row] = new Space(Value.Empty, Team.None); } } } }
/// <summary> /// Checks if move is possible and does it /// </summary> /// <param name="team"> The team moving </param> /// <param name="source"></param> /// <param name="destination"></param> /// @requires source to be a team peice /// <returns>true if does move</returns> public bool ExecuteMove(Team team, string source, string destination) { //check for castling; //1. neither have moved //2. no peice between them //checks that destination is on same team bool executeMove = AvailableSource(team, destination); if (executeMove) { char[] sourceArray = source.ToCharArray(); int colSource = Convert.ToInt32(sourceArray[0]) - 65; int rowSource = Convert.ToInt32(source[1]) - 49; char[] destinationArray = destination.ToCharArray(); int colDest = Convert.ToInt32(destinationArray[0]) - 65; int rowDest = Convert.ToInt32(destinationArray[1]) - 49; executeMove = executeMove ? (!rep[colSource, rowSource].moved && !rep[colDest, rowDest].moved) : executeMove; executeMove = executeMove ? (rep[colSource, rowSource].worth == Value.King || rep[colDest, rowDest].worth == Value.King) : executeMove; if (Math.Abs(colSource - colDest) == 4) { //left castling for (int i = 1; i <= 3; i++) { executeMove = executeMove ? rep[i, rowDest].worth == Value.Empty : executeMove; } if (executeMove) { rep[2, rowDest] = new Space(Value.King, team); rep[3, rowDest] = new Space(Value.Rook, team); rep[colSource, rowSource] = new Space(); rep[colDest, rowDest] = new Space(); } } else // right castling { for (int i = 5; i <= 6; i++) { executeMove = executeMove ? rep[i, rowDest].worth == Value.Empty : executeMove; } if (executeMove) { rep[6, rowDest] = new Space(Value.King, team); rep[5, rowDest] = new Space(Value.Rook, team); rep[colSource, rowSource] = new Space(); rep[colDest, rowDest] = new Space(); } } } if (!executeMove) { executeMove = AvailableDestination(team, source, destination); if (executeMove) { char[] sourceArray = source.ToCharArray(); int colSource = Convert.ToInt32(sourceArray[0]) - 65; int rowSource = Convert.ToInt32(source[1]) - 49; char[] destinationArray = destination.ToCharArray(); int colDest = Convert.ToInt32(destinationArray[0]) - 65; int rowDest = Convert.ToInt32(destinationArray[1]) - 49; //place new piece in source if (rep[colDest, rowDest].worth == Value.King) { this.gameOver = true; } rep[colDest, rowDest] = new Space(rep[colSource, rowSource].worth, team); //clear source rep[colSource, rowSource] = new Space(); //check if pawn made it to the end if (rep[colDest, rowDest].worth == Value.Pawn && ((rowDest == 0 && team == Team.Black) || (rowDest == 7 && team == Team.White))) { bool correctInput = false; do { Console.Write("Enter 'Q' for Queen of 'K' for knight: "); string peice = Console.ReadLine().Trim().ToUpper(); if (peice.Equals("Q")) { rep[colDest, rowDest] = new Space(Value.Queen, team); correctInput = true; } else if (peice.Equals("K")) { rep[colDest, rowDest] = new Space(Value.Knight, team); correctInput = true; } } while (!correctInput); } } } return(executeMove); }