(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



InitializeSetDeck[n_]:= Module[
{SetDeck},
SetDeck=Table[
{i,j,k,m},
{i,1,3},
{j,1,3},
{k,1,3},
{m,1,3}];
SetDeck=Flatten[SetDeck,3];
SetDeck=RandomSample[SetDeck];
{SetDeck[[1;;81-n]],SetDeck[[81+1-n;;81]],{}}
]


(*Here we are testing if 3 cards form a set. (It works for more than 4 properties, if desired.)*)
IsSet[{c1_,c2_,c3_}]:=Module[
{},
Max[Mod[c1+c2+c3,3]]==0
]


FindPopularSet[CT_]:=Module[
{PossibleSets,CheckSet,SetFound,SetPosition,MostPopular,HowPopular,SetPopular,Counts,WherePopular,PopularSetFound},
(* Return a count of the sets and the most popular set (or a random set of the most popular, if tied) if there is one! *)
(* Returns zero and the empty set if there are no sets *)
PossibleSets=Subsets[CT,{3}];
CheckSet=Map[IsSet,PossibleSets];
CheckSet=Position[CheckSet,True];
If[CheckSet=={},Return[{0,{}}]];
HowPopular=Tally[Flatten[PossibleSets[[Flatten[CheckSet]]],1]];
Counts=Flatten[HowPopular[[All,2]]];
WherePopular=Flatten[Position[Counts,Max[Counts]]];
WherePopular=RandomChoice[{WherePopular}];
HowPopular=RandomChoice[HowPopular[[WherePopular,1]]];
SetFound=Position[PossibleSets,HowPopular];
PopularSetFound=SetFound[[All,1]];
CheckSet=Flatten[CheckSet];
SetPosition=Intersection[CheckSet,PopularSetFound];
SetPosition=RandomChoice[SetPosition];
SetFound=PossibleSets[[SetPosition]];
{Length[CheckSet],SetFound}
]


FindRejectSet[CT_]:=Module[
{PossibleSets,CheckSet,SetFound,SetPosition,MostPopular,HowPopular,SetPopular,Counts,WherePopular,PopularSetFound},
(* Return a count of the sets and the most popular set (or a random set of the most popular, if tied) if there is one! *)
(* Returns zero and the empty set if there are no sets *)
PossibleSets=Subsets[CT,{3}];
CheckSet=Map[IsSet,PossibleSets];
CheckSet=Position[CheckSet,True];
If[CheckSet=={},Return[{0,{}}]];
HowPopular=Tally[Flatten[PossibleSets[[Flatten[CheckSet]]],1]];
Counts=Flatten[HowPopular[[All,2]]];
WherePopular=Flatten[Position[Counts,Min[Counts]]];
WherePopular=RandomChoice[{WherePopular}];
HowPopular=RandomChoice[HowPopular[[WherePopular,1]]];
SetFound=Position[PossibleSets,HowPopular];
PopularSetFound=SetFound[[All,1]];
CheckSet=Flatten[CheckSet];
SetPosition=Intersection[CheckSet,PopularSetFound];
SetPosition=RandomChoice[SetPosition];
SetFound=PossibleSets[[SetPosition]];
{Length[CheckSet],SetFound}
]


PopularSetPlay[{CDIn_,CTIn_,CFIn_}]:= Module[
{CD=CDIn, CT=CTIn,CF=CFIn,NumberOfSets,FoundSet,NumberOfCardsLeft,m,NumberOfCardsTable},
(* using FindSet to chase down a set *)
{NumberOfSets,FoundSet}=FindPopularSet[CT];
(* Counting the cards left *)
NumberOfCardsLeft=Length[CD];
(* Termination condition is input is static *)
If[And[NumberOfCardsLeft==0, NumberOfSets==0],Return[{CD,CT,CF}]];
(* *)
m=Min[3,NumberOfCardsLeft];

Switch[NumberOfSets,
0,  CT=Join[CT, Take[CD,m]]; CD=Drop[CD,m],
_, CT=Complement[CT,FoundSet]; 
       CF=Join[CF, FoundSet];
       NumberOfCardsTable= Length[CT] ;
       If[ NumberOfCardsTable<12, CT=Join[CT, Take[CD,m]];CD=Drop[CD,m]]; 
];
{CD,CT,CF} 
]


RejectSetPlay[{CDIn_,CTIn_,CFIn_}]:= Module[
{CD=CDIn, CT=CTIn,CF=CFIn,NumberOfSets,FoundSet,NumberOfCardsLeft,m,NumberOfCardsTable},
(* using FindSet to chase down a set *)
{NumberOfSets,FoundSet}=FindRejectSet[CT];
(* Counting the cards left *)
NumberOfCardsLeft=Length[CD];
(* Termination condition is input is static *)
If[And[NumberOfCardsLeft==0, NumberOfSets==0],Return[{CD,CT,CF}]];
(* *)
m=Min[3,NumberOfCardsLeft];

Switch[NumberOfSets,
0,  CT=Join[CT, Take[CD,m]]; CD=Drop[CD,m],
_, CT=Complement[CT,FoundSet]; 
       CF=Join[CF, FoundSet];
       NumberOfCardsTable= Length[CT] ;
       If[ NumberOfCardsTable<12, CT=Join[CT, Take[CD,m]];CD=Drop[CD,m]]; 
];
{CD,CT,CF} 
]


PopularSetPlayRepeat[]:=Module[
{SetGame,CardsRemaining},
{CD,CT,CF}=InitializeSetDeck[12];
SetGame=Do[{CD,CT,CF}=PopularSetPlay[{CD,CT,CF}],{50}];(*This "plays" 50 hands, finding up to 27 sets (81 cards). It is impossible to find more than 27 sets because there are only 81 cards, however, a hand is counted when 3 extra cards are added to the table. In the worst conditions, 49 hands will finish the game.*)
{CDEnd,CTEnd,CFEnd}=Map[Length,{CD,CT,CF}]; (*This counts the number of cards at the end of one game*)
(* Added this line AAS March 14th to save special configs for Stefan *)
If[CTEnd==18, PutAppend[CT,"18.txt"]; Print["Got One"]];
{CDEnd,CTEnd,CFEnd} (*This returns the number of cards in each pile after playing 1 game*)
]


RejectSetPlayRepeat[]:=Module[
{SetGame,CardsRemaining},
{CD,CT,CF}=InitializeSetDeck[12];
SetGame=Do[{CD,CT,CF}=RejectSetPlay[{CD,CT,CF}],{50}];(*This "plays" 50 hands, finding up to 27 sets (81 cards). It is impossible to find more than 27 sets because there are only 81 cards, however, a hand is counted when 3 extra cards are added to the table. In the worst conditions, 49 hands will finish the game.*)
{CDEnd,CTEnd,CFEnd}=Map[Length,{CD,CT,CF}]; (*This counts the number of cards at the end of one game*)
(* Added this line AAS March 14th to save special configs for Stefan *)
If[CTEnd==18, PutAppend[CT,"18.txt"]; Print["Got One"]];
{CDEnd,CTEnd,CFEnd} (*This returns the number of cards in each pile after playing 1 game*)
]



