/// <inheritdoc cref="Player.DecideNextMove"/> public override Move DecideNextMove(Rules rules, Playground playground) { if (_gamePlan is null || rules != _gamePlan.Rules) { _gamePlan = new GamePlan(rules); _gamePlan.Generate(); } Dictionary <Move, float> chances = new Dictionary <Move, float>(); List <Tuple <Move, float, float> > tuples = _gamePlan.GetChances(playground); float weight = Math.Abs(_difficulty); foreach ((Move move, float winChance, float looseChance) in tuples) { chances[move] = (float)_random.NextDouble() * (1f - weight) + (_difficulty < 0 ? looseChance : winChance) * weight; } List <KeyValuePair <Move, float> > keyValuePairs = chances.OrderBy(p => p.Value).ThenBy(p => p.Key.ChangesPerRow.Sum()).ToList(); return(keyValuePairs.Last().Key); }
/// <summary> /// Creates a new AI Player /// </summary> /// <param name="name">The name for this player. Also used as seed for the internal randomization</param> /// <param name="difficulty">The difficulty level of this AI player. May range anywhere from 1 to -1, where 1 results in the best, 0 in random and -1 in the worst possible choices</param> /// <param name="teacher">An existing AI Player to copy the decision tree from</param> public AiPlayerMinMax(string name, float difficulty, AiPlayerMinMax teacher) : this(name, difficulty) { _gamePlan = teacher._gamePlan; }
/// <summary> /// Creates a new AI Player /// </summary> /// <param name="name">The name for this player. Also used as seed for the internal randomization</param> /// <param name="difficulty">The difficulty level of this AI player. May range anywhere from 1 to -1, where 1 results in the best, 0 in random and -1 in the worst possible choices</param> /// <param name="rules">The rules to initialize the player with. Pre-loads the decision tree</param> public AiPlayerMinMax(string name, float difficulty, Rules rules) : this(name, difficulty) { _gamePlan = new GamePlan(rules); _gamePlan.Generate(); }