示例#1
0
        private void TakeShot(object sender, EventArgs e)
        {
            // consider adding a check for type in the future to made it more modular
            Label selected = (Label)sender;

            // create a Coords for the player shot and send it to the opponent
            if (selected.BackColor == Color.DodgerBlue)
            {
                Coords playerShot = new Coords(OpponentBoard.GetRow(selected), OpponentBoard.GetColumn(selected));
                int    result     = AI.ResolveShot(playerShot);
                UpdateLabel(true, result);

                // if a miss, chance to miss color, otherwise turn hit color and check for sunk
                if (result == 0)
                {
                    selected.BackColor = Color.AliceBlue;
                }
                else
                {
                    selected.BackColor = Color.Red;

                    // adjust the ship labels if a ship was sunk
                    if (result > 1)
                    {
                        switch (result)
                        {
                        case 2:
                            OpponentPTBoatLabel.Font = new Font(OpponentPTBoatLabel.Font, FontStyle.Strikeout);
                            break;

                        case 3:
                            OpponentSubmarineLabel.Font = new Font(OpponentSubmarineLabel.Font, FontStyle.Strikeout);
                            break;

                        case 4:
                            OpponentDestroyerLabel.Font = new Font(OpponentDestroyerLabel.Font, FontStyle.Strikeout);
                            break;

                        case 5:
                            OpponentBattleshipLabel.Font = new Font(OpponentBattleshipLabel.Font, FontStyle.Strikeout);
                            break;

                        case 6:
                            OpponentCarrierLabel.Font = new Font(OpponentCarrierLabel.Font, FontStyle.Strikeout);
                            break;

                        default:
                            break;
                        }
                    }
                }
            }
            // if the have already selected that space it will not be the normal color and we can discout their click
            else
            {
                return;
            }

            if (AI.CheckLose())
            {
                MessageBox.Show("You won!", "Victory!");
                Close();
            }

            // now the opponent shoots at us **temporary code ***
            Coords opponentShot = AI.TakeTurn();
            int    shotResult   = ResolveShot(opponentShot);

            AI.Report(shotResult);
            UpdateLabel(false, shotResult);

            Control label = BoardTable.GetControlFromPosition(opponentShot.x, opponentShot.y);

            // if a miss, chance to miss color, otherwise turn hit color and check for sunk
            if (shotResult == 0)
            {
                label.BackColor = Color.AliceBlue;
            }
            else
            {
                label.BackColor = Color.Red;

                // adjust the ship labels if a ship was sunk
                if (shotResult > 1)
                {
                    switch (shotResult)
                    {
                    case 2:
                        PlayerPTBoatLabel.Font = new Font(PlayerPTBoatLabel.Font, FontStyle.Strikeout);
                        break;

                    case 3:
                        PlayerSubmarineLabel.Font = new Font(PlayerSubmarineLabel.Font, FontStyle.Strikeout);
                        break;

                    case 4:
                        PlayerDestroyerLabel.Font = new Font(PlayerDestroyerLabel.Font, FontStyle.Strikeout);
                        break;

                    case 5:
                        PlayerBattleshipLabel.Font = new Font(PlayerBattleshipLabel.Font, FontStyle.Strikeout);
                        break;

                    case 6:
                        PlayerCarrierLabel.Font = new Font(PlayerCarrierLabel.Font, FontStyle.Strikeout);
                        break;

                    default:
                        break;
                    }
                }
            }

            if (shipsSunk > 4)
            {
                MessageBox.Show("You lost, better luck next time", "Defeat");
                Close();
            }
        }
示例#2
0
 // reverses the direction modifier in case we need to swap
 private void reverseDirection()
 {
     directionModifier = new Coords(0 - directionModifier.x, 0 - directionModifier.y);
 }
示例#3
0
 //get a modifier that we can add to a coordinate to get a new coordinate in the correct direction
 private void findDirection()
 {
     directionModifier = new Coords((pastHits[pastHits.Count - 1].x - pastHits[pastHits.Count - 2].x), (pastHits[pastHits.Count - 1].y - pastHits[pastHits.Count - 2].y));
 }
示例#4
0
        // used to subract a sunk ship amount of coordinates from past hits in the case that we tagged two ships
        private void TrimHits(int size)
        {
            //int count = pastHits.Count - 1;
            //int trimTo = count - size;
            //for (int i = count; i > trimTo; i--)
            //{
            //    pastHits.RemoveAt(i);
            //}

            // new code to replace old starts here
            Coords lastHit = pastHits[pastHits.Count - 1];

            // if we are horizontal
            if ((lastHit.y - pastHits[0].y) == 0)
            {
                if ((lastHit.x - pastHits[0].x) < 0)
                {
                    // O(n^m) which is worrisome, possible candidate for refactor, might not matter with the max of m being 5 though
                    for (int i = 0; i < size; i++)
                    {
                        foreach (Coords coord in pastHits)
                        {
                            if ((coord.x - i) == lastHit.x)
                            {
                                pastHits.Remove(coord);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < size; i++)
                    {
                        foreach (Coords coord in pastHits)
                        {
                            if ((coord.x + i) == lastHit.x)
                            {
                                pastHits.Remove(coord);
                                break;
                            }
                        }
                    }
                }
            }
            // otherwise we are vertical orientation
            else
            {
                if ((lastHit.y - pastHits[0].y) < 0)
                {
                    for (int i = 0; i < size; i++)
                    {
                        foreach (Coords coord in pastHits)
                        {
                            if ((coord.y - i) == lastHit.y)
                            {
                                pastHits.Remove(coord);
                                break;
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < size; i++)
                    {
                        foreach (Coords coord in pastHits)
                        {
                            if ((coord.y + i) == lastHit.y)
                            {
                                pastHits.Remove(coord);
                                break;
                            }
                        }
                    }
                }
            }
        }
示例#5
0
        public Coords TakeTurn()
        {
            Coords guess = new Coords(0, 0);
            Coords lastGuess;
            bool   valid = false;

            /* Handle the AI behavior based on state. The states are as follows:
             * 1 - random guesses to find a hit.
             * 2 - got a hit but searching for a path to keep getting hits
             * 3 - following the path that is found until sinking a ship or getting a miss
             * 4 - path reached end, now going the other direction to score a sink
             * 5 - continuing the direction following the reversal, similar to state 3
             * 6 - go to a multihit location and start going, similar to state 4
             * 7 - continue the direction, similar to state 3 and 5
             * 8 - When we have already flipped during the multihit stage, look out for multihits within multihits
             * 9 - contrinuing along post reverse looking out for multihits within multihits
             * */

            while (!valid)
            {
                switch (AIstate)
                {
                case 1:
                    guess = RandomGuess();
                    // validation built into the function
                    valid = true;
                    break;

                case 2:
                    int trialHit = randomizer.Next(hitArea.Count);
                    guess = hitArea[trialHit];
                    // validation built into the function
                    valid = true;
                    pastGuesses.Add(guess);
                    hitArea.RemoveAt(trialHit);
                    break;

                case 3:
                    lastGuess = pastGuesses[pastGuesses.Count - 1];
                    guess     = new Coords((lastGuess.x + directionModifier.x), (lastGuess.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 4:
                    guess = new Coords((hitSpot.x + directionModifier.x), (hitSpot.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 5:
                    lastGuess = pastGuesses[pastGuesses.Count - 1];
                    guess     = new Coords((lastGuess.x + directionModifier.x), (lastGuess.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 6:
                    guess = new Coords((hitSpot.x + directionModifier.x), (hitSpot.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 7:
                    lastGuess = pastGuesses[pastGuesses.Count - 1];
                    guess     = new Coords((lastGuess.x + directionModifier.x), (lastGuess.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 8:
                    guess = new Coords((hitSpot.x + directionModifier.x), (hitSpot.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                case 9:
                    lastGuess = pastGuesses[pastGuesses.Count - 1];
                    guess     = new Coords((lastGuess.x + directionModifier.x), (lastGuess.y + directionModifier.y));
                    if (ValidateGuess(guess))
                    {
                        pastGuesses.Add(guess);
                        valid = true;
                    }
                    else
                    {
                        Report(0);
                    }
                    break;

                default:
                    valid = true;
                    guess = RandomGuess();
                    break;
                }
            }

            return(guess);
        }
示例#6
0
        // takes the result of the guess and sets state accordingly
        public void Report(int status)
        {
            // this controls the logic in case of a miss
            if (status == 0)
            {
                // this gets the last guess so we can use as a reference
                Coords guess = pastGuesses[pastGuesses.Count - 1];

                switch (AIstate)
                {
                case 1:
                    break;

                case 2:
                    if (hitArea.Count == 0)
                    {
                        AIstate = 1;
                    }
                    break;

                case 3:
                    reverseDirection();
                    AIstate = 4;
                    break;

                case 4:
                    ConvertToMultiHit();
                    pastHits.Clear();
                    hitSpot = multiHit.Dequeue();
                    pastHits.Add(hitSpot);
                    findDirectionMulti(hitSpot);
                    AIstate = 6;
                    break;

                case 5:
                    ConvertToMultiHit();
                    pastHits.Clear();
                    hitSpot = multiHit.Dequeue();
                    pastHits.Add(hitSpot);
                    findDirectionMulti(hitSpot);
                    AIstate = 6;
                    break;

                case 6:
                    reverseDirection();
                    AIstate = 8;
                    break;

                case 7:
                    reverseDirection();
                    AIstate = 8;
                    break;

                case 8:
                    SaveMultiHit();
                    break;

                case 9:
                    SaveMultiHit();
                    break;

                default:
                    AIstate = 1;
                    break;
                }
            }

            // this controls the logic if a hit is scored
            else if (status == 1)
            {
                // this gets the last guess so we can use as a reference
                Coords guess = pastGuesses[pastGuesses.Count - 1];

                switch (AIstate)
                {
                case 1:
                    hitSpot = guess;
                    createHitArea(guess);
                    pastHits.Add(guess);
                    AIstate = 2;
                    break;

                case 2:
                    pastHits.Add(guess);
                    findDirection();
                    AIstate = 3;
                    break;

                case 3:
                    pastHits.Add(guess);
                    break;

                case 4:
                    pastHits.Add(guess);
                    AIstate = 5;
                    break;

                case 5:
                    pastHits.Add(guess);
                    break;

                case 6:
                    pastHits.Add(guess);
                    AIstate = 7;
                    break;

                case 7:
                    pastHits.Add(guess);
                    break;

                case 8:
                    pastHits.Add(guess);
                    AIstate = 9;
                    break;

                case 9:
                    pastHits.Add(guess);
                    break;

                default:
                    AIstate = 1;
                    break;
                }
            }

            // this controls the logic if a ship is sunk
            else if (status > 1)
            {
                int    size;
                Coords guess = pastGuesses[pastGuesses.Count - 1];
                pastHits.Add(guess);

                switch (status)
                {
                case 2:
                    size = 2;
                    break;

                case 3:
                    size = 3;
                    break;

                case 4:
                    size = 3;
                    break;

                case 5:
                    size = 4;
                    break;

                case 6:
                    size = 5;
                    break;

                default:
                    //something has gone horribly wrong
                    size = 0;
                    break;
                }

                switch (AIstate)
                {
                case 1:
                    resetState();
                    AIstate = 1;
                    break;

                case 2:
                    resetState();
                    AIstate = 1;
                    break;

                case 3:
                    if (pastHits.Count == size)
                    {
                        resetState();
                        AIstate = 1;
                    }
                    else
                    {
                        TrimHits(size);
                        reverseDirection();
                        AIstate = 4;
                    }
                    break;

                case 4:
                    if (pastHits.Count == size)
                    {
                        resetState();
                        AIstate = 1;
                    }
                    else
                    {
                        TrimHits(size);
                        ConvertToMultiHit();
                        pastHits.Clear();
                        hitSpot = multiHit.Dequeue();
                        pastHits.Add(hitSpot);
                        findDirectionMulti(hitSpot);
                        AIstate = 6;
                        break;
                    }
                    break;

                case 5:
                    if (pastHits.Count == size)
                    {
                        resetState();
                        AIstate = 1;
                    }
                    else
                    {
                        TrimHits(size);
                        ConvertToMultiHit();
                        pastHits.Clear();
                        hitSpot = multiHit.Dequeue();
                        pastHits.Add(hitSpot);
                        findDirectionMulti(hitSpot);
                        AIstate = 6;
                        break;
                    }
                    break;

                case 6:
                    if (pastHits.Count == size)
                    {
                        pastHits.Clear();
                        if (multiHit.Count == 0)
                        {
                            resetState();
                            AIstate = 1;
                        }
                        else
                        {
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                        }
                    }
                    else
                    {
                        TrimHits(size);
                        reverseDirection();
                        AIstate = 6;
                    }
                    break;

                case 7:
                    if (pastHits.Count == size)
                    {
                        pastHits.Clear();
                        if (multiHit.Count == 0)
                        {
                            resetState();
                            AIstate = 1;
                        }
                        else
                        {
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            AIstate = 6;
                        }
                    }
                    else
                    {
                        TrimHits(size);
                        reverseDirection();
                        AIstate = 6;
                    }
                    break;

                case 8:
                    if (pastHits.Count == size)
                    {
                        pastHits.Clear();
                        if (multiHit.Count == 0)
                        {
                            resetState();
                            AIstate = 1;
                        }
                        else
                        {
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                        }
                    }
                    else
                    {
                        TrimHits(size);
                        SaveMultiHit();

                        // get a new multihit going
                        if (multiHit.Count == 0)
                        {
                            multiHit = chainedMultiHits.Dequeue();
                            pastHits.Clear();
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            findDirectionMulti(hitSpot);
                            AIstate = 6;
                        }
                        // save for later
                        else
                        {
                            pastHits.Clear();
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            AIstate = 6;
                        }
                    }
                    break;

                case 9:
                    if (pastHits.Count == size)
                    {
                        pastHits.Clear();
                        if (multiHit.Count == 0)
                        {
                            resetState();
                            AIstate = 1;
                        }
                        else
                        {
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            AIstate = 6;
                        }
                    }
                    else
                    {
                        TrimHits(size);
                        SaveMultiHit();

                        // get a new multihit going
                        if (multiHit.Count == 0)
                        {
                            multiHit = chainedMultiHits.Dequeue();
                            pastHits.Clear();
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            findDirectionMulti(hitSpot);
                            AIstate = 6;
                        }
                        // save for later
                        else
                        {
                            pastHits.Clear();
                            hitSpot = multiHit.Dequeue();
                            pastHits.Add(hitSpot);
                            AIstate = 6;
                        }
                    }
                    break;

                default:
                    resetState();
                    AIstate = 1;
                    break;
                }
            }
        }