Tit for Tat
logo
Article written by: Emanuele CassaniHome pubblicazioni  

Explanations of Single Turnament Results
Tit for Tat Evolution Strategies Simulator

How to configure the strategies

To configure the strategies, it is necessary to modify the file participants.js that is given with all the other file in the .zIP archive at the page download.
In that file it is possible to configure:
1. number of participant to the turnament
2. number of rounds per game
3. game strategies of the participants

Open the file with a text editor (Notepad o similar), and you will find immediately the first two parameters:

tot=7; // number of participants
cicli=20; // number of round per game

to add or remove participants, just modify the first number (default is 7).
to rise the number of round per game, just increase the second number (default is 20), but pay attention and avoid to stress too mutch your PC.

Let see in details the first turnament participant:

spiega[1]="this strategy will cooperate if the other did not defect";
nome[1] = "Tit for Tat";
DNA[1] = "AAATTTAG";

All the parameters between "quotation marks" are modificable.
The variable: spiega is the explanation that will appear in the recap tables in the turnament, nome is the name of the strategy, the DNA give the data about the characteristics.

The variable DNA (DeoxyriboNucleic Acid), is inspired to the real DNA and the following letters are used:
A = adenine
T = thymine (only for DNA)
U = uracil (only for RNA)
C = cytosine
G = guanine
that usually identify the nucleoids, to indicate the possible states.

First three characters of the DNA

We are using as an example the first strategy: Tit for Tat.

The first character indicates the color in the table (AAATTTAG)
A = green these are very good strategies
T = red these are very bad strategies
C = yellow these are normally good strategies, but not always
G = orange normally bad strategies, but not always
It is possible to configure the colours whitout considering the above indications.

The second character is used only for the generations turnaments (AAATTTAG)
In order to recognize it immediately, the character U is used (normally present in the RNA) this indicates that the strategy is a mutant of one of the estinguish standard, any other character (A,T,C,G) means this is an original strategy defined by us in this file. Not used for the single turnament.

The third character indicates the first round (AAATTTAG)
A= cooperates, the strategy starts the game by cooperating
T= cooperates, the strategy always starts the game by cooperating
C= defect, the strategy always starts the game by defecting
G= random, the strategy always starts in a random way

Second three character of the DNA

The gropu from the forth to sixth character, indicates the strategyto follow durng the game (AAATTTAG)
Each strategy correspond to one participant, and is configurable just below the lines we have seen:

function tit_for_tat ()
{
// gene TTT

if (attenzione=="A"){
if (giocoB1==0){giocoA=0}
else {giocoA=1}
}
else {
if (giocoA1==0){giocoB=0}
else {giocoB=1}
}
}

We now can see in detail how the Java script works, but is is easy:
This function is the same part of the program activated if the strategy plays a game as A or B participant (A=1 versus B=2 or A=5 versus B=1).
The variable called attenzione is activated in the case Tit for Tat is the A participant by stating: If Tit for tat is participant A then perform all the commands inside this curly brackets:

if (attenzione=="A"){

else perform all the commands inside this other brackets

else {

If Tit for Tat is the A player, we find another condition:

if (giocoB1==0){giocoA=0}
else {giocoA=1}

gioco B1 is the variable that contains the previous play of the opponent, 0 (giocoB1==0) means that the opponent defected, so for this round contained in the variable giocoA, Tit for Tat will play 0 defecting as well {giocoA=0}.
for all the other cases else the opponent did not defect (so the strategy cooperated by playing 1) and Tit for Tat than plays also 1 to cooperate {giocoA=1}.
Also other strategies are set using the conditional if, and works in a similar way.

Third three character of the DNA

The group from the seventh to the ninth character, is avaialable and you can use it as needed (AAATTTAG) - last character is not indicated
For example, it could indicate if the strategy has an inclination to betray, or how how many rounds before your strategy will betray, or also can be used for a form of prejudice, by checking the color of the opponent (red at the beginning indicates a bed strategy), it could use a good or bed strategy.
At the moment this group is not used.

How the script works

The real program is in the file turnament.js given with all the other files in the .ZIP archive available at the download page.
In the file it is possible to configure:
1. The DNA corrispondence with the colors and game strategies

The first problem to write this program, was to prepare a function that was able to make the participant to fight against themself and all the others, setted in a way that it will be easy to add or remove participants without the need to change the function.

This is the solution found:

function torneo ()
{
for (numero=1; numero<=tot;numero++) {punti[numero]=0};
puntiA=0;puntiB=0;

var giocoA=new Array(5);
giocoA5=3;giocoB5=3;giocoA4=3;giocoB4=3;giocoA3=3;
giocoB3=3;giocoA2=3;giocoB2=3;giocoA1=3;giocoB1=3;

for (x = 1; x <= tot; x++) {
partita=partita+1;
scontro(a=x,b=x);
punti[x]=punti[x]+puntiA+puntiB
puntiA=0;puntiB=0;

for (i = 1; i < tot+1; i++) {
if (x<=tot-i) {
partita=partita+1;
scontro(a=x,b=x+i)

punti[x]=punti[x]+puntiA;
punti[x+i]=punti[x+i]+puntiB;
puntiA=0;puntiB=0;
}
}
}
}

The variables giocoA from 1 to 5 and giocoB from 1 to 5 rappresents the memory of the last 5 rounds, so the participants could use them to plan their strategy.

The cycle:
for (x = 1; x <= tot; x++)
is repeted from 1 to the total number of participants, inside it contains the other cycle:
for (i = 1; i < tot+1; i++)
So at the first passage, when x will be equal to 1 we will have:
scontro(a=x,b=x);
We will see the function scontro (fight) later on, for now it is enough to understand that the game will be between the participants called A and B, and because x now is = 1 we will have:
a=1 versus b=1 (the strategy number 1 versus itself)
going on, we will find the secong cycle:
for (i = 1; i < tot+1; i++)
were i assumes the value from 1 to the number of participants, at the first round we will have x=1 and i=1 so:
scontro(a=x,b=x+i)
means a=1 versus b=2
i continues to increment, so we will have all the combinations of fights that involves strategy number 1:
a=1 versus b=3, a=1 versus b=4 etc.
at the end of the cycle, x is incremented and everything restarts with x=2 but before:
a=2 versus b=2 (the strategy number 2 versus itself)
and then, entering in the i cycle:
scontro(a=x,b=x+i)
correpond to a=2 versus b=3
i continues to increment so we will have all the combinations of fights for strategy number 2 exept 2 versus 1 that was cover when x was equal to 1:
In this way, everybody fight against everybody.

After each game, the points of each strategy are incremented in this way:
punti[x]=punti[x]+puntiA;
punti[x+i]=punti[x+i]+puntiB;

and we reset the points for the next game:
puntiA=0;puntiB=0;

The function for the fight

function scontro (a,b)
{
document.write("<b>A ="+a+" versus B = "+b+"<\/b><br>");

apertura ();
punteggio ();

for (xx = 2; xx <= cicli; xx++) {
strategia ();
punteggio ();
}
}

With:
document.write(
are displayed the fight participants, the opening play starts and the points for the first round are calculated.
Next, for the round that goes from 2 to cicli (the number of rounds per game) the game is carried on until the end.

This is the function for the first play of each game, called during the fight expleined above:

function apertura ()
{
giocoA=DNA[a].substr(2,1);
switch (giocoA)
{case "A": giocoA=1;
break
case "T": giocoA=1;
break
case "C": giocoA=0;
break
case "G": giocoA=Math.floor(Math.random()*2);
break
default: document.write("<br>* Error g3 on DNA of "+[a]+" * ");
}

giocoB=DNA[b].substr(2,1); // extract the 3rd character
switch (giocoB)
{case "A": giocoB=1;
break
case "T": giocoB=1;
break
case "C": giocoB=0;
break
case "G": giocoB=Math.floor(Math.random()*2);
break
default: document.write("<br>* Error g3 on DNA of "+[b]+" * ");
}
}

The first play, depends on the DNA third character of the participant. The row:

giocoB=DNA[a].substr(2,1);

With the number 2 we extract 1 character starting from the third position, starting to count from zero.

The extracted character will detrmine the play in this way:
If the character is A the variable giocoA became 1, this correspond to the play: cooperate
If the character is T, giocoA will be 1 again
If the character is C,giocoA will be 0 and the first play will be defect
If the character is G the strategy will play ramdomly between 1 and 0, extracted from the following line:

Math.floor(Math.random()*2);

The same method will be applied for participant B

After the opening play, for the following rounds the specific strategy indicated in the DNA of each participant will be adopted

function strategia ()
{

giocoA5=giocoA4;giocoB5=giocoB4;
giocoA4=giocoA3;giocoB4=giocoB3;
giocoA3=giocoA2;giocoB3=giocoB2;
giocoA2=giocoA1;giocoB2=giocoB1;
giocoA1=giocoA;giocoB1=giocoB;

strategia[a]=DNA[a].substr(3,3);
attenzione="A";
switch (strategia[a])
{case "TTT": tit_for_tat ();
break
case "TTG": tit_for_2tat ();
break
case "AAG": collabora_sempre ();
break
case "AAA": defeziona_sempre ();
break
case "TTA": tit_for_tat_TRD ();
break
case "TTC": tit_for_tat_RIM ();
break
case "AAC": casuale_sempre ();
break
default: document.write("<br><b>* Error 4,5,6 on DNA of "+[a]+" *<\/b> ");
}

strategia[b]=DNA[b].substr(3,3);
attenzione="B";
switch (strategia[b])
{ case "TTT": tit_for_tat ();
break
case "TTG": tit_for_2tat ();
break
case "AAG": collabora_sempre ();
break
case "AAA": defeziona_sempre ();
break
case "TTA": tit_for_tat_TRD ();
break
case "TTC": tit_for_tat_RIM ();
break
case "AAC": casuale_sempre ();
break
default: document.write("<br><b>* Error 4,5,6 on DNA of "+[b]+" *<\/b>");
}
}

At the begin the memory of the previous play is filled, bacause it was resetted.
Then using a similar method of the opening play, the three character of the DNA indicating the strategy are extracted. they can be:

TTT for the strategy callef from the function tit_for_tat ();
TTG for tit_for_2tat ();
AAG for collabora_sempre ();
AAA for defeziona_sempre ();
TTA for tit_for_tat_TRD ();
TTC for tit_for_tat_RIM ();
AAC for casuale_sempre ();

If the DNA does not match, on the screen there is a message indicating the line with the error:

document.write("<br><b>* Error 4,5,6 on DNA of "+[b]+" *<\/b>")

At the end, the function that determines the score:

function punteggio ()
{
if (giocoA=="1" && giocoB=="0") {puntiB=puntiB+5};
if (giocoA=="0" && giocoB=="1") {puntiA=puntiA+5};
if (giocoA=="1" && giocoB=="1") {puntiA=puntiA+3;puntiB=puntiB+3};
if (giocoA=="0" && giocoB=="0") {puntiA=puntiA+1;puntiB=puntiB+1};
document.write(" A plays="+giocoA+" B gioca="+giocoB+" --> Points A ="+puntiA+" Points B = "+puntiB+"<br>")
}

As the table indicates, the points are given depending on what the opponents play, and the result is displayed.

Back to this article index

Go to the Generation Turnaments