I am trying to simulate the card game War to find approximations to the stopping time distribution for different types of decks, and study conditional probabilities of winning given a certain deck. (Maybe 3, 5, or 20 suits instead of the conventional 4).
This problem is fairly recursive, because if a War occurs, and it ends with a tie, there is another war. A war starts when two competing cards are equal in value.
I am pretty sure that the comparison function needs to be fixed the most. I can't seem to get to Mathematica reassign the variables within the function.
Here is the code I wrote so far:
messageHandler = If[Last[#],Abort[]] & ;Internal`AddHandler["Message", messageHandler];$Messages = {};$Post = Function[Null, Unevaluated@# /. $Aborted -> Null, HoldAllComplete];
Deck[suits_, values_] :=
RandomSample[
Flatten[
Table[
Table[{suit, value}, {value, 1, values}],
{suit, 1, suits}
],
1
]
];
comparisonFunction[consecutiveWars_,increment_,battleAmount_,warAmount_,list1_,list2_]:=
Which[list1[[increment,2]]<list2[[increment,2]],consecutiveWars=0;
list1=RandomSample[Join[list1,list2[[1;;increment]]]];
list2=Drop[list2,increment],list1[[increment,2]]>list2[[increment,2]],consecutiveWars=0;
list2=RandomSample[Join[list2,list1[[1;;increment]]]];
list1=Drop[list1,increment],list1[[increment,2]]==list2[[increment,2]],consecutiveWars=consecutiveWars + 1;
increment=consecutiveWars*warAmount;
comparisonFunction[consecutiveWars,increment,battleAmount,warAmount,list1,list2]];
commenceWarCardGame[consecutiveWars_,increment_,battleAmount_,warAmount_,list1_,list2_]:=
untilCount=0;minimumHandLength=Min[Length[list1],Length[list2]];
Until[minimumHandLength <= 0||untilCount==maximumStoppingTime,minimumHandLength=Min[Length[list1],Length[list2]];
comparisonFunction[consecutiveWars,increment,battleAmount,warAmount,list1,list2];untilCount++]
warGameSimulation[consecutiveWars_,suits_,values_,battleAmount_,warAmount_,maximumStoppingTime_]:=
(deck=Deck[suits,values];
If[EvenQ[Length[deck]]==True,player1Hand=deck[[1;;Length[deck]/2]];
player2Hand=deck[[Length[deck]/2+1;;Length[deck]]];
commmenceWarCardGame[consecutiveWars, suits, values, battleAmount, warAmount, maximumStoppingTime],Print["Deck length is not even."]])
The first line is just to help ignore error messages. It is not related to the actual game simulation. The second line generates a random deck with $m-suits$ and $n-values$. The comparison function compares the value of the cards to presented by the players, then is supposed to add the cards to the winner, while taking them away from the loser. The commenceWarCardGame is supposed to run the program until the cards runs out or the stopping time takes too long. The last function just puts them all together, checks if the deck can be split evenly. Then commences the game if it can be split evenly.
In real life, the card game is a game of elimination. Once one player has all of the cards or at least one of the players cannot play anymore, the game is over.
It was mentioned in the comments that I cannot put a function inside of a function like I tried to do for the comparison function.
Deckmore succinctly asClearAll[Deck]; Deck[suits_, values_] := RandomSample@ Tuples[{Range[suits], Range[values]}]. Note also that aTablecan have more than one iterator, soTable[{suit, value}, {suit, 1, suits}, {value, 1, values}]is equivalent to your nested tables. – MarcoB Jun 01 '23 at 02:56