<?php function rack_block_shooter($opponents_last_move = NULL, $round = 0) { //returns TRUE for cooperate //FALSE for defect //in most loops, $i is the currently considered frequency of cooperation static $probs = array(); static $prev_strat; static $maybe_playing_self; if ($round == 0) { //setup probability arrays //first key is our previous move //second keys are frequency of opponent's coop $probs = array(); //reset probabilities for first round of a match $maybe_playing_self = TRUE; for ($i = 0.00; $i <= 1.00; $i += 0.01) { $probs[TRUE][(string)$i] = 1 / 101; $probs[FALSE][(string)$i] = 1 / 101; } $prev_strat = FALSE; //Start with Defection to make self-indent slightly easier, defection as sign of a good/nice strategy -- therefore prob. other LWers more likely to start with coop; Also immediately sorts out Tit-for-Tat } else { //update probs if ($maybe_playing_self) { if ($prev_strat != $opponents_last_move) { //are we playing against ourselves? $maybe_playing_self = FALSE; //Not if both sides don't make the same move } } $prob_see_coop = 0.00; for ($i = 0.00; $i <= 1.00; $i += 0.01) { //the probability we would see cooperation given our move $prob_see_coop += ($probs[$prev_strat][(string)$i] * $i); } for ($i = 0.00; $i <= 1.00; $i += 0.01) { if ($opponents_last_move) { //opp coop $probs[$prev_strat][(string)$i] = $i * $probs[$prev_strat][(string)$i]/$prob_see_coop; } else { //opp defect $probs[$prev_strat][(string)$i] = (1 - $i) * $probs[$prev_strat][(string)$i]/(1 - $prob_see_coop); } } //Now, decide what to do if ($round == 1) { //second round, do the opposite of whatever we did the first round $prev_strat = !$prev_strat; } else { //middle of play, choose move randomly proportional to expected payout //Begin by calc'ing the prob of coop again for both cooperation and defection $prob_see_coop = array(); $prob_see_coop[TRUE] = 0.00; //the probability we'll see coop if we coop $prob_see_coop[FALSE] = 0.00; //the probability we'll see coop if we defect for ($i = 0.00; $i <= 1.00; $i += 0.01) { $prob_see_coop[TRUE] += ($probs[TRUE][(string)$i] * $i); $prob_see_coop[FALSE] += ($probs[FALSE][(string)$i] * $i); } if ($maybe_playing_self) { $prev_strat = TRUE; } else { if ($round == 99) { //be slightly evil -- always defect on the last round if not playing against self $prev_strat = FALSE; } else { $expected_value = array(); $expected_value[TRUE] = 4 * $prob_see_coop[TRUE]; //+ 0 * (1 - $prob_see_coop[TRUE]); $expected_value[FALSE] = 7 * $prob_see_coop[FALSE] + 1 * (1 - $prob_see_coop[FALSE]); $total_exp = array_sum($expected_value); $prop_coop = ($expected_value[TRUE] - $expected_value[FALSE])/$total_exp; $choose_mixed = lcg_value(); //random in the range (0,1) -- differs from rand() as rand generates integers only if ($expected_value[FALSE] > 1.5 * $expected_value[TRUE]) { $prev_strat = FALSE; } elseif ($expected_value[TRUE] > 1.5 * $expected_value[FALSE]) { $prev_strat = TRUE; } else { if ($choose_mixed <= $prop_coop) { $prev_strat = TRUE; } else { $prev_strat = FALSE; } } } } } } return $prev_strat; }