The Prisoner's Dilemma Applet: Frequently Asked Questions

 

"Do the cells only do whatever seems immediately most to their advantage (with a memory of the previous turn), or do they employ strategies to encourage behaviour in their neighbours which is the most likely to give satisfactory results (like TFT or Gradual)?"

There is no such strategy involved. The behaviour of each individual cell is determined by its direct neighbours in each round. Note that every cell has 8 neighbours because the boundaries have been 'wrapped around' so the first row and the first column are bounded by the last in the 60*60 matrix. This is accomplished by the boundary array bc (n=60):

      int[] setBoundary(int n)                        
      {  int bc[] = new int[n+2];                            
         for (int i=1; i<=n; i++)                            
         { bc[i]=i;                                          
         }                                                   
         bc[0]=n;                                            
         bc[n+1]=1;                                          
         return bc;                                          
      }

First the strategies (1 or 2) are determined randomly (using the p value from the input box) and stored in s (for all cells):

      int[][] generate(int n, double p)                       
      {  int s[][] = new int[n+1][n+1];                      
         for (int i=1; i<=n; i++)                            
         {                                                   
            for (int j=1; j<=n; j++)                         
            {                                                
               s[i][j] = 1;                                  
               if (Math.random()<p) s[i][j] = 2;             
            }                                                
         }                                                   
         return s;                                              
      }                                                                

Here is the payoff matrix:

         pm[1][1]=1;                                                                            
         pm[1][2]=0;                                                                            
         pm[2][1]=b;                                                                            
         pm[2][2]=0;   

During each round the payoff is calculated for each individual cell (as a function of s and pm of course):

      void calculate()
      {  int i,j,k,l;                                                                         
         double pa,hp;                                                                             
         for (i=1; i<=n; i++)                                                                     
         {  for (j=1; j<=n; j++)                                                                  
            {  pa=0;                                                                              
               for (k=-1; k<=1; k++)                                                              
               {  for (l=-1; l<=1; l++)                                                           
                  {  pa += pm[s[i][j]][s[bc[i+k]][bc[j+l]]];                                      
                  }                                                                               
               }                                                                                  
               payoff[i][j] = pa;                                                                 
            }                                                                                     
         }                     

Finally the new strategy sn is determined by the highest payoff hp:

         for (i=1; i<=n; i++)                                                                     

         {  
            for (j=1; j<=n; j++)                                                                  
            {  hp = payoff[i][j];                                                                 
               sn[i][j] = s[i][j];                                                                 
               for (k=-1; k<=1; k++)                                                              
               {  
                  for (l=-1; l<=1; l++)                                                           
                  {  
                     if (payoff[bc[i+k]][bc[j+l]] > hp)                                           
                     {  hp = payoff[bc[i+k]][bc[j+l]];                                            
                        sn[i][j] = s[bc[i+k]][bc[j+l]];                                                
                     }                                                                            
                  }                                                                               
               }                                                                                  
            }                                                                                     
         }                                                                                        
      }

 

"What is 'delay'?"

The delay just introduces a 'sleep', like this:

               try {Thread.sleep(ap.delay);} 
               catch(InterruptedException e){}

'Delay' can be increased if the applet runs too fast - f.i. some Java VM implementations cannot handle the multithreading used in this applet if the main thread isn't suspended by a certain delay (say 50 or 100 in the old Linux 'green thread' implementation).

 

1)"I encountered a 'walking figure' with certain settings but i forgot to jot them down. have you encountered this same phenomenon? If so, do you have the settings?"
2)"There's a marked bias for the lower-right corner -- when B=1.5, the result is a sort of streaming pattern falling downward at 135° (with 12:00 being 0°, 135°~4:30 position), these streams never go in any other direction. With B=2, there's a very distinct show of bias where the resulting blocks of Red stream oscillating kite-tails to along the bottom left, bottom right, and upper right corners -- again, they all point in the 4:30 direction."

It has to do with undecidability: a decision is forced. The following pattern starts falling downward at 135° when b=1.5:

CCCCCCCCC
CCCCCCCCC
CCCCCCCCC
CCCDDCCCC
CCCCDDCCC
CCCCCCCCC
CCCCCCCCC
CCCCCCCCC

These are the payoffs:

9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  8.0  7.0* 7.0  8.0  9.0  9.0  9.0  
9.0  9.0  8.0  9.0  7.5  6.0  8.0  9.0  9.0  
9.0  9.0  8.0  6.0  7.5  9.0  8.0  9.0  9.0  
9.0  9.0  9.0  8.0  7.0  7.0# 8.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  

For both cells marked '*' and '#' the highest payoff is 9.0. Note that the evaluation starts in the upper left corner and ends in the lower right (135°):

        for (i=1; i<n; i++)                                                                     
         {  
            for (j=1; j<n; j++)                                                                  
            {  hp = payoff[i][j];                                                                 
               sn[i][j] = s[i][j];                                                                 
               for (k=-1; k<1; k++)                                                              
               {  
                  for (l=-1; l<1; l++)                                                           
                  {  
                     if (payoff[bc[i+k]][bc[j+l]] > hp)                                           
                     {  hp = payoff[bc[i+k]][bc[j+l]];                                            
                        sn[i][j] = s[bc[i+k]][bc[j+l]];                                                
                     }                                                                            
                  }                                                                               
               }                                                                                  
            }                                                                                     
         }                                                                                        

So if the 9.0 is encountered first, for '*' this is a cooperator's payoff while for '#' it is a defector's payoff:

9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0 C9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  8.0  7.0* 7.0  8.0  9.0  9.0  9.0  
9.0  9.0  8.0  9.0  7.5  6.0  8.0  9.0  9.0  
9.0  9.0  8.0  6.0  7.5 D9.0  8.0  9.0  9.0  
9.0  9.0  9.0  8.0  7.0  7.0# 8.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  

The highest payoff (hp) will be overruled only if a higher payoff ( > 9.0 ) is encountered during the evaluation loop, which is obviously not being the case. The new payoffs will be:

9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  
9.0  9.0  8.0  7.0  7.0  8.0  9.0  9.0  9.0  
9.0  9.0  7.0  7.5  6.0  6.0  8.0  9.0  9.0  
9.0  9.0  7.0  6.0  3.0  4.5  6.0  8.0  9.0  
9.0  9.0  8.0  6.0  6.0  6.0  9.0  8.0  9.0  
9.0  9.0  9.0  8.0  7.0  6.0  7.0  8.0  9.0  
9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0  9.0 

As you can see, the pattern starts tumbling down.

 

Applet source code