1- import java .util .ArrayDeque ;
2- import java .util .Deque ;
3- import java .util .HashSet ;
41import java .util .List ;
5- import java .util .Set ;
62
73public class Camicia {
84
9- private Status status ;
10- private int cards ;
11- private int tricks ;
12-
13- private enum Player {
14- PLAYER_A , PLAYER_B
15- }
16-
17- private enum Status {
18- FINISHED , LOOP
19- }
20-
21- private static int penaltyOf (String card ) {
22- return switch (card ) {
23- case "J" -> 1 ;
24- case "Q" -> 2 ;
25- case "K" -> 3 ;
26- case "A" -> 4 ;
27- default -> 0 ;
28- };
29- }
30-
31- private static boolean isPaymentCard (String card ) {
32- return penaltyOf (card ) > 0 ;
33- }
34-
35- /**
36- * Return a snapshot of the current state
37- */
38- private static String stateKey (Deque <String > deckA , Deque <String > deckB ) {
39- StringBuilder sb = new StringBuilder ();
40-
41- for (String card : deckA ) {
42- sb .append (isPaymentCard (card ) ? card : "N" );
43- }
44-
45- sb .append ('|' );
46-
47- for (String card : deckB ) {
48- sb .append (isPaymentCard (card ) ? card : "N" );
49- }
50-
51- return sb .toString ();
52- }
53-
54- private static Player otherPlayer (Player player ) {
55- return player == Player .PLAYER_A ? Player .PLAYER_B : Player .PLAYER_A ;
56- }
57-
58- private static Deque <String > deckOf (Player player , Deque <String > deckA , Deque <String > deckB ) {
59- return player == Player .PLAYER_A ? deckA : deckB ;
60- }
61-
62- public void simulateGame (List <String > playerA , List <String > playerB ) {
63- Deque <String > deckA = new ArrayDeque <>(playerA );
64- Deque <String > deckB = new ArrayDeque <>(playerB );
65-
66- int cardsPlayed = 0 ;
67- int tricksCount = 0 ;
68- Player current = Player .PLAYER_A ;
69-
70- Set <String > seenStates = new HashSet <>();
71-
72- while (true ) {
73- String key = stateKey (deckA , deckB );
74- // Key already exists, which means this is a loop
75- if (!seenStates .add (key )) {
76- finishGame (Status .LOOP , cardsPlayed , tricksCount );
77- return ;
78- }
79-
80- // Otherwise, play next round
81- RoundResult result = playRound (deckA , deckB , current );
82-
83- cardsPlayed += result .pileSize ();
84- tricksCount ++;
85-
86- // Check if someone wins and finish the game
87- if (hasWinner (deckA , deckB )) {
88- finishGame (Status .FINISHED , cardsPlayed , tricksCount );
89- return ;
90- }
91-
92- // Otherwise, play next round
93- current = result .nextStarter ();
94- }
95- }
96-
97- private RoundResult playRound (Deque <String > deckA , Deque <String > deckB , Player startingPlayer ) {
98- Deque <String > pile = new ArrayDeque <>(); // cards played in this round
99- Player currentPlayer = startingPlayer ;
100- int pendingPenalty = 0 ;
101-
102- while (true ) {
103- Deque <String > currentPlayerDeck = deckOf (currentPlayer , deckA , deckB );
104- Player opponent = otherPlayer (currentPlayer );
105- Deque <String > opponentDeck = deckOf (opponent , deckA , deckB );
106-
107- // Current player deck is empty, opponent collects all pile, end this round
108- if (currentPlayerDeck .isEmpty ()) {
109- opponentDeck .addAll (pile );
110- return new RoundResult (opponent , pile .size ());
111- }
112-
113- // Otherwise, current player plays 1 card, add to pile
114- String card = currentPlayerDeck .poll ();
115- pile .addLast (card );
116-
117- // Current player must pay off pending penalty
118- if (pendingPenalty > 0 ) {
119- // And player reveals a payment card
120- if (isPaymentCard (card )) {
121- // reset penalty based on new card, switch turn
122- pendingPenalty = penaltyOf (card );
123- currentPlayer = opponent ;
124- } else {
125- // Otherwise, deduct penalty
126- pendingPenalty --;
127- // No pending penalty
128- if (pendingPenalty == 0 ) {
129- // Opponent collects all pile and win the round
130- deckOf (opponent , deckA , deckB ).addAll (pile );
131- return new RoundResult (opponent , pile .size ());
132- }
133- }
134- } else {
135- // Normal gameplay, without pending penalty
136- // If player reveals a payment card, update penalty
137- if (isPaymentCard (card )) {
138- pendingPenalty = penaltyOf (card );
139- }
140- currentPlayer = opponent ;
141- }
142- }
143- }
144-
145- private void finishGame (Status status , int cardsPlayed , int tricksCount ) {
146- this .status = status ;
147- this .cards = cardsPlayed ;
148- this .tricks = tricksCount ;
149- }
150-
151- private boolean hasWinner (Deque <String > deckA , Deque <String > deckB ) {
152- return deckA .isEmpty () || deckB .isEmpty ();
153- }
154-
155- public String getStatus () {
156- return status != null ? status .name ().toLowerCase () : "" ;
5+ void simulateGame (List <String > playerA , List <String > playerB ) {
6+ throw new UnsupportedOperationException ("Delete this statement and write your own implementation." );
1577 }
1588
159- public int getCards () {
160- return cards ;
9+ String getStatus () {
10+ throw new UnsupportedOperationException ( "Delete this statement and write your own implementation." ) ;
16111 }
16212
163- public int getTricks () {
164- return tricks ;
13+ int getCards () {
14+ throw new UnsupportedOperationException ( "Delete this statement and write your own implementation." ) ;
16515 }
16616
167- /**
168- * Immutable round result
169- */
170- private record RoundResult (Player nextStarter , int pileSize ) {
17+ int getTricks () {
18+ throw new UnsupportedOperationException ("Delete this statement and write your own implementation." );
17119 }
17220}
0 commit comments