public virtual bool RemoveStartingPeg(Dictionary <char, bool> pegs) { Func <char, bool> HasPeg = (char selectedPeg) => Array.IndexOf(GameInterface.PegChars, selectedPeg) >= 0; Console.Write("Choose the peg to remove: "); var peg = ReadPeg(HasPeg); Console.WriteLine(peg); if (peg.HasValue) { GameInterface.RemovePeg(pegs, peg.Value); } return(peg.HasValue); }
static void ShowStats() { var model = new InteractiveWithHintsModel(new string[0]); Console.Clear(); Console.WriteLine("Calculating game stats for each starting peg.\n"); var totalHints = new Hints(); foreach (var startingPeg in GameInterface.PegChars) { Console.Write($"Peg {startingPeg}: "); var pegs = GameInterface.InitializePegs(); GameInterface.RemovePeg(pegs, startingPeg); var finished = model.CalculateGameStats(pegs, false); if (finished) { var hints = model.GetHints(pegs); Console.WriteLine($"Possibilities: {hints.Possibilities.ToString("N0").PadLeft(9)} - Best/Worst Score: {hints.BestScore.ToString("N0").PadLeft(2)}/{hints.WorstScore.ToString("N0").PadRight(2)} - Wins: {hints.Wins.ToString("N0").PadLeft(7)} - Win Rate: {hints.WinRate.ToString("P2").PadLeft(7)}"); totalHints.Possibilities += hints.Possibilities; totalHints.Wins += hints.Wins; totalHints.BestScore = Math.Min(totalHints.BestScore, hints.BestScore); totalHints.WorstScore = Math.Max(totalHints.WorstScore, hints.WorstScore); } else { Console.WriteLine("Aborted"); if (Console.ReadKey(true).Key == ConsoleKey.Escape) { break; } } } Console.WriteLine(); Console.WriteLine($"Total: Possibilities: {totalHints.Possibilities.ToString("N0").PadLeft(9)} - Best/Worst Score: {totalHints.BestScore.ToString("N0").PadLeft(2)}/{totalHints.WorstScore.ToString("N0").PadRight(2)} - Wins: {totalHints.Wins.ToString("N0").PadLeft(7)} - Win Rate: {totalHints.WinRate.ToString("P2").PadLeft(7)}"); }
static void Main(string[] args) { if (Array.IndexOf(args, "-stats") >= 0) { ShowStats(); return; } IGameModel model; if (Array.IndexOf(args, "-paths") >= 0) { model = new AllPathsModel(args); } else if (Array.IndexOf(args, "-first") >= 0) { model = new FirstWinFromAllPathsModel(); } else if (Array.IndexOf(args, "-expert") >= 0) { model = new InteractiveModel(); } else { model = new InteractiveWithHintsModel(args); } Dictionary <char, bool> pegs; do { pegs = GameInterface.InitializePegs(); GameInterface.PrintPegs(pegs); if (!model.RemoveStartingPeg(pegs)) { model.PrintStats(); return; } GameInterface.PrintPegs(pegs); do { model.PrintStats(); if (Console.KeyAvailable == true) { Console.WriteLine("Game paused. Press a key to continue."); while (Console.KeyAvailable) { Console.ReadKey(true); } var unpause = Console.ReadKey(true).Key; if (unpause == ConsoleKey.Escape) { return; } } if (!model.PerformNextJump(pegs)) { break; } GameInterface.PrintPegs(pegs); }while (GameInterface.GetPossibleJumps(pegs).Length > 0); }while (model.PlayAgain(pegs)); }
public virtual bool PerformNextJump(Dictionary <char, bool> pegs) { var jumps = GameInterface.GetPossibleJumps(pegs); History.JumpRecord thisJump; // If the last path got as far as our previous jump if (lastPath != null && lastPath.Count > currentPath.Count - 1) { // If the paths have been the sae so far, then we need to // decide what to do on this jump based on the last path if (PathsEqual(lastPath, currentPath)) { // The previous jumps were the same (or this is the first jump) // Now we need to look ahead at the next jump to determine if // this jump should be the same var lastPathThisJumpIndex = lastPath[currentPath.Count].JumpIndex; var hasRemainingDecrements = false; for (var i = currentPath.Count + 1; i < lastPath.Count; i++) { if (lastPath[i].JumpIndex > 0) { hasRemainingDecrements = true; break; } } if (hasRemainingDecrements == true) { // There are remaining jumps to decrement, // so we will keep this jump the same thisJump = new History.JumpRecord(jumps[lastPathThisJumpIndex], lastPathThisJumpIndex); } else { // There are no remaining jumps to decrement, // so we need to decrement this one if possible if (lastPathThisJumpIndex > 0) { thisJump = new History.JumpRecord(jumps[lastPathThisJumpIndex - 1], lastPathThisJumpIndex - 1); } else { throw new Exception($"Cannot decrement this jump. Jump number: {currentPath.Count}. Has remaining decrements: {hasRemainingDecrements}."); } } } else { // The previous jumps were different // We will choose the last option for this jump thisJump = new History.JumpRecord(jumps[jumps.Length - 1], jumps.Length - 1); } } else { // The last path didn't get as far as we have gotten // We will choose the last option for this jump thisJump = new History.JumpRecord(jumps[jumps.Length - 1], jumps.Length - 1); } currentPath.Add(thisJump); GameInterface.PerformJump(pegs, thisJump.Jump); return(true); }
public override bool PlayAgain(Dictionary <char, bool> pegs) { var pegsRemaining = GameInterface.GetRemainingPegs(pegs); var gameRecord = new History.GameRecord(currentPath, pegsRemaining); history[startingPeg.Value].Add(gameRecord); if (pegsRemaining.Length == 1) { wins[startingPeg.Value].Add(gameRecord); } PrintStats(); bool hasMoreMoves = false; foreach (var jump in history[startingPeg.Value][history[startingPeg.Value].Count - 1].JumpList) { if (jump.JumpIndex > 0) { hasMoreMoves = true; } } if (!hasMoreMoves || wins[startingPeg.Value].Count >= 1) { nextStartingPeg++; lastPath = null; } if (GameInterface.PegChars.Length > nextStartingPeg) { return(true); } var output = new System.Text.StringBuilder(); output.Append("Wins:\n"); foreach (var peg in wins.Keys) { output.Append($"Starting Peg: {peg}\n\n"); if (wins[peg].Count > 0) { foreach (var jump in wins[peg][0].JumpList) { output.Append($" Jumped {jump.From} over {jump.Over}.\n"); } output.Append("\n"); } else { output.Append("No wins\n\n"); } } Console.WriteLine(output); return(false); }