summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Shangreaux <grant@unabridgedsoftware.com>2022-01-31 21:31:50 -0600
committerGrant Shangreaux <grant@unabridgedsoftware.com>2022-01-31 21:31:50 -0600
commit89d1ee2973ff2c65ff72c09efa8f99225037e8f8 (patch)
tree15ffafe5d44f84e3829cec981620f4698b81d207
parent6dc6517af29e9b942b74a3b0216d1473324293c8 (diff)
Fix: endless game loop
-rw-r--r--mafia.org40
1 files 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