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); }
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); }
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); }
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); } }