49714 Programming for Online Prototypes
· 9 members
A hands on introduction to building online products and services through code
BlackJack with a Twist
I wanted to make a chatbot that can play blackjack with you. However, I wanted to explore elements of trust and deception, so I programmed the house (the bot) to lie. The house knows what your next card is, and will tell you (truthfully or not) whether your next card will cause you to bust. The probability that the house is lying is made known to the player, and can be used as an additional advantage against the house.
I drew inspiration for the bot from a variety of sources including deception-based games like mafia and resistance along with games with a variety of complexities from the card-game war up to handheld Pokemon. These games are very rigid in what choices the game allows users to make, and any deviation from these choices is met with "these are your choices for actions, pick one." I knew I needed to keep the interaction with the bot very controlled and specific, so I leveraged that strategy when designing the chat interface.
The game of blackjack has a variety of different inputs that happen at specific stages of the game, so I had to design an internal structure for the game's code that could parse appropriate inputs at appropriate times while rejecting inputs that might be appropriate at other times, just not at that point (ie trying to bet when you are in the process of hitting or staying).
In order to do this, I implemented a state machine using a large case statement.
When: Start #welcomes the user to the game, giving the options: "play" or "rules"
When: play_or_rules #explains the rules or starts the game
When: hand_init #betting happens here, and the hand is generated
When: hit_or_stay #the user decides progressively whether to hit or to stay
After the player busts or decides to stay, the outcome is determined and relayed to the player. If the player still has money, they can bet again (or they win if they reach $500). If the player runs out of money, they lose, and can play again.
I used the DeckOfCards API in order to generate the hands for the player and for the house. I programmed all the betting and predicting and calculations by hand.
One counterintuitive aspect of the code is how it calculates the next hit. In order for the house to taunt the player and tell it whether or not the next card will bust, it has to know what the next card is. Therefore, on the first deal, the API gets pulled for not just the first two cards in the player's hand, but also the next card after that. That next card is held in code limbo until the player decides whether to hit or stay. If hit, then the card is "officially" revealed and added to the pile. Otherwise it is not saved.
I really enjoyed this project. I learned a lot about how to both program and prompt from people simple yet fun interactions with a bot. I wanted to play with the element of trust and what that feels like to trust (or not) a computer. I experimented with whether or not to tell players the odds that the computer is lying. I decided that element of discovery took too much time during gameplay and that it was more fun to know immediately what the odds are of truth-telling.
Some of the elements I used in my code to achieve the state machine are not best practice. I over-relied on global variables and should have used sessions to keep track of my persistent qualities. I also was not entirely consistent with the way that I delivered the value of the cards to the player. However, I am very happy with the completeness of the interactions and I have not found a way to break the code (yet).
Overall I feel like I learned a lot and ended up with a fun little game that helps pass the time.