diff --git a/config.json b/config.json index 9309188..cf155c6 100644 --- a/config.json +++ b/config.json @@ -1103,6 +1103,14 @@ "prerequisites": [], "difficulty": 5 }, + { + "slug": "camicia", + "name": "Camicia", + "uuid": "7aaaf5fa-1a22-433b-9c0d-0e1c035eba3d", + "practices": [], + "prerequisites": [], + "difficulty": 5 + }, { "slug": "rectangles", "name": "Rectangles", diff --git a/exercises/practice/camicia/.docs/instructions.md b/exercises/practice/camicia/.docs/instructions.md new file mode 100644 index 0000000..db62fce --- /dev/null +++ b/exercises/practice/camicia/.docs/instructions.md @@ -0,0 +1,84 @@ +# Instructions + +In this exercise, you will simulate a game very similar to the classic card game **Camicia**. +Your program will receive the initial configuration of two players' decks and must simulate the game until it ends (or detect that it will never end). + +## Rules + +- The deck is split between **two players**. + The player's cards are read from left to right, where the leftmost card is the top of the deck. +- A round consists of both players playing at least one card. +- Players take turns placing the **top card** of their deck onto a central pile. +- If the card is a **number card** (2-10), play simply passes to the other player. +- If the card is a **payment card**, a penalty must be paid: + - **J** → opponent must pay 1 card + - **Q** → opponent must pay 2 cards + - **K** → opponent must pay 3 cards + - **A** → opponent must pay 4 cards +- If the player paying a penalty reveals another payment card, that player stops paying the penalty. + The other player must then pay a penalty based on the new payment card. +- If the penalty is fully paid without interruption, the player who placed the **last payment card** collects the central pile and places it at the bottom of their deck. + That player then starts the next round. +- If a player runs out of cards and is unable to play a card (either while paying a penalty or when it is their turn), the other player collects the central pile. +- The moment when a player collects cards from the central pile is called a **trick**. +- If a player has all the cards in their possession after a trick, the game **ends**. +- The game **enters a loop** as soon as the decks are identical to what they were earlier during the game, **not** counting number cards! + +## Examples + +A small example of a match that ends. + +| Round | Player A | Player B | Pile | Penalty Due | +| :---- | :----------- | :------------------------- | :------------------------- | :---------- | +| 1 | 2 A 7 8 Q 10 | 3 4 5 6 K 9 J | | - | +| 1 | A 7 8 Q 10 | 3 4 5 6 K 9 J | 2 | - | +| 1 | A 7 8 Q 10 | 4 5 6 K 9 J | 2 3 | - | +| 1 | 7 8 Q 10 | 4 5 6 K 9 J | 2 3 A | Player B: 4 | +| 1 | 7 8 Q 10 | 5 6 K 9 J | 2 3 A 4 | Player B: 3 | +| 1 | 7 8 Q 10 | 6 K 9 J | 2 3 A 4 5 | Player B: 2 | +| 1 | 7 8 Q 10 | K 9 J | 2 3 A 4 5 6 | Player B: 1 | +| 1 | 7 8 Q 10 | 9 J | 2 3 A 4 5 6 K | Player A: 3 | +| 1 | 8 Q 10 | 9 J | 2 3 A 4 5 6 K 7 | Player A: 2 | +| 1 | Q 10 | 9 J | 2 3 A 4 5 6 K 7 8 | Player A: 1 | +| 1 | 10 | 9 J | 2 3 A 4 5 6 K 7 8 Q | Player B: 2 | +| 1 | 10 | J | 2 3 A 4 5 6 K 7 8 Q 9 | Player B: 1 | +| 1 | 10 | - | 2 3 A 4 5 6 K 7 8 Q 9 J | Player A: 1 | +| 1 | - | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - | +| 2 | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - | - | + +status: `"finished"`, cards: 13, tricks: 1 + +This is a small example of a match that loops. + +| Round | Player A | Player B | Pile | Penalty Due | +| :---- | :------- | :------- | :---- | :---------- | +| 1 | J 2 3 | 4 J 5 | - | - | +| 1 | 2 3 | 4 J 5 | J | Player B: 1 | +| 1 | 2 3 | J 5 | J 4 | - | +| 2 | 2 3 J 4 | J 5 | - | - | +| 2 | 3 J 4 | J 5 | 2 | - | +| 2 | 3 J 4 | 5 | 2 J | Player A: 1 | +| 2 | J 4 | 5 | 2 J 3 | - | +| 3 | J 4 | 5 2 J 3 | - | - | +| 3 | J 4 | 2 J 3 | 5 | - | +| 3 | 4 | 2 J 3 | 5 J | Player B: 1 | +| 3 | 4 | J 3 | 5 J 2 | - | +| 4 | 4 5 J 2 | J 3 | - | - | + +The start of round 4 matches the start of round 2. +Recall, the value of the number cards does not matter. + +status: `"loop"`, cards: 8, tricks: 3 + +## Your Task + +- Using the input, simulate the game following the rules above. +- Determine the following information regarding the game: + - **Status**: `"finished"` or `"loop"` + - **Cards**: total number of cards played throughout the game + - **Tricks**: number of times the central pile was collected + +~~~~exercism/advanced +For those who want to take on a more exciting challenge, the hunt for other records for the longest game with an end is still open. +There are 653,534,134,886,878,245,000 (approximately 654 quintillion) possibilities, and we haven't calculated them all yet! +~~~~ diff --git a/exercises/practice/camicia/.docs/introduction.md b/exercises/practice/camicia/.docs/introduction.md new file mode 100644 index 0000000..761d8a8 --- /dev/null +++ b/exercises/practice/camicia/.docs/introduction.md @@ -0,0 +1,24 @@ +# Introduction + +One rainy afternoon, you sit at the kitchen table playing cards with your grandmother. +The game is her take on [Camicia][bmn]. + +At first it feels like just another friendly match: cards slapped down, laughter across the table, the occasional victorious grin from Nonna. +But as the game stretches on, something strange happens. +The same cards keep cycling back. +You play card after card, yet the end never seems to come. + +You start to wonder. +_Will this game ever finish? +Or could we keep playing forever?_ + +Later, driven by curiosity, you search online and to your surprise you discover that what happened wasn't just bad luck. +You and your grandmother may have stumbled upon one of the longest possible sequences! +Suddenly, you're hooked. +What began as a casual game has turned into a quest: _how long can such a game really last?_ +_Can you find a sequence even longer than the one you played at the kitchen table?_ +_Perhaps even long enough to set a new world record?_ + +And so, armed with nothing but a deck of cards and some algorithmic ingenuity, you decide to investigate... + +[bmn]: https://en.wikipedia.org/wiki/Beggar-my-neighbour diff --git a/exercises/practice/camicia/.meta/Camicia.example.ps1 b/exercises/practice/camicia/.meta/Camicia.example.ps1 new file mode 100644 index 0000000..4564c14 --- /dev/null +++ b/exercises/practice/camicia/.meta/Camicia.example.ps1 @@ -0,0 +1,130 @@ +using namespace System.Collections.Generic +using namespace System.Text + +enum Status { + Finished + Loop +} + +Function Invoke-Camicia() { + <# + .SYNOPSIS + Simulate a game very similar to the classic card game Camicia. + + .DESCRIPTION + Given two hands of cards, simulate a game (similar to Camicia) until it ends (or detect if it is in a loop). + Read instruction for rules and game example. + + .PARAMETER PlayerA + An array of string(s) represents the first player's cards. + + .PARAMETER PlayerB + An array of string(s) represents the second player's cards. + #> + [CmdletBinding()] + Param( + [string[]]$PlayerA, + [string[]]$PlayerB + ) + $gameState = [GameState]::New($PlayerA, $PlayerB) + $stateSet = [HashSet[string]]::new() + $resultStatus = [Status]::Loop + + while ($true) { + $stateRepresent = $gameState.ToString() + if ($stateSet.Contains($stateRepresent)) { + break + } + if ($stateRepresent -match '[JQKA]') { + $stateSet.Add($stateRepresent) | Out-Null + } + PlayTurn($gameState) + if ($gameState.HasWinner()) { + $resultStatus = [Status]::Finished + break + } + } + [PSCustomObject]@{ + Status = $resultStatus + Cards = $gameState.CardsPlayed + Tricks = $gameState.Tricks + } +} + +Function PlayTurn ([GameState]$state) { + while ($true) { + $startDebt = $state.Debt + $player = $state.PlayerTurn -eq "A" ? $state.PAHand : $state.PBHand + $other = $state.PlayerTurn -eq "A" ? $state.PBHand : $state.PAHand + if ($player.Count -eq 0) { + $state.Piles | ForEach-Object { $other.Enqueue($_) } + $state.Piles.Clear() + $state.Tricks++ + break + } + + $top = $player.Dequeue() + $state.Piles.Add($top) + $state.CardsPlayed++ + + if ($state.PaymentCards -match $top) + { + $state.Debt = $state.PaymentCards.IndexOf($top) + 1 + $state.SwitchPlayer() + } else { + $state.Debt = $state.Debt -gt 0 ? $state.Debt - 1 : 0 + if ($startDebt -gt 0 -and $state.Debt -eq 0) { + $state.SwitchPlayer() + $state.Piles | ForEach-Object { $other.Enqueue($_) } + $state.Piles.Clear() + $state.Tricks++ + break + } + + if ($state.Debt -eq 0) { + $state.SwitchPlayer() + } + } + } +} + +class GameState { + [Queue[string]]$PAHand + [Queue[string]]$PBHand + [List[string]]$Piles + [string]$PlayerTurn + [int]$Tricks + [int]$Debt + [string]$PaymentCards + [int]$CardsPlayed + + GameState([string[]]$PlayerA, [string[]]$PlayerB) { + $this.PAHand = [Queue[string]]::New($PlayerA) + $this.PBHand = [Queue[string]]::New($PlayerB) + $this.Piles = [List[string]]::New() + $this.PlayerTurn = "A" + $this.Tricks = 0 + $this.Debt = 0 + $this.PaymentCards = "JQKA" + } + + [bool]HasWinner() { + return ($this.Piles.Count -eq 0) -and ($this.PAHand.Count -eq 0 -or $this.PBHand.Count -eq 0) + } + + [string]ToString() { + $sb = [StringBuilder]::new() + foreach ($card in $this.PAHand) { + $sb.Append( $card -match '[JQKA]' ? $card : '_') + } + $sb.Append(' ') + foreach ($card in $this.PBHand) { + $sb.Append( $card -match '[JQKA]' ? $card : '_') + } + return $sb.ToString() + } + + [void] SwitchPlayer() { + $this.PlayerTurn = $this.PlayerTurn -eq "A" ? "B" : "A" + } +} diff --git a/exercises/practice/camicia/.meta/config.json b/exercises/practice/camicia/.meta/config.json new file mode 100644 index 0000000..c60b191 --- /dev/null +++ b/exercises/practice/camicia/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glaxxie" + ], + "files": { + "solution": [ + "Camicia.ps1" + ], + "test": [ + "Camicia.tests.ps1" + ], + "example": [ + ".meta/Camicia.example.ps1" + ] + }, + "blurb": "Simulate the card game and determine whether the match ends or enters an infinite loop.", + "source": "Beggar-My-Neighbour", + "source_url": "https://www.richardpmann.com/beggar-my-neighbour-records.html" +} diff --git a/exercises/practice/camicia/.meta/tests.toml b/exercises/practice/camicia/.meta/tests.toml new file mode 100644 index 0000000..18d3fdd --- /dev/null +++ b/exercises/practice/camicia/.meta/tests.toml @@ -0,0 +1,94 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[0b7f737c-3ecd-4a55-b34d-e65c62a85c28] +description = "two cards, one trick" + +[27c19d75-53a5-48e5-b33b-232c3884d4f3] +description = "three cards, one trick" + +[9b02dd49-efaf-4b71-adca-a05c18a7c5b0] +description = "four cards, one trick" + +[fa3f4479-466a-4734-a001-ab79bfe27260] +description = "the ace reigns supreme" + +[07629689-f589-4f54-a6d1-8ce22776ce72] +description = "the king beats ace" + +[54d4a1c5-76fb-4d1e-8358-0e0296ac0601] +description = "the queen seduces the king" + +[c875500c-ff3d-47a4-bd1e-b60b90da80aa] +description = "the jack betrays the queen" + +[436875da-96ca-4149-be22-0b78173b8125] +description = "the 10 just wants to put on a show" + +[5be39bb6-1b34-4ce6-a1cd-0fcc142bb272] +description = "simple loop with decks of 3 cards" + +[2795dc21-0a2a-4c38-87c2-5a42e1ff15eb] +description = "the story is starting to get a bit complicated" + +[6999dfac-3fdc-41e2-b64b-38f4be228712] +description = "two tricks" + +[83dcd4f3-e089-4d54-855a-73f5346543a3] +description = "more tricks" + +[3107985a-f43e-486a-9ce8-db51547a9941] +description = "simple loop with decks of 4 cards" + +[dca32c31-11ed-49f6-b078-79ab912c1f7b] +description = "easy card combination" + +[1f8488d0-48d3-45ae-b819-59cedad0a5f4] +description = "easy card combination, inverted decks" + +[98878d35-623a-4d05-b81a-7bdc569eb88d] +description = "mirrored decks" + +[3e0ba597-ca10-484b-87a3-31a7df7d6da3] +description = "opposite decks" + +[92334ddb-aaa7-47fa-ab36-e928a8a6a67c] +description = "random decks #1" + +[30477523-9651-4860-84a3-e1ac461bb7fa] +description = "random decks #2" + +[20967de8-9e94-4e0e-9010-14bc1c157432] +description = "Kleber 1999" + +[9f2fdfe8-27f3-4323-816d-6bce98a9c6f7] +description = "Collins 2006" + +[c90b6f8d-7013-49f3-b5cb-14ea006cca1d] +description = "Mann and Wu 2007" + +[a3f1fbc5-1d0b-499a-92a5-22932dfc6bc8] +description = "Nessler 2012" + +[9cefb1ba-e6d1-4ab7-9d8f-76d8e0976d5f] +description = "Anderson 2013" + +[d37c0318-5be6-48d0-ab72-a7aaaff86179] +description = "Rucklidge 2014" + +[4305e479-ba87-432f-8a29-cd2bd75d2f05] +description = "Nessler 2021" + +[252f5cc3-b86d-4251-87ce-f920b7a6a559] +description = "Nessler 2022" + +[b9efcfa4-842f-4542-8112-8389c714d958] +description = "Casella 2024, first infinite game found" diff --git a/exercises/practice/camicia/Camicia.ps1 b/exercises/practice/camicia/Camicia.ps1 new file mode 100644 index 0000000..d153193 --- /dev/null +++ b/exercises/practice/camicia/Camicia.ps1 @@ -0,0 +1,30 @@ +using namespace System.Collections.Generic +using namespace System.Text + +enum Status { + Finished + Loop +} + +Function Invoke-Camicia() { + <# + .SYNOPSIS + Simulate a game very similar to the classic card game Camicia. + + .DESCRIPTION + Given two hands of cards, simulate a game (similar to Camicia) until it ends (or detect if it is in a loop). + Read instruction for rules and game example. + + .PARAMETER PlayerA + An array of string(s) represents the first player's cards. + + .PARAMETER PlayerB + An array of string(s) represents the second player's cards. + #> + [CmdletBinding()] + Param( + [string[]]$PlayerA, + [string[]]$PlayerB + ) + Throw "Please implement this function" +} diff --git a/exercises/practice/camicia/Camicia.tests.ps1 b/exercises/practice/camicia/Camicia.tests.ps1 new file mode 100644 index 0000000..6ec2288 --- /dev/null +++ b/exercises/practice/camicia/Camicia.tests.ps1 @@ -0,0 +1,307 @@ +BeforeAll { + . "./Camicia.ps1" +} + +Describe "Camicia test cases" { + It "two cards, one trick" { + $got = Invoke-Camicia -PlayerA @("2") -PlayerB @("3") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 2 + $got.Tricks | Should -Be 1 + + } + + It "three cards, one trick" { + $got = Invoke-Camicia -PlayerA @("2", "4") -PlayerB @("3") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 3 + $got.Tricks | Should -Be 1 + } + + It "four cards, one trick" { + $got = Invoke-Camicia -PlayerA @("2", "4") -PlayerB @("3", "5", "6") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 4 + $got.Tricks | Should -Be 1 + } + + It "the ace reigns supreme" { + $got = Invoke-Camicia -PlayerA @("2", "A") -PlayerB @("3", "4", "5", "6", "7") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7 + $got.Tricks | Should -Be 1 + } + + It "the king beats ace" { + $got = Invoke-Camicia -PlayerA @("2", "A") -PlayerB @("3", "4", "5", "6", "K") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7 + $got.Tricks | Should -Be 1 + } + + It "the queen seduces the king" { + $got = Invoke-Camicia -PlayerA @("2", "A", "7", "8", "Q") -PlayerB @("3", "4", "5", "6", "K") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 10 + $got.Tricks | Should -Be 1 + } + + It "the jack betrays the queen" { + $got = Invoke-Camicia -PlayerA @("2", "A", "7", "8", "Q") -PlayerB @("3", "4", "5", "6", "K", "9", "J") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 12 + $got.Tricks | Should -Be 1 + } + + It "the 10 just wants to put on a show" { + $got = Invoke-Camicia -PlayerA @("2", "A", "7", "8", "Q", "10") -PlayerB @("3", "4", "5", "6", "K", "9", "J") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 13 + $got.Tricks | Should -Be 1 + } + + It "simple loop with decks of 3 cards" { + $got = Invoke-Camicia -PlayerA @("J", "2", "3") -PlayerB @("4", "J", "5") + + $got.Status | Should -Be "Loop" + $got.Cards | Should -Be 8 + $got.Tricks | Should -Be 3 + } + + It "the story is starting to get a bit complicated" { + $got = Invoke-Camicia -PlayerA @( + "2","6","6","J","4","K","Q","10","K","J","Q","2","3","K","5","6","Q","Q","A","A","6","9","K","A","8","K", + "2","A","9","A","Q","4","K","K","K","3","5","K","8","Q","3","Q","7","J","K","J","9","J","3","3","K","K", + "Q","A","K","7","10","A","Q","7","10","J","4","5","J","9","10","Q","J","J","K","6","10","J","6","Q","J", + "5","J","Q","Q","8","3","8","A","2","6","9","K","7","J","K","K","8","K","Q","6","10","J","10","J","Q", + "J","10","3","8","K","A","6","9","K","2","A","A","10","J","6","A","4","J","A","J","J","6","2","J","3","K", + "2","5","9","J","9","6","K","A","5","Q","J","2","Q","K","A","3","K","J","K","2","5","6","Q","J","Q","Q", + "J","2","J","9","Q","7","7","A","Q","7","Q","J","K","J","A","7","7","8","Q","10","J","10","J","J","9","2","A","2" + ) -PlayerB @( + "7","2","10","K","8","2","J","9","A","5","6","J","Q","6","K","6","5","A","4","Q","7","J","7","10","2","Q","8", + "2","2","K","J","A","5","5","A","4","Q","6","Q","K","10","8","Q","2","10","J","A","Q","8","Q","Q","J","J","A", + "A","9","10","J","K","4","Q","10","10","J","K","10","2","J","7","A","K","K","J","A","J","10","8","K","A","7", + "Q","Q","J","3","Q","4","A","3","A","Q","Q","Q","5","4","K","J","10","A","Q","J","6","J","A","10","A","5","8", + "3","K","5","9","Q","8","7","7","J","7","Q","Q","Q","A","7","8","9","A","Q","A","K","8","A","A","J","8","4", + "8","K","J","A","10","Q","8","J","8","6","10","Q","J","J","A","A","J","5","Q","6","J","K","Q","8","K","4","Q", + "Q","6","J","K","4","7","J","J","9","9","A","Q","Q","K","A","6","5","K" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 361 + $got.Tricks | Should -Be 1 + } + + + It "two tricks" { + $got = Invoke-Camicia -PlayerA @("J") -PlayerB @("3", "J") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 5 + $got.Tricks | Should -Be 2 + } + + It "more tricks" { + $got = Invoke-Camicia -PlayerA @("J", "2", "4") -PlayerB @("3", "J", "A") + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 12 + $got.Tricks | Should -Be 4 + } + + It "simple loop with decks of 4 cards" { + $got = Invoke-Camicia -PlayerA @("2", "3", "J", "6") -PlayerB @("K", "5", "J", "7") + + $got.Status | Should -Be "Loop" + $got.Cards | Should -Be 16 + $got.Tricks | Should -Be 4 + } + + It "easy card combination" { + $got = Invoke-Camicia -PlayerA @( + "4","8","7","5","4","10","3","9","7","3","10","10","6","8","2","8","5","4","5","9","6","5","2","8","10","9" + ) -PlayerB @( + "6","9","4","7","2","2","3","6","7","3","A","A","A","A","K","K","K","K","Q","Q","Q","Q","J","J","J","J" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 40 + $got.Tricks | Should -Be 4 + } + + It "easy card combination, inverted decks" { + $got = Invoke-Camicia -PlayerA @( + "3","3","5","7","3","2","10","7","6","7","A","A","A","A","K","K","K","K","Q","Q","Q","Q","J","J","J","J" + ) -PlayerB @( + "5","10","8","2","6","7","2","4","9","2","6","10","10","5","4","8","4","8","6","9","8","5","9","3","4","9" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 40 + $got.Tricks | Should -Be 4 + } + + It "mirrored decks" { + $got = Invoke-Camicia -PlayerA @( + "2","A","3","A","3","K","4","K","2","Q","2","Q","10","J","5","J","6","10","2","9","10","7","3","9","6","9" + ) -PlayerB @( + "6","A","4","A","7","K","4","K","7","Q","7","Q","5","J","8","J","4","5","8","9","10","6","8","3","8","5" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 59 + $got.Tricks | Should -Be 4 + } + + It "opposite decks" { + $got = Invoke-Camicia -PlayerA @( + "4","A","9","A","4","K","9","K","6","Q","8","Q","8","J","10","J","9","8","4","6","3","6","5","2","4","3" + ) -PlayerB @( + "10","7","3","2","9","2","7","8","7","5","J","7","J","10","Q","10","Q","3","K","5","K","6","A","2","A","5" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 151 + $got.Tricks | Should -Be 21 + } + + It "random decks #1" { + $got = Invoke-Camicia -PlayerA @( + "K","10","9","8","J","8","6","9","7","A","K","5","4","4","J","5","J","4","3","5","8","6","7","7","4","9" + ) -PlayerB @( + "6","3","K","A","Q","10","A","2","Q","8","2","10","10","2","Q","3","K","9","7","A","3","Q","5","J","2","6" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 542 + $got.Tricks | Should -Be 76 + } + + It "random decks #2" { + $got = Invoke-Camicia -PlayerA @( + "8","A","4","8","5","Q","J","2","6","2","9","7","K","A","8","10","K","8","10","9","K","6","7","3","K","9" + ) -PlayerB @( + "10","5","2","6","Q","J","A","9","5","5","3","7","3","J","A","2","Q","3","J","Q","4","10","4","7","4","6" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 327 + $got.Tricks | Should -Be 42 + } + + It "Kleber 1999" { + $got = Invoke-Camicia -PlayerA @( + "4","8","9","J","Q","8","5","5","K","2","A","9","8","5","10","A","4","J","3","K","6","9","2","Q","K","7" + ) -PlayerB @( + "10","J","3","2","4","10","4","7","5","3","6","6","7","A","J","Q","A","7","2","10","3","K","9","6","8","Q" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 5790 + $got.Tricks | Should -Be 805 + } + + It "Collins 2006" { + $got = Invoke-Camicia -PlayerA @( + "A","8","Q","K","9","10","3","7","4","2","Q","3","2","10","9","K","A","8","7","7","4","5","J","9","2","10" + ) -PlayerB @( + "4","J","A","K","8","5","6","6","A","6","5","Q","4","6","10","8","J","2","5","7","Q","J","3","3","K","9" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 6913 + $got.Tricks | Should -Be 960 + } + + It "Mann and Wu 2007" { + $got = Invoke-Camicia -PlayerA @( + "K","2","K","K","3","3","6","10","K","6","A","2","5","5","7","9","J","A","A","3","4","Q","4","8","J","6" + ) -PlayerB @( + "4","5","2","Q","7","9","9","Q","7","J","9","8","10","3","10","J","4","10","8","6","8","7","A","Q","5","2" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7157 + $got.Tricks | Should -Be 1007 + } + + It "Nessler 2012" { + $got = Invoke-Camicia -PlayerA @( + "10","3","6","7","Q","2","9","8","2","8","4","A","10","6","K","2","10","A","5","A","2","4","Q","J","K","4" + ) -PlayerB @( + "10","Q","4","6","J","9","3","J","9","3","3","Q","K","5","9","5","K","6","5","7","8","J","A","7","8","7" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7207 + $got.Tricks | Should -Be 1015 + } + + It "Anderson 2013" { + $got = Invoke-Camicia -PlayerA @( + "6","7","A","3","Q","3","5","J","3","2","J","7","4","5","Q","10","5","A","J","2","K","8","9","9","K","3" + ) -PlayerB @( + "4","J","6","9","8","5","10","7","9","Q","2","7","10","8","4","10","A","6","4","A","6","8","Q","K","K","2" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7225 + $got.Tricks | Should -Be 1016 + } + + It "Rucklidge 2014" { + $got = Invoke-Camicia -PlayerA @( + "8","J","2","9","4","4","5","8","Q","3","9","3","6","2","8","A","A","A","9","4","7","2","5","Q","Q","3" + ) -PlayerB @( + "K","7","10","6","3","J","A","7","6","5","5","8","10","9","10","4","2","7","K","Q","10","K","6","J","J","K" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7959 + $got.Tricks | Should -Be 1122 + } + + It "Nessler 2021" { + $got = Invoke-Camicia -PlayerA @( + "7","2","3","4","K","9","6","10","A","8","9","Q","7","A","4","8","J","J","A","4","3","2","5","6","6","J" + ) -PlayerB @( + "3","10","8","9","8","K","K","2","5","5","7","6","4","3","5","7","A","9","J","K","2","Q","10","Q","10","Q" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 7972 + $got.Tricks | Should -Be 1106 + } + + It "Nessler 2022" { + $got = Invoke-Camicia -PlayerA @( + "2","10","10","A","J","3","8","Q","2","5","5","5","9","2","4","3","10","Q","A","K","Q","J","J","9","Q","K" + ) -PlayerB @( + "10","7","6","3","6","A","8","9","4","3","K","J","6","K","4","9","7","8","5","7","8","2","A","7","4","6" + ) + + $got.Status | Should -Be "Finished" + $got.Cards | Should -Be 8344 + $got.Tricks | Should -Be 1164 + } + + It "Casella 2024, first infinite game found" { + $got = Invoke-Camicia -PlayerA @( + "2","8","4","K","5","2","3","Q","6","K","Q","A","J","3","5","9","8","3","A","A","J","4","4","J","7","5" + ) -PlayerB @( + "7","7","8","6","10","10","6","10","7","2","Q","6","3","2","4","K","Q","10","J","5","9","8","9","9","K","A" + ) + + $got.Status | Should -Be "Loop" + $got.Cards | Should -Be 474 + $got.Tricks | Should -Be 66 + } +}