(defun main () (introduction) (catch 'end (main-loop))) (defun introduction () (format t "~32tHAMURABI~%~ ~15tCREATIVE COMPUTING MORRISTOWN, NEW JERSEY~%~%~%~%~ TRY YOUR HAND AT GOVERNING ANCIENT SUMERIA~%~ SUCCESSFULLY FOR A TEN-YEAR TERM OF OFFICE.~%~%")) (defun main-loop () (let* ((*random-state* (make-random-state t)) (total-deaths 0) (percent-deaths 0) (year 0) (population 95) (stored-bushels 2800) (harvest 3000) (eaten (- harvest stored-bushels)) (yield 3) (acres-of-land (/ harvest yield)) (immigrants 5) (plague-p nil) (deaths 0)) (loop (format t "~%~%HAMURABI: I BEG TO REPORT TO YOU,~%") (incf year) (format t "IN YEAR ~a, ~a PEOPLE STARVED, ~a CAME TO THE CITY.~%" year deaths immigrants) (incf population immigrants) (when plague-p (setf population (floor population 2)) (format t "A HORRIBLE PLAGUE STRUCK! HALF THE PEOPLE DIED.~%")) (format t "POPULATION IS NOW ~a~%" population) (format t "THE CITY NOW OWNS ~a ACRES.~%" acres-of-land) (format t "YOU HARVESTED ~a BUSHELS PER ACRE.~%" yield) (format t "RATS ATE ~a BUSHELS.~%" eaten) (format t "YOU NOW HAVE ~a BUSHELS IN STORE.~%~%" stored-bushels) (when (= year 11) (end-of-term percent-deaths total-deaths acres-of-land population)) (let ((price (+ (random 10) 17))) (format t "LAND IS TRADING AT ~a BUSHELS PER ACRE.~%" price) (ask-number "HOW MANY ACRES DO YOU WISH TO BUY" acres-to-buy (<= (* price acres-to-buy) stored-bushels) (not-enough-grain stored-bushels) (cond ((plusp acres-to-buy) (incf acres-of-land acres-to-buy) (decf stored-bushels (* price acres-to-buy))) ('otherwise (ask-number "HOW MANY ACRES DO YOU WISH TO SELL" acres-to-sell (< acres-to-sell acres-of-land) (not-enough-land acres-of-land) (decf acres-of-land acres-to-sell) (incf stored-bushels (* price acres-to-sell))))))) (ask-number "HOW MANY BUSHELS DO YOU WISH TO FEED YOUR PEOPLE" bushels-to-feed ;; TRYING TO USE MORE GRAIN THAN IN THE SILOS? (<= bushels-to-feed stored-bushels) (not-enough-grain stored-bushels) (decf stored-bushels bushels-to-feed) ;; A BOUNTYFULL HARVEST!! (setf yield (random1-5)) (setf harvest (cultivate acres-of-land stored-bushels population yield)) (setf eaten (let ((rats (random1-5))) (if (evenp rats) ; THE RATS ARE RUNNING WILD!! (floor stored-bushels rats) 0))) (incf stored-bushels (- harvest eaten)) (let ((growth (random1-5))) ;; LET'S HAVE SOME BABIES (setf immigrants (floor (1+ (/ (* growth (+ (* 20 acres-of-land) stored-bushels)) population 100))))) ;; HOW MANY PEOPLE HAD FULL TUMMIES? (let ((fed-people (floor bushels-to-feed 20))) ;; HORRORS, A 15% CHANCE OF PLAGUE (setf plague-p (< (random 2.0) .3)) (if (< population fed-people) (setf deaths 0) (progn ;; STARVE ENOUGH FOR IMPEACHMENT? (setf deaths (- population fed-people)) (when (> deaths (* .45 population)) (format t "~%YOU STARVED ~a PEOPLE IN ONE YEAR!!!~%" deaths) (impeachment)) (setf percent-deaths (/ (+ (* (1- year) percent-deaths) (/ (* deaths 100) population)) year)) (setf population fed-people) (incf total-deaths deaths)))))))) (defmacro ask-number (prompt var test error &body body) `(let (,var) (loop do (format t "~%~a? " ,prompt) (setf ,var (read)) (when (minusp ,var) (resignment)) until ,test do ,error) ,@body)) (defun cultivate (acres-of-land stored-bushels population yield) (ask-number "HOW MANY ACRES DO YOU WISH TO PLANT WITH SEED" acres-to-cultivate ;; TRYING TO PLANT MORE ACRES THAN YOU OWN? (<= acres-to-cultivate acres-of-land) (not-enough-land acres-of-land) (unless (zerop acres-to-cultivate) ;; ENOUGH GRAIN FOR SEED? (unless (< (floor acres-to-cultivate 2) stored-bushels) (not-enough-grain stored-bushels) (cultivate acres-of-land stored-bushels population yield)) ;; ENOUGH PEOPLE TO TEND THE CROPS? (unless (< acres-to-cultivate (* 10 population)) (format t "BUT YOU HAVE ONLY ~a PEOPLE TO TEND THE~ FIELDS. NOW THEN," population) (cultivate acres-of-land stored-bushels population yield)) (decf stored-bushels (floor acres-to-cultivate 2))) (* acres-to-cultivate yield))) (defun impeachment () (format t "DUE TO THIS EXTREME MISMANAGEMENT YOU HAVE NOT ONLY~%") (format t "BEEN IMPEACHED AND THROWN OUT OF OFFICE BUT YOU HAVE~%") (format t "ALSO BEEN DECLARED 'NATIONAL FINK' !!~%") (the-end)) (defun not-enough-grain (stored-bushels) (format t "HAMURABI: THINK AGAIN. YOU HAVE ONLY~%") (format t "~a BUSHELS OF GRAIN. NOW THEN," stored-bushels)) (defun not-enough-land (acres-of-land) (format t "HAMURABI: THINK AGAIN. YOU OWN ONLY ~a ACRES. NOW THEN," acres-of-land)) (defun random1-5 () (1+ (random 5))) (defun resignment () (format t "~%HAMURABI: I CANNOT DO WHAT YOU WISH.~%") (format t "GET YOURSELF ANOTHER STEWARD!!!!!~%") (the-end)) (defun end-of-term (percent-deaths total-deaths acres-of-land population) (format t "IN YOUR 10-YEAR TERM OF OFFICE, ~,1f PERCENT OF THE~%" percent-deaths) (format t "POPULATION STARVED PER YEAR ON AVERAGE, I.E., A TOTAL OF~%~ ~a PEOPLE DIED!!~%" total-deaths) (let ((land-per-person (/ acres-of-land population))) (format t "YOU STARTED WITH 10 ACRES PER PERSON AND ENDED WITH~%~ ~,1f ACRES PER PERSON.~%~%" land-per-person) (cond ((> percent-deaths 33) (impeachment)) ((< land-per-person 7) (impeachment)) ((> percent-deaths 10) (bad-review)) ((< land-per-person 9) (bad-review)) ((> percent-deaths 3) (mediocre-review population)) ((< land-per-person 10) (mediocre-review population)) ('otherwise (great-review)))) (the-end)) (defun great-review () (format t "A FANTASTIC PERFORMANCE!!! CHARLEMANGE, DISRAELI, AND~%~ JEFFERSON COMBINED COULD NOT HAVE DONE BETTER!~%")) (defun bad-review () (format t "YOUR HEAVY-HANDED PERFORMANCE SMACKS OF NERO AND IVAN IV.~%~ THE PEOPLE (REMAINING) FIND YOU AN UNPLEASANT RULER, AND,~%~ FRANKLY, HATE YOUR GUTS!~%")) (defun mediocre-review (population) (format t "YOUR PERFORMANCE COULD HAVE BEEN SOMEWHAT BETTER, BUT~%~ REALLY WASN'T TOO BAD AT ALL. ~a PEOPLE~%" (floor (* population .8 (random 1.0)))) (format t "DEARLY LIKE TO SEE YOU ASSASSINATED BUT WE ALL HAVE OUR~%~ TRIVIAL PROBLEMS.~%")) (defun the-end () (loop repeat 10 do (princ #\Bel)) (format t "~%SO LONG FOR NOW.~%~%") (throw 'end nil))