示例#1
0
        // randomly places all ships on the gameboard
        public List <Ship> PlaceShips()
        {
            List <Ship> tempList = new List <Ship>();
            ShipPart    sp;
            int         shipLength = 0;
            Direction   d;

            foreach (Ship s in this.board.Ships)
            {
                sp         = new ShipPart(GetRandomLegalSquare());
                shipLength = s.GetInitialShipLength();
                d          = (Direction)rand.Next(3);
                int tries = 0;

                // try to find a direction that fits the length of the ship
                // if we haven't found a direction after x tries, get a new square
                while (!IsLegalDirection(sp, shipLength, d) && tries < 20)
                {
                    if (IsLegalDirection(sp, shipLength, d))
                    {
                        break;
                    }
                    else
                    {
                        d = (Direction)rand.Next(3);
                        tries++;
                        if (tries == 19)
                        {
                            sp    = new ShipPart(GetRandomLegalSquare(false));
                            tries = 0;
                        }
                    }
                }

                RemoveIllegalSquares(s.PlaceShip(sp, d));
                tempList.Add(s);
            }
            return(tempList);
        }
示例#2
0
        // if the ai has hit a ShipPart in the previous turn, try destroying the ship it belongs to
        private Square TargetShip()
        {
            ShipPart  sp             = null;
            Square    targetSquare   = null;
            Boolean   squareHit      = false;
            Boolean   isTargetedShip = false;
            Direction randomDir      = ViableDirections[rand.Next(ViableDirections.Count - 1)];

            // loop through all squares we have already hit
            foreach (Square sq in hitLog)
            {
                // check if the square is a shippart and belongs to an undestroyed ship
                if (sq.IsShipPart())
                {
                    sp = new ShipPart(sq);

                    foreach (Ship ship in board.Ships)
                    {
                        if (!ship.isDestroyed())
                        {
                            // check if that ship contains the current square
                            if (ship.ShipParts.Any(x => x == sp))
                            {
                                isTargetedShip = true;
                            }
                        }
                    }

                    if (isTargetedShip)
                    {
                        // analyse the next square in a direction until we find a not already hit square
                        // the direction is chosen randomly until we find a viable direction which yields undestroyed shipparts
                        do
                        {
                            // when we aren't sure where the ship actually is
                            if (TargetDirection == Direction.NONE)
                            {
                                targetSquare = GetNextSquareInDirection(sp, randomDir, board.Squares);

                                // while we haven't found a targetable square, try targeting squares in different directions
                                while (ReferenceEquals(targetSquare, null) || (!targetSquare.IsShipPart() && targetSquare.IsHit))
                                {
                                    ViableDirections.Remove(randomDir);
                                    randomDir    = ViableDirections[rand.Next(ViableDirections.Count - 1)];
                                    targetSquare = GetNextSquareInDirection(sp, randomDir, board.Squares);
                                }
                            }
                            // when we are sure where (at least part of) the ship is
                            else
                            {
                                targetSquare = GetNextSquareInDirection(sp, TargetDirection, board.Squares);

                                // if the targeted square isn't targetable, invert the targetdirection and pursue it
                                if (ReferenceEquals(targetSquare, null) || (!targetSquare.IsShipPart() && targetSquare.IsHit))
                                {
                                    TargetDirection = InvertDirection(TargetDirection);
                                    targetSquare    = GetNextSquareInDirection(sp, TargetDirection, board.Squares);
                                }
                            }

                            if (targetSquare.IsShipPart())
                            {
                                sp = new ShipPart(targetSquare);
                            }
                        }while (targetSquare.IsShipPart() && sp.Destroyed);

                        // if we haven't yet figured out where the ship is, target the previously chosen square, which might actually be a miss
                        if (TargetDirection == Direction.NONE)
                        {
                            // if it hit, set the TargetDirection to the current direction
                            if (TargetSquare(targetSquare))
                            {
                                TargetDirection = randomDir;
                            }
                            // if it was a miss, remove the current direction from the ViableDirections list and get a new random direction from the list
                            else
                            {
                                ViableDirections.Remove(randomDir);
                                randomDir = ViableDirections[rand.Next(ViableDirections.Count - 1)];
                            }
                            squareHit = true;
                        }
                        // when we have a targetdirection
                        else
                        {
                            // if we've missed, invert the targetdirection
                            if (!TargetSquare(targetSquare))
                            {
                                TargetDirection = InvertDirection(TargetDirection);
                            }
                            squareHit = true;
                        }

                        if (squareHit)
                        {
                            foreach (Ship ship in this.board.Ships)
                            {
                                // if we destroyed the ship, reset the targetdirection and the viabledirections list
                                if (ship.isDestroyed() && ship.ShipParts.Any(x => x == targetSquare))
                                {
                                    TargetDirection = Direction.NONE;
                                    ResetDirections();
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }

            return(targetSquare);
        }