Skip to content

Commit bfd3e79

Browse files
authored
Add camicia (#2459)
1 parent 5b2d551 commit bfd3e79

File tree

13 files changed

+955
-0
lines changed

13 files changed

+955
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,6 +2793,14 @@
27932793
"string-formatting"
27942794
],
27952795
"difficulty": 6
2796+
},
2797+
{
2798+
"slug": "camicia",
2799+
"name": "Camicia",
2800+
"uuid": "7747b8bf-a535-42c2-9e51-5b007419bccb",
2801+
"practices": [],
2802+
"prerequisites": [],
2803+
"difficulty": 5
27962804
}
27972805
],
27982806
"foregone": [

exercises/Exercises.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RelativeDistance", "practic
371371
EndProject
372372
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlowerField", "practice\flower-field\FlowerField.csproj", "{88E165C6-5E27-4F48-942A-0D41A9A6326D}"
373373
EndProject
374+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Camicia", "practice\camicia\Camicia.csproj", "{637DEB61-9832-42B0-9907-0671611A92EB}"
375+
EndProject
374376
Global
375377
GlobalSection(SolutionConfigurationPlatforms) = preSolution
376378
Debug|Any CPU = Debug|Any CPU
@@ -2553,6 +2555,18 @@ Global
25532555
{88E165C6-5E27-4F48-942A-0D41A9A6326D}.Release|x64.Build.0 = Release|Any CPU
25542556
{88E165C6-5E27-4F48-942A-0D41A9A6326D}.Release|x86.ActiveCfg = Release|Any CPU
25552557
{88E165C6-5E27-4F48-942A-0D41A9A6326D}.Release|x86.Build.0 = Release|Any CPU
2558+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2559+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
2560+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|x64.ActiveCfg = Debug|Any CPU
2561+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|x64.Build.0 = Debug|Any CPU
2562+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|x86.ActiveCfg = Debug|Any CPU
2563+
{637DEB61-9832-42B0-9907-0671611A92EB}.Debug|x86.Build.0 = Debug|Any CPU
2564+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
2565+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|Any CPU.Build.0 = Release|Any CPU
2566+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|x64.ActiveCfg = Release|Any CPU
2567+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|x64.Build.0 = Release|Any CPU
2568+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|x86.ActiveCfg = Release|Any CPU
2569+
{637DEB61-9832-42B0-9907-0671611A92EB}.Release|x86.Build.0 = Release|Any CPU
25562570
EndGlobalSection
25572571
GlobalSection(SolutionProperties) = preSolution
25582572
HideSolutionNode = FALSE
@@ -2740,6 +2754,7 @@ Global
27402754
{9A073412-4B64-48EB-A346-A56DE6847CCC} = {FA726133-BC1C-D753-28C5-C9ACB44C0776}
27412755
{2C37454E-8624-47B8-A09B-ADE201C2B04C} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
27422756
{88E165C6-5E27-4F48-942A-0D41A9A6326D} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
2757+
{637DEB61-9832-42B0-9907-0671611A92EB} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
27432758
EndGlobalSection
27442759
GlobalSection(ExtensibilityGlobals) = postSolution
27452760
SolutionGuid = {AB4EA6C9-5461-4024-BDC7-2AE0C3A85CD1}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Instructions
2+
3+
In this exercise, you will simulate a game very similar to the classic card game **Camicia**.
4+
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).
5+
6+
## Rules
7+
8+
- The deck is split between **two players**.
9+
The player's cards are read from left to right, where the leftmost card is the top of the deck.
10+
- A round consists of both players playing at least one card.
11+
- Players take turns placing the **top card** of their deck onto a central pile.
12+
- If the card is a **number card** (2-10), play simply passes to the other player.
13+
- If the card is a **payment card**, a penalty must be paid:
14+
- **J** → opponent must pay 1 card
15+
- **Q** → opponent must pay 2 cards
16+
- **K** → opponent must pay 3 cards
17+
- **A** → opponent must pay 4 cards
18+
- If the player paying a penalty reveals another payment card, that player stops paying the penalty.
19+
The other player must then pay a penalty based on the new payment card.
20+
- 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.
21+
That player then starts the next round.
22+
- 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.
23+
- The moment when a player collects cards from the central pile is called a **trick**.
24+
- If a player has all the cards in their possession after a trick, the game **ends**.
25+
- The game **enters a loop** as soon as the decks are identical to what they were earlier during the game, **not** counting number cards!
26+
27+
## Examples
28+
29+
A small example of a match that ends.
30+
31+
| Round | Player A | Player B | Pile | Penalty Due |
32+
| :---- | :----------- | :------------------------- | :------------------------- | :---------- |
33+
| 1 | 2 A 7 8 Q 10 | 3 4 5 6 K 9 J | | - |
34+
| 1 | A 7 8 Q 10 | 3 4 5 6 K 9 J | 2 | - |
35+
| 1 | A 7 8 Q 10 | 4 5 6 K 9 J | 2 3 | - |
36+
| 1 | 7 8 Q 10 | 4 5 6 K 9 J | 2 3 A | Player B: 4 |
37+
| 1 | 7 8 Q 10 | 5 6 K 9 J | 2 3 A 4 | Player B: 3 |
38+
| 1 | 7 8 Q 10 | 6 K 9 J | 2 3 A 4 5 | Player B: 2 |
39+
| 1 | 7 8 Q 10 | K 9 J | 2 3 A 4 5 6 | Player B: 1 |
40+
| 1 | 7 8 Q 10 | 9 J | 2 3 A 4 5 6 K | Player A: 3 |
41+
| 1 | 8 Q 10 | 9 J | 2 3 A 4 5 6 K 7 | Player A: 2 |
42+
| 1 | Q 10 | 9 J | 2 3 A 4 5 6 K 7 8 | Player A: 1 |
43+
| 1 | 10 | 9 J | 2 3 A 4 5 6 K 7 8 Q | Player B: 2 |
44+
| 1 | 10 | J | 2 3 A 4 5 6 K 7 8 Q 9 | Player B: 1 |
45+
| 1 | 10 | - | 2 3 A 4 5 6 K 7 8 Q 9 J | Player A: 1 |
46+
| 1 | - | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - |
47+
| 2 | - | 2 3 A 4 5 6 K 7 8 Q 9 J 10 | - | - |
48+
49+
status: `"finished"`, cards: 13, tricks: 1
50+
51+
This is a small example of a match that loops.
52+
53+
| Round | Player A | Player B | Pile | Penalty Due |
54+
| :---- | :------- | :------- | :---- | :---------- |
55+
| 1 | J 2 3 | 4 J 5 | - | - |
56+
| 1 | 2 3 | 4 J 5 | J | Player B: 1 |
57+
| 1 | 2 3 | J 5 | J 4 | - |
58+
| 2 | 2 3 J 4 | J 5 | - | - |
59+
| 2 | 3 J 4 | J 5 | 2 | - |
60+
| 2 | 3 J 4 | 5 | 2 J | Player A: 1 |
61+
| 2 | J 4 | 5 | 2 J 3 | - |
62+
| 3 | J 4 | 5 2 J 3 | - | - |
63+
| 3 | J 4 | 2 J 3 | 5 | - |
64+
| 3 | 4 | 2 J 3 | 5 J | Player B: 1 |
65+
| 3 | 4 | J 3 | 5 J 2 | - |
66+
| 4 | 4 5 J 2 | J 3 | - | - |
67+
68+
The start of round 4 matches the start of round 2.
69+
Recall, the value of the number cards does not matter.
70+
71+
status: `"loop"`, cards: 8, tricks: 3
72+
73+
## Your Task
74+
75+
- Using the input, simulate the game following the rules above.
76+
- Determine the following information regarding the game:
77+
- **Status**: `"finished"` or `"loop"`
78+
- **Cards**: total number of cards played throughout the game
79+
- **Tricks**: number of times the central pile was collected
80+
81+
~~~~exercism/advanced
82+
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.
83+
There are 653,534,134,886,878,245,000 (approximately 654 quintillion) possibilities, and we haven't calculated them all yet!
84+
~~~~
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Introduction
2+
3+
One rainy afternoon, you sit at the kitchen table playing cards with your grandmother.
4+
The game is her take on [Camicia][bmn].
5+
6+
At first it feels like just another friendly match: cards slapped down, laughter across the table, the occasional victorious grin from Nonna.
7+
But as the game stretches on, something strange happens.
8+
The same cards keep cycling back.
9+
You play card after card, yet the end never seems to come.
10+
11+
You start to wonder.
12+
_Will this game ever finish?
13+
Or could we keep playing forever?_
14+
15+
Later, driven by curiosity, you search online and to your surprise you discover that what happened wasn't just bad luck.
16+
You and your grandmother may have stumbled upon one of the longest possible sequences!
17+
Suddenly, you're hooked.
18+
What began as a casual game has turned into a quest: _how long can such a game really last?_
19+
_Can you find a sequence even longer than the one you played at the kitchen table?_
20+
_Perhaps even long enough to set a new world record?_
21+
22+
And so, armed with nothing but a deck of cards and some algorithmic ingenuity, you decide to investigate...
23+
24+
[bmn]: https://en.wikipedia.org/wiki/Beggar-my-neighbour
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
###############################
2+
# Core EditorConfig Options #
3+
###############################
4+
5+
; This file is for unifying the coding style for different editors and IDEs.
6+
; More information at:
7+
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
8+
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
9+
10+
root = true
11+
12+
[*]
13+
indent_style = space
14+
15+
[Camicia.cs]
16+
indent_size = 4
17+
18+
###############################
19+
# .NET Coding Conventions #
20+
###############################
21+
22+
# Organize usings
23+
dotnet_sort_system_directives_first = true
24+
dotnet_separate_import_directive_groups = true
25+
26+
# this. preferences
27+
dotnet_style_qualification_for_field = false:suggestion
28+
dotnet_style_qualification_for_property = false:suggestion
29+
dotnet_style_qualification_for_method = false:suggestion
30+
dotnet_style_qualification_for_event = false:suggestion
31+
32+
# Language keywords vs BCL types preferences
33+
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
34+
dotnet_style_predefined_type_for_member_access = true:suggestion
35+
36+
# Parentheses preferences
37+
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
38+
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
39+
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
40+
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
41+
42+
# Modifier preferences
43+
dotnet_style_require_accessibility_modifiers = always:suggestion
44+
dotnet_style_readonly_field = true:suggestion
45+
46+
# Expression-level preferences
47+
dotnet_style_object_initializer = true:suggestion
48+
dotnet_style_collection_initializer = true:suggestion
49+
dotnet_style_explicit_tuple_names = true:suggestion
50+
dotnet_style_prefer_inferred_tuple_names = true:suggestion
51+
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
52+
dotnet_style_prefer_auto_properties = true:suggestion
53+
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
54+
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
55+
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
56+
dotnet_style_coalesce_expression = true:suggestion
57+
dotnet_style_null_propagation = true:suggestion
58+
59+
###############################
60+
# Naming Conventions #
61+
###############################
62+
63+
# Style Definitions
64+
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
65+
66+
# Use PascalCase for constant fields
67+
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
68+
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
69+
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
70+
dotnet_naming_symbols.constant_fields.applicable_kinds = field
71+
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
72+
dotnet_naming_symbols.constant_fields.required_modifiers = const
73+
74+
###############################
75+
# C# Code Style Rules #
76+
###############################
77+
78+
# var preferences
79+
csharp_style_var_for_built_in_types = true:none
80+
csharp_style_var_when_type_is_apparent = true:none
81+
csharp_style_var_elsewhere = true:none
82+
83+
# Expression-bodied members
84+
csharp_style_expression_bodied_methods = true:suggestion
85+
csharp_style_expression_bodied_constructors = true:suggestion
86+
csharp_style_expression_bodied_operators = true:suggestion
87+
csharp_style_expression_bodied_properties = true:suggestion
88+
csharp_style_expression_bodied_indexers = true:suggestion
89+
csharp_style_expression_bodied_accessors = true:suggestion
90+
91+
# Pattern-matching preferences
92+
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
93+
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
94+
95+
# Null-checking preferences
96+
csharp_style_throw_expression = true:suggestion
97+
csharp_style_conditional_delegate_call = true:suggestion
98+
99+
# Modifier preferences
100+
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
101+
102+
# Expression-level preferences
103+
csharp_prefer_braces = true:none
104+
csharp_prefer_simple_default_expression = true:suggestion
105+
csharp_style_deconstructed_variable_declaration = true:suggestion
106+
csharp_style_pattern_local_over_anonymous_function = true:suggestion
107+
csharp_style_inlined_variable_declaration = true:suggestion
108+
109+
###############################
110+
# C# Formatting Rules #
111+
###############################
112+
113+
# New line preferences
114+
csharp_new_line_before_open_brace = all
115+
csharp_new_line_before_else = true
116+
csharp_new_line_before_catch = true
117+
csharp_new_line_before_finally = true
118+
csharp_new_line_before_members_in_object_initializers = false
119+
csharp_new_line_before_members_in_anonymous_types = false
120+
csharp_new_line_between_query_expression_clauses = true
121+
122+
# Indentation preferences
123+
csharp_indent_case_contents = true
124+
csharp_indent_switch_labels = true
125+
csharp_indent_labels = flush_left
126+
127+
# Space preferences
128+
csharp_space_after_cast = false
129+
csharp_space_after_keywords_in_control_flow_statements = true
130+
csharp_space_between_method_declaration_parameter_list_parentheses = false
131+
csharp_space_between_method_call_parameter_list_parentheses = false
132+
csharp_space_before_colon_in_inheritance_clause = true
133+
csharp_space_after_colon_in_inheritance_clause = true
134+
csharp_space_around_binary_operators = before_and_after
135+
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
136+
csharp_space_between_method_call_name_and_opening_parenthesis = false
137+
csharp_space_between_method_call_empty_parameter_list_parentheses = false
138+
139+
# Wrapping preferences
140+
csharp_preserve_single_line_blocks = true
141+
csharp_preserve_single_line_statements = true
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
public static class Camicia
6+
{
7+
public enum GameStatus
8+
{
9+
Finished,
10+
Loop
11+
}
12+
13+
public record GameResult(GameStatus Status, int Tricks, int Cards);
14+
15+
public static GameResult SimulateGame(string[] playerA, string[] playerB)
16+
{
17+
Func<string, int> GetValue = (string card) => card switch
18+
{
19+
"J" => 1,
20+
"Q" => 2,
21+
"K" => 3,
22+
"A" => 4,
23+
_ => 0
24+
};
25+
Queue<int> handA = new(playerA.Select(GetValue));
26+
Queue<int> handB = new(playerB.Select(GetValue));
27+
var turn = "A";
28+
List<int> pile = new();
29+
HashSet<string> seen = new();
30+
int totalTricks = 0;
31+
int cardsPlayed = 0;
32+
int currentDebt = 0;
33+
34+
while (true)
35+
{
36+
if (pile.Count == 0)
37+
{
38+
var state = $"{string.Join(",", handA)}|{string.Join(",", handB)}|{turn}";
39+
if (seen.Contains(state))
40+
{
41+
return new GameResult(GameStatus.Loop, totalTricks, cardsPlayed);
42+
}
43+
seen.Add(state);
44+
}
45+
46+
var activeHand = turn == "A" ? handA : handB;
47+
var otherHand = turn == "A" ? handB : handA;
48+
49+
if (activeHand.Count == 0)
50+
{
51+
int extraTrick = pile.Count > 0 ? 1 : 0;
52+
return new GameResult(GameStatus.Finished, totalTricks + extraTrick, cardsPlayed);
53+
}
54+
55+
int cardVal = activeHand.Dequeue();
56+
pile.Add(cardVal);
57+
cardsPlayed++;
58+
59+
if (cardVal > 0)
60+
{
61+
currentDebt = cardVal;
62+
turn = turn == "A" ? "B" : "A";
63+
}
64+
else
65+
{
66+
if (currentDebt > 0)
67+
{
68+
currentDebt--;
69+
if (currentDebt == 0)
70+
{
71+
foreach (int card in pile)
72+
{
73+
otherHand.Enqueue(card);
74+
}
75+
pile.Clear();
76+
totalTricks++;
77+
currentDebt = 0;
78+
79+
if (handA.Count == 0 || handB.Count == 0)
80+
{
81+
return new GameResult(GameStatus.Finished, totalTricks, cardsPlayed);
82+
}
83+
84+
turn = turn == "A" ? "B" : "A";
85+
}
86+
}
87+
else
88+
{
89+
turn = turn == "A" ? "B" : "A";
90+
}
91+
}
92+
}
93+
}
94+
}

0 commit comments

Comments
 (0)