/// <summary> /// Generate a play action for current scene. /// </summary> /// <param name="scene">The scene.</param> /// <returns>The cards to be played.</returns> public RockAction GetPlayAction(RockScene scene) { // You can just return an null or empty list, which means ends turn. //// return null; //// Put your codes in here. RockSceneContext context = new RockSceneContext(scene); double bestScore = 0d; List <int> bestAction = null; Random r = new Random(); foreach (List <int> action in scene.PlayOptions) { double score = PlayActionScore.ComputeScore(context, action); score += r.NextDouble(); if (score >= bestScore) { bestScore = score; bestAction = action; } } if (bestAction != null) { return(RockAction.Create(bestAction)); } return(this.DefaultGetPlayAction(scene)); }
/// <summary> /// Generate a play action for current scene. /// </summary> /// <param name="scene">The scene.</param> /// <returns>The cards to be played.</returns> public RockAction GetPlayAction(RockScene scene) { this.tracer.Verbose(RockJsonSerializer.Serialize(scene)); try { if (string.IsNullOrEmpty(this.configuration.BotEndpoint)) { var robot = new Bot.RockBot(); var action = robot.GetPlayAction(scene); this.tracer.Verbose(RockJsonSerializer.Serialize(action)); return(action); } else { var apiClient = new RockApiClient(); var action = apiClient.Post <RockAction>($"{this.configuration.BotEndpoint}{RockConstants.DefaultBotPlayRelativePath}", scene); this.tracer.Verbose(RockJsonSerializer.Serialize(action)); return(action); } } catch (Exception e) { this.tracer.Error($"Unexpected Exception from Bot: {e}"); return(RockAction.Create()); } }
/// <summary> /// Generate a sample RockScene. /// </summary> /// <returns>A RockScene.</returns> private static RockScene GenerateRockScene() { var rockScene = new RockScene(); rockScene.Self = GenerateRockPlayer(); rockScene.Opponent = GenerateRockPlayer(); return(rockScene); }
/// <summary> /// Generate a mulligan action for current scene. /// </summary> /// <param name="scene">The scene.</param> /// <returns>The cards to be mulligan-ed.</returns> public RockAction GetMulliganAction(RockScene scene) { // You can just return an null or empty list, which means keep all cards. //// return null; //// Put your codes in here. return(this.DefaultGetMulliganAction(scene)); }
/// <summary> /// Initializes a new instance of the <see cref="RockSceneContext" /> class. /// </summary> /// <param name="scene">The RockScene</param> public RockSceneContext(RockScene scene) { this.Scene = scene; this.objects = new Dictionary <int, RockObject>(); this.costs = new Dictionary <int, int>(); this.ExtractRockObjects(scene); this.AnalyzePlayOptionCosts(scene); }
/// <summary> /// The default implementation of GetPlayAction /// </summary> /// <param name="scene">the scene</param> /// <returns>the cards to be played</returns> private RockAction DefaultGetPlayAction(RockScene scene) { if (scene.PlayOptions.Count == 0) { return(RockAction.Create()); } else { // this smart bot will randomly choose an play action. return(RockAction.Create(scene.PlayOptions[new Random().Next(0, scene.PlayOptions.Count)])); } }
/// <summary> /// Snapshot Scene /// </summary> /// <returns>The RockScene.</returns> public static RockScene SnapshotScene() { var rockScene = new RockScene(); Player self = GameState.Get().GetFriendlySidePlayer(); Player opponent = GameState.Get().GetFirstOpponentPlayer(GameState.Get().GetFriendlySidePlayer()); rockScene.Self = SnapshotPlayer(self); rockScene.Opponent = SnapshotPlayer(opponent); rockScene.PlayOptions = SnapshotOptions(); rockScene.Turn = GameState.Get().GetTurn(); return(rockScene); }
/// <summary> /// The default implementation of GetMulliganAction /// </summary> /// <param name="scene">the scene</param> /// <returns>the cards to be mulligan-ed</returns> private RockAction DefaultGetMulliganAction(RockScene scene) { List <int> cards = new List <int>(); foreach (RockCard card in scene.Self.Cards) { if (card.Cost >= 4) { cards.Add(card.RockId); } } return(RockAction.Create(cards)); }
/// <summary> /// Analyze PlayOption costs. /// </summary> /// <param name="scene">The RockScene</param> private void AnalyzePlayOptionCosts(RockScene scene) { foreach (var playOption in scene.PlayOptions) { int id = playOption[0]; if (!this.costs.ContainsKey(id)) { if (this.IsObjectType(id, RockObjectType.FriendlyHeroPower)) { this.costs.Add(id, 2); } else if (this.IsObjectType(id, RockObjectType.FriendlyCard)) { var card = this.GetRockCard(id); this.costs.Add(id, card.Cost); } else { this.costs.Add(id, 0); } } } }
/// <summary> /// Report the result of an action by providing the current scene. /// </summary> /// <param name="scene">The scene.</param> public void ReportActionResult(RockScene scene) { // do nothing in built-in bot. return; }
/// <summary> /// Extract RockObjects in the RockScene into the Dictionary. /// </summary> /// <param name="scene">The RockScene</param> private void ExtractRockObjects(RockScene scene) { this.ExtractRockObjects(scene.Self, true); this.ExtractRockObjects(scene.Opponent, false); }