// Checks if two squares are within a distance of 1 public Boolean SquaresInProximity(Square sq1, Square sq2) { int distance = (int)Math.Sqrt(Math.Pow(sq2.PositionX - sq1.PositionX, 2) + Math.Pow(sq2.PositionY - sq1.PositionY, 2)); return(distance <= 1); }
// returns the list of all targetable squares on the opponent's gameboard protected List <Square> GetLegalSquaresOpp() { List <Square> sqList = new List <Square>(); Boolean tooCloseToShip = false; int shortestShipLength = int.MaxValue; foreach (Square sq in this.board.Squares) { tooCloseToShip = false; if (!sq.IsHit) { // find destroyed ships and check if the target square is within distance of 1 to that ship // if it is, then ignore that square foreach (Ship ship in this.board.Ships) { if (ship.isDestroyed()) { foreach (Square shipsq in ship.ShipParts) { if (SquaresInProximity(shipsq, sq)) { tooCloseToShip = true; break; } } } else if (ship.Length < shortestShipLength) { shortestShipLength = ship.Length; } if (tooCloseToShip) { break; } } // only target squares that aren't blocked off by already hit squares and board limits // add them if the proximity could fit the smallest not destroyed ship Boolean legalDirExists = false; foreach (Direction d in ViableDirections) { Boolean shipFits = true; for (int i = 0; i < shortestShipLength - 1; i++) { Square tempSquare = GetNextSquareInDirection(sq, d, this.board.Squares); if (ReferenceEquals(tempSquare, null)) { shipFits = false; } else if (tempSquare.IsHit) { shipFits = false; } if (shipFits) { break; } } if (shipFits) { legalDirExists = true; break; } } // add the square if it's neither too close to a destroyed ship, nor blocked off if (!tooCloseToShip && legalDirExists) { sqList.Add(sq); } } } return(sqList); }
// checks if direction d is a viable direction for the given length of a ship protected Boolean IsLegalDirection(Square sq, int shipLength, Direction d, Boolean Opp = false) { Boolean DirectionIsLegal = true; int X = sq.PositionX; int Y = sq.PositionY; for (int i = 0; i < shipLength; i++) { switch (d) { case Direction.UP: if (!Opp && !legalSquares.Any(x => x.PositionX == X && x.PositionY == Y - 1)) { DirectionIsLegal = false; } else if (Opp && !GetLegalSquaresOpp().Any(x => x.PositionX == X && x.PositionY == Y - 1)) { DirectionIsLegal = false; } else { Y--; } break; case Direction.DOWN: if (!Opp && !legalSquares.Any(x => x.PositionX == X && x.PositionY == Y + 1)) { DirectionIsLegal = false; } else if (Opp && !GetLegalSquaresOpp().Any(x => x.PositionX == X && x.PositionY == Y + 1)) { DirectionIsLegal = false; } else { Y++; } break; case Direction.LEFT: if (!Opp && !legalSquares.Any(x => x.PositionX == X - 1 && x.PositionY == Y)) { DirectionIsLegal = false; } else if (Opp && !GetLegalSquaresOpp().Any(x => x.PositionX == X - 1 && x.PositionY == Y)) { DirectionIsLegal = false; } else { X--; } break; case Direction.RIGHT: if (!Opp && !legalSquares.Any(x => x.PositionX == X + 1 && x.PositionY == Y)) { DirectionIsLegal = false; } else if (Opp && !GetLegalSquaresOpp().Any(x => x.PositionX == X + 1 && x.PositionY == Y)) { DirectionIsLegal = false; } else { X++; } break; default: break; } if (!DirectionIsLegal) { break; } } return(DirectionIsLegal); }