//Adds a collection of moves for easy manipulation public void Add(MoveList moves) { foreach (Move move in moves) { this.Add(move); } }
public MoveList filterMovesThatBlockAttack(MoveList moves, Location blockedAttack) { if (moves.Count == 0) { return(moves); } MoveList filtered = new MoveList(); foreach (Move move in moves) { GameBoard copy = this.Copy(); copy.movePiece(move); IList <AbstractPiece> attackers = copy.getAttackers(moves[0].startLocation, getPiece(moves[0].startLocation).color); bool allowsAttack = false; foreach (AbstractPiece attacker in attackers) { MoveList attackerMoves = copy.getMoves(attacker); if (attackerMoves.ContainsAttacked(blockedAttack)) { allowsAttack = true; break; } } if (!allowsAttack) { filtered.Add(move); } } return(filtered); }
///Constructors public Move() { subsequentMoves = new MoveList(); attackedLocations = new List <Location>(); neededEmptyLocations = new List <Location>(); ignorePossibleMoves = false; }
public Move(Location startLocal, Location endLocal, MoveList subsequentMoves, IList <Location> attackedLocations, IList <Location> neededEmtpyLocations) : this(startLocal, endLocal) { this.subsequentMoves = subsequentMoves; this.attackedLocations = attackedLocations; this.neededEmptyLocations = neededEmtpyLocations; }
///Methods //Overidden with Knight piece logic public override MoveList getPieceMoves(GameBoard board, Location startLocation, ColorEnum color) { MoveList moves = new MoveList(); for (int i = 0; i <= 1; i++) { for (int j = -1; j <= 1; j += 2) { for (int k = -1; k <= 1; k += 2) { int xShift = (1 + i) * j, yShift = (2 - i) * k; Location poss = startLocation.Shift(xShift, yShift); if (board.locationOnBoard(poss)) { if (!board.pieceAtLocation(poss)) { Move newMove = new Move(startLocation, poss); newMove.AddNeededEmtpyLocations(poss.Copy()); moves.Add(newMove); } else if (board.getPiece(poss).color != color) { Move attack = new Move(startLocation, poss); attack.AddAttackedLocation(poss); moves.Add(attack); } } } } } return(moves); }
///Methods //Overidden with King piece logic //Does not include that a king cannot move to an attacked square, that is added in FilteringMoves public override MoveList getPieceMoves(GameBoard board, Location startLocation, ColorEnum color) { MoveList moves = new MoveList(); for (int i = 0; i < 8; i++) { Location possible = startLocation.Shift(Location.directionIndex(i)); if (board.locationOnBoard(possible)) {// Cannot include the idea that a king cant move to an attack space as it links to the king and creates an infinite loop //Needs to be filtered on the outside of the gameboard if (!board.pieceAtLocation(possible)) { Move newMove = new Move(startLocation, possible); newMove.AddNeededEmtpyLocations(possible.Copy()); moves.Add(newMove); } else if (board.getPiece(possible).color != color) { Move attack = new Move(startLocation, possible); attack.AddAttackedLocation(possible); moves.Add(attack); } } } return(moves); }
//Creates a shallow copy of the List public MoveList Copy() { MoveList newList = new MoveList(); foreach (Move move in this) { newList.Add(move); } return(newList); }
public MoveList getMoves(ColorEnum color) { MoveList moves = new MoveList(); foreach (AbstractPiece piece in getPieces(color)) { moves.Add(getMoves(piece)); } return(moves); }
///Methods //Overidden with Queen piece logic public override MoveList getPieceMoves(GameBoard board, Location startLocation, ColorEnum color) { MoveList moves = new MoveList(); Location local; for (int i = 0; i < 8; i++) { local = new Location(startLocation); IList <Location> previousEmpty = new List <Location>(); while (true) { local = local.Shift(Location.directionIndex(i)); //Conditional for stopping the array if (!board.locationOnBoard(local)) { break; } if (board.pieceAtLocation(local)) { if (board.getPiece(local).color != color) { Move attack = new Move(startLocation, local); attack.AddAttackedLocation(local); foreach (Location empty in previousEmpty) { attack.AddNeededEmtpyLocations(empty.Copy()); } moves.Add(attack); } break; } previousEmpty.Add(local); Move nonAttack = new Move(startLocation, local); //Includes the end location as it is non attack foreach (Location empty in previousEmpty) { nonAttack.AddNeededEmtpyLocations(empty.Copy()); } moves.Add(nonAttack); } } return(moves); }
protected MoveList OnFilterMoves(AbstractPiece piece, MoveList moves) { MoveFilteringHandler handler = FilterMoves; if (handler != null) { return(handler(piece, moves)); } //Nothing was handling this event pass on the original return(moves); }
///Methods //Selects and Deselects the possible moves of a location private void SelectMovePossibilites(Location local) { MoveList moves = gameBoard.getMoves(local); if (moves == null) { return; } foreach (Move move in moves) { Tile tile = gameBoard.getTile(move.endLocation); tile.overlay.BackgroundImage = Chess_Program.Properties.Resources.Targeting; } }
private void DeselectMovePossibilites(Location local) { //Might stor the moves from last selection, less on the computer MoveList moves = gameBoard.getMoves(local); if (moves == null) { return; } foreach (Move move in moves) { Tile tile = gameBoard.getTile(move.endLocation); tile.overlay.BackgroundImage = null; } }
public bool isMoveBlockingAttack(Move move, Location blockedAttack) { GameBoard copy = this.Copy(); copy.movePiece(move);//Allows for simulation IList <AbstractPiece> attackers = getAttackers(getPiece(move.startLocation)); foreach (AbstractPiece attacker in attackers) { MoveList moves = copy.getMoves(attacker); if (moves.ContainsAttacked(blockedAttack)) { return(true); } } return(false); }
public MoveList getMovesToBlockMove(Move attackingMove, ColorEnum color) { MoveList list = new MoveList(); IList <Location> blockedLocations = attackingMove.GetNeededEmtpyLocations(); foreach (AbstractPiece piece in getPieces(color)) { foreach (Move move in getMoves(piece)) { if (doesMoveContainEndLocation(move, blockedLocations)) { list.Add(move); } } } return(list); }
///Methods //Overidden with Pawn piece logic public override MoveList getPieceMoves(GameBoard board, Location startLocation, ColorEnum color) { MoveList moves = new MoveList(); int forward = getYForward(); Location forwardLoc = startLocation.Shift(0, forward); if (board.locationOnBoard(forwardLoc) && !board.pieceAtLocation(forwardLoc)) { Move newMove = new Move(startLocation, forwardLoc); newMove.AddNeededEmtpyLocations(forwardLoc.Copy()); moves.Add(newMove); //Needs to be able to do the first forward in order to do the second one Location doubleForwardLoc = forwardLoc.Shift(0, forward); if (board.locationOnBoard(doubleForwardLoc) && !board.pieceAtLocation(doubleForwardLoc) && !getHasMoved()) { Move doubleForwardNewMove = new Move(startLocation, doubleForwardLoc); doubleForwardNewMove.AddNeededEmtpyLocations(forwardLoc.Copy()); doubleForwardNewMove.AddNeededEmtpyLocations(doubleForwardLoc.Copy()); moves.Add(doubleForwardNewMove); } } //Two attacks for (int i = -1; i <= 1; i += 2) { Location sideAttack = startLocation.Shift(i, forward); if (board.locationOnBoard(sideAttack) && board.pieceAtLocation(sideAttack) && board.getPiece(sideAttack).color != color) { Move sideAttackMove = new Move(startLocation, sideAttack); sideAttackMove.AddAttackedLocation(sideAttack); moves.Add(sideAttackMove); } } return(moves); }
public IList <AbstractPiece> getAttackers(Location startLocation, ColorEnum color) { if (!locationOnBoard(startLocation)) { return(null); } //Loop through each derived type IList <AbstractPiece> attackers = new List <AbstractPiece>(); foreach (Type type in AbstractPiece.getDerivedTypes()) { Type[] parameterTypes = { typeof(GameBoard), typeof(Location), typeof(ColorEnum) }; MethodInfo method = type.GetMethod("getPieceMoves", parameterTypes); if (method == null) { continue; // Should have exceptions here } object[] parameters = { this, startLocation, color }, constructor = { color, startLocation }; MoveList moves = (MoveList)method.Invoke(Activator.CreateInstance(type, constructor), parameters); foreach (Move move in moves) { IList <AbstractPiece> pieces = getPieces(move.GetAttackedLocations()); foreach (AbstractPiece piece in pieces)//Kinda wonky { if (piece != null && piece.GetType().Equals(type)) { //Means the reverse attack met with a piece of the correct type attackers.Add(piece); } } } } return(attackers); }
/* * Modifies the moves that come from GameBoard.getMoves() by handling the FilterMoves event * This allows for programmers to have more control over the moves that pieces are allowed to make * * Currently adds the Castling to a kings moveset * As well as disallowing pieces to move in a way the puts the king into check */ public MoveList FilteringMoves(AbstractPiece piece, MoveList moves) { //Need to filter certain moves out of this and return a new list //Need to filter out moves that put the king in check (By moving out of the way), having the king move into check, and that don't stop the king from being in check (Not taking out the current king attacker or blocking the attack path) if (piece.getPieceType().Contains("King")) { MoveList kingMoves = new MoveList(); //Readding moves with the added specification that they can't be attacked foreach (Move move in moves) { if (!gameBoard.checkAttacked(move.endLocation, piece.color)) { kingMoves.Add(move); } } //Add castling as a special move if (!piece.getHasMoved()) { //check for rooks in position that have not moved int baseDistance = 2; for (int i = -1; i <= 1; i += 2) { //baseDistance +1 or +0 for (int j = 1; j <= 2; j++) { Location rook = piece.location.Shift(i * (baseDistance + j), 0); if (gameBoard.locationOnBoard(rook) && gameBoard.pieceAtLocation(rook)) { AbstractPiece checkedPiece = gameBoard.getPiece(rook); if (checkedPiece.getPieceType() == "Rook" && checkedPiece.color == piece.color && !checkedPiece.getHasMoved()) { //The piece itself is fine now check for spaces inbetween bool allEmpty = true; for (int x = rook.x - i; x != piece.location.x; x -= i) { Location emptyLocation = new Location(x, piece.location.y); if (!gameBoard.locationOnBoard(emptyLocation) || gameBoard.pieceAtLocation(emptyLocation)) { allEmpty = false; break; } } //And check to see if the spaces the king will pass are under attack bool allNotUnderAttack = true; for (int x = piece.location.x; x != piece.location.x + (baseDistance + 1) * i; x += i) { Location attackLocation = new Location(x, piece.location.y); if (gameBoard.checkAttacked(attackLocation, piece.color)) { allNotUnderAttack = false; break; } } if (allEmpty && allNotUnderAttack) { //Need to switch over to a move based system Move kingMove = new Move(piece.location, piece.location.Shift(i * baseDistance, 0)); Move rookMove = new Move(rook, piece.location.Shift(i * (baseDistance - 1), 0)); rookMove.SetIgnorePossibleMoves(true); kingMove.AddSubsequentMove(rookMove); kingMoves.Add(kingMove); } } } } } } //A special case that needs to be handled externally return(kingMoves); } //Filter out moves that put the king in check else { MoveList returnMoves = moves.Copy(); //Filter out moves that don't stop a check IList <AbstractPiece> kings = gameBoard.getPieces(typeof(King), piece.color); IList <AbstractPiece> attackers = gameBoard.getAttackers(kings); if (attackers.Count > 0) { for (int i = 0; i < returnMoves.Count; i++) { Move move = returnMoves[i]; bool unhandled = true; foreach (AbstractPiece attacker in attackers) { //Take out the attacking piece or Block the attack if (move.GetAttackedLocations().Contains(attacker.location) || gameBoard.doesMoveBlockMove(attacker.getMoves(gameBoard).GetAttackedMove(kings[0].location), move)) { continue; } else { //If any attacker is still attacking the king after the move, move is invalid unhandled = false; break; } } if (!unhandled) { returnMoves.Remove(move); i--;//Needs back down one index to account for the removed object } } } //Filter out moves that put the king into check returnMoves = gameBoard.filterMovesThatBlockAttack(returnMoves, kings[0]); return(returnMoves); } return(moves); }
//Takes a list of moves and removes any that allow an attack to pass public MoveList filterMovesThatBlockAttack(MoveList moves, AbstractPiece blockedPiece) { return(filterMovesThatBlockAttack(moves, blockedPiece.location)); }