示例#1
0
    /*
    public void NewGame(Size size)
    {
        width = size.Width;
        height = size.Height;
        state = new State[width, height];
        left = new int[width, height];
        right = new int[width, height];
        below = new int[width, height];
        above = new int[width, height];
        space = new int[width, height];
        hits = new int[width, height];
        remainingShips = new List<int>();
        mustExplore = new List<Point>();
    }

    // nothing fancy, just random placement.  Also note which ships we have available.
    public void PlaceShips(ReadOnlyCollection<Ship> ships)
    {
        remainingShips.Clear();
        foreach (Ship s in ships)
        {
            remainingShips.Add(s.Length);
            s.Place(
                new Point(
                    rand.Next(width),
                    rand.Next(height)),
                (ShipOrientation)rand.Next(2),new Size(10,10));
        }
    }*/
    public System.Collections.IEnumerator PlaceShip(Ship ship)
    {
        yield return null;// return new WaitForSeconds(0.5f);

        if (ship != null)
        {
            int tries = 0;
            bool success = false;
            while (!success)
            {
                if (tries > 100) break; // no infinite loops

                if (!ship.Place(new Point(rand.Next(this.gameSize.Width), rand.Next(this.gameSize.Height)),
                            (ShipOrientation)rand.Next(2), gameSize))
                    continue;

                remainingShips.Add(ship.Length);

                success = true;
                foreach (Ship s in mShips)
                {
                    if(s != ship)
                        success &= !ship.ConflictsWith(s);
                }

                tries++;
            }

            if (!success) throw new OperationCanceledException("PlaceShip");

            if (mPlayer)
            {
                /*foreach (Point p in ship.GetAllLocations())
                {
                    Init_board.gameGrid[p.X, p.Y].renderer.material.color = Color.green;
                }*/
                ship.LoadModel();
                ship.ShowModel();
            }

        }

        waitingForRoutine = false;
        curship++;
    }
        // Renvoie une liste de bâteaux placés intelligemment dans la grille
        private List <Ship> placeShips(int[] ship_sizes)
        {
            int max_opp_shots = 0;              // Plus grand nombre de coups tirés par l'adversaire sur un même point

            foreach (int x in opponent_shots)
            {
                max_opp_shots = Math.Max(max_opp_shots, x);
            }
            max_opp_shots++;                            // Précaution pour éviter la division par 0

                        #if DEBUG
            Console.WriteLine("square shot scores");
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    Console.Write("{0,-4} ", 1000 * opponent_shots [x, y] / max_opp_shots);
                }
                Console.WriteLine();
            }
                        #endif

            // Génération aléatoire de 100 placements : liste de 100 listes de bâteaux
            const int           N           = 100;
            List <List <Ship> > allocations = new List <List <Ship> > ();

            for (int n = 0; n < N; n++)
            {
                List <Ship> allocation = new List <Ship> ();            // Nouvelle liste de bâteaux
                foreach (int size in ship_sizes)                        // Pour toutes les tailles de bâteaux demandées...
                {
                    Ship s = new Ship(size);                            // Nouveau bâteau de taille 'size'
                    while (true)
                    {
                        // Position et orientation aléatoires
                        int x      = rand.Next(w);
                        int y      = rand.Next(h);
                        int orient = rand.Next(2);
                        s.Place(new Point(x, y), (ShipOrientation)orient);

                        // Si le placement obtenu n'est pas valide on repars au début de la boucle while
                        if (!s.IsValid(new Size(w, h)))
                        {
                            continue;
                        }

                        // S'il n'y a pas de conflits entre les bâteaux on sort de la boucle while
                        bool ok = true;
                        foreach (Ship t in allocation)
                        {
                            if (s.ConflictsWith(t))
                            {
                                ok = false;
                                break;
                            }
                        }
                        if (ok)
                        {
                            break;
                        }
                    }
                    allocation.Add(s);                          // Ajout du bâteau à la liste
                }
                allocations.Add(allocation);                    // Ajout de la liste à allocations
            }

            /* Notation des 100 placements et choix du meilleur :
             * Pour chaque cas on incrémente un score selon différents critères.
             * Le meilleur score (celui qu'on garde) est le plus faible.
             */
            int         minscore       = 1000000000;                    // Score minimum initialisé avec une grande valeur
            List <Ship> min_allocation = null;                          // Placement optimal : correspond au score minimum

            foreach (List <Ship> allocation in allocations)             // Pour chaque placement proposé...
            {
                int score = 0;                                          // Initialisation du score à 0
                foreach (Ship s in allocation)                          // Pour chaque bâteau s...
                {
                    foreach (Point p in s.GetAllLocations())            // Pour chaque point appartenant au bâteau...
                    // Incrémentation du score en fonction du nombre de tirs adverse sur ce point
                    {
                        score += 100 * opponent_shots [p.X, p.Y] / max_opp_shots;
                    }
                    foreach (Ship t in allocation)                              // Pour chaque bâteau t...
                    // Si s et t son adjacents et que l'option standard_touching est désactivée : faible pénalité
                    {
                        if (!standard_touching && shipsAdjacent(s, t))
                        {
                            score += 20;
                        }
                        // Si s et t son adjacents et que l'option place_notouching est activée : forte pénalité
                        if (place_notouching && shipsAdjacent(s, t))
                        {
                            score += 1000000;
                        }
                    }
                }
                score += rand.Next(15);                         // Ajout d'une faible valeur aléatoire pour éviter les doublons
                if (score < minscore)                           // Si le score obtenu est meilleure que minscore, on le prend comme référence.
                {
                    minscore       = score;                     // Nouveau score min de référence.
                    min_allocation = allocation;                // Nouveau placement optimal
                }
            }
            return(min_allocation);
        }
示例#3
0
        // Mise à jour de ship_possibilities suite à un coup réussi : bateau touché
        void updatePossibilitiesHit(Point p)
        {
            // This is the hard one.  If a hit was on a ship in the list,
            // check a few things.  Otherwise, we need to add to the list
            // all possible ships/positions that can cover the new hit.

            // Nouvelle liste de possibilités qui remplacera ship_possibilities
            List <List <Ship> > new_possibilities = new List <List <Ship> > ();

            foreach (List <Ship> list in ship_possibilities)            // Pour chaque liste de bateaux dans ship_possibilities...
            {
                // Recherche du bateau qui a été touché
                Ship hit_ship = null;
                foreach (Ship s in list)
                {
                    if (s.IsAt(p))
                    {
                        hit_ship = s;
                    }
                }

                if (hit_ship != null)                   // Si un bateau a été trouvé...
                {
                    // Vérification : le bateau n'a pas été entièrement touché (coulé)
                    foreach (Point q in hit_ship.GetAllLocations())     // Pour chaque point du bateau...
                    {
                        if (state [q.X, q.Y] == SeaState.CLEAR)         // Si le SeaState est CLEAR : OK, bateau non coulé
                        {
                            new_possibilities.Add(list);                // On ajoute cette liste aux nouvelles possibilités
                            break;                                      // On arrête la recherche, on sait que le bateau n'est pas coulé
                        }
                    }
                    continue;
                }

                // Autres cas : tir en dehors des bateaux de la liste.
                // Ajout de toutes les nouvelles positions possibles
                // d'un bateau qui intersecte ce point
                // (création de plusieurs listes).
                List <int> t = new List <int> (orig_ship_sizes); // Liste des tailles des bateaux au départ du jeu

                foreach (Ship s in list)                         // Pour chaque bateau déjà placé dans la liste list...
                {
                    t.Remove(s.Length);                          // on supprime la valeur correspondante dans t
                }
                // t est donc la liste des tailles des bateaux non placés dans cette liste de bateaux

                // Liste sans doublons des tailles des bateaux non placés dans cette liste de bateaux
                List <int> possible_sizes = new List <int> ();
                foreach (int v in t)                                            // pour chaque valeur v de t
                {
                    if (!possible_sizes.Contains(v))                            // si v n'est pas déjà dans possible_size
                    {
                        possible_sizes.Add(v);                                  // ajout de v dans possible_size
                    }
                }

                // ...
                foreach (int size in possible_sizes)                    // Pour chaque taille possible de bateau non placé
                {
                    for (int offset = 0; offset < size; offset++)
                    {
                        for (int orient = 0; orient < 2; orient++)
                        {
                            int dy = orient;
                            int dx = 1 - dy;
                            int x  = p.X - offset * dx;
                            int y  = p.Y - offset * dy;
                            if (x < 0 || y < 0)
                            {
                                continue;
                            }
                            if (x + size * dx > boardSize.Width)
                            {
                                continue;
                            }
                            if (y + size * dy > boardSize.Height)
                            {
                                continue;
                            }
                            bool valid = true;
                            for (int i = 0; i < size; i++)
                            {
                                if (i == offset)
                                {
                                    continue;                                      // the new hit
                                }
                                if (state [x + i * dx, y + i * dy] != SeaState.CLEAR)
                                {
                                    valid = false;
                                    break;
                                }
                            }
                            if (!valid)
                            {
                                continue;
                            }
                            Ship s = new Ship(size);
                            s.Place(new Point(x, y), (ShipOrientation)orient);
                            foreach (Ship w in list)
                            {
                                if (s.ConflictsWith(w))
                                {
                                    valid = false;
                                    break;
                                }
                            }
                            if (!valid)
                            {
                                continue;
                            }
                            List <Ship> new_list = new List <Ship> (list);
                            new_list.Add(s);
                            new_possibilities.Add(new_list);
                        }
                    }
                }
            }

            // Enregistrement des nouvelle possibilités dans ship_possibilities
            ship_possibilities = new_possibilities;
        }
    public System.Collections.IEnumerator PlaceShip(Ship ship)
    {
        bool placed = false;
        bool valid = false;

        if (ship != null)
        {
            ship.LoadModel();
            ship.HideModel();

            while (!placed)
            {
                yield return null;

                if (Input.GetKeyDown("r"))
                {
                    if(placeOrientation == ShipOrientation.Horizontal)
                        placeOrientation = ShipOrientation.Vertical;
                    else placeOrientation = ShipOrientation.Horizontal;
                }

                if (Input.GetMouseButtonDown(0) && valid)
                {
                    placed = true;
                    break;
                }

                Point cast = getBoardRayCast(false, Color.white);

                if (ship.Place(cast, placeOrientation, gameSize))
                {
                    bool collides = false;
                    foreach (Ship s in mShips)
                    {
                        if (s != ship)
                            collides |= ship.ConflictsWith(s);
                    }

                    if (!collides)
                    {
                        ship.ShowModel();
                        valid = true;
                    }
                    else
                    {
                        ship.HideModel();
                        valid = false;
                    }
                }
                else
                {
                    ship.HideModel();
                    valid = false;
                }
            }
        }

        waitingForRoutine = false;
        curship++;
    }