Skip to content

Commit

Permalink
added the ultimatum game and roshambo
Browse files Browse the repository at this point in the history
  • Loading branch information
vii committed Sep 29, 2009
1 parent 259b84e commit b80797a
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 4 deletions.
21 changes: 18 additions & 3 deletions src/game/web.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@
(declare (ignore game-state))
(my add-announcement (<p :class "game-message" (player-controller-name-to-ml (player-controller (getf args :player))) " played " (output-object-to-ml (make-card-from-number (getf args :choice))) ".")))

(my-defun web-state 'inform (game-state (message (eql :select-demand)) &key player choice &allow-other-keys)
(declare (ignore game-state))
(my add-announcement (<p :class "game-message" (player-controller-name-to-ml (player-controller player)) " demanded " choice ".")))

(my-defun web-state 'inform (game-state (message (eql :select)) &key player selection &allow-other-keys)
(declare (ignore game-state))
(my add-announcement (<p :class "game-message" (player-controller-name-to-ml (player-controller player)) " chose " (friendly-string selection) ".")))

(my-defun web-state 'inform (game-state (message (eql :reject-cards)) &rest args)
(declare (ignore game-state))
(my add-announcement (<p :class "game-message" (player-controller-name-to-ml (player-controller (getf args :player)))
Expand Down Expand Up @@ -187,6 +195,13 @@
(defun keyword-to-friendly-string (keyword)
(string-capitalize (string-downcase (match-replace-all (force-string keyword) ("-" " "))) :end 1))

(defun friendly-string (object)
(typecase object
(symbol
(keyword-to-friendly-string object))
(t
object)))

(my-defun move-state 'object-to-ml ()
(<div :class "move-state"
(let ((friendly-move-type (keyword-to-friendly-string (my move-type))))
Expand All @@ -209,17 +224,17 @@
(with-ml-output " from " (reduce #'min (choices-list (my choices))) " to "
(reduce #'max (choices-list (my choices))) ". "))
(t
(with-ml-output (format nil " ~{~A ~}" (my args)) " from " (format nil "~A" (my choices) ))))
(with-ml-output (format nil " ~{~A ~}" (my args)) " from ")))

(loop for c in (choices-list (my choices)) do
(let-current-values (c)
(with-ml-output " "
(html-action-link c
(html-action-link (friendly-string c)
(my queue-choice c)))))

(html-action-form
""
((choice (first (choices-list (my choices)))))
(choice)
(my queue-choice (read-safely-from-string choice))
(values))))))))

Expand Down
8 changes: 8 additions & 0 deletions src/packages.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,14 @@
(:use #:tpd2.game #:tpd2.ml #:tpd2.lib #:teepeedee2.webapp #:common-lisp #:tpd2.ml.html)
(:export #:nash-bargain))

(defpackage #:teepeedee2.game.ultimatum
(:nicknames #:tpd2.game.ultimatum)
(:use #:tpd2.game #:tpd2.ml #:tpd2.lib #:teepeedee2.webapp #:common-lisp #:tpd2.ml.html))

(defpackage #:teepeedee2.game.roshambo
(:nicknames #:tpd2.game.roshambo)
(:use #:tpd2.game #:tpd2.ml #:tpd2.lib #:teepeedee2.webapp #:common-lisp #:tpd2.ml.html))

(defpackage #:teepeedee2.game.prisoners-dilemma
(:nicknames #:tpd2.game.prisoners-dilemma)
(:use #:tpd2.game #:tpd2.ml #:tpd2.lib #:teepeedee2.webapp #:common-lisp #:tpd2.ml.html #:tpd2.game.nash-bargain))
Expand Down
42 changes: 42 additions & 0 deletions src/small-games/roshambo.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
(in-package #:tpd2.game.roshambo)

(defvar *objects* '(rock paper scissors))

(defgame roshambo ()
()
(defplayer ()
(choice))
(:game-name "Rock, Paper, Scissors")
(:game-description
(with-ml-output
"Two players simultaneously choose either rock, paper or scissors. Rock blunts scissors, scissors cut paper, and paper covers rock. Also called roshambo." (<br)
"Read more at "
(<a :href "http://en.wikipedia.org/wiki/Rock,_Paper,_Scissors" "Wikipedia") ".")))

(my-defun roshambo 'play ()
(with-game
(my new-state)
(with-join-spawn/cc ()
(loop for p in (my players)
do
(let-current-values (p)
(spawn/cc ()
(setf (its choice p) (my secret-move :select p `(:one ,@*objects*)))))))

(loop for p in (my players)
do (my announce :select :player p :selection (its choice p)))

(let ((winner
(without-call/cc
(flet ((v (c)
(position c *objects*)))
(loop for p in (my players)
for vp = (v (its choice p))
thereis (loop for q in (my players)
for vq = (v (its choice q))
thereis (when (= vp (mod (1+ vq) (length *objects*)))
p)))))))
(cond (winner
(my finished :winner winner))
(t
(my finished :result :draw))))))
47 changes: 47 additions & 0 deletions src/small-games/ultimatum.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
(in-package #:tpd2.game.ultimatum)

(defvar *max-pot* 20)
(defvar *min-pot* 1)
(defvar *max-penalty* 4)
(defvar *min-penalty* 0)

(defgame ultimatum (coin-game)
((pot (random-between *min-pot* *max-pot*))
(penalty (random-between *min-penalty* *max-penalty*)))
(defplayer ()
((demand 0)))
(:game-name "The Ultimatum Game")
(:game-description
(with-ml-output
"There is a pot of coins to be shared. The first player decides how to share them. The second player can accept the choice, and receive the allotment, or reject it, in which case the players will both be fined." (<br)
"Read more at "
(<a :href "http://en.wikipedia.org/wiki/Ultimatum_game" "Wikipedia") ".")))

(my-defun ultimatum 'play ()
(with-game
(my new-state)
(destructuring-bind (proposer acceptor)
(random-shuffle (my players))
(with-its-type (proposer ultimatum-player)
(with-its-type (acceptor ultimatum-player)

(let ((demand (my move :select-demand proposer `(:integer 0 ,(my pot)))))
(let ((ok (my move :cooperate acceptor :boolean)))
(cond (ok
(its give-coins proposer demand)
(its give-coins acceptor (- (my pot) demand))
(my finished :result :sharing))
(t
(its give-coins proposer (- (my penalty)))
(its give-coins acceptor (- (my penalty)))
(my finished :result :penalty))))))))))

(my-defun ultimatum 'object-to-ml ()
(flet ((coins (c) (format nil "~R coin~:P" c)))
(with-ml-output
(call-next-method)
(<h3 "Pot: " (my pot) ", penalty: " (my penalty) ".")
(<p "The first player demands some portion of " (coins (my pot)) ". The second player will get the rest, "
"but if he or she is unhappy with this division then both players lose " (coins (my penalty)) ". "))))


6 changes: 5 additions & 1 deletion teepeedee2.asd
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@
))
(:module :small-games
:depends-on (:game)
:components ((:file "nash-bargain") (:file "prisoners-dilemma")))
:components (
(:file "nash-bargain")
(:file "prisoners-dilemma")
(:file "ultimatum")
(:file "roshambo")))
(:module :blog
:depends-on (:webapp :ml :datastore)
:components ((:file "entry")
Expand Down

0 comments on commit b80797a

Please sign in to comment.