Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Building a Card Playing Twitter Bot: Storing and Retrieving Game State To/From AWS DynamoDB

DZone's Guide to

Building a Card Playing Twitter Bot: Storing and Retrieving Game State To/From AWS DynamoDB

· AI Zone ·
Free Resource

Did you know that 50- 80% of your enterprise business processes can be automated with AssistEdge?  Identify processes, deploy bots and scale effortlessly with AssistEdge.

I recently built a Twitter Bot that plays Blackjack. Here are my previous posts so far if you are catching up:

Since interaction with the Bot is via Twitter, there will be an unknown length of time between when a player chooses to reply and interact with the bot, which could be seconds, minutes, or days. Therefore, we need to store the gameplay state for each player, retrieve it on the next interaction from the user, and store it again after the response from the bot while we wait for the next player interaction.

The bot can support any number of players in parallel. For each bot/player interaction, we need to store the following:

  • the player's twitter handle
  • current cards remaining in the deck
  • cards in the player's hand
  • cards in the bot's hand
  • who's turn is it next

In a "traditional" data model, we could easily model this with some relational tables, but with DynamoDB as a key/value/document based data store, since we only need to store one interaction state per user, we can store this whole data structure in a single row keyed by the user's Twitter handle.

DynamoDB's supported types of scalar values (number, string) and set types (collections of scalar types) allow us to store everything we need in the game state (I did consider the document type, persisting JSON documents), but for retrieving game state values in an easy to use format, this didn't appear as useful and straightforward as scalar types and sets).

Browsing the table in DynamoDB using the AWS console, here's what the schema currently looks like for a completed game:

AWS DynamoDB offers three different APIs for interacting with tables and your data, described in the docs here: low level, document, high-level object mapper. With the AWS Java SDK APIs, using Java POJO classes to represent your data together with the DynamoDB Object Mapper APIs is probably the simplest of the three approaches and will feel familiar if you've used JPA, Hibernate, or other object/relational type mappers before.

Similar to JPA, the AWS DynamoDB APIs provide a number of annotations to map Java Pojos to your DynamoDB tables and columns. Here's the Pojo class that represents the game state:

@DynamoDBTable(tableName = "twitterbot-blackjack")
public class PlayerGameState {

  private String twitterhandle;
  private Hand playerHand;
  private Hand botHand;
  private Deck deck;
...
}

twitterhandle is the key. The annotation for the key column looks like this:

@DynamoDBHashKey
public String getTwitterhandle() {
  return this.twitterhandle;
}

deck, playerHand, and botHand are all collections of Card. As a "sub-document" type used by each of these other collections of Cards, the type is annotated with @DynamoDBDocument (instead of @DynamoDBTable):

@DynamoDBDocument
public class Card {

  private Suit suit;
  private CardName name;
  private int pointsValue;

  ...
}

DynamoDB supports maps of scalar values, so these fit well for representing a deck of cards and the player's hands of cards. If a single Card is a map of values, a collection of Cards is a map of Cards, so a map of maps. To map these more complex structures, a DynamoDB Type Converter is needed to tell the DynamoDB API how to map the structure to the table and back:

@DynamoDBDocument
public class Hand {

  private List<Card> cards = new ArrayList<>();

  @DynamoDBTypeConverted(converter = ListOfCardsToMapOfMapsConverter.class)
  public List<Card> getCards(){
    return this.cards;
  }

  ...

}

Next up, I'll describe how these Type Converters are used in more detail, and we'll look at storing and retrieving from a DynamoDB table.

Consuming AI in byte sized applications is the best way to transform digitally. #BuiltOnAI, EdgeVerve’s business application, provides you with everything you need to plug & play AI into your enterprise.  Learn more.

Topics:
artificial intelligence ,bot ,tutorial ,dynamodb ,aws

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}