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; }
protected override void DoSolve() { RuleOutcome outcome; GameState actualGameState = Coordinator.CurrentGameState.Clone(); Position initialPosition = actualGameState.YourOriginalCell.Position; int initialY = initialPosition.Y; int initialX = initialPosition.X; int equatorY; int distance; bool flipY = false; if (initialY > 14) { equatorY = 15; flipY = true; distance = initialY - equatorY; } else { equatorY = 14; flipY = false; distance = equatorY - initialY; } /* Original... * Step<PendulumState> program = new StepSequence<PendulumState> { * FlipX = FlipSetting.No, * FlipY = (flipY ? FlipSetting.Yes : FlipSetting.No), * Steps = new Step<PendulumState>[] { * new MoveInALine<PendulumState> { * Name = "MoveToEquator", * Direction = Direction.Down, * Distance = distance, * AfterStep = InitializePendulumState * }, * new RepeatWithIncreasingLevels<PendulumState> { * Name = "Pendulum", * GetInitialLevel = previousLevel => 1, * GetFinalLevel = previousLevel => (Constants.Rows - 2)/4, // Lower hemisphere => divide by 2; go down 2 blocks per turn => divide by 2 again * Steps = new Step<PendulumState>[] { * new MoveInALine<PendulumState>{ Name = "1_L", Direction = Direction.Left, GetDistanceFromLevel = level => level }, // N left * new MoveInALine<PendulumState>{ Name = "2_U", Direction = Direction.Up, GetDistanceFromLevel = level => 2 * level - 1}, // Nth odd number up * new MoveInALine<PendulumState>{ Name = "3_L", Direction = Direction.Left, Distance = 1}, // 1 left * new MoveInALine<PendulumState>{ Name = "4_D", Direction = Direction.Down, GetDistanceFromLevel = level => 2 * level}, // Nth odd number +1 down * new MoveInALine<PendulumState>{ Name = "5_R", Direction = Direction.Right, GetDistanceFromLevel = level => level + 2}, // N+2 right - split into N+1 right, then evaluate whether to backtrack or expand right * new MoveInALine<PendulumState>{ Name = "6_U", Direction = Direction.Up, GetDistanceFromLevel = level => level + 1}, // N+1 up * new MoveInALine<PendulumState>{ Name = "7_R", Direction = Direction.Right, Distance = 1}, // 1 right * new MoveInALine<PendulumState>{ Name = "8_D", Direction = Direction.Down, GetDistanceFromLevel = level => level + 2}, // N+2 down * new MoveInALine<PendulumState>{ Name = "9_L", Direction = Direction.Left, GetDistanceFromLevel = level => level + 2} // Move back under the vertical line * } * } * } * }; */ Step <PendulumState> program = new StepSequence <PendulumState> { FlipX = FlipSetting.No, FlipY = (flipY ? FlipSetting.Yes : FlipSetting.No), Steps = new Step <PendulumState>[] { new MoveInALine <PendulumState> { Name = "MoveToEquator", Direction = Direction.Down, Distance = distance, AfterStep = InitializePendulumState }, new StepSequence <PendulumState> { Name = "Pendulum", Repeat = true, Steps = new Step <PendulumState>[] { new MoveToAPoint <PendulumState> { Name = "1_L", GetPosition = GetFirstPosition, AfterEachMove = AfterFirstPosition }, // N left new MoveInALine <PendulumState> { Name = "2_U", Direction = Direction.Up, GetDistanceFromLevel = level => 2 * level - 1 }, // Nth odd number up new MoveInALine <PendulumState> { Name = "3_L", Direction = Direction.Left, Distance = 1 }, // 1 left new MoveInALine <PendulumState> { Name = "4_D", Direction = Direction.Down, GetDistanceFromLevel = level => 2 * level }, // Nth odd number +1 down new MoveInALine <PendulumState> { Name = "5_R", Direction = Direction.Right, GetDistanceFromLevel = level => level + 2 }, // N+2 right - split into N+1 right, then evaluate whether to backtrack or expand right new MoveInALine <PendulumState> { Name = "6_U", Direction = Direction.Up, GetDistanceFromLevel = level => level + 1 }, // N+1 up new MoveInALine <PendulumState> { Name = "7_R", Direction = Direction.Right, Distance = 1 }, // 1 right new MoveInALine <PendulumState> { Name = "8_D", Direction = Direction.Down, GetDistanceFromLevel = level => level + 2 }, // N+2 down new MoveInALine <PendulumState> { Name = "9_L", Direction = Direction.Left, GetDistanceFromLevel = level => level + 2 } // Move back under the vertical line } } } }; outcome = program.RunRulesEngine(actualGameState); if (outcome.Status == RuleStatus.NextMoveSuggested) { actualGameState.MakeMove(outcome.SuggestedMove); Coordinator.SetBestMoveSoFar(actualGameState); } else { NegaMaxSolver solver = new NegaMaxSolver(); DelegateSolvingToAnotherSolver(solver); } }