public static BommenBepalerStats BepaalBommenMulti2(Vakje[,] deVakjesArray, BotConfig botConfig) { var stats = new BommenBepalerStats(); int width = deVakjesArray.GetLength(0); int height = deVakjesArray.GetLength(1); var initialIteratie = new BommenBepalerStatsIteratie(); stats.Iteraties.Add(initialIteratie); var flatVakjes = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null); var allSets = new List <VakjeSetDeluxe>(); foreach (var vakje in flatVakjes) { if (vakje.IsNumber) { var unrevealedTilesOmMeHeen = vakje.SurroundingVakjes.Where(t => !t.Revealed).ToList(); var revealedBommenOmMeHeen = vakje.SurroundingVakjes.Where(t => t.IsBomb).ToList(); var revealedNietBommenOmMeHeen = vakje.SurroundingVakjes.Where(t => t.IsNumber).ToList(); var bommenInDitSet = vakje.Number - revealedBommenOmMeHeen.Count; var nietBommenInDitSet = unrevealedTilesOmMeHeen.Count - bommenInDitSet; AddSetDeluxe(allSets, initialIteratie, bommenInDitSet, nietBommenInDitSet, unrevealedTilesOmMeHeen); } } bool doorGaan = true; int iteraties = 1; while (doorGaan) { var iteratie = BepaalBommen2(deVakjesArray, width, height, botConfig); iteratie.IteratieNummer = iteraties; stats.Iteraties.Add(iteratie); doorGaan = iteratie.Vondsten.Any(); iteraties++; //GalaxyVisualizator.RenderToConsole(deVakjesArray, DefaultLoggerFactory.CreateLoggerForTests()); } BepaalBommenBasedOnSetsDeluxe(flatVakjes); Debug.WriteLine($"Totaal iteraties: {iteraties}"); return(stats); }
public void DoesntFindAllTheseFalsePositives() { var logger = DefaultLoggerFactory.CreateLoggerForTests(); //Hier vond hij random bommen string[] data = new[] { "########B3..1.B10", "#######BRR2.B3310", "######1233BR3BR10", "#####001B.2..B200", "####0002B..R21000", "###210013B2100001", "##BB101.R3000001R", "#.3201B3R1000002.", "..R102..1111112R.", ".1.12B2..R.R.R.1#", "...R.3RB21.2RB.##", "...1.R3.....R2###", "....B3..B.12.####", "...B3R..3..R#####", ".....1.2..2######", "..........#######", ".........########" }; var game = new GalaxySweeperGame { field = data.ToList() }; var deVakjesArray = GalaxyGameHelper.CreateVakjesArray(game); var stats = BommenBepaler.BepaalBommenMulti2(deVakjesArray, TestBotConfig()); stats.Log(logger); var flattened = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null).ToList(); LogTopBombs(flattened, logger); GalaxyVisualizator.RenderToConsole(deVakjesArray, logger); Assert.Equal(0, flattened.Count(t => t.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedBom)); }
public void FindsNonGuaranteedBombsAndThenRecursivelyFindsGuaranteedBombs() { var logger = DefaultLoggerFactory.CreateLoggerForTests(); string[] data = new[] { "########.........", "#######..........", "######...........", "#####............", "####.............", "###..............", "##...............", "#................", "...........1.....", "........12..4...#", "........11.....##", "..............###", ".............####", "............#####", "...........######", "..........#######", ".........########" }; var game = new GalaxySweeperGame { field = data.ToList() }; var deVakjesArray = GalaxyGameHelper.CreateVakjesArray(game); var stats = BommenBepaler.BepaalBommenMulti2(deVakjesArray, TestBotConfig()); stats.Log(logger); var flattened = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null).ToList(); LogTopBombs(flattened, logger); GalaxyVisualizator.RenderToConsole(deVakjesArray, logger); Assert.Equal(5, flattened.Count(t => t.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedBom)); Assert.Equal(7, flattened.Count(t => t.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedNoBom)); }
public void FindsThisOneThatSjoerdsOneDoesToo() { var logger = DefaultLoggerFactory.CreateLoggerForTests(); string[] data = new[] { "########B21000000", "#######13R2000000", "######11RB1011000", "#####B23R201R2121", "####B3R42113R2BB2", "###B33RR3R2R22B3B", "##13B23R4211.113B", "#.1R213BB2....1RR", ".1211R3BB31.1124R", "1R1.1124BB11R2R2#", "11...1R22212321##", ".....11.1R2RB1###", "..121...11132####", ".1BR2.....1B#####", ".12..4...12######", "......3.1B#######", "....2...1########" }; var game = new GalaxySweeperGame { field = data.ToList() }; var deVakjesArray = GalaxyGameHelper.CreateVakjesArray(game); var stats = BommenBepaler.BepaalBommenMulti2(deVakjesArray, TestBotConfig()); stats.Log(logger); var flattened = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null).ToList(); LogTopBombs(flattened, logger); GalaxyVisualizator.RenderToConsole(deVakjesArray, logger); Assert.Equal(3, flattened.Count(t => t.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedBom)); }
public static BommenBepalerStatsIteratie BepaalBommen(Vakje[,] deVakjesArray, int width, int height, BotConfig botConfig) { var iteratie = new BommenBepalerStatsIteratie(); //Clear de sets var flatVakjes = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null); foreach (var vakje in flatVakjes) { vakje.VakjeBerekeningen.Sets.Clear(); } var alleUnrevealedDieMisschienEenBomZijn = flatVakjes.Where(t => !t.Revealed && t.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom).ToList(); var theBigUnrevealedSet = new VakjeSet(51 - flatVakjes.Count(t => t.IsBomb), alleUnrevealedDieMisschienEenBomZijn); foreach (var unrev in alleUnrevealedDieMisschienEenBomZijn) { unrev.VakjeBerekeningen.TheBigUnrevealedSet = theBigUnrevealedSet; } foreach (var vakje in flatVakjes) { var bommenOmMeHeen = vakje.SurroundingVakjes.Count(t => t.IsBomb); var unrevealedTilesOmMeHeenZonderGuaranteedNoBom = vakje.SurroundingVakjes.Where(t => !t.Revealed && t.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom).ToList(); var unrevealedTilesOmMeHeen = vakje.SurroundingVakjes.Where(t => !t.Revealed).ToList(); if (vakje.IsNumber && vakje.Number - bommenOmMeHeen == unrevealedTilesOmMeHeenZonderGuaranteedNoBom.Count) { foreach (var unrevealed in unrevealedTilesOmMeHeenZonderGuaranteedNoBom) { if (unrevealed.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedBom) { unrevealed.VakjeBerekeningen.BerekendVakjeType = BerekendVakjeType.GuaranteedBom; iteratie.Vondsten.Add(new BommenBepalerStatsIteratieVondst(iteratie, unrevealed, VondstType.SimpleGuaranteedBomb)); } } } else if (vakje.IsNumber && vakje.Number == bommenOmMeHeen) { foreach (var unrevealed in unrevealedTilesOmMeHeen) { if (unrevealed.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom) { unrevealed.VakjeBerekeningen.BerekendVakjeType = BerekendVakjeType.GuaranteedNoBom; iteratie.Vondsten.Add(new BommenBepalerStatsIteratieVondst(iteratie, unrevealed, VondstType.SimpleGuaranteedNoBomb)); } } } } foreach (var vakje in flatVakjes) { if (vakje.IsNumber) { var bommenOmMeHeen = vakje.SurroundingVakjes.Count(t => t.IsBomb); var unrevealedTilesOmMeHeenZonderGuaranteedNoBom = vakje.SurroundingVakjes.Where(t => !t.Revealed && t.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom).ToList(); var unrevealedTilesOmMeHeen = vakje.SurroundingVakjes.Where(t => !t.Revealed).ToList(); AddSet(iteratie, vakje.Number - bommenOmMeHeen, unrevealedTilesOmMeHeenZonderGuaranteedNoBom); } } if (botConfig.UseSetDetection) { var allSets = flatVakjes.SelectMany(t => t.VakjeBerekeningen.Sets).Distinct(); foreach (var set in allSets) { //we kijken nu per set foreach (var vakjeInSet in set.Vakjes) { foreach (var setVanDeze in vakjeInSet.VakjeBerekeningen.Sets) { if (set != setVanDeze) { var vakjesInBeideSets = set.Vakjes.Intersect(setVanDeze.Vakjes).ToList(); var bommenInVakjesInBeideNodigGezienVanuitSet = set.CountVanBommenDieErMoetenZijn - (set.Vakjes.Count - vakjesInBeideSets.Count); var countGuaranteedNotBombsInIntersection = vakjesInBeideSets.Count - set.CountVanBommenDieErMoetenZijn; if (bommenInVakjesInBeideNodigGezienVanuitSet == setVanDeze.CountVanBommenDieErMoetenZijn) { var vakjesNietGedeeld = setVanDeze.Vakjes.Except(vakjesInBeideSets).ToList(); foreach (var vakjeNietGedeeld in vakjesNietGedeeld) { if (vakjeNietGedeeld.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom) { vakjeNietGedeeld.VakjeBerekeningen.BerekendVakjeType = BerekendVakjeType.GuaranteedNoBom; iteratie.Vondsten.Add(new BommenBepalerStatsIteratieVondst(iteratie, vakjeNietGedeeld, VondstType.SetsBasedGuaranteedNoBomb)); } } } //Alleen als we 2 vakjes hebben die overlappen is er de mogelijkheid dat maar 1 van de 2 een bom is //if (vakjesInBeideSets.Count > 1 && bommenInVakjesInBeideNodigGezienVanuitSet > 0) //{ //if (setVanDeze.CountVanBommenDieErMoetenZijn - countGuaranteedNotBombsInIntersection == setVanDeze.Vakjes.Count - vakjesInBeideSets.Count) if (setVanDeze.Vakjes.Count - countGuaranteedNotBombsInIntersection == setVanDeze.CountVanBommenDieErMoetenZijn) { var vakjesNietGedeeld = setVanDeze.Vakjes.Except(vakjesInBeideSets).ToList(); foreach (var vakjeNietGedeeld in vakjesNietGedeeld) { if (vakjeNietGedeeld.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedBom) { vakjeNietGedeeld.VakjeBerekeningen.BerekendVakjeType = BerekendVakjeType.GuaranteedBom; iteratie.Vondsten.Add(new BommenBepalerStatsIteratieVondst(iteratie, vakjeNietGedeeld, VondstType.SetsBasedGuaranteedBomb)); } } } //} } } } } } return(iteratie); }
public static BommenBepalerStatsIteratie BepaalBommen2(Vakje[,] deVakjesArray, int width, int height, BotConfig botConfig) { var iteratie = new BommenBepalerStatsIteratie(); var flatVakjes = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null); var allSets = flatVakjes.SelectMany(t => t.VakjeBerekeningen.SetsDeluxe).Distinct().ToList(); var setsToAdd = new List <VakjeSetDeluxe>(); foreach (var set in allSets) { var alleOverlappendeSets = set.Vakjes.SelectMany(t => t.VakjeBerekeningen.SetsDeluxe).Distinct().ToList(); var filledIntersections = SetBepaler.BepaalSetsThatFillMeCompletely(set, alleOverlappendeSets); foreach (var filledIntersection in filledIntersections) { var totGuaranteedNotBombs = filledIntersection.Sum(t => t.MinCountGuaranteedNotBombsInIntersection); if (totGuaranteedNotBombs == set.Vakjes.Count - set.MinCountGuaranteedBombs) { //Shouldn't be required but we're now sure that the max count of bombs here is in fact this //set.MinCountGuaranteedNotBombs = Math.Min(set.Vakjes.Count - set.MinCountGuaranteedBombs, set.MinCountGuaranteedNotBombs); foreach (var intersectionSet in filledIntersection) { var guaranteedBommenHier = intersectionSet.Intersection.Count - intersectionSet.MinCountGuaranteedNotBombsInIntersection; var newSet = new VakjeSetDeluxe(guaranteedBommenHier, intersectionSet.MinCountGuaranteedNotBombsInIntersection, intersectionSet.Intersection); setsToAdd.Add(newSet); } } } var notCompletelyFilledIntersections = SetBepaler.BepaalSetsThatDontFillMeCompletely(set, alleOverlappendeSets); foreach (var notCompletelyFilledIntersection in notCompletelyFilledIntersections) { var maxBommen = set.Vakjes.Count - set.MinCountGuaranteedNotBombs; var bommenInTheseIntersections = notCompletelyFilledIntersection.Sum(t => t.MinCountGuaranteedBombsInIntersection); if (bommenInTheseIntersections == maxBommen) { var vakjesOver = set.Vakjes.Except(notCompletelyFilledIntersection.SelectMany(t => t.VakjeSetDeluxe.Vakjes)).ToList(); if (vakjesOver.Count > 0) { //Heeft alleen zin als er dus echt nog een set is met vakjes die dus als niet bomb kunnen worden gemarkeerd var newSet = new VakjeSetDeluxe(0, vakjesOver.Count, vakjesOver); setsToAdd.Add(newSet); } } var guaranteedNotBombs = notCompletelyFilledIntersection.Sum(t => t.MinCountGuaranteedNotBombsInIntersection); if (set.Vakjes.Count - set.MinCountGuaranteedBombs == guaranteedNotBombs) { var vakjesOver = set.Vakjes.Except(notCompletelyFilledIntersection.SelectMany(t => t.VakjeSetDeluxe.Vakjes)).ToList(); if (vakjesOver.Count > 0) { //Heeft alleen zin als er dus echt nog een set is met vakjes die dus als bomb kunnen worden gemarkeerd var newSet = new VakjeSetDeluxe(vakjesOver.Count, 0, vakjesOver); setsToAdd.Add(newSet); } } //var theRest = filledIntersection.Except(new List<IntersectionAndSet>() { intersectionSet }).ToList(); //if (set.Vakjes.Count - set.MinCountGuaranteedNotBombs == intersectionSet.MinCountGuaranteedBombsInIntersection) //{ // var vakjesOfTheRest = theRest.SelectMany(t => t.VakjeSetDeluxe.Vakjes).ToList(); // var newSet = new VakjeSetDeluxe(0, vakjesOfTheRest.Count, vakjesOfTheRest); // setsToAdd.Add(newSet); //} } } foreach (var newSet in setsToAdd) { var changed = AddSetDeluxe(allSets, iteratie, newSet.MinCountGuaranteedBombs, newSet.MinCountGuaranteedNotBombs, newSet.Vakjes); if (changed) { //Debug.WriteLine("Added set"); iteratie.Vondsten.Add(new BommenBepalerStatsIteratieVondst(iteratie, newSet.Vakjes.First(), VondstType.SetsBasedGuaranteedBomb)); } } return(iteratie); }
public void DetermineBestMove(GalaxySweeperGame game, bool executeMove) { if (game.isFinished) { return; } if (!game.myTurn) { executeMove = false; } var deVakjesArray = GalaxyGameHelper.CreateVakjesArray(game); //Nu is alle data goed var stats = BommenBepaler.BepaalBommenMulti(deVakjesArray, _botconfig); stats.Log(_logger); var unrevealedVakjes = TwoDimensionalArrayHelper.Flatten(deVakjesArray).Where(t => t != null).Where(t => !t.Revealed).OrderByDescending(t => t.VakjeBerekeningen.BerekendeVakjeKans).ToList(); var potentialBombs = unrevealedVakjes.Where(t => t.VakjeBerekeningen.BerekendVakjeType != BerekendVakjeType.GuaranteedNoBom).ToList(); var guaranteedBombs = potentialBombs.Where(t => t.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedBom).ToList(); var vakjesMetBomErnaast = potentialBombs.Where(t => t.SurroundingVakjes.Any(z => z != null && z.IsBomb)).ToList(); var vakjesMetBomErnaastDieOokGuaranteedGeenBomKunnenZijn = unrevealedVakjes.Where(t => t.SurroundingVakjes.Any(z => z != null && z.IsBomb)).ToList(); GalaxyVisualizator.RenderToConsole(deVakjesArray, _logger); _logger.WriteLine(string.Empty); _logger.WriteLine("Best chance bombs (top 5):"); foreach (var maybeBom in potentialBombs.Take(5)) { _logger.Write($"\t{maybeBom.ToString()}"); if (maybeBom.VakjeBerekeningen.BerekendVakjeType == BerekendVakjeType.GuaranteedBom) { var vondst = stats.GetVondstVoorVakje(maybeBom); if (vondst != null) { ConsoleColor c = ConsoleColor.DarkGreen; if (vondst.Vakje.SurroundingVakjes.Any(t => stats.GetVondstVoorVakje(t)?.VondstType == VondstType.SetsBasedGuaranteedNoBomb)) { c = ConsoleColor.DarkYellow; } if (vondst.VondstType == VondstType.SetsBasedGuaranteedBomb) { c = ConsoleColor.Magenta; } _logger.Write($"\t\t Gevonden in iteratie {vondst.Iteratie.IteratieNummer}. Type: {vondst.VondstType}", c); } } _logger.WriteLine(""); } _logger.WriteLine(string.Empty); _logger.WriteLine("Vakjes die op z'n minst een bom er naast hebben (dus sowieso geen 0 zijn):"); foreach (var maybeBom in vakjesMetBomErnaast.Take(5)) { _logger.WriteLine($"\t{maybeBom.ToString()}"); } _logger.WriteLine(string.Empty); var deBom = guaranteedBombs.FirstOrDefault(); if (deBom != null) { _logger.WriteLine($"Beste keuze (Guaranteed bom): {deBom}", ConsoleColor.DarkGreen); if (game.myTurn) { _logger.WriteLine("Sweeping...", ConsoleColor.Red); _galaxySweeperApiHelper.Sweep(game.id, deBom.X, deBom.Y); } } else { if (vakjesMetBomErnaast.Any()) { var hetVakjeWatWeGaanKlikken = vakjesMetBomErnaast.First(); _logger.WriteLine($"Beste keuze (Vakje met bom ernaast): {hetVakjeWatWeGaanKlikken}", ConsoleColor.DarkCyan); if (game.myTurn) { _logger.WriteLine("Sweeping...", ConsoleColor.Red); _galaxySweeperApiHelper.Sweep(game.id, hetVakjeWatWeGaanKlikken.X, hetVakjeWatWeGaanKlikken.Y); } } else if (_botconfig.AlwaysAvoidClickingOpenFields && vakjesMetBomErnaastDieOokGuaranteedGeenBomKunnenZijn.Any()) { var hetVakjeWatWeGaanKlikken = vakjesMetBomErnaastDieOokGuaranteedGeenBomKunnenZijn.First(); _logger.WriteLine($"Beste keuze (Vakje met bom ernaast wat een Guaranteed Not Bomb is): {hetVakjeWatWeGaanKlikken}", ConsoleColor.DarkCyan); if (game.myTurn) { _logger.WriteLine("Sweeping...", ConsoleColor.Red); _galaxySweeperApiHelper.Sweep(game.id, hetVakjeWatWeGaanKlikken.X, hetVakjeWatWeGaanKlikken.Y); } } else { var hetVakjeWatWeGaanKlikken = potentialBombs.First(); _logger.WriteLine($"Beste keuze (Hoogste kans): {hetVakjeWatWeGaanKlikken}", ConsoleColor.DarkBlue); if (game.myTurn) { _logger.WriteLine("Sweeping...", ConsoleColor.Red); _galaxySweeperApiHelper.Sweep(game.id, hetVakjeWatWeGaanKlikken.X, hetVakjeWatWeGaanKlikken.Y); } } } _logger.WriteLine(string.Empty); _logger.WriteLine(string.Empty); }