public void Debug()
        {
            var stateInput = "...1...|..344..|.44433.|2444443|.41421.|..113..|...0...|5 2|0 3|2 1|3 5|";
            var state      = StateReader.Read(stateInput);
            var action     = new AlphaBetaAi(evaluator, 1).GetAction(state, 100);

            Assert.That(action.ToString(), Is.EqualTo("MOVE&BUILD 0 SE SW"));
        }
        public void AssignValueToLastSearchTreeSizeProperty_DuringSearch(int depth, int expectedSize)
        {
            var state = StateReader.Read("002|022|200|0 0|1 0|-1 -1|-1 -1|");
            var ai    = new AlphaBetaAi(evaluator, depth);

            ai.GetAction(state, 1000);
            ai.LastSearchTreeSize.Should().Be(expectedSize);
        }
        public void AssignValueToLastDepthFullySearchedProperty_DuringSearch(int depth)
        {
            var state = StateReader.Read("00000|00000|00000|00000|00000|1 1|2 3|-1 -1|-1 -1|");
            var ai    = new AlphaBetaAi(evaluator, depth);

            ai.GetAction(state, 1000);
            ai.LastDepthFullySearched.Should().Be(depth);
        }
        public void MeasureSearchTreeSize()
        {
            var stateInput = "...2...|..303..|.13033.|0010031|.01412.|..121..|...1...|3 5|5 2|2 2|5 4|";
            var state      = StateReader.Read(stateInput);

            new AlphaBetaAi(evaluator).GetAction(state, 1); // heat up
            var ai = new AlphaBetaAi(evaluator, 3);

            ai.GetAction(state, 3000); // measure
            Console.WriteLine($"SearchTreeSize: {ai.LastSearchTreeSize}");
        }
        public void BeEquivalentToGreedy_WhenSearchDepthIs1(string input)
        {
            var state            = StateReader.Read(input);
            var initialStateDump = state.ToString();

            var greedyAction = new GreedyAi(evaluator).GetAction(state, 100);
            var abAction     = new AlphaBetaAi(evaluator, 1).GetAction(state, 100);

            Console.WriteLine(state.ToString());
            Console.WriteLine($"[{abAction}]");

            state.ToString().Should().Be(initialStateDump, "ai.GetAction should not change state");
            abAction.ToString().Should().Be(greedyAction.ToString(), "ab-ai with depth=1 should be exactly gready ai");
        }
        public void MeasurePerformance()
        {
            var state = new StateReader("...0...|..000..|.00000.|0000000|.00010.|..000..|...1...|3 5|5 4|3 4|1 1|")
                        .ReadState(new InitializationData(7, 2));
            var alphabetaAi = new AlphaBetaAi(evaluator)
            {
                LoggingEnabled = false
            };
            var totalNodesProcessed = 0;
            var totalDepths         = 0;
            var count = 50;

            for (var turn = 0; turn < count; turn++)
            {
                var action = alphabetaAi.GetAction(state, turn == 0 ? 100 : 50);
                action.ApplyTo(state);
                state.ChangeCurrentPlayer();
                totalNodesProcessed += alphabetaAi.LastSearchTreeSize;
                totalDepths         += alphabetaAi.LastDepthFullySearched;
            }
            Console.WriteLine($"Total Nodes Searched: {totalNodesProcessed}");
            Console.WriteLine($"Average search depth: {totalDepths / (double)count}");
        }