In Game Theory, extensive analysis has been performed on specific games with fixed payoffs. However, not as much work has been done to generalize or explore what happens when the payoffs are variable. This project analyzes the effect that changing the payoffs of simple systems of two-player games has on the optimal strategy. The method begins by generating the list of possible distinct two-state Finite State Machines (FSMs) and defining functions that simulate updating game states using the rules provided. I then started by analyzing simple games of Match-or-Not, and determined that the rankings of each strategy’s effectiveness is fixed regardless of the games payoff. I then moved onto variations of the Prisoner’s Dilemma, analyzing both games where the payoffs must be ordered based on the original Prisoner’s Dilemma and games where the payoffs can be in any arbitrary order and then graphically representing the results. The results of my analysis showed that despite payoff variance modeling randomness, there still emerge concrete trends showing which strategies consistently succeed across all game variations.
Introduction
Introduction
In game theory, computer simulations are often used to analyze the outcomes of different strategies for a particular game. In this project, I analyze systems of games where each player has two choices a turn, such as Prisoner’s Dilemma, to see how adjusting the payoffs for each combination of moves affects the results. To do this, each strategy was simulated as a Finite State Machine (FSM), or a model with finite states that determines the next move given the current game state, then ran against every other strategy to determine the average payoff per turn for each strategy. This project was based on Stephen Wolfram’s (2026) article, Games Between Programs: The Ruliology of Competition (https://writings.stephenwolfram.com/2026/06/games-between-programs-the-ruliology-of-competition/#the-space-of-all-possible-games).
Basic Function Setup
Basic Function Setup
Generating Rules (List Form)
Generating Rules (List Form)
The first thing needed is a way to generate all distinct two-state FSMs needed for computation. The two-state FSMs used are defined on two parameters, being the current player’s last move and the opponent’s last move. Since the games being analyzed are games where each player only has 2 choices, each player’s choice can be denoted as either Green or Red, with 1 representing Green and 2 representing Red. There are 4 possible combinations of the current player and opponent’s last turns, each of which has 2 choices for what the player’s next move will be. An extra parameter is also necessary to determine what the first move is when there is no move history to look at to run the FSM off of.
Thus, to generate the set of possible FSMs, use a Table that creates all possible combinations of 5 choices of 1 or 2. To make sense of these lists of data, define the following:
Index 1: Next move if the current player’s last move was Green and opponent’s last move was Green
Index 2: Next move if the current player’s last move was Green and opponent’s last move was Red
Index 3: Next move if the current player’s last move was Red and opponent’s last move was Green
Index 4: Next move if the current player’s last move was Red and opponent’s last move was Red
Index 5: First turn
Thus, to generate the set of possible FSMs, use a Table that creates all possible combinations of 5 choices of 1 or 2. To make sense of these lists of data, define the following:
Index 1: Next move if the current player’s last move was Green and opponent’s last move was Green
Index 2: Next move if the current player’s last move was Green and opponent’s last move was Red
Index 3: Next move if the current player’s last move was Red and opponent’s last move was Green
Index 4: Next move if the current player’s last move was Red and opponent’s last move was Red
Index 5: First turn
Construct all 5-element lists of 1s or 2s:
In[]:=
listRules=Flatten[Table[{a,b,c,d,s},{s,1,2},{a,1,2},{b,1,2},{c,1,2},{d,1,2}],4]
Out[]=
{{1,1,1,1,1},{1,1,1,2,1},{1,1,2,1,1},{1,1,2,2,1},{1,2,1,1,1},{1,2,1,2,1},{1,2,2,1,1},{1,2,2,2,1},{2,1,1,1,1},{2,1,1,2,1},{2,1,2,1,1},{2,1,2,2,1},{2,2,1,1,1},{2,2,1,2,1},{2,2,2,1,1},{2,2,2,2,1},{1,1,1,1,2},{1,1,1,2,2},{1,1,2,1,2},{1,1,2,2,2},{1,2,1,1,2},{1,2,1,2,2},{1,2,2,1,2},{1,2,2,2,2},{2,1,1,1,2},{2,1,1,2,2},{2,1,2,1,2},{2,1,2,2,2},{2,2,1,1,2},{2,2,1,2,2},{2,2,2,1,2},{2,2,2,2,2}}
However, a few of these have duplicate behaviors: In the first four rules (1,2,3,4), the player will always play Green, and there are another set of four rules (20,24,28,32) that always play Red. To account for these duplicates, all cases of all-Green rules and all-Red rules are removed except for one to get the following list of rules:
In[]:=
listRules={{1,1,1,1,1},{1,2,1,1,1},{1,2,1,2,1},{1,2,2,1,1},{1,2,2,2,1},{2,1,1,1,1},{2,1,1,2,1},{2,1,2,1,1},{2,1,2,2,1},{2,2,1,1,1},{2,2,1,2,1},{2,2,2,1,1},{2,2,2,2,1},{1,1,1,1,2},{1,1,1,2,2},{1,1,2,1,2},{1,2,1,1,2},{1,2,1,2,2},{1,2,2,1,2},{2,1,1,1,2},{2,1,1,2,2},{2,1,2,1,2},{2,2,1,1,2},{2,2,1,2,2},{2,2,2,1,2},{2,2,2,2,2}};
Function to Run an FSM
Function to Run an FSM
To actually use the list of FSM rules to generate moves, create a function that takes the rule being used, the current player’s last move, and the opponent’s last move, and returns the player’s next move using the provided rule.
If the game has not started yet, automatically default to the rule’s starting value; otherwise, evaluate what the player’s next move will be using the index determined by the last round’s results.
In[]:=
ClearAll[fsmfunc];fsmfunc[rule_,pos_,lastEnemyMove_]:=If[pos==0,rule[[-1]],rule[[2(pos-1)+lastEnemyMove]]]
Running Simple Match-or-Not Games
Running Simple Match-or-Not Games
The next step is to simulate full games by repeatedly updating each player’s moves.
For now, scores in the game will start at 0 and will be updated each turn by giving one point from player 2 to player 1 (player 1 gains a point, player 2 loses a point) if the two player choices are the same and giving one point from player 1 to player 2 if the two choices are different. This is called the “Match-or-Not” game, and is an example of a zero-sum game where the sum of both players’ scores is constant.
To make a game function that simulates one full turn of a game, simply apply the FSM function to get the next game’s outputs for both Player 1 and 2.
For now, scores in the game will start at 0 and will be updated each turn by giving one point from player 2 to player 1 (player 1 gains a point, player 2 loses a point) if the two player choices are the same and giving one point from player 1 to player 2 if the two choices are different. This is called the “Match-or-Not” game, and is an example of a zero-sum game where the sum of both players’ scores is constant.
To make a game function that simulates one full turn of a game, simply apply the FSM function to get the next game’s outputs for both Player 1 and 2.
Using player 1 and player 2 to represent both player’s last moves, update both player 1 and player 2’s positions with their next move and update total score for each player.
In[]:=
ClearAll[game];game[rule1_,rule2_]:=({player1,player2}={fsmfunc[rule1,player1,player2],fsmfunc[rule2,player2,player1]};If[player1==player2,{score1,score2}+={1,-1},{score1,score2}+={-1,1}];)
Now, make a function that visualizes playing multiple rounds of the game by repeatedly iterating the game function:
Resets all variables and runs the game function 12 times, displaying each player’s pick mapped to colors and their current total scores after each turn:
In[]:=
simulateGame[rule1_,rule2_]:=(player1=0;player2=0;score1=0;score2=0;Column[Table[game[rule1,rule2];{{player1,player2}/.{1->Green,2->Red},{score1,score2}},{12}]])
Example of running the game with two fixed rulesets:
In[]:=
rule1={1,2,1,2,1};rule2={1,2,2,1,2};simulateGame[rule1,rule2]
Out[]=
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
{{ |
Average Payoffs for Match-or-Not
Average Payoffs for Match-or-Not
Average Payoff Function Setup
Average Payoff Function Setup
The first goal is to find what strategy actually wins in this particular case. To concretely quantify the effectiveness of each strategy, record the average payoff per turn for each rule running against each other. Since the number of possible turn combinations is finite (4, to be precise) and an already visited game state necessarily creates a loop, each player’s average payoff per turn for one game can be defined as the average payoff per turn in that loop.
To calculate the average payoff per turn, the game function can first be redefined to record the payoff every turn instead of the total score.
In[]:=
ClearAll[game];game[rule1_,rule2_]:=({player1,player2}={fsmfunc[rule1,player1,player2],fsmfunc[rule2,player2,player1]};If[player1==player2,{score1,score2}={1,-1},{score1,score2}={-1,1}];)
To find the actual average payoff per player, the game is first played out until it reaches a looping state. This is determined by recording the current game state and payoffs for each player into lists until the current game state has already appeared, which would then determine the loop. Then, to find the average payoff, the payoffs of the steps within the loop are summed up and divided by the length of the loop, giving the average payoff for both player 1 and player 2 for given a specific game.
ClearAll[avgPayoffMoN];avgPayoffMoN[rule1_,rule2_]:=(player1=0;player2=0;score1=0;score2=0;visited={};points={};game[rule1,rule2];While[!MemberQ[visited,{player1,player2}],visited=Join[visited,{{player1,player2}}];points=Join[points,{{score1,score2}}];game[rule1,rule2];];loopStart=Position[visited,{player1,player2}][[1,1]];avg1=N[Sum[points[[i,1]],{i,loopStart,Length[visited]}]/(Length[visited]-loopStart+1),2];avg2=N[Sum[points[[j,2]],{j,loopStart,Length[visited]}]/(Length[visited]-loopStart+1),2];{avg1,avg2})
Calculating Results Across All Matchups
Calculating Results Across All Matchups
Having made a function that calculates the average payoff per turn for one specific game, for each rule, the function can be iterated over all other rules to get how well that specific rule does on average. Looking at the average outcome for how each rule performs as Player 1 gives the following dataset:
First, define a function that displays results tables as a dataset:
In[]:=
dataDisplay[x_]:=Dataset[Join[{{"Rule #","Average Payoff Per Turn"}},x]]
Create a list of results for each combination of two rules playing against each other:
In[]:=
gameResults=Table[avgPayoffMoN[listRules[[i]],listRules[[j]]],{i,Length[listRules]},{j,Length[listRules]}];
For each rule, calculate the average of its results when it plays against all other rules by iterating across the results table, represented by the average of the elements in each sublist of gameResults:
In[]:=
player1results=SortBy[Table[{i,Total[Table[gameResults[[i,j,1]],{j,Length[listRules]}]]/Length[listRules]},{i,Length[listRules]}],Last];dataDisplay[player1results]
Out[]=
The two winning rules are 2 and 24:
The two winning strategies for player 1 (the player trying to match) are redemptive variations of the Tit-for-Tat strategy: Player 1 sticks with one color to pick throughout the round. If player 2 chooses the other color, Player 1 will switch to their color for the next round before switching back.
The results table for the optimal strategy for Player 2 is the results table for Player 1 in reverse order. This is because the payoffs for Player 1 and Player 2 are flipped; for example, if a rule loses points as Player 1 because it did not match, it would instead have gained points if it were Player 2, meaning the average payoffs for each rule as Player 2 is the average payoff for that rule as Player 1 with flipped sign, thus flipping the ranking order as well.
Rules 6 and 25 are similar to Rules 2 and 24 in that the player chooses a color to stick with throughout the round; however, in these scenarios, Player 2 switches color for a round if Player 1 matches their color, instead of if they differ.
Pitting the winning Player 1 and winning Player 2 strategies against each other, it can be seen that the expected payoff per turn is 0.33 for the winning player, with Player 1 winning if the first choices are the same and Player 2 winning if the first choices differ.
Changing Match or Not Payoffs
Changing Match or Not Payoffs
In the previous model, the payoffs were explicitly defined as permutations of {1,-1} What happens if the values of these payoffs are changed?
Instead of using constants, define payoff1 to be the payoff for winning a round, and define payoff2 to be the payoff for losing a round, where Player 1 wins a round by matching and Player 2 wins a round by differing. Using these variables, redefine the game function to use the variable payoffs instead of the constant {1,-1}:
Using the same procedure of calculating each rule’s average results after being ran against all other rules, define a function that takes the desired payoff parameters and returns the rule rankings.
Make a table to find the payoff results across all games with winning and losing payoffs between -5 and 5 to keep the results in a fixed list.
Use a manipulate to show the results table for Player 1 and Player 2 based on the user’s choice of the winning and losing payoffs:
Using the manipulate, it can be observed that the order of rankings never actually changes. This is not too surprising; regardless of how big the payoff actually is, a strategy’s success is determined solely by how often it wins.
To prove this result, first note that for any constant C, all games with payoffs of the form {a+C, a} are analogous to the game with payoffs {C,0}, since adding a constant value to both the winning and losing players’ payoffs each turn simply increases the average payoff per turn by the same constant. Thus, the sample space of all games can be treated as the sample space of games with payoffs of the form {C, 0}.
Leaving C as a variable, calculate the average payoff per turn for each rule as expressions in terms of C:
Leaving C as a variable, calculate the average payoff per turn for each rule as expressions in terms of C:
Get the dataset of each rule’s player 1 payoffs in terms of C
The average payoff for each turn is directly proportional to C, meaning that (if C > 0), the order of rule rankings does not depend on the value of C.
Looking at the list, the optimal strategy ranking for Player 1 is:
and the optimal strategy ranking for Player 2 is the reversed list (Note ties),
Prisoner’s Dilemma
Prisoner’s Dilemma
Prisoner’s Dilemma Basics
Prisoner’s Dilemma Basics
Now Match-or-Not has been analyzed, what about more complex games? The Prisoner’s Dilemma functions similarly to Match-or-Not, but instead of red and green being analogous and only having two possible payoff combinations of win or lose, in the Prisoner’s Dilemma, the two player choices actually behave differently and all 4 combinations of moves have different payoffs.
In the Prisoner’s Dilemma, each player picks between cooperating or defecting. There are then 4 possible payoffs:
-If both players cooperate, they both get the reward (R) payoff (low punishment)
-If one player cooperates but the other defects, the person who cooperated gets the sucker (S) payoff (harshest punishment), and the person who defected gets the temptation (T) payoff (least punishment)
-If both players defect, both get the punishment (P) payoff (moderate punishment)
For example, let R be -1, S be -3, T be 0, and P be -2. This means:
-If both players choose to cooperate, both players get 1 year in jail (Low punishment).
-If one player chooses to cooperate but the other defects, the defector gets away with no jail time (least punishment) while the cooperator gets 3 years in jail (worst punishment).
-If both players choose to defect, both players get 2 years of jail time (Moderate punishment).
The goal is to find which strategies minimize the amount of jail time when repeating the game multiple times. To start, first redefine the game function to check all 4 cases, where 1 = cooperate, and 2 = defect.
In the Prisoner’s Dilemma, each player picks between cooperating or defecting. There are then 4 possible payoffs:
-If both players cooperate, they both get the reward (R) payoff (low punishment)
-If one player cooperates but the other defects, the person who cooperated gets the sucker (S) payoff (harshest punishment), and the person who defected gets the temptation (T) payoff (least punishment)
-If both players defect, both get the punishment (P) payoff (moderate punishment)
For example, let R be -1, S be -3, T be 0, and P be -2. This means:
-If both players choose to cooperate, both players get 1 year in jail (Low punishment).
-If one player chooses to cooperate but the other defects, the defector gets away with no jail time (least punishment) while the cooperator gets 3 years in jail (worst punishment).
-If both players choose to defect, both players get 2 years of jail time (Moderate punishment).
The goal is to find which strategies minimize the amount of jail time when repeating the game multiple times. To start, first redefine the game function to check all 4 cases, where 1 = cooperate, and 2 = defect.
Simulate one turn and record the payoff by checking which of the 4 cases the game ends up on:
The method of finding the payoffs per game does not change significantly. However, one important difference is that the player numbers are analogous in Prisoner’s Dilemma but not Match-or-not: for example, choosing Green when your opponent picked Red in Match-or-Not benefits Player 2 but not Player 1, but in Prisoner’s Dilemma, both you and your opponent will get the same payoff regardless of which player number they are. Thus, the avgPayoff and payoffResults functions must be modified to better fit with the Prisoner’s Dilemma scenario.
The avgPayoff function is the same as before, but only returns the results for the first Player.
The payoffResults function is also changed to only give the results table for Player 1, since Player 2’s results would be the same. Additionally, the Prisoner’s Dilemma has 4 possible payoffs instead of 2 in Match-or-Not, so the function also is redefined to take 4 parameters corresponding to the payoffs.
Running this code now gives:
The winning rule is Rule 5:
This rule is known as Grim Trigger, where the player begins by cooperating but always defects as soon as the other player defects for the first time.
There is a three way tie for second place: Rules 26, 13, and 25.
There is a three way tie for second place: Rules 26, 13, and 25.
Rule 26 represents always defecting.
Rule 13 cooperates on the first turn, but always defects after that.
(As an aside, Rules 26 and 13 do actually have different behaviors despite only ever differing in the first move: for example, if Player 2 plays Rule 15 ({1,1,1,2,2}),which defects until the other player cooperates, Player 2 will always defect against Rule 26 but always cooperate against Rule 13.)
(As an aside, Rules 26 and 13 do actually have different behaviors despite only ever differing in the first move: for example, if Player 2 plays Rule 15 ({1,1,1,2,2}),which defects until the other player cooperates, Player 2 will always defect against Rule 26 but always cooperate against Rule 13.)
Rule 25 will always defect except if the other player also defects, during which the player will cooperate for a turn before defecting again.
For all 3 of the tying 2nd place strategies, the players will almost always choose to defect. This represents the Nash Equilibrium of the Prisoner’s Dilemma, where the best option for both players is to defect, as choosing to cooperate without knowing if the opponent will defect is much riskier than sticking with defection.
The worst rule is Rule 15:
This is the reverse of the Grim Trigger, where it starts by defecting but starts cooperating after the enemy cooperates.
Altering the Dilemma
Altering the Dilemma
The best scenario for the standard setup is to always defect. However, there are ways to shift the game away from a defect strategy. An obvious example of this is drastically increasing the punishment for both players defecting:
Outcome of the results when the Punishment payoff is increased to 100 years:
The best rule is now Rule 16:
For this scenario, the winning strategy becomes defecting at the start, but cooperating if the enemy starts to defect. (Games are treated as running for infinitely long, so taking a penalty once does not affect the results, which may seem counterintuitive. For future use, this issue could be corrected by calculating the average payoff after a large but finite number of turns.)
However, this scenario does noticeably change the core structure of the Prisoner’s Dilemma, since the punishment for cooperating while the other defects is no longer worse than the punishment for both defecting.
To maintain the core structure of the Prisoner’s Dilemma, the payoffs must be strictly be in the order:
T ≥ R ≥ P ≥ S
Keeping the Punishment payoff as -100 and making S= -110 to preserve the payoff order gives:
However, this scenario does noticeably change the core structure of the Prisoner’s Dilemma, since the punishment for cooperating while the other defects is no longer worse than the punishment for both defecting.
To maintain the core structure of the Prisoner’s Dilemma, the payoffs must be strictly be in the order:
T ≥ R ≥ P ≥ S
Keeping the Punishment payoff as -100 and making S= -110 to preserve the payoff order gives:
Results when sucker punishment is accordingly increased to 110 years in jail:
The winning rule is still Rule 5, Grim Trigger. However, if S is closer to T, a different winner emerges:
Results after decreasing the Sucker punishment to 105 years:
The winner is now no longer Grim Trigger, but rather Rule 19.
The winning rule follows the pattern of keeping the last turn’s choice if the other player cooperates, and switching choices if the other player defects.
For the game being tested, the payoffs for R and T are drastically better than S or P, so the payoffs can be split into Good payoffs (R,T) and Bad payoffs (S,P). However, if the ratio of S/P is very close to 1, the difference between an S or P payoff is negligible. Analyzing the logic behind each move gives the following chart:
{Player 1, Player 2}
{C, C}: Both players get a good payoff, so no incentive to switch
{C,D}: Player 1 gets the worst outcome of S, so they switch to D for a marginally better outcome of P or a good outcome of T
{D,C}: Player 1 gets a good payoff of T and makes no changes
{D,D}: Player 1 gets a bad payoff of P, so they switch strategy to cooperating. This is the most counterintuitive part, as no matter what the opponent does, it seems like defecting will give a better result: If player 2 cooperates, player 1 would get 0 years defecting but 1 year cooperating, and if player 2 defects, player 1 will still get a harsh punishment.
This is an example of a Pavlov rule, where the player does the same thing if the outcome of their last turn was good but switches their strategy if they got a bad outcome.
For the game being tested, the payoffs for R and T are drastically better than S or P, so the payoffs can be split into Good payoffs (R,T) and Bad payoffs (S,P). However, if the ratio of S/P is very close to 1, the difference between an S or P payoff is negligible. Analyzing the logic behind each move gives the following chart:
{Player 1, Player 2}
{C, C}: Both players get a good payoff, so no incentive to switch
{C,D}: Player 1 gets the worst outcome of S, so they switch to D for a marginally better outcome of P or a good outcome of T
{D,C}: Player 1 gets a good payoff of T and makes no changes
{D,D}: Player 1 gets a bad payoff of P, so they switch strategy to cooperating. This is the most counterintuitive part, as no matter what the opponent does, it seems like defecting will give a better result: If player 2 cooperates, player 1 would get 0 years defecting but 1 year cooperating, and if player 2 defects, player 1 will still get a harsh punishment.
This is an example of a Pavlov rule, where the player does the same thing if the outcome of their last turn was good but switches their strategy if they got a bad outcome.
Testing different values of S to find exactly when Rule 5 beats Rule 19 eventually yields the threshold as between S=-107 and -108:
If P = -100, the cutoff for when Grim Trigger beats Rule 19 is when S ≤ -108. Looking at results for games with higher P values shows similar results, where the winning strategy is rule 19 if S is close to P and Grim Trigger otherwise. In fact, the ratio of S/P for the cutoff value seems to be constant and roughly equal to 1.07: For example,
Testing the threshold value for S when P = -1000:
Taking a deeper look into what actually happens in a game where Rule 19 wins reveals interesting information.
Set the parameters of a game where Rule 19 is the best strategy:
Using avgPayoffs, make a list of Rule 19’s average payoff per turn against every other rule:
Repeat the process for Rule 5:
Looking at total sum of all average payoffs per turn shows that Rule 19 just barely edges out Rule 5.
Sum of average payoffs per turn for Rule 19:
Sum of average payoffs per turn for Rule 5:
Comparing both lists rule by rule gives:
For each Rule i, compare Rule 19’s average payoff per turn against Rule i versus Rule 5’s average payoff per turn against Rule i. Then, give a list that returns 0 if both Rule 19 and Rule 5 perform equally well and returns the winning rule as well as the difference in average payoff per turn otherwise.
Tallies the number of times Rule 19 beats Rule 5, how many draws there are, and number of times Rule 5 beats Rule 19.
From the tally, it can be seen that Rule 19 does better than Grim Trigger less often that it loses to Grim Trigger. However, it still wins in the end because of the option to revert to mutual cooperation in combination with the fact that the additional penalty from choosing to cooperate if the other player defects is relatively small. The two following cases illustrate this well:
Here, having the redemptive option to start cooperating even after mutual defection allows Rule 19 to end up in a situation that benefits both players. However, Grim Trigger never chooses to cooperate afterwards, meaning it alternates between good and bad payoffs.
In this scenario, Rule 19 still puts player 1 in situations where they get the sucker punishment. However, because the ratio of S/P is small, the difference is made up for by making player 2 switch to cooperating when player 1 defects for a T payoff. In contrast, Grim Trigger ends up with the same loop of only getting the Punishment payoff.
However, as S/P becomes larger, the risk of choosing to cooperate if the other player sticks with defection becomes higher, resulting in Grim Trigger outperforming Rule 19.
However, as S/P becomes larger, the risk of choosing to cooperate if the other player sticks with defection becomes higher, resulting in Grim Trigger outperforming Rule 19.
Generalized Prisoner’s Dilemma
Generalized Prisoner’s Dilemma
Having tested some concrete examples, the next goal is to see what information can be gathered regarding the behavior across all game variations by keeping the payoff variables unassigned.
No changes are made to the following two functions; they are only being brought up again for evaluation convenience.
payoffResults is effectively the same, except left unsorted and kept in index order
This information is incredibly versatile. For example, it can be used to understand the threshold between Rule 5 and Rule 19 in the previous analysis.
Compare the two average payoff equations for Rule 5 and Rule 19:
Compare the two average payoff equations for Rule 5 and Rule 19:
Get the coefficients for Rule 19:
WIth more precision, these values are:
Another helpful function to define is a function that automatically returns the winning strategy for a specific game.
With this function, it becomes simple to determine which functions are ever optimal and how often.
It can be seen that the only possible winning strategies in the standard Prisoner’s Dilemma format are Rules 26, 19, and 5, which correspond to always defecting, the previously mentioned Pavlov rule, and Grim Trigger. Grim Trigger ends up being optimal in the vast majority of cases, with Rule 26 winning less than half as often and Rule 19 winning only in very rare scenarios.
Plotting
Plotting
Equations generalizing results across all possible parameters are useful not just analytically, but also for visualizing scenarios with graphics. For example, by fixing 2 of the 4 parameters, a 2-D plot can be constructed to visualize on which regions each strategy wins.
The first step is defining a function that determines which of the three possible winning rules is optimal at each point
This function is used to then create a 2-D plot that represents s and p as the coordinate axes given fixed values of r and t to graph the regions where each strategy wins.
Analyzing this graph, it can be seen that Rule 5 wins in most cases. However, when T and R are very close, Rule 19 wins in a few rare cases, while when T and R get further apart, Rule 26 wins for cases where P is close to R and irrespective of the value of S.
This data can also be visualized as a graph in 3D by making R a third variable dimension. For this graphic, an additional option is included to isolate which strategy’s region to look at for each section.
This data can also be visualized as a graph in 3D by making R a third variable dimension. For this graphic, an additional option is included to isolate which strategy’s region to look at for each section.
Increase the time allowed before a manipulate graphic auto-aborts:
Creates a manipulable graphic that fixes T and checks for all valid points with integer coordinates whose corresponding game variation’s winning strategy is the selected strategy number and creates a cube around each point to fill up the space.
Other Orders
Other Orders
Take only the rule numbers to get a list of possible winning rules:
This data can be plotted in a bar chart:
The two by far most common winning strategies are now Rules 14 and 26. Rule 26 is the strategy of always defecting. However, interestingly, Rule 14 involves defecting first and then always cooperating:
With this new list of possible rules, a new 2-D graph that functions identically to the last graph, but has more possible rules and has a bigger range of possible points to plot.
Redefine maxMainRule to test all new possible winning rules:
Using these new rules, the 3-D plot can be updated to show a wider range of fillable blocks and possible rules to check, creating a complete visualization on the effectiveness of each rule in 3-D space.
Conclusion
Conclusion
In this project, I simulated different varieties of two-choice games and observed what trends showed up from the data. The findings of this project show that even for games with payoffs chosen completely arbitrarily, there are still patterns that persist across all variations. In the context of game theory, the existence of trends despite simulated randomness hint towards even these very simple examples of two-choices games having core structural patterns invariant across game variations that lead to certain strategies having a general edge compared to other strategies. Many of these patterns also exist only under specific conditions, such as certain strategies only working well for a specific payoff order, showing how random distributions can still be organized into defined regions. All in all, the findings of this project demonstrate how structured patterns can naturally emerge in random contexts.
Future Direction
Future Direction
Currently, my code is generalized to work for many variations of games model-able with two-state FSMs. However, it has no functionality for more complex games or strategies that involve more than a fixed ruleset involving two sets. Thus, the biggest future additions to this project would be finding a way to increase the complexity of the rulesets. For example, instead of each FSM only having two states, one could create code that generates FSMs with three states. This could mean including a third option, or having functionality that requires looking at chains from older ancestors - for example, having a rule where a red move proceeded by a green move behave differently than a red move proceeded by a red move. Additionally, the strategies the programs run are not adaptive, which does not accurately reflect how people act in real life. To this end, I would likely try to add functionality to my rules that would periodically update each player’s rules based on pattern recognition.
I would also likely try to improve my methodology a little by incorporating the weight of the first turn into payoff calculations instead of looking solely at loops by instead calculating the average payoff based on a fixed turn limit. Additionally, I would spend more time going over the underlying basis for why each winning rule succeeds and where others fall short by more closely analyzing individual game scenarios.
I would also likely try to improve my methodology a little by incorporating the weight of the first turn into payoff calculations instead of looking solely at loops by instead calculating the average payoff based on a fixed turn limit. Additionally, I would spend more time going over the underlying basis for why each winning rule succeeds and where others fall short by more closely analyzing individual game scenarios.
References
References
Wolfram, S. (2026, June 4). Games Between Programs: The Ruliology of Competition.Stephen Wolfram Writings, https://writings.stephenwolfram.com/2026/06/games-between-programs-the-ruliology-of-competition/#the-space-of-all-possible-games.
Acknowledgements
Acknowledgements
I want to first thank my mentor Peter Barendse for all his help in guiding me in my project, both with brainstorming ideas for how to proceed when I got stuck and in helping with any questions I had about code. I also want to thank Daniel Sanchez for coding help and Arnay Garhyan for inspiration in how to get my 3-D Graphics working. I would also like to express special thanks to Stephen Wolfram for pioneering the technology to make such projects possible, the entire team at Wolfram for creating such a wonderful youth research experience, and Math Kangaroo for reaching out to me about this incredible opportunity.
Additional thanks to Stephen Wolfram for suggesting this project.
Additional thanks to Stephen Wolfram for suggesting this project.
CITE THIS NOTEBOOK
CITE THIS NOTEBOOK
Exploring the effects of payoffs on games between programs
by William Xiao
Wolfram Community, STAFF PICKS, July 9, 2026
https://community.wolfram.com/groups/-/m/t/3753754
by William Xiao
Wolfram Community, STAFF PICKS, July 9, 2026
https://community.wolfram.com/groups/-/m/t/3753754