private static int PartitionX(int left, int right) { int pivot = grid[left].Center.X; while (true) { while (grid[left].Center.X < pivot) { left++; } while (grid[right].Center.X > pivot) { right--; } if (left < right) { if (grid[left].Center.X == grid[right].Center.X) { return(right); } SweeperGrid temp = grid[left]; grid[left] = grid[right]; grid[right] = temp; } else { return(right); } } }
// Update the grid private void UpdateImage(Bitmap bitmap) { for (int i = grid.Count - 1; i >= 0; i--) { SweeperGrid tmpSquare = DetectStatus(CropImage(bitmap, grid[i].Rect), grid[i].Center, grid[i].Rect); if (grid[i].Num == tmpSquare.Num && !tmpSquare.BombVisible) { continue; } else { grid[i] = tmpSquare; if (!grid[i].Hidden) { finishedProcessing = false; clicked = false; //hiddenCoord.Remove(i); if (grid[i].Num != 0) { available.Add(i); //hiddenCoord.RemoveAt(i); } else { //hiddenCoord.RemoveAt(i); } } } } //Console.WriteLine(hiddenCoord.Count); }
private void UpdateImage(Bitmap bmp) { for (int i = hiddenCoord.Count - 1; i >= 0; i--) { SweeperGrid tmpSquare = DetectStatus(CropImage(bmp, grid[hiddenCoord[i]].Rect), grid[hiddenCoord[i]].Center, grid[hiddenCoord[i]].Rect); if (tmpSquare.Hidden != grid[hiddenCoord[i]].Hidden) { finishedProcessing = false; clicked = false; grid[hiddenCoord[i]] = tmpSquare; visibleCoord.Add(hiddenCoord[i]); hiddenCoord.RemoveAt(i); } } }
// the main algorithm public void FindBestMove(ToolStripStatusLabel toolStripStatusLabel1) { int squareToProcess = 0; if (available.Count == 0) { for (int i = 0; i < grid.Count; i++) { if (!grid[i].Hidden && grid[i].Num != 0) { available.Add(i); } else if (grid[i].Hidden) { if (hiddenCoord.Any(s => i == s)) { continue; } else { hiddenCoord.Add(i); } } } if (available.Count == 0) { squareToProcess = (grid.Count / 2) + 1; int clickCenter = (((grid.Count / rowCount) / 2) * rowCount) - (rowCount / 2); p1.X = grid[clickCenter].Center.X; p1.Y = grid[clickCenter].Center.Y; clicked = true; } } else { InsertionSort(); for (int i = 0; i < available.Count; i++) { int coordY = grid[available[i]].Center.Y; int possibleBomb = 0; String missingSide = ""; List <int> surroundingCoord = new List <int>(); // check left if ((available[i] - 1) >= 0) { if (Math.Abs(coordY - grid[available[i] - 1].Center.Y) < 10) { if (grid[available[i] - 1].Hidden) { possibleBomb++; surroundingCoord.Add(available[i] - 1); } } } else { missingSide += "Left "; } // check right if ((available[i] + 1) < grid.Count) { if (Math.Abs(coordY - grid[available[i] + 1].Center.Y) < 10) { if (grid[available[i] + 1].Hidden) { possibleBomb++; surroundingCoord.Add(available[i] + 1); } } } else { missingSide += "Right "; } // check top if ((available[i] - rowCount) >= 0) { if (grid[available[i] - rowCount].Hidden) { possibleBomb++; surroundingCoord.Add(available[i] - rowCount); } } else { missingSide += "Top "; } // check bottom if ((available[i] + rowCount) < grid.Count) { if (grid[available[i] + rowCount].Hidden) { possibleBomb++; surroundingCoord.Add(available[i] + rowCount); } } else { missingSide += "Bottom "; } // check top left if ((available[i] - rowCount) >= 0 && (available[i] - rowCount - 1) >= 0) { if (grid[available[i] - rowCount - 1].Hidden) { if (Math.Abs(grid[available[i] - rowCount].Center.Y - grid[available[i] - rowCount - 1].Center.Y) < 10) { possibleBomb++; surroundingCoord.Add(available[i] - rowCount - 1); } } } // check top right if ((available[i] - rowCount) >= 0 && (available[i] - rowCount + 1) >= 0) { if (grid[available[i] - rowCount + 1].Hidden) { if (Math.Abs(grid[available[i] - rowCount].Center.Y - grid[available[i] - rowCount + 1].Center.Y) < 10) { possibleBomb++; surroundingCoord.Add(available[i] - rowCount + 1); } } } // check bottom left if ((available[i] + rowCount) < grid.Count && (available[i] + rowCount - 1) < grid.Count) { if (grid[available[i] + rowCount - 1].Hidden) { if (Math.Abs(grid[available[i] + rowCount].Center.Y - grid[available[i] + rowCount - 1].Center.Y) < 10) { possibleBomb++; surroundingCoord.Add(available[i] + rowCount - 1); } } } // check bottom right if ((available[i] + rowCount) < grid.Count && (available[i] + rowCount + 1) < grid.Count) { if (grid[available[i] + rowCount + 1].Hidden) { if (Math.Abs(grid[available[i] + rowCount].Center.Y - grid[available[i] + rowCount + 1].Center.Y) < 10) { possibleBomb++; surroundingCoord.Add(available[i] + rowCount + 1); } } } // determine if bomb or not: click if it's safe, mark if it's dangerous, pass if undetermined int confirmedBomb = 0; for (int j = surroundingCoord.Count - 1; j >= 0; j--) { if (bombCoord.Any(s => surroundingCoord[j].Equals(s)) || grid[surroundingCoord[j]].IsBomb) { confirmedBomb++; surroundingCoord.RemoveAt(j); } } // the guessing algorithm, slightly random but should be wary of bombs if (guess) { //method 1 if (surroundingCoord.Count > 0) { for (int j = 0; j < grid.Count; j++) { if (grid[i].Hidden) { if (bombCoord.Any(s => i.Equals(s)) || grid[i].IsBomb) { continue; } else { //Console.WriteLine("guess method 1 failing"); squareToProcess = (surroundingCoord[j]) + 1; guessCheck = true; squaresProcessed = 0; finishedProcessing = false; guess = false; p1.X = grid[surroundingCoord[j]].Center.X; p1.Y = grid[surroundingCoord[j]].Center.Y; clicked = true; break; } } } } if (guessCheck) { break; } else { // method 2 for (int j = 0; j < surroundingCoord.Count; j++) { if (bombCoord.Any(s => surroundingCoord[j].Equals(s)) || grid[surroundingCoord[j]].IsBomb) { continue; } else { if (grid[surroundingCoord[j]].Num == 10) { //Console.WriteLine("guess method 2 failing"); squareToProcess = (surroundingCoord[j]) + 1; guessCheck = true; guess = false; finishedProcessing = false; squaresProcessed = 0; p1.X = grid[surroundingCoord[j]].Center.X; p1.Y = grid[surroundingCoord[j]].Center.Y; clicked = true; break; } } } } if (guessCheck) { break; } else { squaresProcessed = grid.Count * 2; } } //Console.WriteLine("Processing: " + grid[available[i]].Num + " at grid: " + (available[i] + 1) + " without side: " + missingSide + " and found possible: " + confirmedBomb + "/" + possibleBomb + " and counter is at " + surroundingCoord.Count); if (possibleBomb == grid[available[i]].Num && !finishedProcessing) { for (int j = 0; j < surroundingCoord.Count; j++) { //if (!grid[surroundingCoord[j]].IsBomb) //{ grid[surroundingCoord[j]] = new SweeperGrid(grid[surroundingCoord[j]].BMP, grid[surroundingCoord[j]].Rect, true, grid[surroundingCoord[j]].Center, 9, false, true, true); if (bombCoord.Any(s => surroundingCoord[j].Equals(s))) { continue; } else { bombCoord.Add(surroundingCoord[j]); } //Console.WriteLine("Grid " + (available[i] + 1) + " has a bomb nearby at " + (surroundingCoord[j] + 1)); //} } grid[available[i]] = new SweeperGrid(grid[available[i]].BMP, grid[available[i]].Rect, false, grid[available[i]].Center, grid[available[i]].Num, false, false, true); squareToProcess = available[i] + 1; } else if (possibleBomb > grid[available[i]].Num && finishedProcessing) { if (confirmedBomb == grid[available[i]].Num) { //Console.WriteLine(grid[available[i]].Num + " is at Grid: " + (available[i] + 1) + " has " + confirmedBomb + " of " + possibleBomb); for (int j = 0; j < surroundingCoord.Count; j++) { if (bombCoord.Any(s => surroundingCoord[j].Equals(s)) || grid[surroundingCoord[j]].IsBomb) { continue; } else { if (grid[surroundingCoord[j]].Num == 10) { //Console.WriteLine("if statement failing"); squareToProcess = (surroundingCoord[j]) + 1; p1.X = grid[surroundingCoord[j]].Center.X; p1.Y = grid[surroundingCoord[j]].Center.Y; clicked = true; break; } } } break; } } if (!finishedProcessing && i == available.Count - 1) { finishedProcessing = true; //Console.WriteLine("done processing"); } else if (finishedProcessing && i == available.Count - 1 && !guess) { //Console.WriteLine("should start guessing"); guess = true; squaresProcessed = grid.Count; break; } //Console.WriteLine(grid[available[i]].Num + " is at Grid: " + (available[i] + 1) + " has " + confirmedBomb + " of " + possibleBomb + " | finished processing: " + finishedProcessing); //Console.WriteLine(available[i]+1 + ":" + grid[60].IsBomb); } squaresProcessed++; if (!guess) { toolStripStatusLabel1.Text = "Processing node: " + squareToProcess; } else { toolStripStatusLabel1.Text = "Guessing next move"; } //Console.WriteLine("Processing: " + squaresProcessed + " | " + "Out of: " + available.Count + " nodes"); } }
private void FindBestMove(IProgress <string> progress) { InsertionSort(); for (int i = visibleCoord.Count - 1; i >= 0; i--) { List <int> surroundingCoord = new List <int>(); int coordY = grid[visibleCoord[i]].Center.Y; int possibleBomb = 0; int confirmedBomb = 0; // check left if ((visibleCoord[i] - 1) >= 0) { if (Math.Abs(coordY - grid[visibleCoord[i] - 1].Center.Y) < 15) { if (grid[visibleCoord[i] - 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] - 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] - 1); } } } } // check right if ((visibleCoord[i] + 1) < grid.Count) { if (Math.Abs(coordY - grid[visibleCoord[i] + 1].Center.Y) < 15) { if (grid[visibleCoord[i] + 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] + 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] + 1); } } } } // check top if ((visibleCoord[i] - rowCount) >= 0) { if (grid[visibleCoord[i] - rowCount].Hidden) { possibleBomb++; if (grid[visibleCoord[i] - rowCount].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] - rowCount); } } } // check bottom if ((visibleCoord[i] + rowCount) < grid.Count) { if (grid[visibleCoord[i] + rowCount].Hidden) { possibleBomb++; if (grid[visibleCoord[i] + rowCount].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] + rowCount); } } } // check top left if ((visibleCoord[i] - rowCount - 1) >= 0) { if (Math.Abs(grid[visibleCoord[i] - rowCount].Center.Y - grid[visibleCoord[i] - rowCount - 1].Center.Y) < 15) { if (grid[visibleCoord[i] - rowCount - 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] - rowCount - 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] - rowCount - 1); } } } } // check top right if ((visibleCoord[i] - rowCount + 1) > 0) { if (Math.Abs(grid[visibleCoord[i] - rowCount].Center.Y - grid[visibleCoord[i] - rowCount + 1].Center.Y) < 15) { if (grid[visibleCoord[i] - rowCount + 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] - rowCount + 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] - rowCount + 1); } } } } // check bottom left if ((visibleCoord[i] + rowCount - 1) < grid.Count - 1) { if (Math.Abs(grid[visibleCoord[i] + rowCount].Center.Y - grid[visibleCoord[i] + rowCount - 1].Center.Y) < 15) { if (grid[visibleCoord[i] + rowCount - 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] + rowCount - 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] + rowCount - 1); } } } } // check bottom right if ((visibleCoord[i] + rowCount + 1) < grid.Count) { if (Math.Abs(grid[visibleCoord[i] + rowCount].Center.Y - grid[visibleCoord[i] + rowCount + 1].Center.Y) < 15) { if (grid[visibleCoord[i] + rowCount + 1].Hidden) { possibleBomb++; if (grid[visibleCoord[i] + rowCount + 1].IsBomb) { confirmedBomb++; } else { surroundingCoord.Add(visibleCoord[i] + rowCount + 1); } } } } if (guess) { for (int j = 0; j < surroundingCoord.Count; j++) { if (!grid[surroundingCoord[j]].IsBomb) { clicked = true; p1.X = grid[surroundingCoord[j]].Center.X; p1.Y = grid[surroundingCoord[j]].Center.Y; break; } } guess = false; break; } //Console.WriteLine(grid[visibleCoord[i]].Num + " at grid: " + (visibleCoord[i] + 1) + " has " + confirmedBomb + "/" + possibleBomb + " hidden"); // detect if the number at this coord = the number of hidden tiles, means those are definitely bombs if (possibleBomb == grid[visibleCoord[i]].Num && !finishedProcessing) { for (int j = 0; j < surroundingCoord.Count; j++) { grid[surroundingCoord[j]] = new SweeperGrid(grid[surroundingCoord[j]].BMP, grid[surroundingCoord[j]].Rect, true, grid[surroundingCoord[j]].Center, 9, false, true, true); } grid[visibleCoord[i]] = new SweeperGrid(grid[visibleCoord[i]].BMP, grid[visibleCoord[i]].Rect, false, grid[visibleCoord[i]].Center, grid[visibleCoord[i]].Num, false, false, true); current = visibleCoord[i] + 1; progress.Report("Processing node " + current); visibleCoord.RemoveAt(i); } // after we finish processing everything, start looking at what we can click else if (possibleBomb > grid[visibleCoord[i]].Num && confirmedBomb == grid[visibleCoord[i]].Num && finishedProcessing) { //Console.WriteLine(grid[visibleCoord[i]].Num + " at grid: " + (visibleCoord[i] + 1) + " has " + confirmedBomb + "/" + possibleBomb + " hidden"); clicked = true; p1.X = grid[surroundingCoord[0]].Center.X; p1.Y = grid[surroundingCoord[0]].Center.Y; break; } if (i == 0 && !finishedProcessing) { finishedProcessing = true; } else if (i == 0 && finishedProcessing) { //Console.WriteLine("Guessing"); progress.Report("Guessing"); guess = true; } } }