예제 #1
0
        public void CalculatesTurnsForZeroAugmentColumnPriorToGaussianElimination()
        {
            const int nodeCount = 25;
            const int mineCount = 1;

            Span <Node> nodes = stackalloc Node[]
            {
                new(0, false, 0, NodeState.Revealed),
                new(1, false, 1, NodeState.Revealed),
                new(2, true, 0, NodeState.Flagged),
                new(3, false, 0, NodeState.Hidden),
                new(4, false, 0, NodeState.Hidden),

                new(5, false, 0, NodeState.Revealed),
                new(6, false, 1, NodeState.Revealed),
                new(7, false, 1, NodeState.Revealed),
                new(8, false, 0, NodeState.Hidden),
                new(9, false, 0, NodeState.Hidden),

                new(10, false, 1, NodeState.Revealed),
                new(11, false, 1, NodeState.Revealed),
                new(12, false, 1, NodeState.Revealed),
                new(13, false, 0, NodeState.Hidden),
                new(14, false, 0, NodeState.Hidden),

                new(15, false, 0, NodeState.Hidden),
                new(16, false, 0, NodeState.Hidden),
                new(17, false, 3, NodeState.Revealed),
                new(18, false, 0, NodeState.Hidden),
                new(19, false, 0, NodeState.Hidden),

                new(20, false, 0, NodeState.Hidden),
                new(21, false, 0, NodeState.Hidden),
                new(22, false, 0, NodeState.Hidden),
                new(23, false, 0, NodeState.Hidden),
                new(24, false, 0, NodeState.Hidden)
            };

            var buffs = new BufferKeeper
            {
                Turns          = stackalloc Turn[nodeCount],
                EdgeIndexes    = stackalloc int[Engine.MaxNodeEdges],
                Mines          = stackalloc int[mineCount],
                VisitedIndexes = stackalloc int[nodeCount - mineCount],
                RevealedMineCountNodeIndexes = stackalloc int[nodeCount - mineCount],
                AdjacentHiddenNodeIndexes    = stackalloc int[nodeCount],
                Grid = stackalloc float[nodeCount * nodeCount]
            };

            var matrix = new Matrix <Node>(nodes, 5);

            var turnCount = MatrixSolver.CalculateTurns(matrix, buffs, false);

            Assert.Equal(3, turnCount);
            Assert.Equal(new Turn(3, NodeOperation.Reveal), buffs.Turns[0]);
            Assert.Equal(new Turn(8, NodeOperation.Reveal), buffs.Turns[1]);
            Assert.Equal(new Turn(13, NodeOperation.Reveal), buffs.Turns[2]);
        }
예제 #2
0
        public static void Simulation(Matrix <Node> matrix, Span <Turn> turns, int firstTurnNodeIndex, int mineCount)
        {
            var nodeCount = matrix.Nodes.Length;
            var buffs     = new BufferKeeper
            {
                Turns          = stackalloc Turn[nodeCount],
                EdgeIndexes    = stackalloc int[Engine.MaxNodeEdges],
                Mines          = stackalloc int[mineCount],
                VisitedIndexes = stackalloc int[nodeCount - mineCount],
                RevealedMineCountNodeIndexes = stackalloc int[nodeCount - mineCount],
                AdjacentHiddenNodeIndexes    = stackalloc int[nodeCount],
                Grid = stackalloc float[nodeCount * nodeCount]
            };

            Engine.FillCustomBoard(matrix, buffs.Mines, firstTurnNodeIndex);

            var firstTurn = new Turn(firstTurnNodeIndex, NodeOperation.Reveal);

            Engine.ComputeBoard(matrix, firstTurn, buffs.VisitedIndexes);

            while (true)
            {
                var turnCount = MatrixSolver.CalculateTurns(matrix, buffs, false);
                if (turnCount == 0)
                {
                    turnCount = MatrixSolver.CalculateTurns(matrix, buffs, true);
                    if (turnCount == 0)
                    {
                        break;
                    }
                }
                foreach (var turn in turns.Slice(0, turnCount))
                {
                    Engine.ComputeBoard(matrix, turn, buffs.VisitedIndexes);
                }
            }
        }
    }
예제 #3
0
        public void CalculatesTurnsForVectorSumEqualsAugmentColumnPriorToGaussianElimination()
        {
            const int nodeCount = 64;
            const int mineCount = 4;

            Span <Node> nodes = stackalloc Node[]
            {
                new(0, false, 0, NodeState.Revealed),
                new(1, false, 0, NodeState.Revealed),
                new(2, false, 0, NodeState.Revealed),
                new(3, false, 0, NodeState.Revealed),
                new(4, false, 1, NodeState.Revealed),
                new(5, false, 0, NodeState.Hidden),
                new(6, false, 1, NodeState.Revealed),
                new(7, false, 0, NodeState.Revealed),

                new(8, false, 1, NodeState.Revealed),
                new(9, false, 1, NodeState.Revealed),
                new(10, false, 2, NodeState.Revealed),
                new(11, false, 1, NodeState.Revealed),
                new(12, false, 2, NodeState.Revealed),
                new(13, false, 0, NodeState.Hidden),
                new(14, false, 1, NodeState.Revealed),
                new(15, false, 0, NodeState.Revealed),

                new(16, false, 1, NodeState.Revealed),
                new(17, true, 0, NodeState.Flagged),
                new(18, false, 2, NodeState.Revealed),
                new(19, true, 0, NodeState.Flagged),
                new(20, false, 2, NodeState.Revealed),
                new(21, false, 1, NodeState.Revealed),
                new(22, false, 1, NodeState.Revealed),
                new(23, false, 0, NodeState.Revealed),

                new(24, false, 2, NodeState.Revealed),
                new(25, false, 2, NodeState.Revealed),
                new(26, false, 3, NodeState.Revealed),
                new(27, false, 1, NodeState.Revealed),
                new(28, false, 2, NodeState.Revealed),
                new(29, false, 0, NodeState.Hidden),
                new(30, false, 1, NodeState.Revealed),
                new(31, false, 0, NodeState.Revealed),

                new(32, false, 2, NodeState.Revealed),
                new(33, true, 0, NodeState.Flagged),
                new(34, false, 2, NodeState.Revealed),
                new(35, false, 0, NodeState.Revealed),
                new(36, false, 1, NodeState.Revealed),
                new(37, false, 0, NodeState.Hidden),
                new(38, false, 3, NodeState.Revealed),
                new(39, false, 2, NodeState.Revealed),

                new(40, false, 3, NodeState.Revealed),
                new(41, true, 0, NodeState.Flagged),
                new(42, false, 3, NodeState.Revealed),
                new(43, false, 1, NodeState.Revealed),
                new(44, false, 1, NodeState.Revealed),
                new(45, false, 2, NodeState.Revealed),
                new(46, false, 0, NodeState.Hidden),
                new(47, false, 0, NodeState.Hidden),

                new(48, false, 0, NodeState.Hidden),
                new(49, false, 0, NodeState.Hidden),
                new(50, false, 0, NodeState.Hidden),
                new(51, false, 0, NodeState.Hidden),
                new(52, false, 0, NodeState.Hidden),
                new(53, false, 0, NodeState.Hidden),
                new(54, false, 0, NodeState.Hidden),
                new(55, false, 0, NodeState.Hidden),

                new(56, false, 0, NodeState.Hidden),
                new(57, false, 0, NodeState.Hidden),
                new(58, false, 0, NodeState.Hidden),
                new(59, false, 0, NodeState.Hidden),
                new(60, false, 0, NodeState.Hidden),
                new(61, false, 0, NodeState.Hidden),
                new(62, false, 0, NodeState.Hidden),
                new(63, false, 0, NodeState.Hidden)
            };

            var buffs = new BufferKeeper
            {
                Turns          = stackalloc Turn[nodeCount],
                EdgeIndexes    = stackalloc int[Engine.MaxNodeEdges],
                Mines          = stackalloc int[mineCount],
                VisitedIndexes = stackalloc int[nodeCount - mineCount],
                RevealedMineCountNodeIndexes = stackalloc int[nodeCount - mineCount],
                AdjacentHiddenNodeIndexes    = stackalloc int[nodeCount],
                Grid = stackalloc float[nodeCount * nodeCount]
            };
            var matrix = new Matrix <Node>(nodes, 8);

            var turnCount = MatrixSolver.CalculateTurns(matrix, buffs, false);

            Assert.Equal(2, turnCount);
            Assert.Equal(new Turn(46, NodeOperation.Flag), buffs.Turns[0]);
            Assert.Equal(new Turn(47, NodeOperation.Flag), buffs.Turns[1]);
        }
예제 #4
0
        public void CalculatesTurnsWhenGaussianEliminationProducesNonIntegers()
        {
            const int nodeCount = 64;
            const int mineCount = 10;

            Span <Node> nodes = stackalloc Node[]
            {
                new(0, false, 1, NodeState.Revealed),
                new(1, false, 1, NodeState.Revealed),
                new(2, false, 1, NodeState.Revealed),
                new(3, true, 1, NodeState.Flagged),
                new(4, false, 2, NodeState.Revealed),
                new(5, false, 1, NodeState.Revealed),
                new(6, false, 1, NodeState.Revealed),
                new(7, false, 1, NodeState.Hidden),

                new(8, true, 1, NodeState.Flagged),
                new(9, false, 2, NodeState.Revealed),
                new(10, false, 3, NodeState.Revealed),
                new(11, false, 3, NodeState.Revealed),
                new(12, true, 2, NodeState.Hidden),
                new(13, false, 1, NodeState.Hidden),
                new(14, false, 1, NodeState.Revealed),
                new(15, true, 0, NodeState.Hidden),

                new(16, false, 2, NodeState.Revealed),
                new(17, true, 1, NodeState.Flagged),
                new(18, false, 2, NodeState.Revealed),
                new(19, true, 2, NodeState.Flagged),
                new(20, false, 3, NodeState.Hidden),
                new(21, false, 2, NodeState.Revealed),
                new(22, false, 1, NodeState.Revealed),
                new(23, false, 1, NodeState.Revealed),

                new(24, false, 1, NodeState.Revealed),
                new(25, false, 1, NodeState.Revealed),
                new(26, false, 3, NodeState.Revealed),
                new(27, false, 3, NodeState.Revealed),
                new(28, true, 2, NodeState.Hidden),
                new(29, false, 1, NodeState.Hidden),
                new(30, false, 0, NodeState.Hidden),
                new(31, false, 0, NodeState.Hidden),

                new(32, false, 0, NodeState.Revealed),
                new(33, false, 0, NodeState.Revealed),
                new(34, false, 1, NodeState.Revealed),
                new(35, true, 1, NodeState.Flagged),
                new(36, false, 2, NodeState.Revealed),
                new(37, false, 1, NodeState.Hidden),
                new(38, false, 0, NodeState.Hidden),
                new(39, false, 0, NodeState.Hidden),

                new(40, false, 0, NodeState.Revealed),
                new(41, false, 0, NodeState.Revealed),
                new(42, false, 1, NodeState.Revealed),
                new(43, false, 1, NodeState.Revealed),
                new(44, false, 2, NodeState.Revealed),
                new(45, false, 2, NodeState.Revealed),
                new(46, false, 2, NodeState.Hidden),
                new(47, false, 1, NodeState.Hidden),

                new(48, false, 0, NodeState.Revealed),
                new(49, false, 0, NodeState.Revealed),
                new(50, false, 0, NodeState.Revealed),
                new(51, false, 0, NodeState.Revealed),
                new(52, false, 1, NodeState.Revealed),
                new(53, true, 1, NodeState.Hidden),
                new(54, true, 1, NodeState.Hidden),
                new(55, false, 1, NodeState.Hidden),

                new(56, false, 0, NodeState.Revealed),
                new(57, false, 0, NodeState.Revealed),
                new(58, false, 0, NodeState.Revealed),
                new(59, false, 0, NodeState.Revealed),
                new(60, false, 1, NodeState.Revealed),
                new(61, false, 2, NodeState.Hidden),
                new(62, false, 2, NodeState.Hidden),
                new(63, false, 1, NodeState.Hidden)
            };

            var buffs = new BufferKeeper
            {
                Turns          = stackalloc Turn[nodeCount],
                EdgeIndexes    = stackalloc int[Engine.MaxNodeEdges],
                Mines          = stackalloc int[mineCount],
                VisitedIndexes = stackalloc int[nodeCount - mineCount],
                RevealedMineCountNodeIndexes = stackalloc int[nodeCount - mineCount],
                AdjacentHiddenNodeIndexes    = stackalloc int[nodeCount],
                Grid = stackalloc float[nodeCount * nodeCount]
            };

            var matrix    = new Matrix <Node>(nodes, 8);
            var turnCount = MatrixSolver.CalculateTurns(matrix, buffs, false);

            Assert.Equal(2, turnCount);

            // changing float to sbyte will cause our solver to generate incorrect turns
            Assert.NotEqual(6, turnCount);

            Assert.Equal(new Turn(29, NodeOperation.Reveal), buffs.Turns[0]);
            Assert.Equal(new Turn(61, NodeOperation.Reveal), buffs.Turns[1]);
        }
예제 #5
0
        static void Main(string[] args)
        {
            var options = new ChromeOptions();

            //options.AddArgument("-headless");
            using var driver = new ChromeDriver(options);

            // some key aspects have been omitted from this bot
            // also, performance is purposefully degraded
            driver.Navigate().GoToUrl("");

            var squares = driver
                          .FindElementById("game")
                          .FindElements(By.ClassName("square"))
                          .Where(x => x.Displayed)
                          .ToList();

            Debug.Assert(squares.Count == nodeCount);

            LeftClickNode(squares, 93);

            var buffs = new BufferKeeper
            {
                Turns          = stackalloc Turn[nodeCount],
                EdgeIndexes    = stackalloc int[Engine.MaxNodeEdges],
                Mines          = stackalloc int[mineCount],
                VisitedIndexes = stackalloc int[nodeCount - mineCount],
                RevealedMineCountNodeIndexes = stackalloc int[nodeCount - mineCount],
                AdjacentHiddenNodeIndexes    = stackalloc int[nodeCount],
                Grid = stackalloc float[nodeCount * nodeCount]
            };

            while (IsGamePending(driver))
            {
                var nodes = squares
                            .Select(x => x.GetAttribute("class"))
                            .Select((x, i) => new Node(i, false, GetMineCount(x), GetNodeState(x)))
                            .ToArray()
                            .AsSpan();

                var matrix    = new Matrix <Node>(nodes, columns);
                var turnCount = MatrixSolver.CalculateTurns(matrix, buffs, true);

                if (turnCount == 0)
                {
                    break;
                }

                // ignore the other turns for now
                var turn = buffs.Turns[0];

                if (turn.Operation == NodeOperation.Reveal)
                {
                    LeftClickNode(squares, turn.NodeIndex);
                }
                else
                {
                    RightClickNode(squares, turn.NodeIndex, driver);
                }

                Console.WriteLine(turn);
            }

            Console.WriteLine("finished");
            Console.ReadLine();
        }