From 89d1ee2973ff2c65ff72c09efa8f99225037e8f8 Mon Sep 17 00:00:00 2001 From: Grant Shangreaux Date: Mon, 31 Jan 2022 21:31:50 -0600 Subject: Fix: endless game loop --- mafia.org | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/mafia.org b/mafia.org index 263a044..1c6051e 100644 --- a/mafia.org +++ b/mafia.org @@ -115,6 +115,9 @@ use inheritance here to set apart the killer with its own ~:initform~. :initarg :target :documentation "Actor currently being observed." :accessor mafia-actor-target) + (status + :initform 'alive + :documentation "'alive, 'dying, or 'dead") (notes :initform '() :documentation "An alist containing pairs of (actor-id . target-id)")) @@ -125,10 +128,9 @@ use inheritance here to set apart the killer with its own ~:initform~. "Actor subclass to represent the killer.") (defclass mafia-innocent (mafia-actor) - ((status :initform 'alive - :documentation "'alive, 'dying, or 'dead") - (death-countdown :initform (1+ (random 10)) - :documentation "The number of ticks to go from dying to dead"))) + ((death-countdown + :initform (1+ (random 10)) + :documentation "The number of ticks to go from dying to dead"))) #+end_src Then the function ~mafia-initial-actors~ will handle initializing N actors @@ -239,6 +241,21 @@ later on it will be "fuzzy." (setf notes (cons `(,id . ,(mafia-actor-id their-target)) notes))))))) #+end_src +For now, we just need to give the innocents random chance to target a +new person. Otherwise, the sim will go into an endless loop as the killer +will never make eye contact. + +#+name: observe-innocent +#+begin_src emacs-lisp + (cl-defmethod mafia-observe ((actor mafia-innocent)) + (when (> 5 (random 11)) + (with-slots (id target) actor + (let ((new-target (mafia-random-other actor (slot-value mafia-active-game 'actors)))) + (mafia-log "Innocent %d observes %d and sees they are %s" id (mafia-actor-id new-target) (slot-value new-target 'status)) + (setf target new-target)))) + (cl-call-next-method)) +#+end_src + We may not have to specialize the other actors, but while the killer is observing, they will decide whether or not to wink. But first we'll need a method to determine eye-contact and one for the killer to determine if @@ -290,14 +307,13 @@ If they're being watched, simply have them target a random other actor (?) "Specialized behavior for the `mafia-killer'." (with-slots (target) killer (if (mafia-being-watched? killer) - (let ((new-target (mafia-random-other killer (slot-value mafia-active-game 'actors)))) + (let ((new-target (mafia-random-other killer (mafia-living-innocents mafia-active-game)))) (mafia-log "the killer targets %d" (mafia-actor-id new-target)) (setf target new-target)) (if (mafia-eye-contact? killer target) (progn (mafia-log "the killer winks at %d." (mafia-actor-id target)) - (mafia-innocent-die target)) - (mafia-log "the killer abides"))) + (mafia-innocent-die target)))) (cl-call-next-method killer))) #+end_src @@ -409,9 +425,9 @@ watched by someone else. ??? :END: #+begin_src emacs-lisp - (cl-defmethod mafia-alive-p ((obj mafia-innocent)) + (defun mafia-alive-p (actor) "Returns `t' if the actor is alive, otherwise `nil'" - (eql (slot-value obj 'status) 'alive)) + (eql (slot-value actor 'status) 'alive)) #+end_src *** Dying Actors @@ -425,9 +441,9 @@ to the game rules, we should start some "timer" so that it will count down its ~death-countown~, but I'm not quite prepared for that at this moment. #+begin_src emacs-lisp - (cl-defmethod mafia-innocent-die ((obj mafia-innocent)) - (with-slots (id status) obj - (print (format "Innocent %s has been killed!" id)) + (defun mafia-innocent-die (actor) + (with-slots (id status) actor + (mafia-log "Innocent %s has been killed!" id) (setf status 'dead))) #+end_src -- cgit v1.2.3