[from now] 2012/05/29 07:52:39

diff --git a/README.md b/README.md
index 17a8878..81965e2 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
 lesswrong-dilemma
 =================

-An Iterated Prisoner's Dilemma simulator and Tournament manager.
+An Iterated Prisoner's Dilemma simulator and Tournament manager.

-TODO:
+TODO:
 Make a proper main.coffee.
-	- Botlist
+	- Population
 	- Analytics
-Make info a thing.
-Make some more bots.
\ No newline at end of file
+
+Make some more bots - TFT-Dn, TFT-DnC, CRD.
\ No newline at end of file
diff --git a/bots.coffee b/bots.coffee
index 56016cb..edf13ef 100644
--- a/bots.coffee
+++ b/bots.coffee
@@ -3,7 +3,6 @@ root = exports ? window
 class root.Bot

   constructor: (@name) ->
-    @results = []

   move: (info) =>
     ###
@@ -12,13 +11,17 @@ class root.Bot

     info is an object with some useful info for your bot.
     info.last_turn gives you an array of your move, their move
-    e.g. ['c', 'd'].
+    e.g. ['c', 'd']. it is undefined if this is the first turn.
     info.turn gives you the current turn as an integer
     e.g. 5
+    note that turn starts at 1.
+    info.game_length gives you the length of the game as an integer
+    e.g. 100
+    note that the game ends after the turn counter hits this number, so that info.turn == 100 means the last turn in this case.
     info.current_scores gives you an array of your score, their score
-    e.g. [51, 30]
-    info.payoffs gives you a dictionary of the payoff structure
-    e.g. {'d_c': 5, 'c_c': 3, 'd_d': 1, 'c_d': 0}
+    e.g. [51, 30]. it is undefined if this is the first turn.
+    info.payoffs gives you an array of arrays of the payoff structure
+    e.g. [ ['d_c', 5], ['c_c', 3], ['d_d', 1], ['c_d', 0] ]

     your bot should shadow the move method, taking the info argument.

@@ -39,9 +42,36 @@ class root.CooperateBot extends root.Bot
   constructor: ->
     super 'CooperateBot'

-  move: =>
+  move: (info) =>
     'c'

+class root.TitForTat extends root.Bot
+
+  constructor: ->
+    super 'TitForTat'
+
+  move: (info) =>
+
+    if info.turn == 1 then 'c' else info.last_turn[1]
+
+
+class root.Random extends root.Bot
+
+  constructor: ->
+    super 'Random'
+
+  move: (info) =>
+    if Math.random() > 0.5 then 'c' else 'd'
+

+class root.GrimTrigger extends root.Bot
+
+  constructor: ->
+    @trigger = false
+    super 'GrimTrigger'

+  move: (info) =>
+    if info.last_turn[1] == 'd' then @trigger = true
+    if @trigger then 'd' else 'c'
+

\ No newline at end of file
diff --git a/game.coffee b/game.coffee
index 02a98d2..456a3f0 100644
--- a/game.coffee
+++ b/game.coffee
@@ -3,30 +3,46 @@ root = exports ? window

 class root.Game

-  constructor: (@length = 100, @payoffs, @player_one, @player_two) ->
+  constructor: (@length, @payoffs, @player_one, @player_two) ->
+    @player_one_results = []
+    @player_two_results = []
     @history = {}
-    @turn = 0
+    @turn = 1

   record: (one_move, two_move) =>
-    [p1name, p2name] = [@player_one.name, @player_two.name]
-    @history[@turn] = {p1name: one_move, p2name: two_move}
+    @history[@turn] = [[@player_one.name, one_move], [@player_two.name, two_move]]
+
+
+  info: (player) =>
+    if @turn == 1
+      new root.Info [], @turn, @length, [], ([key, value] for key, value of @payoffs)
+    else
+      turn = @turn
+      last_turn = [@history[(@turn - 1)][0][1], @history[(@turn - 1)][1][1]]
+      game_length = @length
+      current_scores = (arr[1] for arr in @results())
+      payoffs = ([key, value] for key, value of @payoffs)
+      switch player
+        when 1
+          return new root.Info last_turn, turn, game_length, current_scores, payoffs
+        when 2
+          return new root.Info last_turn.reverse(), turn, game_length, current_scores.reverse(), payoffs
+

   tick: =>
-    info = 1
-    [p1m, p2m] = [@player_one.move(info), @player_two.move(info)]
+    [p1m, p2m] = [@player_one.move(@info 1), @player_two.move(@info 2)]
     @record p1m, p2m
     [p1v, p2v] = @value p1m, p2m
-    @player_one.results.push p1v
-    @player_two.results.push p2v
+    @player_one_results.push p1v
+    @player_two_results.push p2v
     @turn++

   results: ->
-    one = @player_one.results.reduce (t, s) -> t + s
-    two = @player_two.results.reduce (t, s) -> t + s
+    one = @player_one_results.reduce (t, s) -> t + s
+    two = @player_two_results.reduce (t, s) -> t + s
     one_name = "#{@player_one.name}"
     two_name = "#{@player_two.name}"
-    obj = [[one_name, one], [two_name, two]]
-    return obj
+    return [[one_name, one], [two_name, two]]

   value: (p1m, p2m) =>
     switch p1m
@@ -47,17 +63,18 @@ class root.Game
       else null

   play: =>
-    while @turn < @length
+    while @turn <= @length
       @tick()
     @results()

 class root.Payoffs
-
   constructor: (@d_c, @c_c, @d_d, @c_d) ->
-    # yay

+class root.Info
+  constructor: (@last_turn, @turn, @game_length, @current_scores, @payoffs) ->
+

\ No newline at end of file
diff --git a/main.coffee b/main.coffee
index b1b7882..7b1498c 100644
--- a/main.coffee
+++ b/main.coffee
@@ -1,28 +1,65 @@
 g = require './game'
 b = require './bots'

-PAYOFF = new g.Payoffs 5, 3, 1, 0
+
+###
+    options:
+###
+round_robin = true
+natural_selection = false
+LENGTH = 100
+
+
+
+
+
 ###
     set your payoff structure here.
+###
+PAYOFF = new g.Payoffs 5, 3, 1, 0
+###
     you need to provide:
       the value of defecting against a cooperator
       the value of cooperating with a cooperator
       the value of defecting against a defector
-      the value of cooperating against a defector
-    and these should be in decreasing order.
-    that is, new Payoffs(a, b, c, d) should satisfy:
+      the value of cooperating against a defector.
+    also note that `new Payoffs(a, b, c, d)` should satisfy:
       a > b > c > d
+      b * 2 > a + d
     otherwise, the interesting things that are true about the iterated prisoner's dilemma aren't true of tournaments using this structure.
 ###

-test: ->
-  player_one = new b.CooperateBot
-  player_two = new b.DefectBot

-  tournament = new g.Game 100, PAYOFF, player_one, player_two
-  console.log tournament
+###
+    the round robin tournament
+###
+if round_robin
+  botlist = [b.TitForTat, b.Random, b.GrimTrigger, b.DefectBot, b.CooperateBot]
+  records = []
+  for bot_one in botlist
+    for bot_two in botlist
+      player_one = new bot_one
+      player_two = new bot_two
+      tournament = new g.Game LENGTH, PAYOFF, player_one, player_two
+      records.push tournament.play()
+
+  dict =
+    'TitForTat': 0
+    'Random': 0
+    'GrimTrigger': 0
+    'DefectBot': 0
+    'CooperateBot': 0
+
+  for record in records
+    for contestant in record
+      dict[contestant[0]] += contestant[1]
+
+  console.log dict
+
+
+
+

-  console.log tournament.play()