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);
        }
Пример #7
0
        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);
        }