# Game Theory Template

1. Bash Game
There is only a stack of n items from which two people take turns. It is stipulated to take at least one item at a time and at most m items at a time. The winner is the last one who takes light.
If n%(m+1)==0 the later hand will win, otherwise the first hand will win, if n>m, take n%(m+1) for the first time, if n<=m, any one between n~m for the first time
II. Wazov Game
There are two stacks of several items each. Two people take at least one item from one of them in turn, at most unlimited, or take the same item from both stacks at the same time, which stipulates that the final winner will win.

```while(cin>>n1>>n2)
{
if(n1>n2)  swap(n1,n2);
temp=floor((n2-n1)*(1+sqrt(5.0))/2.0);
if(temp==n1) cout<<"Backhand wins"<<endl;
else cout<<"Win first"<<endl;
}
```

3. Nim Game
There are any stacks of items, and the number of items in each stack is arbitrary. Both parties take turns to take items from each stack. Only part or all of the items can be taken from one stack at a time. At least one item can be taken. The person who takes the last item wins.
Conclusion: If the value obtained is 0, the first hand will lose, otherwise the first hand will win.
If the rule is transformed into a maximum of K in the Nim game, then only mod(k+1) is needed for each heap of stones.

```while(cin>>n)
{
temp=0;
for(int i=0;i<n;i++)
{
cin>>ans;
temp^=ans;
}
if(temp==0)  cout<<"Backhand wins"<<endl
else cout<<"Win first"<<endl;
}
```

4. Game of Fibonacci
There is a stack of items, two people take turns to take at least one by hand, no upper limit at most, but they can't get all the items out. After that, they can't take more than twice the number of items last taken and at least one item at a time. The person who takes the last item wins.
Conclusion: First-hand wins if and only if n is not a Fibonacci number (n is the total number of items)

```const int N = 55;
int f[N];
void Init()
{
f = f = 1;
for(int i=2;i<N;i++)
f[i] = f[i-1] + f[i-2];
}
int main()
{
Init();
int n;
while(cin>>n)
{
if(n == 0) break;
bool flag = 0;
for(int i=0;i<N;i++)
{
if(f[i] == n)
{
flag = 1;
break;
}
}
if(flag) puts("Second win");
else     puts("First win");
}
return 0;
}
```

Fair Portfolio Game:
(1) Two participants.
(2) The set of state of a game situation is limited.
(3) For the same situation, the operational set of the two players is identical.
(4) Players take turns in the game.
(5) When the game is over when the operation cannot be performed, the one that cannot perform the operation at this time is counted as a loss.
(6) No matter how the game is played, it can always end in a limited number of steps.
SG function:
g(x)=mex{g(y)|y is the successor of x}
Mex: Operates on a set to represent the smallest non-negative integer that does not belong to the set, such as mex{0,1,2,3}=4,mex{2,3,5}=0
SG Theorem: g(G)=g(G1) g(G2) g(G3)...The SG value of a game is XOR of its sub-game SG value
Conclusion: When g(G)=0, the first hand must lose, otherwise, the first hand must win

Solving Model:
1. If the original game is divided into several independent sub-games, the SG function value of the original game is the exclusive or of the SG function values of all its sub-games.
That is sg(G)=sg(G1)sg(G2)...^sg(Gn).
2. Consider that there is no subgame and calculate its SG value.
The calculation method of SG value: (key)
1. Continuous integers with optional steps of 1~m can be directly modeled, SG(x) = x% (m+1);
2. The optional number of steps is arbitrary, SG(x) = x;
3. Optional steps are a series of discontinuous numbers, calculated using a template.

Template 1-Tabulate

```const int N=10005;
int f[N],SG[N],S[N];                 //N must be large enough to contain all cases
void  getSG(int n,int m)        //n for the length of the SG and m for the length of the f array
{
int i,j;
sort(f,f+m);
memset(SG,0,sizeof(SG));
//Because SG always equals 0, i starts from 1
for(i = 1; i <= n; i++)
{
//Reset successor sets of the previous state each time
memset(S,0,sizeof(S));
for(j = 0; f[j] <= i && j<m; j++)
S[SG[i-f[j]]] = 1;  //Mark the SG function value of the succeeding state
for(j = 0;; j++) if(!S[j])
{   //Query for the minimum non-zero value in the SG value of the current succeeding state
SG[i] = j;
break;
}
}
}
```

Template 2-Search

```const int N=10000;
int sg[N];                       //sg is all initialized to -1
int getsg(int x)
{
if(sg[x]!=-1)
return sg[x];
int mex[N];
memset(mex,0,sizeof(mex));
for(int i=0;i<e[x].size();i++)
mex[getsg(e[x][i])]=1;
for(int i=0;;i++)
{
if(!mex[i])
return sg[x]=i;            //Memorized Search
}
}
```

Posted on Fri, 10 Sep 2021 12:09:42 -0400 by mac007