示例#1
0
        public static double EVOpening(int d, double p)
        {
            double ev;
            string key = d + ":" + p;

            if (EVOpeningCache.TryGetValue(key, out ev))
            {
                return(ev);
            }

            if (p >= MinOpen || p >= WinScore)
            {
                EVOpeningCache.Add(key, p);
                return(p);
            }

            ev = Dice.Permute[d]
                 .Average(x => Farkle.GenerateActions(x)
                          .Max(y => (double?)EVOpening(y.DiceToRoll, p + y.ScoreToAdd)) ?? 0D);

            ev = (p < MinBank || p < MinOpen) ? ev : Math.Max(ev, p);
            EVOpeningCache.Add(key, ev);
            Console.Write('.');
            return(ev);
        }
示例#2
0
        public static double ChanceToWin(int d, double p)
        {
            double ev;
            string key = d + ":" + p;

            if (EVCache.TryGetValue(key, out ev))
            {
                return(ev);
            }

            if (p >= WinScore && p >= MinBank)
            {
                EVCache.Add(key, 1);
                return(1);
            }

            ev = Dice.Permute[d]
                 .Average(x => Farkle.GenerateActions(x)
                          .Max(y => (double?)ChanceToWin(y.DiceToRoll, p + y.ScoreToAdd)) ?? 0D);

            EVCache.Add(key, ev);
            Console.Write('.');
            return(ev);
        }
示例#3
0
        public static void Interactive()
        {
            Reset();

            string cmd = string.Empty, cmdData = null, cmdData2 = null;

            while (!UserCommand.Quit.Equals(cmd))
            {
                if (Mode == AIMode.Manual || State == GameState.NoGame || PlayerWithTheDice.Value.Type == PlayerType.Human)
                {
                    Write("<farkler{0}> $ ", PlayerWithTheDice == null ? "" : " : " + PlayerWithTheDice.Value.Name);
                    var cmdtext = Console.ReadLine().Replace("  ", " ").Trim().Split(' ');
                    cmd      = cmdtext[0];
                    cmdData  = cmdtext.Length > 1 ? cmdtext[1] : null;
                    cmdData2 = cmdtext.Length > 2 ? cmdtext[2] : null;
                }
                else
                {
                    RandomRoll();
                    WriteLine(Roll);
                    cmd = string.Empty;
                    //Thread.Sleep(2000);
                }

                switch (cmd)
                {
                case UserCommand.Reset:
                    Reset();
                    break;

                case UserCommand.AddPlayer:
                    if (State == GameState.InGame)
                    {
                        WriteLine("ERR - cannot add a player while a game is in progress.");
                    }
                    else if (cmdData == null)
                    {
                        WriteLine("ERR - (p) Usage:  p-PlayerName");
                    }
                    else if (Players.Any(x => x.Name.Equals(cmdData)))
                    {
                        WriteLine("ERR - player with that name already exists.");
                    }
                    else
                    {
                        Players.AddFirst(new FarklePlayer(cmdData));
                        WriteLine("Added new player {0}, now there are {1} players.", cmdData, Players.Count);
                    }
                    break;

                case UserCommand.AddPlayerAI:
                    if (State == GameState.InGame)
                    {
                        WriteLine("ERR - cannot add a player while a game is in progress.");
                    }
                    else if (cmdData == null)
                    {
                        WriteLine("ERR - (p) Usage:  p-PlayerName");
                    }
                    else if (Players.Any(x => x.Name.Equals(cmdData)))
                    {
                        WriteLine("ERR - player with that name already exists.");
                    }
                    else
                    {
                        Players.AddFirst(new FarklePlayer(cmdData, PlayerType.AI));
                        WriteLine("Added new AI player {0}, now there are {1} players.", cmdData, Players.Count);
                    }
                    break;

                case UserCommand.ModeAutomatic:
                    Mode = AIMode.Automatic;
                    WriteLine("Mode set to Automatic");
                    break;

                case UserCommand.ModeManual:
                    Mode = AIMode.Manual;
                    WriteLine("Mode set to Manual");
                    break;

                case UserCommand.RandomRoll:
                    if (Roll != null)
                    {
                        WriteLine("ERR - cannot Roll until current roll is acted upon.");
                    }
                    else
                    {
                        RandomRoll();
                        WriteLine(Roll);
                    }
                    break;

                case UserCommand.Roll:
                    if (Roll != null)
                    {
                        WriteLine("ERR - cannot Roll until current roll is acted upon.");
                    }
                    else if (cmdData == null || !Regex.IsMatch(cmdData, @"^\d{" + DiceToRoll + "}$"))
                    {
                        WriteLine("ERR - (r) Usage:  r-122245");
                    }
                    else
                    {
                        Roll            = new Roll(cmdData);
                        ActionsPossible = Farkle.GenerateActions(Roll);
                        WriteLine(Roll);
                    }
                    break;

                case UserCommand.Action:
                    if (PlayerWithTheDice.Value.Type != PlayerType.Human)
                    {
                        WriteLine("ERR - cannot perform Action, player is not human.");
                    }
                    else if (Roll == null)
                    {
                        WriteLine("ERR - cannot perform Action, there is no roll on the table.");
                    }
                    else if (cmdData == null)
                    {
                        WriteLine("ERR - (a) Usage:  a-400-3 (a-points-dicetoroll)");
                    }
                    else
                    {
                        int points;
                        if (!int.TryParse(cmdData, out points))
                        {
                            WriteLine("ERR - (a) Usage:  a-400-3 (a-points-dicetoroll)"); break;
                        }
                        if (!ActionsPossible.Any(x => x.ScoreToAdd == points))
                        {
                            WriteLine("ERR - no matching possible action."); break;
                        }

                        if (cmdData2 == null)
                        {
                            if (TurnScore + points < 300)
                            {
                                WriteLine("ERR - cannot bank less than 300 points."); break;
                            }
                            TurnScore += points;
                            PlayerWithTheDice.Value.BankedScore += TurnScore;
                            WriteLine("{0} BANKS {1}", CurrentPlayerInfo(), TurnScore);
                            EndTurn();
                        }
                        else
                        {
                            int dice;
                            if (!int.TryParse(cmdData2, out dice))
                            {
                                WriteLine("ERR - (a) Usage:  a-400-3 (a-points-dicetoroll)"); break;
                            }
                            if (!ActionsPossible.Any(x => x.ScoreToAdd == points && x.DiceToRoll == dice))
                            {
                                WriteLine("ERR - no matching possible action."); break;
                            }

                            TurnScore += points;
                            DiceToRoll = dice;
                            WriteLine("{0} STASHES {1} and WILL ROLL {2}", CurrentPlayerInfo(), points, dice);
                            Roll = null;
                        }
                    }
                    break;

                case UserCommand.NewGame:
                    NewGame();
                    break;

                case UserCommand.Quit:
                    State = GameState.NoGame;
                    break;

                default:
                    break;
                }

                if (GameState.NoGame.Equals(State))
                {
                    continue;
                }

                if (Roll != null)
                {
                    bool turnIsOver = false;
                    switch (PlayerWithTheDice.Value.Type)
                    {
                    case PlayerType.AI:
                        turnIsOver = ChooseAndPerformAction();
                        Roll       = null;
                        ActionsPossible.Clear();
                        break;

                    case PlayerType.Human:
                        turnIsOver = false;
                        if (!ActionsPossible.Any())
                        {
                            TurnScore = 0;
                            WriteLine("{0} BUSTED!", CurrentPlayerInfo());
                            turnIsOver = true;
                        }

                        break;
                    }

                    if (turnIsOver)
                    {
                        EndTurn();
                    }
                }

                FarklePlayer winner = Players.FirstOrDefault(x => x.BankedScore >= ExpectedValueCalc.WinScore);
                if (winner != null)
                {
                    WriteLine("\n\n---------- {0} WINS! ----------", winner.Name);
                    WriteLine("{0} Turns for an average of {1} points per turn.", winner.TurnsTaken, (double)winner.BankedScore / winner.TurnsTaken);
                    NewGame();
                    State = GameState.NoGame;
                }
            } //while
        }
示例#4
0
 static void RandomRoll()
 {
     Roll            = Dice.RandomRoll(DiceToRoll);
     ActionsPossible = Farkle.GenerateActions(Roll);
 }