public async Task OnGameActionRequested(GameActionRequest actionRequest, StateHelper stateHelper) { // Always roll if it's an option. if (actionRequest.PossibleActions.Contains(GameActionType.RollDice)) { // If we can roll the dice.... LET'S DO IT! // Always roll ALL THE DICE int maxDiceCount = stateHelper.Player.GetMaxCountOfDiceCanRoll(); // Check if we have another roll. int rollsSoFar = stateHelper.GetState().CurrentTurnState.Rolls; bool canReRoll = stateHelper.Player.GetMaxRollsAllowed() < rollsSoFar; // If we can't reroll, auto commit the dice. Otherwise don't, so we can reroll if we want. Logger.Log(Log.Info, "Requesting a dice roll! BIG MONEY NO WHAMMIES..."); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateRollDiceAction(maxDiceCount, !canReRoll)); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to roll dice.", result.Error); } else { Logger.Log(Log.Info, "Trust the dice gods, we roll the dice and commit!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.BuildBuilding)) { // WE ARE A BIG ROLLER... let's build. // Get all building that are in the marketplace currently. List <int> buildable = stateHelper.Marketplace.GetBuildingTypesBuildableInMarketplace(); // Filter it down to only buildings we can afford. List <int> affordable = stateHelper.Player.FilterBuildingIndexesWeCanAfford(buildable); // Randomly pick one. int buildingIndex = affordable[m_random.RandomInt(0, affordable.Count - 1)]; // IF WE BUILD IT... Logger.Log(Log.Info, $"Requesting to build {stateHelper.BuildingRules[buildingIndex].GetName()}..."); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateBuildBuildingAction(buildingIndex)); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to build building.", result.Error); } else { Logger.Log(Log.Info, $"We just bought {stateHelper.BuildingRules[buildingIndex].GetName()}!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.EndTurn)) { // If we can't roll the dice or build a building, we must not have enough funds. // Just end the turn. // End it! Logger.Log(Log.Info, "There's nothing to do, requesting turn end..."); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateEndTurnAction()); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to end our turn.", result.Error); } else { Logger.Log(Log.Info, $"We have {stateHelper.Player.GetPlayer().Coins} coins and can't buy anything, so we ended the turn."); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.TvStationPayout)) { // Our Tv Station activated! Let's take 5 coins from a player at random. GamePlayer randomPlayer = GetRandomPlayer(stateHelper); // DO IT!!! Logger.Log(Log.Info, $"Our Tv Station was activated, let's take coins from player {randomPlayer.Name}!"); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateTvStationPayoutAction(randomPlayer.PlayerIndex)); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to respond to tv station payout.", result.Error); } else { Logger.Log(Log.Info, $"We taken coins from player {randomPlayer.Name} for our tv station!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.BusinessCenterSwap)) { // Our Business Center activated! Let's randomly pick a player and building to swap. GamePlayer randomPlayer = GetRandomPlayer(stateHelper); BuildingBase ourBuilding = GetRandomOwnedNonMajorBuidling(stateHelper, null); BuildingBase theirBuilding = GetRandomOwnedNonMajorBuidling(stateHelper, randomPlayer.PlayerIndex); GameActionResponse result; if (randomPlayer == null || ourBuilding == null || theirBuilding == null) { // If there aren't any building we can use, skip the action. Logger.Log(Log.Info, $"Our Business Center was activated, but there weren't the correct building to swap. So we will skip!"); result = await m_bot.SendAction(GameAction <object> .CreateBusinessCenterSwapAction(0, 0, 0, true)); } else { Logger.Log(Log.Info, $"Our Business Center was activated, swap our {ourBuilding.GetName()} for {randomPlayer.Name}'s {theirBuilding.GetName()}!"); result = await m_bot.SendAction(GameAction <object> .CreateBusinessCenterSwapAction(randomPlayer.PlayerIndex, ourBuilding.GetBuildingIndex(), theirBuilding.GetBuildingIndex())); } if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to respond to business center swap.", result.Error); } else { Logger.Log(Log.Info, $"Business center swap done!"); } return; } Logger.Log(Log.Error, $"Hmm, we were asked for an action but didn't know what to do with..."); foreach (GameActionType type in actionRequest.PossibleActions) { Logger.Log(Log.Error, $" ... {type.ToString()}"); await Shutdown("received an unknown action.", null); } }
public async Task OnGameActionRequested(GameActionRequest actionRequest, StateHelper stateHelper) { // OnGameActionRequested is called when the bot actually needs to take an action. Below is an example of how this can // be done and what events your bot will need to handle. // // To see all of the actions your must handle, look at GameActionType. // // actionRequest.State is the root of the state object for the game. This holds all things like players, coin amounts, // what building are in the marketplace, states of the current turn, etc. // Essentially, this object is everything you would see on the table when playing the game. // // The statehelper is a very useful tool that will answer many current state questions. The state helper takes a perspective user // when it's created, that it will use as a default player if no player is given. // For example, the Player.GetPlayerName function takes an option playerIndex. If not given, it will return your name. // // There are 4 modules to the state helper. Each helper has functions specific the to topic. // Player // ex. GetPlayer(), GetNumberOfLandmarksOwned(), GetMaxRollsAllowed(), CanHaveExtraTurn() // Marketplace // ex. GetMaxBuildingsInGame(), GetBuiltBuildingsInCurrentGame(), GetBuildingTypesBuildableInMarketplace() // CurrentTurn // ex. CanRollOrReRoll(), GetPossibleActions(), CanTakeAction() // BuildingRules // This helper holds all of the building types and the rules of them. ex. BuildingRules[buildingIndex].GetColor() // // Always roll if it's an option. if (actionRequest.PossibleActions.Contains(GameActionType.RollDice)) { // How many dice can we roll? int maxDiceCount = stateHelper.Player.GetMaxCountOfDiceCanRoll(); // Can we re-roll int rollsSoFar = stateHelper.GetState().CurrentTurnState.Rolls; bool canReRoll = stateHelper.Player.GetMaxRollsAllowed() < rollsSoFar; // If we can't reroll, auto commit the dice. Otherwise don't, so we can reroll if we want. Logger.Log(Log.Info, "Rolling the dice!"); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateRollDiceAction(maxDiceCount, !canReRoll)); if (!result.Accepted) { await Shutdown("failed to roll dice.", result.Error); } else { Logger.Log(Log.Info, "Done"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.CommitDiceResult)) { // This action is used if you want to see the dice results before they are committed. // It's useful to see the results if you have the ability to re-roll, so you can decided to re-roll. // But if the `autoCommitResults` flag is set to true when you call `CreateRollDiceAction` this wont' get called, // because the server will always do this for you. GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateCommitDiceResultAction()); if (!result.Accepted) { await Shutdown("failed to commit dice.", result.Error); } else { Logger.Log(Log.Info, "Done"); } } if (actionRequest.PossibleActions.Contains(GameActionType.BuildBuilding)) { // Get all building that are in the marketplace currently. List <int> buildable = stateHelper.Marketplace.GetBuildingTypesBuildableInMarketplace(); // Filter it down to only buildings we can afford. List <int> affordable = stateHelper.Player.FilterBuildingIndexesWeCanAfford(buildable); // Randomly pick one. int buildingIndex = affordable[m_random.RandomInt(0, affordable.Count - 1)]; Logger.Log(Log.Info, $"Requesting to build {stateHelper.BuildingRules[buildingIndex].GetName()}..."); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateBuildBuildingAction(buildingIndex)); if (!result.Accepted) { await Shutdown("failed to build building.", result.Error); } else { Logger.Log(Log.Info, $"We just bought {stateHelper.BuildingRules[buildingIndex].GetName()}!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.TvStationPayout)) { // Our Tv Station activated! Let's take 5 coins from a player at random. GamePlayer randomPlayer = GetRandomPlayer(stateHelper); Logger.Log(Log.Info, $"Our Tv Station was activated, let's take coins from player {randomPlayer.Name}!"); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateTvStationPayoutAction(randomPlayer.PlayerIndex)); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to respond to tv station payout.", result.Error); } else { Logger.Log(Log.Info, $"We taken coins from player {randomPlayer.Name} for our tv station!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.BusinessCenterSwap)) { // Our Business Center activated! Let's randomly pick a player and building to swap. GamePlayer randomPlayer = GetRandomPlayer(stateHelper); BuildingBase ourBuilding = GetRandomOwnedNonMajorBuidling(stateHelper, null); BuildingBase theirBuilding = GetRandomOwnedNonMajorBuidling(stateHelper, randomPlayer.PlayerIndex); GameActionResponse result; if (randomPlayer == null || ourBuilding == null || theirBuilding == null) { // If there aren't any building we can use, skip the action. Logger.Log(Log.Info, $"Our Business Center was activated, but there weren't the correct building to swap. So we will skip!"); result = await m_bot.SendAction(GameAction <object> .CreateBusinessCenterSwapAction(0, 0, 0, true)); } else { Logger.Log(Log.Info, $"Our Business Center was activated, swap our {ourBuilding.GetName()} for {randomPlayer.Name}'s {theirBuilding.GetName()}!"); result = await m_bot.SendAction(GameAction <object> .CreateBusinessCenterSwapAction(randomPlayer.PlayerIndex, ourBuilding.GetBuildingIndex(), theirBuilding.GetBuildingIndex())); } if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to respond to business center swap.", result.Error); } else { Logger.Log(Log.Info, $"Business center swap done!"); } return; } if (actionRequest.PossibleActions.Contains(GameActionType.EndTurn)) { // If we can't roll the dice or build a building, we must not have enough funds. // Just end the turn. Logger.Log(Log.Info, "There's nothing to do, requesting turn end..."); GameActionResponse result = await m_bot.SendAction(GameAction <object> .CreateEndTurnAction()); if (!result.Accepted) { // If random bot fails, it instantly shuts down. await Shutdown("failed to end our turn.", result.Error); } else { Logger.Log(Log.Info, $"We have {stateHelper.Player.GetPlayer().Coins} coins and can't buy anything, so we ended the turn."); } return; } Logger.Log(Log.Error, $"Hmm, we were asked for an action but didn't know what to do with..."); foreach (GameActionType type in actionRequest.PossibleActions) { Logger.Log(Log.Error, $" ... {type.ToString()}"); await Shutdown("received an unknown action.", null); } }