protected override SeaState?DecodeCore(GroupCollection groups)
        {
            int pom = groups[1].GetIntValue();

            SeaState ret = (SeaState)pom;

            return(ret);
        }
예제 #2
0
        // Fonction qui choisit un coup au hasard
        private Point getShot_Random()
        {
            // find out which hits are definitely sunk and which might still be
            // on live ships.
            bool[,] possible_unsunk_hits = new bool[w, h];
            foreach (List <Ship> list in state.ship_possibilities)
            {
                foreach (Ship s in list)
                {
                    if (state.isSunk(s))
                    {
                        continue;
                    }
                    foreach (Point p in s.GetAllLocations())
                    {
                        if (state.get(p) == SeaState.HIT)
                        {
                            possible_unsunk_hits [p.X, p.Y] = true;
                        }
                    }
                }
            }
#if DEBUG
            Console.WriteLine("possible unsunk hits");
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    Console.Write("{0}", possible_unsunk_hits [x, y] ? "..H.." : "..O..");
                }
                Console.WriteLine();
            }
#endif

            // find out which squares could hold the remaining ships, and if so
            // what the probability of each square is.
            double[,] ship_prob = new double[w, h];             // probabilité qu'il y ait un bateau en chaque point
            foreach (int len in state.remaining_ship_sizes())
            {
                double[,] aposteriori_prob = new double[w, h];                 //
                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        for (int orient = 0; orient < 2; orient++)
                        {
                            int dy = orient;
                            int dx = 1 - dy;
                            if (x + len * dx > w)
                            {
                                continue;
                            }
                            if (y + len * dy > h)
                            {
                                continue;
                            }
                            bool good = true;
                            for (int i = 0; i < len; i++)
                            {
                                SeaState st = state.get(x + i * dx, y + i * dy);
                                if (!(st == SeaState.CLEAR ||
                                      (!fully_resolve_hits && st == SeaState.HIT && possible_unsunk_hits [x + i * dx, y + i * dy])))
                                {
                                    good = false;
                                    break;
                                }
                            }
                            if (!good)
                            {
                                continue;                                 // On passe à l'autre orientation
                            }
                            double p = apriori_prob(len, new Point(x, y), (ShipOrientation)orient);
                            bool   next_to_other_ship = false;
                            for (int i = 0; i < len; i++)
                            {
                                foreach (Point n in neighbors(new Point(x + i * dx, y + i * dy)))
                                {
                                    if (state.get(n) == SeaState.HIT || state.get(n) == SeaState.SUNK)
                                    {
                                        next_to_other_ship = true;
                                    }
                                }
                            }
                            if (next_to_other_ship)
                            {
                                p *= .2;                                  // TODO: set to .2?
                            }
                            for (int i = 0; i < len; i++)
                            {
                                if (state.get(x + i * dx, y + i * dy) == SeaState.HIT)
                                {
                                    continue;
                                }
                                double wt = history_probability(x + i * dx, y + i * dy);
                                aposteriori_prob [x + i * dx, y + i * dy] += p * wt;
                            }
                        }
                    }
                }
                // normalize aposteriori probability
                if (!normalize_prob(aposteriori_prob))
                {
                    // this condition triggers when there is no place
                    // to put a ship of a particular size.
                    continue;
                }

                // TODO: weight sum of probabilities, for example
                // to prioritize the finding of the 2-ship?
                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        ship_prob [x, y] += aposteriori_prob [x, y];
                    }
                }
            }

            // On retient la proba maximale
            double max_prob = 0;
            foreach (double p in ship_prob)
            {
                if (p > max_prob)
                {
                    max_prob = p;
                }
            }

#if DEBUG
            Console.WriteLine("random choice probabilities");
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    Console.Write("{0,-3}{1} ", (int)(ship_prob [x, y] * 1000), ship_prob [x, y] == max_prob ? "*" : " ");
                }
                Console.WriteLine();
            }
#endif

            // On récupère tous les points à proba maximale
            List <Point> max_points = new List <Point> ();
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    if (ship_prob [x, y] == max_prob)
                    {
                        max_points.Add(new Point(x, y));
                    }
                }
            }

            // pick random one of the prob maximizing spots
            return(max_points [rand.Next(max_points.Count)]);
        }
 public static void SetSeaEmptySea()
 {
     mySeaState = SeaState.EmptySea;
     MessageBox.Show(mySeaState.ToString());
 }
 public static void SetSeaStateCruiser()
 {
     mySeaState = SeaState.Cruiser;
     MessageBox.Show(mySeaState.ToString());
 }