Пример #1
0
        public bool FillCertainNeighborhoods()
        {
            bool change = false;

            for (int i = 0; i < Params.columns; ++i)
            {
                for (int j = 0; j < Params.rows; ++j)
                {
                    if (!board.Fields[i, j].Clicked)
                    {
                        continue;
                    }
                    if (board.Fields[i, j].Flag)
                    {
                        continue;
                    }

                    Neighborhood neighborhood = board.GetNeighborhood(i, j);
                    if (neighborhood.FreeNeighbors.Count == 0)
                    {
                        continue;
                    }

                    bool allFlagsPlanted = neighborhood.FlagsCount == board.Fields[i, j].Number;
                    if (allFlagsPlanted)
                    {
                        foreach (var neighbor in neighborhood.FreeNeighbors)
                        {
                            LeftClickField(neighbor.X, neighbor.Y);
                            if (failure)
                            {
                                return(true);
                            }
                        }
                        change = true;
                    }

                    bool allNeigborsShouldBeFlags =
                        neighborhood.FreeNeighbors.Count == board.Fields[i, j].Number - neighborhood.FlagsCount;
                    if (allNeigborsShouldBeFlags)
                    {
                        foreach (var neighbor in neighborhood.FreeNeighbors)
                        {
                            PlantFlag(neighbor.X, neighbor.Y);
                        }
                        change = true;
                    }
                }
            }
            return(change);
        }
Пример #2
0
        private List <Point> GetFreeFields(bool checkNeighborhood)
        {
            List <Point> freeFields = new List <Point>();

            for (int i = 0; i < Params.columns; ++i)
            {
                for (int j = 0; j < Params.rows; ++j)
                {
                    if (board.Fields[i, j].Clicked)
                    {
                        continue;
                    }
                    if (checkNeighborhood)
                    {
                        Neighborhood neighborhood = board.GetNeighborhood(i, j);
                        bool         corner       = (i == 0 && j == 0) ||
                                                    (i == Params.columns - 1 && j == 0) ||
                                                    (i == 0 && j == Params.rows - 1) ||
                                                    (i == Params.columns - 1 && j == Params.rows - 1);
                        bool border = i == 0 ||
                                      i == Params.columns - 1 ||
                                      j == 0 ||
                                      j == Params.rows - 1;
                        if (corner)
                        {
                            if (neighborhood.FreeNeighbors.Count != 3)
                            {
                                continue;
                            }
                        }
                        if (!corner && border)
                        {
                            if (neighborhood.FreeNeighbors.Count != 5)
                            {
                                continue;
                            }
                        }
                        if (!corner && !border)
                        {
                            if (neighborhood.FreeNeighbors.Count != 8)
                            {
                                continue;
                            }
                        }
                    }
                    freeFields.Add(new Point(i, j));
                }
            }
            return(freeFields);
        }
Пример #3
0
        public Neighborhood GetNeighborhood(int x, int y)
        {
            Neighborhood neighborhood = new Neighborhood();

            for (int i = -1; i <= 1; ++i)
            {
                for (int j = -1; j <= 1; ++j)
                {
                    int neighborX = x + i;
                    int neighborY = y + j;
                    if (i == 0 && j == 0)
                    {
                        continue;
                    }
                    if (!Helpers.IsInBounds(neighborX, neighborY))
                    {
                        continue;
                    }
                    if (Fields[neighborX, neighborY].Clicked && Fields[neighborX, neighborY].Number == 0)
                    {
                        continue;
                    }
                    if (Fields[neighborX, neighborY].Flag)
                    {
                        ++neighborhood.FlagsCount;
                    }
                    else
                    {
                        if (!Fields[neighborX, neighborY].Clicked)
                        {
                            neighborhood.FreeNeighbors.Add(new System.Drawing.Point(neighborX, neighborY));
                        }
                    }
                }
            }
            return(neighborhood);
        }
Пример #4
0
        public void Guess()
        {
            float bestChance   = 0;
            Point bestPoint    = new Point(-1, -1);
            bool  bestIsNumber = false;

            for (int i = 0; i < Params.columns; ++i)
            {
                for (int j = 0; j < Params.rows; ++j)
                {
                    if (!board.Fields[i, j].Clicked)
                    {
                        continue;
                    }
                    if (board.Fields[i, j].Flag)
                    {
                        continue;
                    }

                    Neighborhood neighborhood = board.GetNeighborhood(i, j);
                    if (neighborhood.FreeNeighbors.Count == 0)
                    {
                        continue;
                    }

                    int          flagsRemaining = board.Fields[i, j].Number - neighborhood.FlagsCount;
                    List <int[]> combinations   =
                        Helpers.GetAllSubsets(neighborhood.FreeNeighbors.Count, flagsRemaining);
                    int[]  possibleFlagPlacementCombinationCount = new int[neighborhood.FreeNeighbors.Count];
                    bool[] canPlantFlagOnIndex = new bool[neighborhood.FreeNeighbors.Count];

                    List <int[]> legalCombinations = new List <int[]>();

                    foreach (var comb in combinations)
                    {
                        bool isLegal = true;
                        List <NewFlagsCount> numbersNearNewFlags = new List <NewFlagsCount>();
                        foreach (var ind in comb)
                        {
                            int          flagX            = neighborhood.FreeNeighbors[ind].X;
                            int          flagY            = neighborhood.FreeNeighbors[ind].Y;
                            List <Point> flagNeighborhood = board.GetNumbersAroundFlag(flagX, flagY);

                            foreach (var numberNearFlag in flagNeighborhood)
                            {
                                NewFlagsCount number = numbersNearNewFlags.Find(n => n.Coords == numberNearFlag);
                                if (number == null)
                                {
                                    numbersNearNewFlags.Add(new NewFlagsCount(numberNearFlag));
                                }
                                else
                                {
                                    ++number.Count;
                                }
                            }
                        }
                        foreach (var number in numbersNearNewFlags)
                        {
                            int x         = number.Coords.X;
                            int y         = number.Coords.Y;
                            int flagCount = board.GetNeighborhood(x, y).FlagsCount;
                            if (flagCount + number.Count > board.Fields[x, y].Number)
                            {
                                isLegal = false;
                                break;
                            }
                        }
                        if (!isLegal)
                        {
                            continue;
                        }
                        legalCombinations.Add(comb);
                    }
                    int[] combinationsWithFlagCount = new int[neighborhood.FreeNeighbors.Count];
                    foreach (var legalComb in legalCombinations)
                    {
                        foreach (var num in legalComb)
                        {
                            ++combinationsWithFlagCount[num];
                        }
                    }
                    for (int k = 0; k < combinationsWithFlagCount.Length; ++k)
                    {
                        float chance = (float)combinationsWithFlagCount[k] / legalCombinations.Count;
                        if (chance > bestChance)
                        {
                            bestChance   = chance;
                            bestIsNumber = false;
                            bestPoint    = neighborhood.FreeNeighbors[k];
                        }
                        if (1.0f - chance > bestChance)
                        {
                            bestChance   = 1.0f - chance;
                            bestIsNumber = true;
                            bestPoint    = neighborhood.FreeNeighbors[k];
                        }
                        if (Math.Abs(bestChance - 1.0f) < 0.0000001f)
                        {
                            break;
                        }
                    }
                    if (Math.Abs(bestChance - 1.0f) < 0.0000001f)
                    {
                        break;
                    }
                }
                if (Math.Abs(bestChance - 1.0f) < 0.0000001f)
                {
                    break;
                }
            }
            List <Point> freeFields = new List <Point>();

            if (bestPoint.X == -1 && bestPoint.Y == -1)
            {
                freeFields = GetFreeFields(false);
            }
            else
            {
                freeFields = GetFreeFields(true);
            }

            float mineChance           = (float)minesLeft / freeFieldsCount;
            float chanceForRandomField = 1.0f - mineChance;

            if (freeFields.Count > 0 && chanceForRandomField > bestChance)
            {
                bestIsNumber = true;
                Random rand = new Random(Guid.NewGuid().GetHashCode());
                int    ind  = rand.Next(freeFields.Count);
                bestPoint = freeFields[ind];
            }
            if (freeFields.Count > 0 && mineChance > bestChance)
            {
                bestIsNumber = false;
                Random rand = new Random(Guid.NewGuid().GetHashCode());
                int    ind  = rand.Next(freeFields.Count);
                bestPoint = freeFields[ind];
            }
            if (bestIsNumber)
            {
                LeftClickField(bestPoint.X, bestPoint.Y);
            }
            else
            {
                PlantFlag(bestPoint.X, bestPoint.Y);
            }
        }