BS
king-of-the-hill
The goal of this challenge is to implement an AI for the game of BS, also known as Bull Shit, Cheat, Bluff, and numerous other names.
The game is outlined in this wikipedia article.
The Rules of the Game
For the purposes of this challenge, the game will work like this:
- A standard 52-card deck is dealt out to the players
- The current rank is set to Ace
- The play order is randomized
- The player holding the Ace of Hearts goes first
- On each player's turn:
- The current player plays some number of cards
- The current player states how many of what rank they played
- Other players may declare 'BS'.
- If any player declares 'BS':
- All players are notified of which players declared 'BS'.
- The played cards are revealed to all players.
- If the played cards are inconsistent with the current player's statement:
- The current player adds the played cards and all cards in the pile to their hand
- If the played cards are consistant with the current player's statement:
- The last player to declare 'BS' that round adds the played cards and pile to their hand.
- If no player declares 'BS':
- The played cards are added to the pile, without revealing them.
- If the played cards were inconsistant with the current player's statement, the current player may declare 'Peanut Butter'.
- If the current player has no cards in their hand, the current player wins.
- The current rank is incremented. (If the current rank is King, it becomes Ace.)
The Messaging Protocol
Play will be conducted via messages passed to the standard input and received from the standard output of each program. Each message will be terminated with a single newline character.
Cards
Card ranks are represented as one of A
, 2
, 3
, 4
, 5
, 6
, 7
, 8
, 9
, T
, J
, Q
, or K
. Card suits will be represented as one of S
, C
, H
, or D
.
Cards are represented as the rank, followed immediately by a suit. For instance, the Ten of Clubs would be represented by TC
, and the Three of Hearts would be represented by 3H
.
A hand of cards will be represented as a space-delimited sequence of cards. For instance, a hand containing the Queen of Spades and the Six of Diamonds could be represented as QS 6D
or 6D QS
.
Player Identification
A player will be represented by their nickname, followed by a number from 0 to 32768, in parenthesis, formatted as an integer. This number is guaranteed to be unique within a particular game. A player's nickname must have at least one character, can have up to 32 characters, and may only include letters, numbers, and underscores. For instance, a player with nickname ExampleAI
and ID number 16480 would be identified in the game as ExampleAI(16480)
.
When the game begins, each program will recieve a message containing their unique ID:
Unique ID: uniqueID
Each player will reply with their desired nickname:
Nickname: name
Names may contain only alphanumeric characters and underscores.
After all players have responded with their nickname, the standard play sequence begins.
Standard Play Sequence
When a player's turn begins, each player will receive a be given a list of the players and their card counts, in order of play:
Players: player[count], player[count], ... player[count]
Each player will be informed of the contents of their hands:
Hand: initial_hand
The current the player will then receive this message:
Your turn: current_rank
The current player will reply with a space-separated list of of cards:
Play: list_of_cards
Once they have submitted their play, all players will receive the number of cards, formatted as an integer, along with the current rank:
Player player plays: nunber_of_cards x current_rank
Each other player may then declare BS on that play by sending any message up to 32 characters, containing the capital letters B
and S
, and otherwise only contains lowercase letters and spaces. So any of Bull Shit
, Bananna Split
or Bacon Sandwich
would be acceptable.
During this period, the current player may declare Peanut Butter by sending any message up to 32 characters, as long as it contains the capital letters P
and B
, and otherwise only contains lowercase letters and spaces. So any of Peanut Butter
, Pancake Batter
or Polish Bacon
would be acceptable.
In order to allow the game to move faster, if a player does not wish to declare either of these things, they must instead send:
Pass
After all players have responded, all players will receive a list of players who called BS, in the order they called it:
Called BS: player, player ... player
If no player called BS, this message will still be sent --- it just won't have any players listed.
If any player did call BS, then all players will recieve:
Player player had played: list_of_cards
If they were bluffing, all players recieve:
Player player was bluffing.
And the current player receives:
Your bluff was called: list_of_cards_recieved
If they were not bluffing, all players recieve:
Player player was not bluffing.
Player last_player receives the pile.
The last player who called BS recieves this message:
You misjudged: list_of_cards_received
The list of cards received will contain, in reverse chronological order, the contents of each play since the last call. (Separate plays will not be delimited in the list.)
If no player declared BS, and the current player was bluffing and declared Peanut Butter, then all players recieve the message:
Player player was bluffing.
If the current player has no cards left in their hand, all players receive this message, and the game terminates:
Player player won!
Otherwise, the next player's turn begins.
Example Game
The following might be considered a typical (abbreviated) message transcript:
Unique ID: 16481
> Nickname: Alice
Players: Alice(16481)[18], Bob(16479)[17], Charlie(16480)[17]
Hand: 2D 7S AS TC 5S JS JC 3C 8H 9D 5D AH 7C 6C 4D KC KH KS
Your turn: A
> Play: AS 2D AH
Player Alice(16481) plays: 3 x A
> PB
Called BS:
Player Alice(16481) was bluffing.
Players: Bob(16479)[17], Charlie(16480)[17], Alice(16481)[15]
Hand: 7S TC 5S JS JC 3C 8H 9D 5D 7C 6C 4D KC KH KS
Player Bob(16479) plays: 2 x 2
> BS
Called BS: Alice(16481)
Player Bob(16479) had played: 2H 2C
Player Bob(16479) was not bluffing.
Player Alice(16481) takes the pile.
You misjudged: 2H 2C AS 2D AH
Players: Charlie(16480)[17], Alice(16481)[20], Bob(16479)[15]
Hand: 7S TC 5S JS JC 3C 8H 9D 5D 7C 6C 4D KC KH KS 2H 2C AS 2D AH
.
.
.
Players: Alice(16481)[3], Bob(16479)[41], Charlie(16480)[8]
Hand: KC KH KS
Your turn: K
> Play: KC KH KS
Called BS: Charlie(16480), Bob(16479)
Player Alice(16481) was not bluffing.
Player Bob(16479) receives the pile.
Player Alice(16481) won!
Your implementation may be written in any language, provided that you, upon request, provide a link to a suitable free-as-in-freedom compiler or interpreter that I can download and run at no cost. You also need to provide a UNIX command that can start your program.
Sandbox Questions
I want to gauge the community's interest in my problem before finalizing the spec and writing the control program.
I also need to get some idea of what sort of time-limiting scheme would be reasonable. In order to be able to to a lot of runs, I will need to be able to ensure that each AI doesn't take too much time to make its decisions, or prevent a stuck AI from holding up a game. I also need to be able to ensure that there is no motivation to deliberately stall a game. For example, if an AI determines that it is very unlikely to win, it might stall in order to prevent the game from finishing.
I would also like feedback on the messaging protocol:
- Are there any additional messages that you think should be passed?
- Would it be more convenient/clear if one or more of them were formatted differently?
- Would it be better to use a different format for the
plays
message?
- Would it be better to use different words to help distinguish the
plays
and played
messages?