public IEnumerable<Movement> FindMoves(Board board) { List<Tuple<Block, FlagCombination>> allValidCombinations = new List<Tuple<Block, FlagCombination>>(); for (int i = 0; i < board.Width; i++) { for (int j = 0; j < board.Height; j++) { Block current = board.Grid[i, j]; if (current.State != BlockState.Value || current.Value == 0) continue; var neighbors = new NeighborList(board.Grid, current); if (board.isBlockSolved(current, neighbors)) continue; int flagCount = neighbors.GetFlagCount(); var unknown = neighbors.GetUnknownBlocks().ToList(); allValidCombinations.Add(new Tuple<Block, FlagCombination>(current, board.getValidCombinations(unknown, current.Value - flagCount))); } } yield break; }
public IEnumerable <Movement> FindMoves(Board board) { List <Tuple <Block, FlagCombination> > allValidCombinations = new List <Tuple <Block, FlagCombination> >(); for (int i = 0; i < board.Width; i++) { for (int j = 0; j < board.Height; j++) { Block current = board.Grid[i, j]; if (current.State != BlockState.Value || current.Value == 0) { continue; } var neighbors = new NeighborList(board.Grid, current); if (board.isBlockSolved(current, neighbors)) { continue; } int flagCount = neighbors.GetFlagCount(); var unknown = neighbors.GetUnknownBlocks().ToList(); allValidCombinations.Add(new Tuple <Block, FlagCombination>(current, board.getValidCombinations(unknown, current.Value - flagCount))); } } yield break; }
/// <summary> /// This is the fastest step and is done at the start of ever pass. /// <para></para> /// </summary> /// <returns></returns> private IEnumerable <Movement> getMovesLock0(Board board) { foreach (Block current in board.nonZeroValues) { var neighbors = new NeighborList(board.Grid, current); var unknown = neighbors.GetUnknownBlocks().ToList(); if (unknown.Count == 0) // Already solved { continue; } int flagCount = neighbors.GetFlagCount(); // Check if all neighboring mines have been found if (flagCount == current.Value && unknown.Count != 0) { yield return(new Movement(current, MoveTypes.DoubleClick)); } // Check if rest of unknown neighbors should be flags else if (current.Value - flagCount == unknown.Count) { foreach (var n in neighbors) { if (n.State == BlockState.Unknown) { yield return(new Movement(n, MoveTypes.SetFlag)); } } } else if (unknown.Count != 0 && current.Value - flagCount > 0) { var combinationMoves = board.getCombinationMoves(unknown, current.Value - flagCount); foreach (var c in combinationMoves) { yield return(c); } } } }
public IEnumerable <Movement> FindMoves(Board board) { int flagsLeft = 0; List <Block> allUnknown = board.getUnknownBlocks(out flagsLeft); float overallFlagProb = (float)flagsLeft / allUnknown.Count; Block bestClearChance = null; float bestClearProbability = 0f; Block bestFlag = null; float bestFlagProbability = 0f; //Dictionary<Block, float> probs = new Dictionary<Block, float>(); for (int i = 0; i < board.Width; i++) { for (int j = 0; j < board.Height; j++) { Block current = board.Grid[i, j]; if (current.State != BlockState.Value || current.Value == 0) { continue; } var neighbors = new NeighborList(board.Grid, current); int flagCount = neighbors.GetFlagCount(); var unknown = neighbors.GetUnknownBlocks().ToList(); var combinations = board.getValidCombinations(unknown, current.Value - flagCount).ToList(); foreach (var un in unknown) { int count = combinations.Count(c => c.Any(b => b == un)); float flagProb = (float)count / combinations.Count; float clearProb = 1 - flagProb; //float existing; //if (probs.TryGetValue(un, out existing)) //{ // if (flagProb < existing) // probs[un] = flagProb; //} //else //{ // probs.Add(un, flagProb); //} if (clearProb > bestClearProbability) { bestClearChance = un; bestClearProbability = clearProb; } if (flagProb > bestFlagProbability) { bestFlag = un; bestFlagProbability = flagProb; } } } } float overallClearProb = 1 - overallFlagProb; float max = getHeighestProb(overallClearProb, overallFlagProb, bestFlagProbability, bestClearProbability); if (overallClearProb == max || overallFlagProb == max) { MoveTypes moveType = overallClearProb == max ? MoveTypes.SetClear : MoveTypes.SetFlag; Block random = getBestRandom(board, allUnknown); if (random != null) { yield return(new Movement(random, moveType, overallClearProb == max ? overallClearProb : overallFlagProb)); } } else if (bestClearProbability == max) { yield return(new Movement(bestClearChance, MoveTypes.SetClear, bestClearProbability)); } else { yield return(new Movement(bestFlag, MoveTypes.SetFlag, bestFlagProbability)); } yield break; }
private bool isBoardSolved() { for (int i = 0; i < Grid.GetLength(0); i++) { for (int j = 0; j < Grid.GetLength(1); j++) { if (Grid[i, j].State != BlockState.Value) continue; var neighbors = new NeighborList(Grid, Grid[i, j]); int flagCount = neighbors.GetFlagCount(); var unknown = neighbors.GetUnknownBlocks().ToList(); if (Grid[i,j].Value - flagCount < unknown.Count) return false; } } return true; }
internal bool isBlockSolved(Block block, NeighborList neighbors, bool useGuesses = false) { if (block.State != BlockState.Value) return false; if (neighbors == null) new NeighborList(Grid, block); return neighbors.GetFlagCount(useGuesses) == block.Value; }
/// <summary> /// This is the fastest step and is done at the start of ever pass. /// <para></para> /// </summary> /// <returns></returns> private IEnumerable<Movement> getMovesLock0(Board board) { foreach (Block current in board.nonZeroValues) { var neighbors = new NeighborList(board.Grid, current); var unknown = neighbors.GetUnknownBlocks().ToList(); if (unknown.Count == 0) // Already solved continue; int flagCount = neighbors.GetFlagCount(); // Check if all neighboring mines have been found if (flagCount == current.Value && unknown.Count != 0) { yield return new Movement(current, MoveTypes.DoubleClick); } // Check if rest of unknown neighbors should be flags else if (current.Value - flagCount == unknown.Count) { foreach (var n in neighbors) { if (n.State == BlockState.Unknown) { yield return new Movement(n, MoveTypes.SetFlag); } } } else if (unknown.Count != 0 && current.Value - flagCount > 0) { var combinationMoves = board.getCombinationMoves(unknown, current.Value - flagCount); foreach (var c in combinationMoves) yield return c; } } }
public IEnumerable<Movement> FindMoves(Board board) { int flagsLeft = 0; List<Block> allUnknown = board.getUnknownBlocks(out flagsLeft); float overallFlagProb = (float)flagsLeft / allUnknown.Count; Block bestClearChance = null; float bestClearProbability = 0f; Block bestFlag = null; float bestFlagProbability = 0f; //Dictionary<Block, float> probs = new Dictionary<Block, float>(); for (int i = 0; i < board.Width; i++) { for (int j = 0; j < board.Height; j++) { Block current = board.Grid[i, j]; if (current.State != BlockState.Value || current.Value == 0) continue; var neighbors = new NeighborList(board.Grid, current); int flagCount = neighbors.GetFlagCount(); var unknown = neighbors.GetUnknownBlocks().ToList(); var combinations = board.getValidCombinations(unknown, current.Value - flagCount).ToList(); foreach (var un in unknown) { int count = combinations.Count(c => c.Any(b => b == un)); float flagProb = (float)count / combinations.Count; float clearProb = 1 - flagProb; //float existing; //if (probs.TryGetValue(un, out existing)) //{ // if (flagProb < existing) // probs[un] = flagProb; //} //else //{ // probs.Add(un, flagProb); //} if (clearProb > bestClearProbability) { bestClearChance = un; bestClearProbability = clearProb; } if (flagProb > bestFlagProbability) { bestFlag = un; bestFlagProbability = flagProb; } } } } float overallClearProb = 1 - overallFlagProb; float max = getHeighestProb(overallClearProb, overallFlagProb, bestFlagProbability, bestClearProbability); if (overallClearProb == max || overallFlagProb == max) { MoveTypes moveType = overallClearProb == max ? MoveTypes.SetClear : MoveTypes.SetFlag; Block random = getBestRandom(board, allUnknown); if (random != null) yield return new Movement(random, moveType, overallClearProb == max ? overallClearProb : overallFlagProb); } else if (bestClearProbability == max) { yield return new Movement(bestClearChance, MoveTypes.SetClear, bestClearProbability); } else { yield return new Movement(bestFlag, MoveTypes.SetFlag, bestFlagProbability); } yield break; }