private bool mayKingMoveOrthogonallyHere(AttackedSquare clearMove, IEnumerable <AttackedSquare> attacksOnKing, List <AttackedSquare> attacks) { var kingSquare = (Square)attacksOnKing.First(); //need to detect if we're moving into check var anybodyAttackingThisSquare = attacks.Any(a => a.Index == clearMove.Index && a.AttackingSquare.Piece.Color != kingSquare.Piece.Color); if (anybodyAttackingThisSquare) { return(false); } //now make sure we're not ignoring the issue where an attack isn't displayed because the king was blocking the square //that he would move into, that is still being attacked by the original attacker. var isRankMove = GeneralEngine.GivenOrthogonalMove_IsItARankMove(clearMove.AttackingSquare.Index, clearMove.Index); //find all attackers who attack orthogonally and determine if they are on the same line var orthogonalAttacksOnKing = attacksOnKing.Where(a => orthogonalAttackers.Contains(a.AttackingSquare.Piece.PieceType)); foreach (var x in orthogonalAttacksOnKing) { var oxs = getEntireOrthogonalLine(isRankMove ? false : true, x); //if oxs contains the clearMove.Index, then the king has not moved out of check if (oxs.Contains(clearMove.Index)) { return(false); } } return(true); }
private bool mayKingMoveDiagonallyHere(AttackedSquare clearMove, IEnumerable <AttackedSquare> attacksOnKing, List <AttackedSquare> attacks) { var kingSquare = (Square)attacksOnKing.First(); //need to detect if we're moving into check var anybodyAttackingThisSquare = attacks.Any(a => a.Index == clearMove.Index && a.AttackingSquare.Piece.Color != kingSquare.Piece.Color); if (anybodyAttackingThisSquare) { return(false); } var diagonalAttacksOnKing = attacksOnKing.Where(a => diagonalAttackers.Contains(a.AttackingSquare.Piece.PieceType) && DiagonalEngine.IsDiagonal(a.Index, a.AttackingSquare.Index) ); if (!diagonalAttacksOnKing.Any()) { return(true); } foreach (var x in diagonalAttacksOnKing) { var dxs = DiagonalEngine.GetDiagonalLine(x.Index, x.AttackingSquare.Index); //if dxs contains the clearMove.Index, then the king has not moved out of check if (dxs.Contains(clearMove.Index)) { return(false); } } return(true); }
public static List <AttackedSquare> GetDiagonalLine(GameState gameState, Square square, Piece attackingPiece, DiagonalDirection direction) { var attacks = new List <AttackedSquare>(); var diagonalLine = getIteratorByDirectionEnum(direction); var position = square.Index; var attackPosition = square.Index; do { if (!canDoDiagonalsFromStartPosition(position, diagonalLine)) { break; } attackPosition = attackPosition + diagonalLine; var moveViability = GeneralEngine.DetermineMoveViability(gameState, attackingPiece, attackPosition); //I don't think either of these conditions should occur. if (!moveViability.IsValidCoordinate || moveViability.SquareToAdd == null) { continue; } var attack = new AttackedSquare(square, moveViability.SquareToAdd, isProtecting: moveViability.IsTeamPiece); attacks.Add(attack); if (moveViability.SquareToAdd.Occupied) { break; } } while (isValidDiagonalCoordinate(attackPosition)); return(attacks); }
public List <AttackedSquare> GetOrthogonalLine(GameState gameState, Square square, Direction direction) { var attacks = new List <AttackedSquare>(); var currentPosition = square.Index; var lineTerminator = getOrthogonalLineTerminator(direction, currentPosition); var iterator = getIteratorByDirectionEnum(direction); var nextPositionInTheLine = currentPosition + iterator; for (var position = nextPositionInTheLine; position != lineTerminator; position = position + iterator) { var isValidCoordinate = GeneralEngine.IsValidCoordinate(position); if (!isValidCoordinate) { break; } var moveViability = GeneralEngine.DetermineMoveViability(gameState, square.Piece, position); //these conditions shouldn't occur if (!moveViability.IsValidCoordinate || moveViability.SquareToAdd == null) { continue; } var attack = new AttackedSquare(square, moveViability.SquareToAdd, isProtecting: moveViability.IsTeamPiece); attacks.Add(attack); if (moveViability.SquareToAdd.Occupied) { break; } } return(attacks); }
//private List<int> getEntireDiagonalLine(int pos1, int pos2) //{ // //diagonal moves: rise LtoR / or RtoL \ // var diff = Math.Abs(pos1 - pos2); // var ltr = diff % 9 == 0; // var rtl = diff % 7 == 0; // if (!ltr && !rtl) // { // throw new Exception("What? This is supposed to be diagonal."); // } // var dxs = new List<int> { pos1, pos2 }; // //smallest # will be closest to the left or right in the line // //the left terminating position is evenly divisible by 8 // //the right terminating position is evently divisible by 7 // //find terminators // //left // var increment = ltr ? 9 : 7; // var smallest = dxs.Min(); // var largest = dxs.Max(); // var nextSmallest = smallest; // while (nextSmallest % 8 > 0 && nextSmallest >= 0) // { // nextSmallest = nextSmallest - increment; // if (nextSmallest >= 0 && !dxs.Contains(nextSmallest)) // { // dxs.Add(nextSmallest); // } // }; // //right // var nextLargest = largest; // while (nextLargest % 7 > 0 && nextLargest <= 63) // { // nextLargest = nextLargest + increment; // if (nextLargest <= 63 && !dxs.Contains(nextLargest)) // { // dxs.Add(nextLargest); // } // }; // //fill in the middle // var mid = smallest; // var nextMid = mid; // if (diff > increment) // { // while (nextMid < largest) // { // nextMid = nextMid + increment; // if (!dxs.Contains(nextMid)) // { // dxs.Add(nextMid); // } // } // } // return dxs; //} private List <int> getEntireOrthogonalLine(bool isRankMove, AttackedSquare x, bool trim = false) { List <int> result; if (isRankMove) { var file = NotationEngine.PositionToFile(x.Index); result = this._orthogonalService.GetEntireFile(file); } else { var rank = NotationEngine.PositionToRank(x.Index); result = this._orthogonalService.GetEntireRank(rank); } if (!trim) { return(result); } var low = x.Index > x.AttackingSquare.Index ? x.AttackingSquare.Index : x.Index; var high = x.Index < x.AttackingSquare.Index ? x.AttackingSquare.Index : x.Index; return(result.Where(a => a > low && a < high).ToList()); }