P7147 [THUPC 2021 Preliminary] Mahjong Simulator

Description

Mahjong is a casual four-player board game. Your task is to write a simulator to simulate the process of one game. Next, we will introduce the game rules and each player’s decisions in detail. Note: for implementation convenience and to make the game more interesting, the rules introduced here are slightly different from several mainstream Mahjong rule sets. **Basic Rules:** - A full Mahjong set contains $148$ tiles, including $37$ different tile types, with $4$ tiles of each type. - These $37$ tile types are: 1-wan to 9-wan (`1M ~ 9M`), 1-tong to 9-tong (`1P ~ 9P`), 1-suo to 9-suo (`1S ~ 9S`), East (`E`), South (`S`), West (`W`), North (`N`), White (`B`), Green (`F`), Red (`Z`), and $3$ special tiles: Skip (`PASS`), Reverse (`REVERSE`), Double Turn (`DOUBLE`). - There are $4$ players in the game, denoted as `A`, `B`, `C`, `D`. - Before the game starts, the $148$ tiles are randomly shuffled and placed in a single row, called the tile deck. After that, whenever a player draws a tile, they always draw the frontmost tile from the deck. - Starting from `A` and in the order `ABCDABCD...`, each player draws one tile in turn from the deck until everyone has $13$ tiles. These tiles form each player’s hand. - Then, starting from `A` and in the order `ABCDABCD...`, players enter their turns in sequence. - In a turn, the player first draws one tile into their hand, then discards one tile from their hand. - This continues until someone wins or there are no tiles left to draw, and the game ends. **Special Tiles:** - Skip (`PASS`): when discarding this tile, the player may choose a player, causing that player to skip their next turn. - Reverse (`REVERSE`): when discarding this tile, reverse the turn order, i.e., change `ABCDABCD...` to `ADCBADCB...`, or change `ADCBADCB...` to `ABCDABCD...`. After discarding, turns proceed according to the reversed order, starting from the discarder’s previous player in the original order. - Double Turn (`DOUBLE`): when discarding this tile, the player immediately takes an extra turn. **Meld Types:**​There are the following $3$ meld types: - Sequence: $3$ consecutive-number tiles of the same suit among wan, tong, or suo, e.g., `4P 5P 6P`. - Triplet: $3$ identical non-special tiles, e.g., `B B B`. - Pair: $2$ identical non-special tiles, e.g., `9M 9M`. **Chow and Pong:** - When a player discards a non-special tile, other players may chow or pong: - Chow (`CHOW`): if the discarded tile together with two tiles in your hand can form a sequence, you may take those two tiles from your hand and place them aside together with the discarded tile. - **Note that only the next player of the discarder (the player who would take the next turn under the current turn order) may chow.** - Pong (`PONG`): if the discarded tile together with two tiles in your hand can form a triplet, you may take those two tiles from your hand and place them aside together with the discarded tile. - Pong does not have the above restriction of chow; any other player may pong. - If some player can chow and some player can pong, pong has priority over chow. - Chow (or pong) is not mandatory. That is, when a player satisfies the condition to chow (or pong), they may choose not to chow (or pong). - Chow and pong are collectively called open melds. For convenience, open melds are not considered part of the hand. - After any player chows (or pongs), skip the turns of all players between the previous discarder and this player, and start a new turn directly from the current player. However, in this turn, the player **skips drawing and discards directly**, and returns to normal in the next turn (if there is no chow/pong). - **Note that kongs are not allowed under these rules.** **Winning Rules:** - A player’s tiles are said to be winning if and only if all the following are satisfied: - The number of tiles is $14 - 3 n$, where $n$ is the number of open melds (i.e., chow/pong) of that player. - There are no special tiles among these tiles. - These tiles can be partitioned into $(5 - n)$ groups, where $(4 - n)$ groups each have $3$ tiles and are each either a sequence or a triplet, and the remaining one group has $2$ tiles and is a pair. - **Note that special winning patterns such as Seven Pairs, Thirteen Orphans, and “all non-related” are not supported under these rules.** - Additionally, define the winning distance of a hand with $13 - 3 n$ tiles as the minimum $x$ such that after adding some specific $x$ tiles into these tiles, and then removing $x - 1$ tiles from the hand, the count of each tile type is still at most $4$ and the hand is winning. - Define the winning distance of a hand with $14 - 3 n$ tiles as the minimum $x$ such that after adding some specific $x$ tiles into these tiles, and then removing $x$ tiles from the hand, the count of each tile type is still at most $4$ and the hand is winning. - In particular, a winning hand has winning distance $0$. A hand with winning distance $1$ is called a ready hand (ting, “听牌”). - Note the restriction that “**the count of each tile type is still at most** $\boldsymbol{4}$ **tiles**”: if a hand is `1M 1M 1M 1M` and the number of open melds is $3$, then adding one more `1M` would make it winning, but since there would be $5$ `1M` tiles, this is not allowed, so its winning distance is not considered $1$. - However, if a hand is `1M` and the number of open melds is $4$, and the player has once made a pong of `1M 1M 1M`, it is still considered to have winning distance $1$ (even though the missing `1M` can never be drawn). **Game End:** - Win by discard (`RON`): after a player discards a tile, if some other player’s hand plus this tile is winning, then that player wins by discard (RON). RON has priority over chow/pong. - If multiple players can RON at the same time, only the first player (starting from the previous discarder and moving along the current turn order) who can RON is allowed to RON. The other players cannot RON. This situation is called “intercepted win” (jiehe, “截和”). - Self-draw win (`SELFDRAWN`): after a player draws a tile, if their hand is winning, then the player wins by self-draw. - Once any player wins by RON or SELFDRAWN, the game ends immediately and that player wins. - If a player tries to draw and finds that the deck has no tiles left, the game ends immediately. This is called a draw game. **Discard Strategy:**​All players use the same fixed strategy: - When discarding, if the player has any special tile, they will always discard a special tile first. If there are multiple special tiles, the priority is `PASS`, then `REVERSE`, then `DOUBLE`. When discarding `PASS`, it always targets the next player. - If the player has no special tiles, then for each possible discard, compute the winning distance after discarding, and choose the option with the smallest winning distance. If there is a tie for the minimum, discard according to the priority order `Z`, `F`, `B`, `N`, `W`, `S`, `E`, `9S`, `8S`, …, `1S`, `9P`, …, `1P`, `9M`, …, `1M`. - If the same player can both chow and pong, consider pong first. Since each tile type has only $4$ tiles, there cannot be two players who can pong at the same time. A player will chow (or pong) if and only if doing so makes the winning distance strictly smaller. If there are multiple chow options that make the winning distance strictly smaller, prefer the option with the larger numbers. - If a player can RON, they will definitely RON (unless intercepted). If a player can win by self-draw, they will definitely do so. They will never refuse to win.

Input Format

The input consists of $148$ lines. Each line gives one tile in the order from the front to the back of the deck. Each line contains a string representing the tile. Use `1M`, `2M`, …, `9M` for wan, `1P`, `2P`, …, `9P` for tong, `1S`, `2S`, …, `9S` for suo; `E`, `S`, `W`, `N`, `B`, `F`, `Z` represent East, South, West, North, White, Green, Red; `PASS` represents Skip, `REVERSE` represents Reverse, and `DOUBLE` represents Double Turn.

Output Format

Output according to the following rules: - Whenever any player draws a tile (**including the initial drawing at the start of the game**), output one line: `x IN y` where `x` is the player name and `y` is the drawn tile. - Whenever any player discards a tile, if the discarded tile is not `PASS`, output one line: `x OUT y` where `x` is the player name and `y` is the discarded tile. If the discarded tile is `PASS`, output one line: `x OUT PASS z` where `z` is the target chosen by `PASS`. - Whenever any player chows, output one line: `x CHOW y1 y2 y3` where `x` is the player name, and `y1`, `y2`, `y3$ are the $3$ tiles involved in the chow, output in increasing numeric order. - Whenever any player pongs, output one line: `x PONG y1 y2 y3` where `x` is the player name, and `y1`, `y2`, `y3` are the $3$ tiles involved in the pong. According to the pong rules, `y1`, `y2`, `y3` should be identical. - Whenever any player wins by discard (RON), output one line: `x RON` where `x` is the player name. - Whenever any player wins by self-draw, output one line: `x SELFDRAWN` where `x` is the player name. - At the end of the game, if some player wins, output one line: `x WIN` where `x` is the player name. If the game ends in a draw, output one line: `DRAW` **Note that all English letters in the input and output are uppercase.**

Explanation/Hint

**[Source]** From the THUPC2021 Preliminary Round, Tsinghua University Student Programming Contest and Collegiate Invitational Contest (THUPC2021). Solutions and other resources can be found at . Translated by ChatGPT 5