public Movement(Block target, MoveTypes move) { this.Target = target; this.Move = move; this.isGuess = false; this.Probability = 1.0f; }
public Movement(Block target, MoveTypes move, float probability) { this.Target = target; this.Move = move; this.Probability = probability; this.isGuess = true; }
/// <summary> /// If the given block has a value, then this checks if the neighboring flags/potential flags /// represents a valid block (ie if block is a 2 and there are 3 flags around it, then it is invalid). /// <para>If the given block does not have value, then assume it is a valid block.</para> /// </summary> /// <param name="block"></param> /// <param name="neighbors"></param> /// <returns></returns> private bool isValidGuess(Block block, NeighborList neighbors = null) { if (block.State == BlockState.Unknown || block.State == BlockState.Flag) return true; if (neighbors == null) neighbors = new NeighborList(Grid, block); int flags = neighbors.GetFlagCount(true); int unknown = neighbors.Count(n => n.State == BlockState.Unknown && n.Guess == GuessState.None); if (block.Value < flags || block.Value - flags > unknown) return false; return true; }
/// <summary> /// Gets a list of blocks that can be cleared if the given guess is performed. /// </summary> /// <param name="guess"></param> /// <returns></returns> private IEnumerable<Block> clearBlocksAroundGuess(Block guess) { List<Block> ret = new List<Block>(); var adjacentToGuess = new NeighborList(Grid, guess); var allBlocksToCheck = new List<Block>(); // Loop through each block around the guess foreach (var adj in adjacentToGuess) { allBlocksToCheck.AddRange(new NeighborList(Grid, adj)); } // Loop through each neighbor of an adjacent block to the guess // Basically, search each block around the guess, and get blocks that can cleared around the blocks next to guess foreach (var t in allBlocksToCheck.Distinct()) { if (t.State != BlockState.Value) continue; var neighbors = new NeighborList(Grid, t); int flags = neighbors.Count(n => n.State == BlockState.Flag || n.Guess == GuessState.Flag); int unknown = neighbors.Count(n => n.State == BlockState.Unknown); if (flags == t.Value && unknown != 0) { foreach (var clear in neighbors) if (clear.State == BlockState.Unknown && clear.Guess == GuessState.None) ret.Add(clear); } } return ret.Distinct(); }
/// <summary> /// Checks if the block and all neighboring blocks are in a valid state given /// the current board state plus any guesses that have been made this round. /// <para>The idea is the come up with some guess (of where a flag or value is). Whoever calls this will make the guess (using SetGuess).</para> /// <para>After making the guess, this function will check the game board around that block to see if it is in a valid state.</para> /// <para>If it is not in a valid state, then we can assume that guess is incorrect and the caller can gain some information about a potential move.</para> /// </summary> /// <param name="block">The block to check. All 2-order neighbors around the block will be also checked.</param> /// <param name="potentialvalues">When checking valid blocks, this algorithm marks necessary neighbors as values /// (if a block was solved by the guess) /// <para>Each block that was marked as a value will be added to this parameter.</para> /// </param> /// <returns>True if the block is valid.</returns> internal bool isValidBlock(Block block, List<Block> potentialvalues = null) { var n = new NeighborList(Grid, block); // If the given block is solved, then mark all unknown neighbors as values (using SetGuess) if (isBlockSolved(block, n, true)) { for (int i = 0; i < n.Count; i++) { if (n[i].State == BlockState.Unknown && n[i].Guess != GuessState.Flag) { if (potentialvalues != null) potentialvalues.Add(n[i]); n[i].SetGuess(GuessState.Value, tempGuesses); } } } // Now loop through each neighbor of the block, and perform what was done above. for (int i = 0; i < n.Count; i++) { var test = new NeighborList(Grid, n[i]); if (isBlockSolved(n[i], test, true)) { for (int j = 0; j < test.Count; j++) { if (test[j].State == BlockState.Unknown && test[j].Guess != GuessState.Flag) { if (potentialvalues != null) potentialvalues.Add(test[j]); test[j].SetGuess(GuessState.Value, tempGuesses); } } if (!isValidGuess(n[i], test)) return false; } } return isValidGuess(block, n) && new NeighborList(Grid,block,2).All(b=>isValidGuess(b)); }
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; }