Пример #1
0
        protected override void DoSolve()
        {
            RuleOutcome outcome;
            GameState   actualGameState  = Coordinator.CurrentGameState.Clone();
            Position    initialPosition  = actualGameState.YourOriginalCell.Position;
            int         initialY         = initialPosition.Y;
            GameState   mutableGameState = RulesEngineHelper.GetInitialGameState(actualGameState);

            try
            {
                if (initialY <= 14)  // TODO: Remove hard-coding!
                {
                    outcome = SolveWhenStartingInNorthernHemisphere(mutableGameState, actualGameState);
                }
                else
                {
                    // TODO: outcome = SolveWhenStartingInSouthernHemisphere(mutableGameState, newGameState);
                    outcome = new RuleOutcome
                    {
                        Status = RuleStatus.NoFurtherSuggestions
                    };
                }
            }
            catch (Exception exc)
            {
                outcome = new RuleOutcome
                {
                    Status          = RuleStatus.ExceptionThrown,
                    ExceptionThrown = exc
                };
            }

            if (outcome.Status == RuleStatus.NextMoveSuggested)
            {
                actualGameState.MakeMove(outcome.SuggestedMove);
                Coordinator.SetBestMoveSoFar(actualGameState);
            }
            else
            {
                NegaMaxSolver solver = new NegaMaxSolver();
                DelegateSolvingToAnotherSolver(solver);
            }

            return;
        }
Пример #2
0
        private RuleOutcome SolveWhenStartingInNorthernHemisphere(GameState mutableGameState, GameState actualGameState)
        {
            RuleOutcome outcome;
            Position    nextPosition   = mutableGameState.YourOriginalCell.Position;
            int         nextMoveNumber = 0;

            Block leftBlock  = GetInitialLeftBlock(mutableGameState);
            Block rightBlock = GetInitialRightBlock(mutableGameState);

            /* Move to the equator: */
            int distance = 14 - nextPosition.Y;     // Remove hard-coding

            for (int i = 0; i < distance; i++)
            {
                nextMoveNumber++;
                nextPosition = new Position(nextPosition.X, nextPosition.Y + 1);
                outcome      = RulesEngineHelper.MoveToNextPosition(mutableGameState, actualGameState, nextPosition, nextMoveNumber);
                if (outcome.Status != RuleStatus.NoFurtherSuggestions)
                {
                    return(outcome);
                }

                // TODO: Update leftBlock and rightBlock
            }

            // Set up a state object to track various information:
            Position position = mutableGameState.YourCell.Position;
            NorthernPendulumBlock filledBlock = new NorthernPendulumBlock
            {
                LeftX     = position.X,
                RightX    = position.X,
                TopLeftY  = position.Y,
                TopRightY = position.Y,
                BottomY   = position.Y
            };

            // Swing the pendulum back and forth, increasing its length with each iteration:
            for (int pendulumLevel = 0; pendulumLevel < 13; pendulumLevel++)
            {
                Position targetPosition;
                int      targetX, targetY;

                // *** Move to first position:
                Dijkstra.Perform(mutableGameState);

                // Only move to first and second position if this reduces the opponent's gap:
                // ... bool isOpponentCloserToGapOnLeft =

                if (pendulumLevel % 2 == 0)
                {
                    // Going left:
                    targetX = Helper.NormalizedX(filledBlock.LeftX - 1);
                    targetY = filledBlock.TopLeftY - 1;
                }
                else
                {
                    // Going right:
                    targetX = Helper.NormalizedX(filledBlock.RightX + 1);
                    targetY = filledBlock.TopRightY - 1;
                }
                targetPosition = new Position(targetX, targetY);
                outcome        = RulesEngineHelper.MoveToPositionAlongAnyRoute(mutableGameState, actualGameState, ref nextMoveNumber, targetPosition);
                if (outcome.Status != RuleStatus.NoFurtherSuggestions)
                {
                    return(outcome);
                }

                // Update filled block:
                if (pendulumLevel % 2 == 0)
                {
                    // Going left:
                    filledBlock.LeftX    = targetX;
                    filledBlock.TopLeftY = targetY;
                }
                else
                {
                    // Going right:
                    filledBlock.RightX    = targetX;
                    filledBlock.TopRightY = targetY;
                }

                // *** Move to second position:
                Dijkstra.Perform(mutableGameState);

                if (pendulumLevel % 2 == 0)
                {
                    // Going left:
                    targetX = Helper.NormalizedX(filledBlock.LeftX - 1);
                }
                else
                {
                    // Going right:
                    targetX = Helper.NormalizedX(filledBlock.RightX + 1);
                }
                targetY        = filledBlock.BottomY + 1;
                targetPosition = new Position(targetX, targetY);
                outcome        = RulesEngineHelper.MoveToPositionAlongAnyRoute(mutableGameState, actualGameState, ref nextMoveNumber, targetPosition);
                if (outcome.Status != RuleStatus.NoFurtherSuggestions)
                {
                    return(outcome);
                }

                // Update filled block:
                if (pendulumLevel % 2 == 0)
                {
                    // Going left:
                    filledBlock.LeftX = targetX;
                }
                else
                {
                    // Going right:
                    filledBlock.RightX = targetX;
                }
                filledBlock.BottomY = targetY;

                // *** Move to third position:
                Dijkstra.Perform(mutableGameState);

                if (pendulumLevel % 2 == 0)
                {
                    // Going right:
                    targetX = filledBlock.RightX;
                }
                else
                {
                    // Going left:
                    targetX = filledBlock.LeftX;
                }
                targetY        = filledBlock.BottomY;
                targetPosition = new Position(targetX, targetY);
                outcome        = RulesEngineHelper.MoveToPositionAlongAnyRoute(mutableGameState, actualGameState, ref nextMoveNumber, targetPosition);
                if (outcome.Status != RuleStatus.NoFurtherSuggestions)
                {
                    return(outcome);
                }
            }

            // No more pre-programmed moves to make... hand over to normal solver now:
            outcome = new RuleOutcome
            {
                Status = RuleStatus.NoFurtherSuggestions
            };

            return(outcome);
        }