This is a two-player card game which resembles a vastly simplified game of Texas Hold'em, combined with RPS (rock-paper-scissors) and the most basic mechanic of commercial turn-based card games.
The deck
A single full deck consists of 30 unique cards, where each card has one symbol out of RPS
and one number between 0 and 9 inclusive. Each card is referred to as a 2-char string like R0
or S3
(symbol, then number).
Since the 30-card deck is divided into three smaller decks during the game, let's call the 30-card deck a full deck (as opposed to simply deck).
The match
A single match consists of two phases: Draft phase and Main phase. In the Draft phase, the two players' decks (10 cards each) are decided. In the Main phase, actual games of Poker are played, and each player gets some score based on the number of games won.
Draft phase
- The full deck of 30 cards is shuffled.
- Repeat five times:
- Each player is given two cards from the top of the full deck.
- Each player selects one of them, which will go into their own deck.
- Each player gives the unselected card to their opponent.
At the end of Draft phase, players A and B have a deck of 10 cards each, and the main deck has 10 cards remaining. Additionally, each player gets to know 5 of the 10 cards in the opponent's deck during the process.
Main phase
- Each deck (player's and the remaining) is shuffled.
- Each player draws three cards from their own deck.
- Repeat 10 times:
- A card (called base card) is shown from the remaining deck.
- Each player plays a card from their own hand.
- A winner is determined by comparing (A's play + base) to (B's play + base). The winner gains 1 point.
- Each player draws a card from their own deck (unless there's nothing to draw).
Deciding the winner of a single game
The winner is decided by comparing the two-card combinations in the following order:
- If one combination is a pair (two cards sharing a number) and the other is not, a pair always wins against a non-pair.
- If the two cards played (excluding the base card) have different numbers, the player who played a higher-numbered card wins.
- Otherwise, the two cards are compared under the RPS rules. R wins against S, S wins against P, and P wins against R.
Note that a draw is not possible since every card is unique in a deck.
Bots and the controller
An answer should include a single bot that can handle the Draft phase and the Main phase.
The controller code is here, with three example bots.
A bot has the following structure:
{
name: 'MinimalValid',
draftPick(cards) { return 0; },
draftReceive(card) {},
mainPlay(cards, base) { return 0; },
mainPostprocess(card) {},
},
name
: The name of the bot, a string.draftPick
: Called when the bot is given two cards to choose from during the draft phase (2-2).- Input: an array of cards to choose from
- Output: a valid index in the array of cards
draftReceive
: Called to inform the "unselected-by-opponent" card to the bot (2-3).- Input: a single card
- Output: nothing
mainPlay
: Called when the bot plays a card during the main phase (3-2).- Input: the hand (an array of cards), the base card
- Output: a valid index in the hand
mainPostprocess
: Called to inform the card played by the opponent.- Input: a single card
- Output: nothing
A slightly better bot to illustrate how to keep state in this
:
{
name: 'Simple',
myDeck: new Set(),
draftPick(cards) {
let cardId = cards[0][1] < cards[1][1] ? 1 : 0;
this.myDeck.add(cards[cardId]);
return cardId;
},
draftReceive(card) {
this.myDeck.add(card);
},
mainPlay(cards, base) {
this.myDeck.delete(cards[0]);
return 0;
},
mainPostprocess(card) {
},
},
A bot is immediately disqualified by the controller if it throws an exception or returns an invalid index. A submission is also invalid if it tries to cheat the controller in any way.
Given multiple bots, the controller will run round-robin matches. The entire cycle will be run multiple times (exact number depends on the number of submissions) and all scores will be accumulated to decide the overall winner.
The deadline is 00:00 UTC on June 18, 2021. If we don't have 10 submissions (excluding the two example bots) until then, the deadline will be extended by a week until we do. The winning answer will be accepted at that point.
The winner is Basic Odds by MegaTom. Congratulations!
You can still submit new bots even though the competition is officially over. (assuming I am active) I will run a new round and update the leaderboard. The accepted answer will not change even if the winner changes after the deadline.
The two bots presented here will be included when running the matches.
Leaderboard
The following is the total scores after 100 rounds.
1. BasicOdds 2500
2. ObviousStrats 2336
3. tsh 2016
4. Simple 1916
5. MinimalValid 1232
Object.freeze
on bots introduce some confusion behaviors (you cannot assign its properties). Remove it would make implementation easier. \$\endgroup\$