Пример #1
0
        protected void CompletelyRandom()
        {
            bool done = false;
            int  x, y;
            bool result;

            while (!done)
            {
                x = rand.Next(GameState.BOARDHEIGHT);
                y = rand.Next(GameState.BOARDWIDTH);
                if (opponentBoard.AvailableMove(x, y))
                {
                    result = opponentBoard.MakeMove(x, y);
                    opponentBoard.DisplayAction(x, y, $"NPC player{playerNum}");
                    // DEBUG, Change to display just opponent board later
                    DisplayGameState.DisplayOpponentBoard(opponentBoard);
                    //DisplayGameState.DisplayBothBoards(opponentBoard, ownBoard);
                    if (result)
                    {
                        currentSearch = new HashSet <Tuple <int, int> >();
                        currentSearch.Add(new Tuple <int, int>(x, y));
                        searchNewShip = false;
                    }
                    done = true;
                }
            }
        }
        private void PlaceShips()
        {
            bool done;

            Tuple <int, int>[] shipCoordinates;
            PLACEMENT_STATUS   status = PLACEMENT_STATUS.CONTINUE;

            foreach (Tuple <string, int> piece in Ship.PIECES)
            {
                // initialize ship coordinates
                shipCoordinates = new Tuple <int, int> [piece.Item2];
                // testing just a do something x time loop
                for (int i = 0; i < shipCoordinates.Length; i++)
                {
                    // Go right 1
                    shipCoordinates[i] = new Tuple <int, int>(i * Ship.DIRECTIONS[0].Item1, i * Ship.DIRECTIONS[0].Item2);
                }
                done   = false;
                status = PLACEMENT_STATUS.CONTINUE;
                while (!done)
                {
                    Console.Clear();
                    DisplayInstructions();
                    // Display status related to controls
                    switch (status)
                    {
                    case PLACEMENT_STATUS.CONTINUE:
                        Console.WriteLine($"Please place the size {piece.Item2} {piece.Item1}");
                        break;

                    case PLACEMENT_STATUS.PLACEMENT_ERROR:
                        Console.ForegroundColor = ERROR_COLOR;
                        Console.WriteLine("A ship is already there! Please choose another location");
                        Console.ResetColor();
                        break;

                    default:
                        // in theory should never have PLACEMENT_STATUS.PLACED_OK
                        Console.WriteLine("Should not reach here");
                        break;
                    }
                    DisplayGameState.DisplayOwnBoard(playerGameState, shipCoordinates);
                    // if tried to
                    status = PlaceShipCommands(shipCoordinates);
                    if (status == PLACEMENT_STATUS.CAN_PLACE)
                    {
                        if (playerGameState.ValidPlacement(shipCoordinates))
                        {
                            playerGameState.AddShip(new Ship(piece.Item1, shipCoordinates));
                            done = true;
                        }
                    }
                }
                Console.Clear();
                Console.WriteLine("All ships successfully placed");
                DisplayGameState.DisplayOwnBoard(playerGameState);
            }
        }
        private void PickSpot()
        {
            columnNumber = rowNumber = -1;
            bool done = false;
            // For now result not actually used
            bool            result = false;
            TargetingStatus status = TargetingStatus.Continue;

            while (!done)
            {
                Console.Clear();
                DisplayInstructions();
                DisplayCurrentStatus();
                if (status == TargetingStatus.Continue)
                {
                    Console.WriteLine("");
                }
                else if (status == TargetingStatus.InvalidTarget)
                {
                    Console.ForegroundColor = ERROR_COLOR;
                    Console.WriteLine("Invalid location, please call out another location");
                    Console.ResetColor();
                }
                else
                {
                    // Should not reach here
                    Console.WriteLine("Time to debug why the game did not break out of loop");
                }

                DisplayGameState.DisplayBothBoards(opponentGameState, playerGameState, rowNumber, columnNumber);
                status = HandleInput(ReadUserInput());
                if (status == TargetingStatus.LegalTarget)
                {
                    result = opponentGameState.MakeMove(rowNumber, columnNumber);
                    done   = true;
                }
            }
            Console.Clear();
            opponentGameState.DisplayAction(rowNumber, columnNumber, "Player" + playerNum);
            // Display board state one last time before clearing screen
            DisplayGameState.DisplayBothBoards(opponentGameState, playerGameState, rowNumber, columnNumber);
        }
Пример #4
0
        // Hmmm, there are some really difficult game states for NPC to check
        // In the interest of time, I will not make the AI completely optimal
        // Some ship placement can be really tricky and will require AI to keep track of order of moves
        // For now I do not want to do that
        protected void Nextmove()
        {
            List <int[]> soFar = new List <int[]>();
            // NPC will randomly select a hit, and use DFS to prioritize adjacent hits
            // Continue Adjacent path if able, otherwise, choose any legal move
            // Randomly choose to go thorugh direction list forward or backward
            int index = rand.Next(currentSearch.Count);

            //gotta assign it to something
            Tuple <int, int>            temp;
            HashSet <Tuple <int, int> > highPriority = new HashSet <Tuple <int, int> >();
            HashSet <Tuple <int, int> > lowPriority  = new HashSet <Tuple <int, int> >();
            List <int[]> highPriorityList            = new List <int[]>();
            List <int[]> lowPriorityList             = new List <int[]>();

            // Randomly choosing a number from HashSet
            // O(N) but best to have this here since it's done once per move
            foreach (Tuple <int, int> t in currentSearch)
            {
                foreach (Tuple <int, int> direction in Ship.DIRECTIONS)
                {
                    temp = new Tuple <int, int>(t.Item1 + direction.Item1, t.Item2 + direction.Item2);
                    // check if the move is good
                    if (ValidMove(temp.Item1, temp.Item2))
                    {
                        if (TwoAdjacent(temp.Item1, temp.Item2))
                        {
                            if (!highPriority.Contains(temp))
                            {
                                highPriority.Add(temp);
                                highPriorityList.Add(new int[] { temp.Item1, temp.Item2 });
                            }
                        }
                        else if (!lowPriority.Contains(temp))
                        {
                            lowPriority.Add(temp);
                            lowPriorityList.Add(new int[] { temp.Item1, temp.Item2 });
                        }
                    }
                }
            }
            int[] result;
            if (highPriority.Count > 0)
            {
                result = highPriorityList[rand.Next(highPriorityList.Count)];
            }
            else if (lowPriority.Count > 0)
            {
                result = lowPriorityList[rand.Next(highPriorityList.Count)];
            }
            else
            {
                result = new int[] { 0, 0 };
                Console.WriteLine("Something went seriously wrong at choose next NPC move");
            }
            opponentBoard.MakeMove(result[0], result[1]);
            if (opponentBoard.IsHit(result[0], result[1]))
            {
                currentSearch.Add(new Tuple <int, int>(result[0], result[1]));
            }
            opponentBoard.DisplayAction(result[0], result[1], $"NPC player{playerNum}");
            // DEBUG, Display just opponent board state
            DisplayGameState.DisplayOpponentBoard(opponentBoard);
            //DisplayGameState.DisplayBothBoards(opponentBoard, ownBoard);


            // Check if AI will continue to search for ships or go completely random next turn
            FoundAllNearbyShips();
        }