public bool Play(CardRowConfiguration startConfig, bool isPlayerTurn) { var config = startConfig; DisplayConfig(config, isPlayerTurn); while (config.GetState() != CardGameState.Win && config.GetState() != CardGameState.Lose) { var move = isPlayerTurn ? GetUserMove(config) : _solver.GetBestMove(config); config = config.Move(move); isPlayerTurn = !isPlayerTurn; DisplayConfig(config, isPlayerTurn); } var state = config.GetState(); switch (state) { case CardGameState.Win: return(isPlayerTurn); case CardGameState.Lose: return(!isPlayerTurn); } throw new Exception("Invalid game state."); }
public void DisplayConfig(CardRowConfiguration config, bool isPlayerTurn) { Console.Clear(); config.Draw(); if (!isPlayerTurn) { Thread.Sleep(TimeSpan.FromSeconds(2)); } }
public int GetNodeScore(CardRowConfiguration config, int depth = 1) { var isPlayerTurn = depth % 2 != 0; var state = config.GetState(); if (isPlayerTurn) { switch (state) { case CardGameState.PredictLose: return(-depth); case CardGameState.PredictWin: return(100 - depth); case CardGameState.Lose: return(-100); case CardGameState.Win: return(100); } } else { switch (state) { case CardGameState.PredictLose: return(100 - depth); case CardGameState.PredictWin: return(-depth); case CardGameState.Lose: return(100); case CardGameState.Win: return(-100); } } var children = config.GetChildConfigurations(); return(children.Select(c => GetNodeScore(c, depth + 1)) .OrderBy(x => x < 0) .ThenByDescending(x => x) .First()); }
public Move GetUserMove(CardRowConfiguration configuration) { int row = -1; int maxRowValue = 0; int value = 0; var rowKey = new ConsoleKeyInfo(); while (maxRowValue == 0) { Console.Write("Enter row [0 - 2] -- must have more than 0 items: "); rowKey = Console.ReadKey(); Console.WriteLine(); if (char.IsDigit(rowKey.KeyChar)) { row = int.Parse(rowKey.KeyChar.ToString()); if (row >= 0 && row <= 2) { maxRowValue = configuration.GetMaxRowValue(row); } } } var valueKey = new ConsoleKeyInfo(); while (!char.IsDigit(valueKey.KeyChar) || value < 1 || value > maxRowValue) { Console.Write($"How much to take? [1 - {maxRowValue}]: "); valueKey = Console.ReadKey(); Console.WriteLine(); if (char.IsDigit(valueKey.KeyChar)) { value = int.Parse(valueKey.KeyChar.ToString()); } } var move = new Move(3) { RowSubtracts = { [row] = value } }; return(move); }
// Get next best move public Move GetBestMove(CardRowConfiguration config) { return(config.GetPossibleMoves() .MinBy(move => GetNodeScore(config.Move(move))) .First()); }
public CardRowConfiguration(CardRowConfiguration other) { Row1 = other.Row1; Row2 = other.Row2; Row3 = other.Row3; }