the-feebs-war-cvs
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- 22 discussions
Author: gmilare
Date: Sat Aug 7 09:40:44 2010
New Revision: 21
Log:
Corrected mistakes in feebs.tex and enhanced printing of game (thanks to XIE Wensheng)
Modified:
documentation/feebs.tex
graphics/graphics.lisp
Modified: documentation/feebs.tex
==============================================================================
--- documentation/feebs.tex (original)
+++ documentation/feebs.tex Sat Aug 7 09:40:44 2010
@@ -18,7 +18,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
-% Copyright (c) 2007,2008 Gustavo Henrique Milar�
+% Copyright (c) 2007,2008 Gustavo Henrique Milar�
%
% This file is part of The Feebs War.
%
@@ -76,9 +76,9 @@
\begin{abstract}
\textit{The Feebs War} is a modified version of Planet of The Feebs \url{http://www.cliki.net/Planet\%20of\%20the\%20Feebs},
a game made for people learn and improve their lisp and code manipulation
-tecniques. The graphics are now displayed using Lispbuilder \url{http://lispbuilder.sourceforge.net}'s
+techniques. The graphics are now displayed using Lispbuilder \url{http://lispbuilder.sourceforge.net}'s
libraries, so the problems with portability from CMUCL and X Window
-Sistem do not exist anymore. Also the code is cleaner and more extensible.
+System do not exist anymore. Also the code is cleaner and more extensible.
\end{abstract}
\tableofcontents{}
@@ -87,8 +87,8 @@
The Feebs are intelligent and hostile creatures that live inside maze
tunnels. They also have no mercy with each other, so they frequently
-throw a letal flame from through their mouth, getting rid of their
-opponent and eatting the carcass left. But throwing flames have an
+throw a lethal flame from through their mouth, getting rid of their
+opponent and eating the carcass left. But throwing flames have an
energy cost, so they must keep tracking for food.
This game is intended to help lisp newbies (or maybe a little more
@@ -108,7 +108,7 @@
The main reason of this project is that \textit{Planet of the Feebs}
is really interesting for (not just) newbies to learn lisp, but the
-difficulties to install, unportability and the ausence of competitors
+difficulties to install, unportability and the absence of competitors
make it difficult to someone to be interested in making a feeb. So,
I hope that making these adjustments and maybe creating some contests
over the web make people be more interested in learning lisp.
@@ -116,13 +116,13 @@
So, these are (some of) the changes:
\begin{itemize}
-\item The graphics are not based on X Window Sistem anymore, but on \textit{Lispbuilder},
+\item The graphics are not based on X Window System anymore, but on \textit{Lispbuilder},
and there are no CMUCL's event handler. This way, the code is more
portable and graphics can be improved. Just creating some image files
of a feeb and your feeb is much more personalized!
\item Every element of the map (including walls) is a list, so the brain
of a feeb doesn't need to test all the time if the element is an atom
-or a list (wich, in my opinion, is really boring, unlispy and unnecessary
+or a list (which, in my opinion, is really boring, unlispy and unnecessary
in this case). That was only a reason to duplicate code and work,
adding no results at all...
\item Many functions and variables are changed and others were added
@@ -160,7 +160,7 @@
be a rational number (like 1/2).
But don't panic! These parameters are just for one to know how the
-game is going to be, but in the begining there is no need to explicitly
+game is going to be, but in the beginning there is no need to explicitly
use them when creating the brain of a feeb. The best way to create
a feeb is watching a game (among system feebs), improving it (it is
defined in file brains.lisp) a little more, testing the changes...
@@ -202,13 +202,13 @@
turns that a fireball is guaranteed not to dissipate, unless it encounters
a wall.
\item [{{\textsf{\textbf{'fireball-dissipation-probability}}}}] Probability
-of the flame to dissipate each turn after the apropriate time.
+of the flame to dissipate each turn after the appropriate time.
\item [{{\textsf{\textbf{'fireball-reflection-probability}}}}] Probability
of the flame to reflect when encountering a wall.
\item [{{\textsf{\textbf{'flame-no-recovery-time}}}}] Number of turns
that a feeb cannot fire.
\item [{{\textsf{\textbf{'flame-recovery-probability}}}}] Probability
-of the feeb to recover the hability to throw a flame, after the apropriate
+of the feeb to recover the ability to throw a flame, after the appropriate
time.
\end{lyxlist}
@@ -216,9 +216,9 @@
There are two kinds of food, carcasses and mushrooms. Carcasses usually
give less energy than mushrooms, and may rot, but, while it does not
-rot, a feeb can feed as long as it wishes. Mushrooms disapear after
+rot, a feeb can feed as long as it wishes. Mushrooms disappear after
being eaten. By eating food, the feeb will be able to recover energy,
-wich is important because, if a feeb stays with 0 or less units of
+which is important because, if a feeb stays with 0 or less units of
energy, it starves.
These are the quantities:
@@ -232,7 +232,7 @@
turns that a carcass will surely not rot. After these turns, it can
rot, depending on probabilities.
\item [{{\textsf{\textbf{'carcass-rot-probability}}}}] Probability of
-the carcass to rot, after the apropriate time.
+the carcass to rot, after the appropriate time.
\item [{{\textsf{\textbf{'maximum-energy}}}}] Maximum amount of energy
that a feeb can have eating.
\item [{{\textsf{\textbf{'starting-energy}}}}] Amount of energy a feeb
@@ -266,7 +266,7 @@
After processing the information available, the brain will take a
decision. If this decision is not one of the decisions listed down,
a warning will be signaled, and the result will be like \textsf{\textbf{:wait}}.
-Then, if someone are testing a brain function, he or she will be able
+Then, if someone is testing a brain function, he or she will be able
to know if something goes wrong.
The possible values that the brain function can return are these:
@@ -283,8 +283,8 @@
\item [{{\textsf{\textbf{:peek-left}}}}] Peek to the left around a corner.
The creature does note actually move, but, in the next turn, the creature
will have the same vision that it would have if he had moved one step
-foward and turned left (and one step back because the feeb needs to
-see what is actually in front of it). Peeking used so a feeb can analize
+forward and turned left (and one step back because the feeb needs to
+see what is actually in front of it). Peeking used so a feeb can analyze
a corridor before trespassing it.
\item [{{\textsf{\textbf{:peek-right}}}}] Peek to the right around a
corner, analogous to \textsf{\textbf{:peek-left}}.
@@ -326,7 +326,7 @@
\begin{flushleft}
Where the feeb is facing to, one of the constants provided: \textsf{\textbf{north}},
\textsf{\textbf{east}}, \textsf{\textbf{south}} or \textsf{\textbf{west}},
-wich are 0, 1, 2 and 3 respectivelly.
+which are 0, 1, 2 and 3 respectively.
\par\end{flushleft}
\item [{{\textsf{\textbf{(x-position}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
@@ -379,7 +379,7 @@
\begin{flushleft}
-Related with timing. Returns \textsf{\textbf{T}} if the last move
+Related to timing. Returns \textsf{\textbf{T}} if the last move
of feeb was aborted because of timing issues.
\par\end{flushleft}
@@ -398,7 +398,7 @@
The brain receives also information about what is near the feeb and
what the feeb sees. We note that, contrary to \emph{Planet of the
Feebs}, it is safe to change anything inside these structures, so
-you are alowed to keep them stored and to modify them as you wish.
+you are allowed to keep them stored and to modify them as you wish.
The structure \textsf{\emph{proximity}} has the contents of the squares
near the feeb (not affected by peeking) with these fields:
@@ -432,7 +432,7 @@
Contents of the square behind the feeb.
\par\end{flushleft}
-\item [{{The}}] vector \textsf{\emph{vision}} has the contents of the
+The vector \textsf{\emph{vision}} has the contents of the
squares that are in front of the feeb. For example, \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{0}\textsf{\textbf{)}}
will return the contents of the square in front of the feeb, \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{1}\textsf{\textbf{)}}
will return the contents of the next square, and so on. As said before,
@@ -465,14 +465,14 @@
can access. It is allowed to keep and change its contents because
they won't be used internally.
-These are the accessors available (they read and change the fiels):
+These are the accessors available (they read and change the flies):
\begin{lyxlist}{00.00.0000}
\item [{{\textsf{\textbf{(feeb-image-name}}\textsf{~feeb-image}\textsf{\textbf{)}}}}]~
\begin{flushleft}
-The name of the feeb. (Maybe you know it's weakpoints?)
+The name of the feeb. (Maybe you know it's weak points?)
\par\end{flushleft}
\item [{{\textsf{\textbf{(feeb-image-facing}}\textsf{~feeb-image}\textsf{\textbf{)}}}}]~
@@ -543,8 +543,8 @@
If you want to create a new map, you can start by an empty template
of any size that is provided by \textsf{\textbf{(make-template}}\textsf{~x-size~y-size}\textsf{\textbf{)}},
-or you can get a reandom map calling \textsf{\textbf{(generate-maze}}\textsf{~x-size~y-size~}\textsf{\textbf{:density}}\textsf{~density}\textsf{\textbf{)}}
-The density is a number, recomended to be between 0.25 and 0.45, which
+or you can get a random map calling \textsf{\textbf{(generate-maze}}\textsf{~x-size~y-size~}\textsf{\textbf{:density}}\textsf{~density}\textsf{\textbf{)}}
+The density is a number, recommended to be between 0.25 and 0.45, which
tells the portion of the maze should be blank spaces. The function
quits after a while if it doesn't meet this portion. See its documentation
for more details and options.
@@ -556,7 +556,7 @@
of a feeb when creating it, so your feeb will be more personalized.
The graphic of a feeb is defined by an image file, which should have
-three colunms by eight lines of pictures of the same size. The four
+three columns by eight lines of pictures of the same size. The four
first lines must be the animations of the feeb walking up, left, down
and right, respectively. The next four lines must be the pictures
of the feeb flaming up, left, down and right, respectively. To see
@@ -577,7 +577,7 @@
\section{Contests}
-I sugest that you see this chapter only after you have created at
+I suggest that you read this chapter only after you have created at
least a basic brain feeb, which is better than the (simple) provided
brain, or if you want to participate of a contest or a game with your
friends.
@@ -588,7 +588,7 @@
It is possible to get the maze map during the game, but with only
the corridors. Note that the function that gets the map is purposely
a little slow, so, invoking it too many times in a contest that uses
-timing atributes is not a good idea; anyway, it is possible to invoke
+timing attributes is not a good idea; anyway, it is possible to invoke
this function before defining the feeb, and store its value somewhere.
Also note that the map returned does not have any information about
what is really in the maze, but only the possible ways.
@@ -610,13 +610,13 @@
\item [{{\textsf{\textbf{nil}}}}] An {}``empty'' place, i.e. neither
of the previous.
\end{lyxlist}
-This map can safelly be used since \textsf{\textbf{(get-maze-map)}}
+This map can safely be used since \textsf{\textbf{(get-maze-map)}}
makes a new copy every time it is called.
\subsection{Timing}
-There are also some timing atributes that can be given to the game.
+There are also some timing attributes that can be given to the game.
The more time the feeb takes make a decision, greater is the probability
of its command to be aborted.
Modified: graphics/graphics.lisp
==============================================================================
--- graphics/graphics.lisp (original)
+++ graphics/graphics.lisp Sat Aug 7 09:40:44 2010
@@ -1,6 +1,6 @@
;;; -*- Common Lisp -*-
-#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+#| Copyright (c) 2007,2008 Gustavo Henrique Milaré
This file is part of The Feebs War.
@@ -31,40 +31,50 @@
(3 #\W)))
(defun print-map ()
+ (format t "~%") ;add this line
(dotimes (y *maze-y-size*)
(dotimes (x *maze-x-size*)
(let ((elt (aref *maze* x y)))
- (apply 'format t
- (cond
- ((wallp elt)
- (list " XX"))
- ((feeb-p (car elt))
- (list " F~a"
- (print-direction (feeb-facing (car elt)))))
- ((fireball-p (car elt))
- (list " *~a" (print-direction (fireball-direction (car elt)))))
- ((eq (car elt) :mushroom)
- (list " mm"))
- ((eq (car elt) :carcass)
- (list " cc"))
- (t (list " "))))))
- (format t "~%")))
-
+ (apply 'format t
+ (cond
+ ((wallp elt)
+ (list " XX"))
+ ((feeb-p (car elt))
+ (list " F~a"
+ (print-direction (feeb-facing (car elt)))))
+ ((fireball-p (car elt))
+ (list " *~a" (print-direction (fireball-direction (car elt)))))
+ ((eq (car elt) :mushroom)
+ (list " mm"))
+ ((eq (car elt) :carcass)
+ (list " cc"))
+ (t (list " "))))))
+ (format t "~%"))
+ (format t "~%")) ;add this line
+
(defun simple-play (&optional layout)
(if layout
(change-layout layout))
(make-auto-feebs (- 10 (length *feebs-to-be*)))
(initialize-feebs)
(start-round)
- (loop do
- (play-one-turn)
- (print-map)
- (sleep 0.7)
- (format t "~%~%")
- (if (finish-game-p) (return)))
+ (loop until (finish-game-p)
+ do
+ (play-one-turn)
+ (print-map)
+ (sleep 0.7))
(format t "Game Over!!~%~%Scores:~%~%")
- (dolist (feeb *feebs*)
- (format t "~a: ~d~%" (feeb-name feeb) (feeb-score feeb))))
+ (let ((scores nil))
+ (dolist (feeb *feebs*)
+ (push (list (feeb-name feeb) (feeb-score feeb))
+ scores)) ;collect living feebs' sores
+ (dolist (feeb *dead-feebs*)
+ (push (list (feeb-name feeb) (feeb-score feeb))
+ scores)) ;collect dead feebs' scoes
+ (sort scores #'> :key #'second) ;sort the scores in dcreasing order
+ (dolist (score scores)
+ (format t "~30@<~a:~> ~@d~%"
+ (first score) (second score))))) ;print out scores
#|
1
0
Author: gmilare
Date: Tue Aug 3 20:17:55 2010
New Revision: 20
Log:
Small bug fix.
Modified:
system.lisp
Modified: system.lisp
==============================================================================
--- system.lisp (original)
+++ system.lisp Tue Aug 3 20:17:55 2010
@@ -27,10 +27,10 @@
;;; This class is used by the system
(defclass object ()
- ((direction :accessor object-direction :initarg :direction :initform 0)
+ ((direction :accessor object-direction :initarg :direction)
(x-position :accessor object-x-position :initarg :x-position)
(y-position :accessor object-y-position :initarg :y-position)
- (lifetime :accessor object-lifetime :initarg :lifetime)))
+ (lifetime :accessor object-lifetime :initarg :lifetime :initform 0)))
(defclass feeb (object)
(;; These are structures accessible from behavior functions.
1
0
Author: gmilare
Date: Tue Aug 3 20:09:54 2010
New Revision: 19
Log:
Added fireball-guaranteed-lifetime support
Modified:
definitions/rules.lisp
system.lisp
the-feebs-war.asd
Modified: definitions/rules.lisp
==============================================================================
--- definitions/rules.lisp (original)
+++ definitions/rules.lisp Tue Aug 3 20:09:54 2010
@@ -122,13 +122,19 @@
(def-feeb-parm 'fireball-reflection-probability 2/3
"Probability of the flame to reflect when encountering a wall.")
+(def-feeb-parm 'fireball-guaranteed-lifetime 3
+ "Number of turns that a fireball is guaranteed not to dissipate,
+unless it encounters a wall.")
+
(defmethod make-move-choice ((fireball fireball))
(cond
((wallp (get-forward-pos fireball))
(if (chance (get-feeb-parm 'fireball-reflection-probability))
- :turn-around
- :dissipate))
- ((chance (get-feeb-parm 'fireball-dissipation-probability))
+ :turn-around
+ :dissipate))
+ ((and (>= (object-lifetime fireball)
+ (get-feeb-parm 'fireball-guaranteed-lifetime))
+ (chance (get-feeb-parm 'fireball-dissipation-probability)))
:dissipate)
(t :move-forward)))
Modified: system.lisp
==============================================================================
--- system.lisp (original)
+++ system.lisp Tue Aug 3 20:09:54 2010
@@ -27,9 +27,10 @@
;;; This class is used by the system
(defclass object ()
- ((direction :accessor object-direction :initarg :direction)
+ ((direction :accessor object-direction :initarg :direction :initform 0)
(x-position :accessor object-x-position :initarg :x-position)
- (y-position :accessor object-y-position :initarg :y-position)))
+ (y-position :accessor object-y-position :initarg :y-position)
+ (lifetime :accessor object-lifetime :initarg :lifetime)))
(defclass feeb (object)
(;; These are structures accessible from behavior functions.
@@ -244,3 +245,5 @@
) ; end of make-move generic function
+(defmethod make-move :after (object move)
+ (incf (object-lifetime object)))
Modified: the-feebs-war.asd
==============================================================================
--- the-feebs-war.asd (original)
+++ the-feebs-war.asd Tue Aug 3 20:09:54 2010
@@ -1,4 +1,4 @@
-;;; -*- Common Lisp -*-
+;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
(defpackage :feebs-system
(:use :cl :asdf))
1
0

[the-feebs-war-cvs] Is Israel a democracy? -- The problem with intellectually insecure whites -- Should Christians Support Israeli Terrorism in Gaza?
by Lawrence Auster 23 Jan '09
by Lawrence Auster 23 Jan '09
23 Jan '09
The Jewish State of Israel has no constitution, nor does it name its borders. Israel's hidden constitution is Judaism. Israel's undeclared borders range from the Nile to the Euphrates rivers. Israel's desired jurisdiction extends over the entire Earth.
It could not be more clear that the Jewish State follows a foreign policy which obeys Jewish Law as iterated in the Hebrew Bible, the Talmud, Maimonedes, the Cabalah, and the many commentaries and refinements of same. The Jews are genociding the native inhabitants of Palestine, just as their religion advises, and because
their religion teaches them to do so. They treat non-Jews as if non-humans, just as their religion requires them to do. They make perpetual war on every nation on Earth, just as their genocidal Jewish God has instructed.
The Jews of Israel are simply being Jews. Jews are an existential threat to the human race.
Israel contains one third of the Jews of the World. It is not some aberration of the Jewish spirit, but the condensation and concentration of the perverse Jewish mentality, which malady also pervades the remaining two thirds of Jewry, who almost unanimously support the Jewish State, and who certainly do unanimously support
the Jewish People and its consistent and constant crimes against the human race. Israel is Jewry and the danger of Israel is the danger of the Jewish People to all others, as the Jews have demonstrated each and every day of their existence.
The Jews, the entire Jewish People of 15 million, will not relent until they have wiped out all non-Jews in "Greater Israel". They will not stop destroying all other cultures, nations, religions, ethnicities, races, competition, etc. until they are either stopped, or succeed in their ancient quest to destroy the human race.
What Israel is doing is not some reaction to outside forces, nor was the formation of Israel a response to the Holocaust. Israel is simply following the plan laid out in the Jews' religious texts. The Jews have openly planned to take Palestine and genocide the native population of Palestine for some 2,500 years before the
Holocaust. The Jews have openly complained that "anti-Semitism" is a threat that gives them the right to genocide the Palestinians, not merely since the advent of Nazism, but for some 2,500 years.
The Jewish religion is the Constitution of the Jewish State of Israel, and, to a greater or lesser extent, the constitution of the nature of every Jew alive. The borders of Israel are the range the Jew roams over the entire World. The perverse Jewish mentality is inbred by a Jew's exposure to his parents and to his community. Judaism
passes in the spit and slobber of Jewish mother telling her Jewish child that he is a "Jew", as much as Judaism passes in the poison and pain of a Talmudic tractate. The secular Jews did not suddenly come to life after the Enlightenment and the Jewish Reformation a body of vampires that appeared ex nihilo, in vacuo, mostly
atheistical and undetached from formally practiced Judaism. Judaism is the Jew. It is a mindset that transcends and supercedes religion. It is a belief set, a way of life, a perception of one's self and one's relation to the World that makes a Jew, a Jew, and a danger to all of humanity.
In fact, the religious shell of Judaism is like the stretched and infected skin of a lycanthropic pustule. When you lance it to cure the infection, the virus only becomes more contagious and spills directly on the non-Jew.
The secular Jew is a deliberate product of the hyper-religious Jew, a monster created out of the hewed corpses of the fanatically religious Jew, a Golem which is conjured up to enter the World of the non-Jew and poison its blood, and boil its brain with a rabid lunacy that bites and spreads, until the infected community feeds on
itself and fills the fields with rotting bloating bodies, where once human beings tilled the soil and tended to their families. The religious Jew created the secular Jew as an army of Esthers who seduce with open thighs, broad smiles, and a Siren call that lures in the non-Jew to cast his skull upon the jagged rocks and color the seas
with his blood, sickened and blinded by the venereal disease of Judaism in secular form.
Israel is not a secular democracy. It is a religious mockery. It is a rabid bat flying to the ends of the Earth, to end the Earth. No one will be free nor safe until the disease is quarantined and dies out.
Source: http://www.ziopedia.org/articles/israel/how_can_israel_claim_to_be_a_%27dem…
--------------------
The problem with intellectually insecure whites
By Kevin MacDonald
January 19, 2009
America will soon have a white minority. This is a much desired state of affairs for the hostile elites who hold political power and shape public opinion. But it certainly creates some management issues � at least in the long run. After all, it�s difficult to come up with an historical example of a nation with a solid ethnic majority (90%
white in 1950) that has voluntarily decided to cede political and cultural power. Such transformations are typically accomplished by military invasions, great battles, and untold suffering.
And it�s not as if everyone is doing it. Only Western nations view their own demographic and cultural eclipse as a moral imperative. Indeed, as I have noted previously, it is striking that racial nationalism has triumphed in Israel at the same time that the Jewish intellectual and political movements and the organized Jewish
community have been the most active and effective force for a non-white America. Indeed, a poll in 2008 found that Avigdor Lieberman was the second most popular politician in Israel. Lieberman has advocated expulsion of Arabs from Israel and has declared himself a follower of Vladimir Jabotinsky, the leading pioneer of racial
Zionism. The most popular politician in the poll was Benjamin Netanyahu � another admirer of Jabotinsky. Prime Minister Ehud Olmert and Foreign Minister Tzipi Livni are also Jabotinskyists.
The racial Zionists are now carrying out yet another orgy of mass murder after a starvation-inducing blockade and the usual triggering assault designed to provoke Palestinian retaliation � which then becomes the cover for claims that Israel is merely defending itself against terrorism. This monstrosity was approved by
overwhelming majorities of both Houses of Congress. The craven Bush administration did its part by abstaining from a UN resolution designed by the US Secretary of State as a result of a personal appeal by the Israeli Prime Minister. This is yet another accomplishment of the Israel Lobby, but one they would rather not have
discussed in public. People might get the impression that the Lobby really does dictate US foreign policy in the Mideast. Obviously, such thoughts are only entertained by anti-Semites.
But I digress.
In managing the eclipse of white America, one strategy of the mainstream media is to simply ignore the issue. Christopher Donovan (�For the media, the less whites think about their coming minority status, the better�) has noted that the media, and in particular, the New York Times, are quite uninterested in doing stories that
discuss what white people think about this state of affairs.
It�s not surprising that the New York Times � the Jewish-owned flagship of anti-white, pro-multicultural media � ignores the issue. The issue is also missing from so-called conservative media even though one would think that conservatives would find the eclipse of white America to be an important issue. Certainly, their audiences
would find it interesting.
Now we have an article �The End of White America� written by Hua Hsu, an Assistant Professor of English at Vassar College. The article is a rather depressing display of what passes for intellectual discourse on the most important question confronting white people in America.
Hsu begins by quoting a passage in F. Scott Fitzgerald�s The Great Gatsby in which a character, Tom Buchanan, states: �Have you read The Rise of the Colored Empires by this man Goddard?� � Well, it�s a fine book, and everybody ought to read it. The idea is if we don�t look out the white race will be�will be utterly submerged.
It�s all scientific stuff; it�s been proved.�
Buchanan�s comment is a thinly veiled reference to Lothrop Stoddard�s The Rising Tide of Color which Hsu describes as �rationalized hatred� presented in a scholarly, gentlemanly, and scientific tone. (This wording that will certainly help him when he comes up for tenure.) As Hsu notes, Stoddard had a doctorate from Harvard
and was a member of many academic associations. His book was published by a major publisher. It was therefore �precisely the kind of book that a 1920s man of Buchanan�s profile � wealthy, Ivy League�educated, at once pretentious and intellectually insecure � might have been expected to bring up in casual conversation.�
Let�s ponder that a bit. The simple reality is that in the year 2009 an Ivy League-educated person, "at once pretentious and intellectually insecure," would just as glibly assert the same sort of nonsense as Hsu. To wit:
The coming white minority does not mean that the racial hierarchy of American culture will suddenly become inverted, as in 1995�s White Man�s Burden, an awful thought experiment of a film, starring John Travolta, that envisions an upside-down world in which whites are subjugated to their high-class black oppressors. There will
be dislocations and resentments along the way, but the demographic shifts of the next 40 years are likely to reduce the power of racial hierarchies over everyone�s lives, producing a culture that�s more likely than any before to treat its inhabitants as individuals, rather than members of a caste or identity group.
The fact is that no one can say for certain what multicultural America without a white majority will be like. There is no scientific or historical basis for claims like �the demographic shifts of the next 40 years are likely to reduce the power of racial hierarchies over everyone�s lives, producing a culture that�s more likely than any before
to treat its inhabitants as individuals, rather than members of a caste or identity group.�
Indeed, there is no evidence at all that we are proceeding to a color blind future. The election results continue to show that white people are coalescing in the Republican Party, while the Democrats are increasingly the party of a non-white soon-to-be majority.
Is it so hard to believe that when this coalition achieves a majority that it will further compromise the interests of whites far beyond contemporary concerns such as immigration policy and affirmative action? Hsu anticipates a colorblind world, but affirmative action means that blacks and other minorities are certainly not treated as
individuals. And it means that whites � especially white males � are losing out on opportunities they would have had without these policies and without the massive non-white immigration of the last few decades.
Given the intractability of changing intelligence and other traits required for success in the contemporary economy, it is unlikely that 40 more years of affirmative action will attain the outcomes desired by the minority lobbies. Indeed, in Obama's America, blacks are rioting in Oakland over perceived racial injustices, and from 2002
�2007, black juvenile homicide victims increased 31%, while black juvenile homicide perpetrators increased 43%. Hence, the reasonable outlook is for a continuing need for affirmative action and for racial activism in these groups, even after whites become a minority.
Whites will also lose out because of large-scale importation of relatively talented immigrants from East Asia. Indeed, as I noted over a decade ago, "The United States is well on the road to being dominated by an Asian technocratic elite and a Jewish business, professional, and media elite."
Hsu shows that there already is considerable anxiety among whites about the future. An advertizing executive says, �I think white people feel like they�re under siege right now � like it�s not okay to be white right now, especially if you�re a white male. ... People are stressed out about it. �We used to be in control! We�re losing
control�� Another says, "There�s a lot of fear and a lot of resentment."
It's hard to see why these feelings won't increase in the future.
A huge problem for white people is lack of intellectual and cultural confidence. Hsu quotes Christian (Stuff White People Like) Lander saying, "I get it: as a straight white male, I�m the worst thing on Earth." A professor comments that for his students "to be white is to be culturally broke. The classic thing white students say when
you ask them to talk about who they are is, �I don�t have a culture.� They might be privileged, they might be loaded socioeconomically, but they feel bankrupt when it comes to culture � They feel disadvantaged, and they feel marginalized."
This lack of cultural confidence is no accident. For nearly 100 years whites have been subjected to a culture of critique emanating from the most prestigious academic and media institutions. And, as Hsu points out, the most vibrant and influential aspect of American popular culture is hip-hop�a product of the African American
urban culture.
The only significant group of white people with any cultural confidence centers itself around country music, NASCAR, and the small town values of traditional white America. For this group of whites � and only this group � there is "a racial pride that dares not speak its name, and that defines itself through cultural cues instead�a
suspicion of intellectual elites and city dwellers, a preference for folksiness and plainness of speech (whether real or feigned), and the association of a working-class white minority with 'the real America.'�
This is what I term implicit whiteness � implicit because explicit assertions of white identity have been banned by the anti-white elites that dominate our politics and culture. It is a culture that, as Hsu notes, "cannot speak its name."
But that implies that the submerged white identity of the white working class and the lack of cultural confidence exhibited by the rest of white America are imposed from outside. Although there may well be characteristics of whites that facilitate this process, this suppression of white identity and interests is certainly not the natural
outcome of modernization or any other force internal to whites as a people. In my opinion, it is the result of the successful erection of a culture of critique in the West dominated by Jewish intellectual and political movements.
The result is that educated, intellectually insecure white people these days are far more likely to believe in the utopian future described by Hsu than in hard and cautious thinking about what the future might have in store for them.
It's worth dwelling a bit on the intellectual insecurity of the whites who mindlessly utter the mantras of multiculturalism that they have soaked up from the school system and from the media. Most people do not have much confidence in their intellectual ability and look to elite opinion to shape their beliefs. As I noted elsewhere,
A critical component of the success of the culture of critique is that it achieved control of the most prestigious and influential institutions of the West, and it became a consensus among the elites, Jewish and non-Jewish alike. Once this happened, it is not surprising that this culture became widely accepted among people of very
different levels of education and among people of different social classes.
Most people are quite insecure about their intellectual ability. But they know that the professors at Harvard, and the editorial page of the New York Times and the Washington Post, and even conservative commentators like Rush Limbaugh and Sean Hannity are all on page when it comes to racial and ethnic issues. This is a
formidable array, to the point that you almost have to be a crank to dissent from this consensus.
I think one of the greatest triumphs of the left has been to get people to believe that people who assert white identity and interests or who make unflattering portrayals of organized Jewish movements are morally degenerate, stupid, and perhaps psychiatrically disturbed. Obviously, all of these adjectives designate low status.
The reality is that the multicultural emperor has no clothes and, because of its support for racial Zionism and the racialism of ethnic minorities in America, it is massively hypocritical to boot. The New York Times, the academic left, and the faux conservatives that dominate elite discourse on race and ethnicity are intellectually
bankrupt and can only remain in power by ruthlessly suppressing or ignoring the scientific findings.
This is particularly a problem for college-educated whites. Like Fitzgerald's Tom Buchanan, such people have a strong need to feel that their ideas are respectable and part of the mainstream. But the respectable mainstream gives them absolutely nothing with which to validate themselves except perhaps the idea that the world
will be a better place when people like them no longer have power. Hsu quotes the pathetic Christian Lander: "�Like, I�m aware of all the horrible crimes that my demographic has done in the world. ... And there�s a bunch of white people who are desperate � desperate � to say, �You know what? My skin�s white, but I�m not one
of the white people who�s destroying the world.��
As a zombie leftist during the 1960s and 1970s, I know what that feeling of desperation is like � what it's like to be a self-hating white. We must get to the point where college-educated whites proudly and confidently say they are white and that they do not want to become a minority in America.
This reminds me of the recent docudrama Milk, which depicts the life of gay activist Harvey Milk. Milk is sure be nominated for an Oscar as Best Picture because it lovingly illustrates a triumph of the cultural left. But is has an important message that should resonate with the millions of whites who have been deprived of their
confidence and their culture: Be explicit. Just as Harvey Milk advocated being openly gay even in the face of dire consequences, whites need to tell their family and their friends that they have an identity as a white person and believe that whites have legitimate interests as white people. They must accept the consequences
when they are harassed, fired from their jobs, or put in prison for such beliefs. They must run for political office as openly pro-white.
Milk shows that homosexuals were fired from their jobs and arrested for congregating in public. Now it's the Southern Poverty Law Center and the rest of the leftist intellectual and political establishment that harasses and attempts to get people fired. But it's the same situation with the roles reversed. No revolution was ever
accomplished without some martyrs. The revolution that restores the legitimacy of white identity and the legitimacy of white interests will be no exception.
But it is a revolution that is absolutely necessary. The white majority is foolish indeed to entrust its future to a utopian hope that racial and ethnic identifications will disappear and that they won�t continue to influence public policy in ways that compromise the interests of whites.
It does not take an overactive imagination to see that coalitions of minority groups could compromise the interests of formerly dominant whites. We already see numerous examples in which coalitions of minority groups attempt to influence public policy, including immigration policy, against the interests of the whites. Placing
ourselves in a position of vulnerability would be extremely risky, given the deep sense of historical grievance fostered by many ethnic activists and organized ethnic lobbies.
This is especially the case with Jews. Jewish organisations have been unanimous in condemning Western societies, Western traditions, and Christianity, for past crimes against Jews. Similar sentiments are typical of a great many African Americans and Latinos, and especially among the ethnic activists from these groups. The
�God damn America� sermon by President Obama's pastor comes to mind as a recent notorious example.
The precedent of the early decades of the Soviet Union should give pause to anyone who believes that surrendering ethnic hegemony does not carry risks. The Bolshevik revolution had a pronounced ethnic angle: To a very great extent, Jews and other non-Russians ruled over the Russian people, with disastrous
consequences for the Russians and other ethnic groups that were not able to become part of the power structure. Jews formed a hostile elite within this power structure � as they will in the future white-minority America; Jews were �Stalin�s willing executioners.�
Two passages from my review of Yuri Slezkine's The Jewish Century seem particularly appropriate here. The first passage reminds me of the many American Jews who adopt a veneer of support for leftist versions of social justice and racial tolerance while nevertheless managing to support racial Zionism and the mass murder,
torture, and incarceration of the Palestinian people in one of the largest prison systems the world has ever seen. Such people may be very different when they become a hostile elite in a white-minority America.
Many of the commentators on Jewish Bolsheviks noted the �transformation� of Jews [after the Bolshevik Revolution]. In the words of [a] Jewish commentator, G. A. Landau, �cruelty, sadism, and violence had seemed alien to a nation so far removed from physical activity.� And another Jewish commentator, Ia. A. Bromberg, noted
that:
the formerly oppressed lover of liberty had turned into a tyrant of �unheard-of-despotic arbitrariness��. The convinced and unconditional opponent of the death penalty not just for political crimes but for the most heinous offenses, who could not, as it were, watch a chicken being killed, has been transformed outwardly into a
leather-clad person with a revolver and, in fact, lost all human likeness. ...
After the Revolution, ... there was active suppression of any remnants of the older order and their descendants. ... The mass murder of peasants and nationalists was combined with the systematic exclusion of the previously existing non-Jewish middle class. The wife of a Leningrad University professor noted, �in all the
institutions, only workers and Israelites are admitted; the life of the intelligentsia is very hard� (p. 243). Even at the end of the 1930s, prior to the Russification that accompanied World War II, �the Russian Federation�was still doing penance for its imperial past while also serving as an example of an ethnicity-free society� (p. 276).
While all other nationalities, including Jews, were allowed and encouraged to keep their ethnic identities, the revolution remained an anti-majoritarian movement.
The difference from the Soviet Union may well be that in white-minority America it will not be workers and Israelites who are favored, but non-whites and Israelites. Whites may dream that they are entering the post-racial utopia imagined by their erstwhile intellectual superiors. But it is quite possible that they are entering into a
racial dystopia of unimaginable cruelty in which whites will be systematically excluded in favor of the new elites recruited from the soon-to-be majority. It's happened before.
Kevin MacDonald is a professor of psychology at California State University�Long Beach.
Permanent URL with hyperlinks:
http://www.theoccidentalobserver.net/articles/MacDonald-Hsu.html
-----------
Should Christians Support Israeli Terrorism in Gaza?
A timely discussion between Rev. Ted Pike and Dr. David Duke, one especially important for the Christians in our audience
http://www.davidduke.com/mp3/dukeradio090122DukeandPikeonGaza.mp3
In this vital discussion, Rev. Pike and Dr. Duke explore the Pro-Israel attitude of some Christian evangelical organizations, and why their position not only goes directly against Christian morality and decency, but actually is directly opposite of that expressed by Christian Scriptures. Today, Many Christians are instructed that Jews
and today�s Israel has a special covenant� with God. In fact, the New Testament in the clearest of language states that the Jews �continued not in my covenant, and I considered them not, saith the Lord.� Here�s the quote that Christians aren�t supposed to notice.:
8:10 Not according to the covenant that I made with their fathers, in the day when I took them by the hand out of the land of Egypt; because they continued not in my covenant, and I regarded them not, saith the Lord. (Hebrews 8:10)
They also don�t seem to notice that a 2000 year old Judaic war against Christianity that has been waged since time of Jesus Christ and still goes on today with the most powerful Jewish organizations attempting to destroy European and American traditions, that has even become a war on our Christmas traditions.
Dr. Duke and Ted Pike also speak about how over a hundred thousand Christian Palestinians have suffered with their families from anti-Christian Israel! Christian support of Israel has resulted in the very birthplace of Jesus Christ, go from 90 percent Palestinian Christians to 35 percent today because of Israeli terror and
occupation. They ask, �How could any Christian in good conscience support the anti-Christian state of Israel, bombing the homes, killing and maiming, torturing and oppressing fellow Christian men, women and children?�
This is a vital show for every Christian reader and listener of DavidDuke.com. Next time, you hear someone say, �God tells us that we must support Israel� you will have the clear Christian answer that just the opposite is true!
For documentation on this be sure to read some of the well-footnoted, sample chapters of Jewish Supremacism and My Awakening.
Source :
http://www.davidduke.com/general/should-christians-support-israeli-terroris…
-------------------------------------
You or someone using your email adress is currently subscribed to the Lawrence Auster
Newletter. If you wish to unsubscribe from our mailing list, please let us know by calling to 1 212 865 1284
Thanks,
Lawrence Auster,
238 W 101 St Apt. 3B
New York, NY 10025
Contact: lawrence.auster(a)att.net
-------------------------------------
1
0
Author: gmilare
Date: Sat Mar 15 17:01:02 2008
New Revision: 18
Modified:
documentation/feebs.tex
Log:
Modified: documentation/feebs.tex
==============================================================================
--- documentation/feebs.tex (original)
+++ documentation/feebs.tex Sat Mar 15 17:01:02 2008
@@ -1,5 +1,24 @@
+%% LyX 1.5.1 created this file. For more info, see http://www.lyx.org/.
+%% Do not edit unless you really know what you are doing.
+\documentclass[english]{article}
+\usepackage[T1]{fontenc}
+\usepackage[latin1]{inputenc}
+\IfFileExists{url.sty}{\usepackage{url}}
+ {\newcommand{\url}{\texttt}}
+
+\makeatletter
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+\newenvironment{lyxlist}[1]
+{\begin{list}{}
+{\settowidth{\labelwidth}{#1}
+ \setlength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}[1]{##1\hfil}}}
+{\end{list}}
-% Copyright (c) 2007,2008 Gustavo Henrique Milar�
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
+
+% Copyright (c) 2007,2008 Gustavo Henrique Milar�
%
% This file is part of The Feebs War.
%
@@ -16,24 +35,20 @@
% You should have received a copy of the GNU General Public License
% along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
-\documentclass[english]{article}
-\usepackage[T1]{fontenc}
-\usepackage[latin1]{inputenc}
-\IfFileExists{url.sty}{\usepackage{url}}
+
+
+
+\IfFileExists{url.sty}{\usepackage{url}
+}
{\newcommand{\url}{\texttt}}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
-\newenvironment{lyxlist}[1]
-{\begin{list}{}
-{\settowidth{\labelwidth}{#1}
- \setlength{\leftmargin}{\labelwidth}
- \addtolength{\leftmargin}{\labelsep}
- \renewcommand{\makelabel}[1]{##1\hfil}}}
-{\end{list}}
+
\IfFileExists{url.sty}{\usepackage{url}
+
}
{\newcommand{\url}{\texttt}}
@@ -44,6 +59,9 @@
\makeatother
+
+\makeatother
+
\usepackage{babel}
\makeatother
@@ -56,12 +74,11 @@
\maketitle
\begin{abstract}
-\textit{The Feebs War} is a modified version of Planet of the Feebs
-\url{http://www.cliki.net/}, a game made for people learn and improve
-their lisp and code manipulation tecniques. The graphics are now displayed
-using Lispbuilder \url{http://lispbuilder.sourceforge.net}'s libraries,
-so the problems with portability from CMUCL and X Window Sistem do
-not exist anymore. Also the code is cleaner and more extensible.
+\textit{The Feebs War} is a modified version of Planet of The Feebs \url{http://www.cliki.net/Planet\%20of\%20the\%20Feebs},
+a game made for people learn and improve their lisp and code manipulation
+tecniques. The graphics are now displayed using Lispbuilder \url{http://lispbuilder.sourceforge.net}'s
+libraries, so the problems with portability from CMUCL and X Window
+Sistem do not exist anymore. Also the code is cleaner and more extensible.
\end{abstract}
\tableofcontents{}
@@ -101,24 +118,25 @@
\begin{itemize}
\item The graphics are not based on X Window Sistem anymore, but on \textit{Lispbuilder},
and there are no CMUCL's event handler. This way, the code is more
-portable and graphics can be improved. Just creating some image
-files of a feeb and your feeb is much more personalized!
-\item Every element of the map (including walls) is a list, so the brain of
-a feeb doesn't need to test all the time if the element is an atom
+portable and graphics can be improved. Just creating some image files
+of a feeb and your feeb is much more personalized!
+\item Every element of the map (including walls) is a list, so the brain
+of a feeb doesn't need to test all the time if the element is an atom
or a list (wich, in my opinion, is really boring, unlispy and unnecessary
in this case). That was only a reason to duplicate code and work,
-adding no results at all...
-\item Many functions and variables are changed and others were added
+adding no results at all...
+\item Many functions and variables are changed and others were added
\item Documentation is more objective than the one provided with \textit{Planet
of the Feebs}, and is fully compatible with the code. This way it
-is easier to understand the game.
-\item Security is improved. Now it the behavior functions are allowed to store
-and change structures and vectors passed to it.
-The parameters can't be change by those functions while inside the game.
-\item It is possible now to extend the rules: the code is object oriented and
-new rules, special moves, change the behavior of flames, etc, can be done
-by adding new classes and/or methods. This manual is just the beginning!
-end{itemize}
+is easier to understand the game.
+\item Security is improved. Now it the behavior functions are allowed to
+store and change structures and vectors passed to it. The parameters
+can't be change by those functions while inside the game.
+\item It is possible now to extend the rules: the code is object oriented
+and new rules, special moves, change the behavior of flames, etc,
+can be done by adding new classes and/or methods. This manual is just
+the beginning! end{itemize}
+
\section{The Game}
@@ -132,67 +150,66 @@
After all feebs move, the flames thrown before also move (or dissipate),
carcasses may rot and mushrooms may grow, accordingly to some rules.
-The game rules are defined by parameters. These parameters can be read
-by the command \textsf{\textbf{(get-feeb-parm~}'parameter\textbf{)}}
-To see all parameters, values and also all the documentation, one can use
-\textsf{\textbf{(list-parameter-settings)}}. Using
-\textsf{\textbf{(change-feeb-parm}'parameter~value\textbf{)}}
+The game rules are defined by parameters. These parameters can be
+read by the command \textsf{\textbf{(get-feeb-parm~}}\textsf{'parameter}\textsf{\textbf{)}}
+To see all parameters, values and also all the documentation, one
+can use \textsf{\textbf{(list-parameter-settings)}}. Using \textsf{\textbf{(change-feeb-parm}}\textsf{'parameter~value}\textsf{\textbf{)}}
gives the possibility to change them (but not during the game) and
-\textsf{\textbf{(documentation~}'parameter~'feeb-parm\textbf{)}}
-can be used to know them. Just remember that every probability
-must be a rational number (like 1/2).
-
-But don't panic! These parameters are just for one to know how
-the game is going to be, but in the begining there is no need
-to explicitly use them when creating the brain of a feeb.
-The best way to create a feeb is watching a game (among system feebs),
-improving it (it is defined in file brains.lisp) a little more,
-testing the changes...
+\textsf{\textbf{(documentation~}}\textsf{'parameter~'feeb-parm}\textsf{\textbf{)}}
+can be used to know them. Just remember that every probability must
+be a rational number (like 1/2).
+
+But don't panic! These parameters are just for one to know how the
+game is going to be, but in the begining there is no need to explicitly
+use them when creating the brain of a feeb. The best way to create
+a feeb is watching a game (among system feebs), improving it (it is
+defined in file brains.lisp) a little more, testing the changes...
These are some global parameters:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{'game-length}}}] Number of turns the game
-will last.
-\item [{\textsf{\textbf{'points-for-killing}}}] How many points some
+\item [{{\textsf{\textbf{'game-length}}}}] Number of turns the game will
+last.
+\item [{{\textsf{\textbf{'points-for-killing}}}}] How many points some
feeb earn for killing someone.
-\item [{\textsf{\textbf{'points-for-dying}}}] How many points some
+\item [{{\textsf{\textbf{'points-for-dying}}}}] How many points some
feeb earn for dying (usually negative).
-\item [{\textsf{\textbf{'maze-x-size}}}] Horizontal size of the maze.
-\item [{\textsf{\textbf{'maze-y-size}}}] Vertical size of the maze.
+\item [{{\textsf{\textbf{'maze-x-size}}}}] Horizontal size of the maze.
+\item [{{\textsf{\textbf{'maze-y-size}}}}] Vertical size of the maze.
\end{lyxlist}
\subsection{Throwing flame}
-If a feeb decides to throw a flame, if it is prepared to and has
-enough energy, the next turn there will be a flame in the square
-in front of the feeb, and it will see it, so the feeb shouldn't move
-forward. For a few turns, the feeb will not be able to
-throw flames. Each turn, the flame moves forward destroing mushrooms and
-killing feebs it encounters, transforming them into carcasses. If there
-is a wall, the flame can reflect, and, if so, it will turn 180 degrees.
-
-Once a feeb is killed (or starves), in it's place in the maze there will appear
-a carcass. The feeb goes to the end of the dead feebs line. When the
-carcass rots, the first feeb in line reincarnates. So, dying is not so terrible.
+If a feeb decides to throw a flame, if it is prepared to and has enough
+energy, the next turn there will be a flame in the square in front
+of the feeb, and it will see it, so the feeb shouldn't move forward.
+For a few turns, the feeb will not be able to throw flames. Each turn,
+the flame moves forward destroing mushrooms and killing feebs it encounters,
+transforming them into carcasses. If there is a wall, the flame can
+reflect, and, if so, it will turn 180 degrees.
+
+Once a feeb is killed (or starves), in it's place in the maze there
+will appear a carcass. The feeb goes to the end of the dead feebs
+line. When the carcass rots, the first feeb in line reincarnates.
+So, dying is not so terrible.
These are the parameters related to flames:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{'flame-energy}}}] Amount of energy lost after
+\item [{{\textsf{\textbf{'flame-energy}}}}] Amount of energy lost after
throwing a flame.
-\item [{\textsf{\textbf{'fireball-guaranteed-lifetime}}}] Number of
+\item [{{\textsf{\textbf{'fireball-guaranteed-lifetime}}}}] Number of
turns that a fireball is guaranteed not to dissipate, unless it encounters
-a wall.
-\item [{\textsf{\textbf{'fireball-dissipation-probability}}}] Probability
-of the flame to dissipate each turn after the apropriate time.
-\item [{\textsf{\textbf{'fireball-reflection-probability}}}] Probability
+a wall.
+\item [{{\textsf{\textbf{'fireball-dissipation-probability}}}}] Probability
+of the flame to dissipate each turn after the apropriate time.
+\item [{{\textsf{\textbf{'fireball-reflection-probability}}}}] Probability
of the flame to reflect when encountering a wall.
-\item [{\textsf{\textbf{'flame-no-recovery-time}}}] Number of turns
-that a feeb cannot fire.
-\item [{\textsf{\textbf{'flame-recovery-probability}}}] Probability
+\item [{{\textsf{\textbf{'flame-no-recovery-time}}}}] Number of turns
+that a feeb cannot fire.
+\item [{{\textsf{\textbf{'flame-recovery-probability}}}}] Probability
of the feeb to recover the hability to throw a flame, after the apropriate
-time.
+time.
\end{lyxlist}
\subsection{Eating food}
@@ -200,27 +217,27 @@
There are two kinds of food, carcasses and mushrooms. Carcasses usually
give less energy than mushrooms, and may rot, but, while it does not
rot, a feeb can feed as long as it wishes. Mushrooms disapear after
-being eaten. By eating food, the feeb
-will be able to recover energy, wich is important because, if a feeb
-stays with 0 or less units of energy, it starves.
+being eaten. By eating food, the feeb will be able to recover energy,
+wich is important because, if a feeb stays with 0 or less units of
+energy, it starves.
These are the quantities:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{'mushroom-energy}}}] Amount of energy recovered
+\item [{{\textsf{\textbf{'mushroom-energy}}}}] Amount of energy recovered
when the feeb eats a mushroom.
-\item [{\textsf{\textbf{'carcass-energy}}}] Amount of energy recovered
+\item [{{\textsf{\textbf{'carcass-energy}}}}] Amount of energy recovered
each turn that the feeb eats a carcass.
-\item [{\textsf{\textbf{'carcass-guaranteed-lifetime}}}] Number of
-turns that a carcass will surely not rot. After these turns, it
-can rot, depending on probabilities.
-\item [{\textsf{\textbf{'carcass-rot-probability}}}] Probability of
+\item [{{\textsf{\textbf{'carcass-guaranteed-lifetime}}}}] Number of
+turns that a carcass will surely not rot. After these turns, it can
+rot, depending on probabilities.
+\item [{{\textsf{\textbf{'carcass-rot-probability}}}}] Probability of
the carcass to rot, after the apropriate time.
-\item [{\textsf{\textbf{'maximum-energy}}}] Maximum amount of energy
+\item [{{\textsf{\textbf{'maximum-energy}}}}] Maximum amount of energy
that a feeb can have eating.
-\item [{\textsf{\textbf{'starting-energy}}}] Amount of energy a feeb
+\item [{{\textsf{\textbf{'starting-energy}}}}] Amount of energy a feeb
has when it reincarnates.
-\item [{\textsf{\textbf{'number-of-mushrooms}}}] Quantity of mushrooms
+\item [{{\textsf{\textbf{'number-of-mushrooms}}}}] Quantity of mushrooms
that exist in the maze.
\end{lyxlist}
@@ -231,12 +248,11 @@
\begin{itemize}
\item The name, a string.
\item The brain is a function that decides what the feeb will do next, based
-on what it is seeing and feeling.
+on what it is seeing and feeling.
\item The set of graphics is an image file (of format BMP, JPEG, PNG, and
any others that supported by SDL\_image).
\end{itemize}
-One can create a feeb calling
-\textsf{\textbf{(define-feeb}~name~brain~\textbf{:graphics}~graphics\textbf{)}}.
+One can create a feeb calling \textsf{\textbf{(define-feeb}}\textsf{~name~brain~}\textsf{\textbf{:graphics}}\textsf{~graphics}\textsf{\textbf{)}}.
If name is already used, a warning will be signaled, and the old feeb
will be substituted. Calling \textsf{\textbf{(list-of-feebs)}} will
return the list of the feebs (names only) that will be defined when
@@ -256,28 +272,28 @@
The possible values that the brain function can return are these:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{:move-forward}}}] Move one square forward, unless
-there is a wall in front of the feeb.
-\item [{\textsf{\textbf{:turn-left}}}] Turn 90 degrees to the left.
-\item [{\textsf{\textbf{:turn-right}}}] Turn 90 degrees to the right.
-\item [{\textsf{\textbf{:turn-around}}}] Turn 180 degrees.
-\item [{\textsf{\textbf{:flame}}}] Throw a flame. The flame will be created
-next turn in the front square of the feeb.
-\item [{\textsf{\textbf{:wait}}}] Do nothing in this turn.
-\item [{\textsf{\textbf{:peek-left}}}] Peek to the left around a corner.
+\item [{{\textsf{\textbf{:move-forward}}}}] Move one square forward,
+unless there is a wall in front of the feeb.
+\item [{{\textsf{\textbf{:turn-left}}}}] Turn 90 degrees to the left.
+\item [{{\textsf{\textbf{:turn-right}}}}] Turn 90 degrees to the right.
+\item [{{\textsf{\textbf{:turn-around}}}}] Turn 180 degrees.
+\item [{{\textsf{\textbf{:flame}}}}] Throw a flame. The flame will be
+created next turn in the front square of the feeb.
+\item [{{\textsf{\textbf{:wait}}}}] Do nothing in this turn.
+\item [{{\textsf{\textbf{:peek-left}}}}] Peek to the left around a corner.
The creature does note actually move, but, in the next turn, the creature
will have the same vision that it would have if he had moved one step
-foward and turned left (and one step back because the feeb needs to see
-what is actually in front of it). Peeking used so a feeb can analize a corridor
-before trespassing it.
-\item [{\textsf{\textbf{:peek-right}}}] Peek to the right around a corner,
-analogous to \textsf{\textbf{:peek-left}}.
-\item [{\textsf{\textbf{:eat-carcass}}}] Eat a carcass if there is any
-available in the feeb's square. The amount of the parameter
-\textsf{\textbf{'carcass-energy}} is restored to the feeb's energy.
-\item [{\textsf{\textbf{:eat-mushroom}}}] Eat a mushroom if there is any
-available in the feeb's square. The amount of the parameter
-\textsf{\textbf{'mushroom-energy}} is restored to the feeb's energy.
+foward and turned left (and one step back because the feeb needs to
+see what is actually in front of it). Peeking used so a feeb can analize
+a corridor before trespassing it.
+\item [{{\textsf{\textbf{:peek-right}}}}] Peek to the right around a
+corner, analogous to \textsf{\textbf{:peek-left}}.
+\item [{{\textsf{\textbf{:eat-carcass}}}}] Eat a carcass if there is
+any available in the feeb's square. The amount of the parameter \textsf{\textbf{'carcass-energy}}
+is restored to the feeb's energy.
+\item [{{\textsf{\textbf{:eat-mushroom}}}}] Eat a mushroom if there is
+any available in the feeb's square. The amount of the parameter \textsf{\textbf{'mushroom-energy}}
+is restored to the feeb's energy.
\end{lyxlist}
\subsection{Information available}
@@ -297,174 +313,241 @@
feeb. To access them, one must call:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{(name}}\textsf{\emph{~status}}\textsf{\textbf{)}}}] \begin{flushleft}
-The name of the feeb.
+\item [{{\textsf{\textbf{(name}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The name of the feeb.
\par\end{flushleft}
-\item [{\textsf{\textbf{(facing}}\textsf{\emph{~status}}\textsf{\textbf{)}}}] \begin{flushleft}
-Where the feeb is facing to, one of the constants provided: \textsf{\textbf{north}},
+
+\item [{{\textsf{\textbf{(facing}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Where the feeb is facing to, one of the constants provided: \textsf{\textbf{north}},
\textsf{\textbf{east}}, \textsf{\textbf{south}} or \textsf{\textbf{west}},
-wich are 0, 1, 2 and 3 respectivelly.
+wich are 0, 1, 2 and 3 respectivelly.
\par\end{flushleft}
-\item [{\textsf{\textbf{(x-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
-The horizontal position of the feeb, starting with 0 and increasing to east.
-If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(y-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
-The vertical position of the feeb, starting with 0 and increasing to south.
-If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(peeking}\emph{~status}\textbf{)}}}] \begin{flushleft}
-If it is \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}}, it means
-that the current \textsf{\emph{vision}} provided is result of a previous
-\textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}} command
-of the same feeb. Otherwise, it is \textsf{\textbf{nil}}. Note that
-\textsf{\emph{proximity}} is \emph{not} affected.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(line-of-sight}\emph{~status}\textbf{)}}}] \begin{flushleft}
-Indicates the amount of valid entries in \textsf{\emph{vision}}. It actually
-means that \textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
-will return \textsf{\textbf{'(:rock)}}.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(ready-to-fire}\emph{~status}\textbf{)}}}] \begin{flushleft}
-If \textsf{\textbf{T}} indicates that the feeb is ready to fire.
-If \textsf{\textbf{Nil}} indicates it is not.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(aborted}\emph{~status}\textbf{)}}}] \begin{flushleft}
-Related with timing. Returns \textsf{\textbf{T}} if the last move of feeb
-was aborted because of timing issues.
+
+\item [{{\textsf{\textbf{(x-position}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The horizontal position of the feeb, starting with 0 and increasing
+to east. If \textsf{\textbf{'sense-location-p}} is nil, it returns
+nil instead.
\par\end{flushleft}
-\item [{\textsf{\textbf{(last-move}\emph{~status}\textbf{)}}}] \begin{flushleft}
-The feeb's previous move, or \textsf{\textbf{:dead}} if it has just reincarnated.
+
+\item [{{\textsf{\textbf{(y-position}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The vertical position of the feeb, starting with 0 and increasing
+to south. If \textsf{\textbf{'sense-location-p}} is nil, it returns
+nil instead.
\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(peeking}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+If it is \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}},
+it means that the current \textsf{\emph{vision}} provided is result
+of a previous \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}}
+command of the same feeb. Otherwise, it is \textsf{\textbf{nil}}.
+Note that \textsf{\emph{proximity}} is \emph{not} affected.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(line-of-sight}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Indicates the amount of valid entries in \textsf{\emph{vision}}. It
+actually means that \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{\textbf{(line-of-sight}}\textsf{\emph{~status}}\textsf{\textbf{))}}
+will return \textsf{\textbf{'(:rock)}}.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(ready-to-fire}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+If \textsf{\textbf{T}} indicates that the feeb is ready to fire. If
+\textsf{\textbf{Nil}} indicates it is not.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(aborted}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Related with timing. Returns \textsf{\textbf{T}} if the last move
+of feeb was aborted because of timing issues.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(last-move}}\textsf{\emph{~status}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The feeb's previous move, or \textsf{\textbf{:dead}} if it has just
+reincarnated.
+\par\end{flushleft}
+
\end{lyxlist}
\subsubsection{Proximity and vision}
The brain receives also information about what is near the feeb and
-what the feeb sees. We note that, contrary to \emph{Planet of the Feebs},
-it is safe to change anything inside these structures, so you are
-alowed to keep them stored and to modify them as you wish.
+what the feeb sees. We note that, contrary to \emph{Planet of the
+Feebs}, it is safe to change anything inside these structures, so
+you are alowed to keep them stored and to modify them as you wish.
The structure \textsf{\emph{proximity}} has the contents of the squares
near the feeb (not affected by peeking) with these fields:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
-Contents of the feeb's current square.
+\item [{{\textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Contents of the feeb's current square.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(left-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Contents of the right square of the feeb.
\par\end{flushleft}
-\item [{\textsf{\textbf{(left-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
-Contents of the right square of the feeb.
+
+\item [{{\textsf{\textbf{(right-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Contents of the left square of the feeb.
\par\end{flushleft}
-\item [{\textsf{\textbf{(right-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
-Contents of the left square of the feeb.
+
+\item [{{\textsf{\textbf{(rear-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Contents of the square behind the feeb.
\par\end{flushleft}
-\item [{\textsf{\textbf{(rear-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
-Contents of the square behind the feeb.
-\par\end{flushleft}
-\item [{The}] vector \textsf{\emph{vision}} has the contents of the squares
-that are in front of the feeb. For example,
-\textsf{\textbf{(aref}\emph{~vision~}0\textbf{)}}
-will return the contents of the square in front of the feeb,
-\textsf{\textbf{(aref}\emph{~vision~}1\textbf{)}}
+
+\item [{{The}}] vector \textsf{\emph{vision}} has the contents of the
+squares that are in front of the feeb. For example, \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{0}\textsf{\textbf{)}}
+will return the contents of the square in front of the feeb, \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{1}\textsf{\textbf{)}}
will return the contents of the next square, and so on. As said before,
-\textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
-will be the first \textsf{\textbf{'(:rock)}} encountered. All subsequents square, like
-\textsf{\textbf{(aref}\emph{~vision~}\textbf{(+}~1~\textbf{(line-of-sight}\emph{~status}\textbf{)))}},
-will be garbage and should not be used.
+\textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{\textbf{(line-of-sight}}\textsf{\emph{~status}}\textsf{\textbf{))}}
+will be the first \textsf{\textbf{'(:rock)}} encountered. All subsequents
+square, like \textsf{\textbf{(aref}}\textsf{\emph{~vision~}}\textsf{\textbf{(+}}\textsf{~1~}\textsf{\textbf{(line-of-sight}}\textsf{\emph{~status}}\textsf{\textbf{)))}},
+will be garbage and should not be used.
\end{lyxlist}
The contents of one square returned by any of these calls is either
-a list of elements, a wall \textsf{\textbf{'(:rock)}} (i.e. a list with
-one element, a \textsf{\textbf{:rock}}) or \textsf{\textbf{()}} if the
-square is empty. Each element of the square is one of these:
+a list of elements, a wall \textsf{\textbf{'(:rock)}} (i.e. a list
+with one element, a \textsf{\textbf{:rock}}) or \textsf{\textbf{()}}
+if the square is empty. Each element of the square is one of these:
\begin{itemize}
-\item \textbf{Feeb image.} One can call \textsf{\textbf{(feeb-image-p}~element\textbf{)}}
+\item \textbf{Feeb image.} One can call \textsf{\textbf{(feeb-image-p}}\textsf{~element}\textsf{\textbf{)}}
to see if element is a feeb image.
-\item \textbf{Fireball image.} One can call \textsf{\textbf{(fireball-image-p}~element\textbf{)}}
+\item \textbf{Fireball image.} One can call \textsf{\textbf{(fireball-image-p}}\textsf{~element}\textsf{\textbf{)}}
to check if element is a fireball image.
\item \textsf{\textbf{:carcass}}. If there is a \textsf{\textbf{:carcass}}
in the square of the feeb (i.e. in \textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}),
the call \textsf{\textbf{:eat-carcass}} will make the feeb eat it.
\item \textsf{\textbf{:mushroom}}. Analogous to \textsf{\textbf{:carcass}}.
-A mushroom appears randomly in places previously marked in the map.
+A mushroom appears randomly in places previously marked in the map.
\end{itemize}
\subsubsection{Feebs and fireballs images}
Both fireballs and feebs that are given to the brain function are
not the real ones, but just images with contents that the brain function
-can access. It is allowed to keep and change its contents because they
-won't be used internally.
+can access. It is allowed to keep and change its contents because
+they won't be used internally.
These are the accessors available (they read and change the fiels):
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{(feeb-image-name}~feeb-image\textbf{)}}}] \begin{flushleft}
-The name of the feeb. (Maybe you know it's weakpoints?)
+\item [{{\textsf{\textbf{(feeb-image-name}}\textsf{~feeb-image}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The name of the feeb. (Maybe you know it's weakpoints?)
\par\end{flushleft}
-\item [{\textsf{\textbf{(feeb-image-facing}~feeb-image\textbf{)}}}] \begin{flushleft}
-The facing of the feeb. This way the brain function can
-see if the feeb-image either sees the feeb which is playing or not.
-\par\end{flushleft}
-\item [{\textsf{\textbf{(feeb-image-peeking}~feeb-image\textbf{)}}}] \begin{flushleft}
-Returns \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}} if the
-feeb is peeking to (its) left or right, or \textsf{\textbf{nil}} if
-not.
+
+\item [{{\textsf{\textbf{(feeb-image-facing}}\textsf{~feeb-image}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The facing of the feeb. This way the brain function can see if the
+feeb-image either sees the feeb which is playing or not.
+\par\end{flushleft}
+
+\item [{{\textsf{\textbf{(feeb-image-peeking}}\textsf{~feeb-image}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+Returns \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}}
+if the feeb is peeking to (its) left or right, or \textsf{\textbf{nil}}
+if not.
\par\end{flushleft}
-\item [{\textsf{\textbf{(fireball-image-direction}~fireball-image\textbf{)}}}] \begin{flushleft}
-The direction where the fireball image is going to.
+
+\item [{{\textsf{\textbf{(fireball-image-direction}}\textsf{~fireball-image}\textsf{\textbf{)}}}}]~
+
+
+\begin{flushleft}
+The direction where the fireball image is going to.
\par\end{flushleft}
+
\end{lyxlist}
\subsubsection{Vision-left and vision-right}
\textsf{\emph{vision-left}} and \textsf{\emph{vision-right}} are vectors
similar to vision, but they are less precise in the contents. Also
-their valid contents are limited by \textsf{\textbf{(line-of-sight}~\emph{status}\textbf{)}},
-so \textsf{\textbf{(aref}~\emph{vision-left}~\textbf{(line-of-sight}~\emph{status}\textbf{))}},
+their valid contents are limited by \textsf{\textbf{(line-of-sight}}\textsf{~}\textsf{\emph{status}}\textsf{\textbf{)}},
+so \textsf{\textbf{(aref}}\textsf{~}\textsf{\emph{vision-left}}\textsf{~}\textsf{\textbf{(line-of-sight}}\textsf{~}\textsf{\emph{status}}\textsf{\textbf{))}},
for example, will return \textsf{\textbf{:unknown}}.
Note that feebs that are not peeking, mushrooms and carcasses are
\emph{not} be detected by these vectors. Also, if there is a feeb
-peeking to the opposite side, it won't be detected either. The
-elements in \textsf{\textbf{vision-left}} and \textsf{\textbf{vision-right}}
+peeking to the opposite side, it won't be detected either. The elements
+in \textsf{\textbf{vision-left}} and \textsf{\textbf{vision-right}}
are lists containing these elements:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{:peek-letf}}}] This means that in that square there
-is a feeb peeking to (its) left.
-\item [{\textsf{\textbf{:peek-right}}}] This means that in that square
+\item [{{\textsf{\textbf{:peek-letf}}}}] This means that in that square
+there is a feeb peeking to (its) left.
+\item [{{\textsf{\textbf{:peek-right}}}}] This means that in that square
there is a feeb peeking to (its) right.
-\item [{\textsf{\textbf{:rock}}}] This square is just a wall. In this case,
-this is the only element in the square.
+\item [{{\textsf{\textbf{:rock}}}}] This square is just a wall. In this
+case, this is the only element in the square.
\end{lyxlist}
\subsection{Extra functions provided}
Before making the brain of your feeb, you might want to take a look
-at the Extra functions that are available at the end of the feebs.lisp
-file. The only thing you need so you can use them is to see their
-code and know what they do.
+at the Extra functions that are available in the file \emph{definitions/extra.lisp}.
+The only thing you need so you can use them is to see their code and
+know what they do.
\subsection{Changing the map layout}
-It is possible to change the layout of the map by calling
-\textsf{\textbf{(change-layout}~new-layout\textbf{)}}.
+It is possible to change the layout of the map by calling \textsf{\textbf{(change-layout}}\textsf{~new-layout}\textsf{\textbf{)}}.
There are a few predefined mazes that are in variables \textsf{\textbf{{*}maze-0{*}}}
-(which is set by default) throw \textsf{\textbf{{*}maze-5{*}}}.
-In a layout, `X' represents a wall, `e' represents a feeb entry point
-(there will be as many entry points as feebs in the maze at the same time),
-`m' represents a mushroom site and ` ' is a blank space.
+(which is set by default) throw \textsf{\textbf{{*}maze-5{*}}}. In
+a layout, `X' represents a wall, `e' represents a feeb entry point
+(there will be as many entry points as feebs in the maze at the same
+time), `m' represents a mushroom site and ` ' is a blank space.
If you want to create a new map, you can start by an empty template
-of any size that is provided by \textsf{\textbf{(make-template}~x-size~y-size\textbf{)}},
-or you can get a reandom map calling
-\textsf{\textbf{(generate-maze}~x-size~y-size~\textbf{:density}~density\textbf{)}}
-The density is a number, recomended to be between 0.25 and 0.45,
-which tells the portion of the maze should be blank spaces.
-The function quits after a while if it doesn't meet this portion. See
-its documentation for more details and options.
+of any size that is provided by \textsf{\textbf{(make-template}}\textsf{~x-size~y-size}\textsf{\textbf{)}},
+or you can get a reandom map calling \textsf{\textbf{(generate-maze}}\textsf{~x-size~y-size~}\textsf{\textbf{:density}}\textsf{~density}\textsf{\textbf{)}}
+The density is a number, recomended to be between 0.25 and 0.45, which
+tells the portion of the maze should be blank spaces. The function
+quits after a while if it doesn't meet this portion. See its documentation
+for more details and options.
\subsection{Graphics}
@@ -482,7 +565,7 @@
After creating the image file, you must call \textsf{\textbf{(create-graphics}}\textsf{~path-to-image-file}\textsf{\textbf{)}}.
If you now how to work with sdl surfaces in lispbuilder, you may use
the function with a surface instead of a image file; or you can call
-\textsf{\textbf{(create-graphics}~path-to-image-file~nil\textbf{)}}
+\textsf{\textbf{(create-graphics}}\textsf{~path-to-image-file~nil}\textsf{\textbf{)}}
if the surface should not be freed after the call. The result must
be the third argument given to define-feeb.
@@ -492,13 +575,12 @@
The game loop is started by calling \textsf{\textbf{(simple-play)}}.
-
\section{Contests}
I sugest that you see this chapter only after you have created at
least a basic brain feeb, which is better than the (simple) provided
-brain, or if you want to participate of a contest or a game with
-your friends.
+brain, or if you want to participate of a contest or a game with your
+friends.
\subsection{\label{sub:Map}Map}
@@ -512,25 +594,25 @@
what is really in the maze, but only the possible ways.
To get the map, one can call \textsf{\textbf{(get-maze-map)}}. This
-function will return \textsf{\textbf{nil}} if parameter
-\textsf{\textbf{'may-get-maze-map-p}} is also \textsf{\textbf{nil}}.
-Otherwise, the map returned is an array, so that calling
-\textsf{\textbf{(aref}~map~x~y\textbf{)}} will get the contents
-in the position (x,y) (like euclidean but inverting the y axis).
-The contents of a cell could be one of these:
-
-\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{:mushroom-place}}}] A mushroom patch, i.e. when
-a mushroom is reincarnate, it could reincarnate here.
-\item [{\textsf{\textbf{:feeb-entry-place}}}] A feeb entry, i.e. if a carcass
-rots a feeb can appear here.
-\item [{\textsf{\textbf{:rock}}}] A wall. Feebs cannot come to this place.
-\item [{\textsf{\textbf{nil}}}] An {}``empty'' place, i.e. neither of
-the previous.
+function will return \textsf{\textbf{nil}} if parameter \textsf{\textbf{'may-get-maze-map-p}}
+is also \textsf{\textbf{nil}}. Otherwise, the map returned is an array,
+so that calling \textsf{\textbf{(aref}}\textsf{~map~x~y}\textsf{\textbf{)}}
+will get the contents in the position (x,y) (like euclidean but inverting
+the y axis). The contents of a cell could be one of these:
+
+\begin{lyxlist}{00.00.0000}
+\item [{{\textsf{\textbf{:mushroom-place}}}}] A mushroom patch, i.e.
+when a mushroom is reincarnate, it could reincarnate here.
+\item [{{\textsf{\textbf{:feeb-entry-place}}}}] A feeb entry, i.e. if
+a carcass rots a feeb can appear here.
+\item [{{\textsf{\textbf{:rock}}}}] A wall. Feebs cannot come to this
+place.
+\item [{{\textsf{\textbf{nil}}}}] An {}``empty'' place, i.e. neither
+of the previous.
\end{lyxlist}
+This map can safelly be used since \textsf{\textbf{(get-maze-map)}}
+makes a new copy every time it is called.
-This map can safelly be used since \textsf{\textbf{(get-maze-map)}} makes
-a new copy every time it is called.
\subsection{Timing}
@@ -541,17 +623,17 @@
To make this available, someone must set these parameters:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{'slow-feeb-noop-switch}}}] If is non-nil,
-there is a possibility that the move of a feeb is aborted according
-to its function time.
-\item [{\textsf{\textbf{'slow-feeb-noop-factor}}}] The probability
-of the feeb to abort will be this factor times the amount of time
-the feeb takes to have a decision, divided by the total time taken
+\item [{{\textsf{\textbf{'slow-feeb-noop-switch}}}}] If is non-nil, there
+is a possibility that the move of a feeb is aborted according to its
+function time.
+\item [{{\textsf{\textbf{'slow-feeb-noop-factor}}}}] The probability
+of the feeb to abort will be this factor times the amount of time
+the feeb takes to have a decision, divided by the total time taken
by all the feebs in the current turn or divided by a reference time.
-\item [{\textsf{\textbf{'reference-time}}}] Time taken by reference
-if non-nil.
-\item [{\textsf{\textbf{'points-for-slow-down}}}] Points earned when
-a feeb's move is aborted due to slowness.
+\item [{{\textsf{\textbf{'reference-time}}}}] Time taken by reference
+if non-nil.
+\item [{{\textsf{\textbf{'points-for-slow-down}}}}] Points earned when
+a feeb's move is aborted due to slowness.
\end{lyxlist}
\subsection{Sense of location}
@@ -562,10 +644,9 @@
These are the parameters:
\begin{lyxlist}{00.00.0000}
-\item [{\textsf{\textbf{'sense-location-p}}}] If nil,
-\textsf{\textbf{x-position}} and \textsf{\textbf{y-position}}
-will return nil when someone tries to invoke it.
-Otherwise return the position.
+\item [{{\textsf{\textbf{'sense-location-p}}}}] If nil, \textsf{\textbf{x-position}}
+and \textsf{\textbf{y-position}} will return nil when someone tries
+to invoke it. Otherwise return the position.
\end{lyxlist}
\subsection{Changing the rules}
@@ -574,11 +655,10 @@
feebs are defined, because in a feeb definition it could use the values
of the variables to make a global strategy.
-All the parameters, values and documentation that can be listed using
-\textsf{\textbf{(list-parameter-settings)}} can be changed using
-\textsf{\textbf{(change-feeb-parm name value)}}, which is deactivated
-during the game. Also, they all have documentation about themselves, so feel free to use
-\textsf{\textbf{(documentation~}}\textsf{'parameter~'feeb-parm}\textsf{\textbf{)}}
+All the parameters, values and documentation that can be listed using
+\textsf{\textbf{(list-parameter-settings)}} can be changed using \textsf{\textbf{(change-feeb-parm
+name value)}}, which is deactivated during the game. Also, they all
+have documentation about themselves, so feel free to use \textsf{\textbf{(documentation~}}\textsf{'parameter~'feeb-parm}\textsf{\textbf{)}}
and see what each parameter does. Documentation is available to external
functions as well.
@@ -589,5 +669,6 @@
Fahlman, S. E. \textbf{\emph{Planet of the Feebs -}} \emph{A Somewhat
Educational Game.} \url{ftp://ftp.csl.sri.com/pub/users/gilham/feebs/feebs.tex}.
\end{quote}
+\end{itemize}
\end{document}
1
0

15 Mar '08
Author: gmilare
Date: Sat Mar 15 13:56:01 2008
New Revision: 17
Modified:
definitions/rules.lisp
documentation/feebs.tex
graphics/graphics.lisp
system.lisp
the-feebs-war.asd
Log:
Modified: definitions/rules.lisp
==============================================================================
--- definitions/rules.lisp (original)
+++ definitions/rules.lisp Sat Mar 15 13:56:01 2008
@@ -202,15 +202,14 @@
(total-time)))))
(prog1 nil ; in case that the move was eating something
(incf (feeb-score feeb) (get-feeb-parm 'points-for-slow-down)))
- (call-next-method))
- (call-next-method)))
+ (call-next-method))
+ (call-next-method)))
(defmethod make-move :around ((feeb feeb) (move (eql :move-forward)))
- (let ((thing (find-if #'fireball-p (get-forward-pos feeb))))
- (if thing
- (destroy-object feeb thing)
- (call-next-method))))
-
+ (aif (find-if #'fireball-p (get-forward-pos feeb))
+ (if (call-next-method) ; was the move successfull?
+ (destroy-object feeb it))
+ (call-next-method)))
;;; Eating
@@ -242,6 +241,8 @@
"Amount of energy lost after throwing a flame.")
(defmethod make-move :around ((feeb feeb) (move (eql :flame)))
- (when (>= (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
+ (when (and (feeb-ready-to-fire feeb)
+ (>= (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy)))
+ (setf (feeb-ready-to-fire feeb) nil)
(decf (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
(call-next-method)))
Modified: documentation/feebs.tex
==============================================================================
--- documentation/feebs.tex (original)
+++ documentation/feebs.tex Sat Mar 15 13:56:01 2008
@@ -169,7 +169,7 @@
in front of the feeb, and it will see it, so the feeb shouldn't move
forward. For a few turns, the feeb will not be able to
throw flames. Each turn, the flame moves forward destroing mushrooms and
-killing feebs it encounters, transforming them into carcass. If there
+killing feebs it encounters, transforming them into carcasses. If there
is a wall, the flame can reflect, and, if so, it will turn 180 degrees.
Once a feeb is killed (or starves), in it's place in the maze there will appear
Modified: graphics/graphics.lisp
==============================================================================
--- graphics/graphics.lisp (original)
+++ graphics/graphics.lisp Sat Mar 15 13:56:01 2008
@@ -39,8 +39,7 @@
((wallp elt)
(list " XX"))
((feeb-p (car elt))
- (list "F~1d~a"
- (position (feeb-name (car elt)) *feebs* :key #'feeb-name)
+ (list " F~a"
(print-direction (feeb-facing (car elt)))))
((fireball-p (car elt))
(list " *~a" (print-direction (fireball-direction (car elt)))))
Modified: system.lisp
==============================================================================
--- system.lisp (original)
+++ system.lisp Sat Mar 15 13:56:01 2008
@@ -133,8 +133,8 @@
(:method ((fireball fireball) x-pos y-pos)
(push fireball *fireballs-flying*)
- (setf (object-x-position object) x-pos
- (object-y-position object) y-pos))) ; don't place it yet, only after first move
+ (setf (object-x-position fireball) x-pos
+ (object-y-position fireball) y-pos))) ; don't place it yet, only after first move
;;; Reincarnating
@@ -147,7 +147,7 @@
(defgeneric destroy-object (object cause)
(:documentation "Called when CAUSE destroys OBJECT.
CAUSE could be :starve or a fireball (for feebs)
-or :dissipate (for fireballs)."
+or :dissipate (for fireballs).")
(:method (object cause)
(delete-object object (object-x-position object)
(object-y-position object)))
@@ -191,7 +191,7 @@
returned from MAKE-MOVE-CHOICE for the same object.")
(:method (object move)
- nil)
+ (warn "Unknown move ~a for object ~a." move object))
(:method (object (move (eql :turn-right)))
(setf (object-direction object)
@@ -209,7 +209,8 @@
(multiple-value-bind (stuff new-x new-y)
(get-forward-pos object)
(unless (wallp stuff)
- (change-object-pos object new-x new-y))))
+ (change-object-pos object new-x new-y)
+ t)))
(:method ((fireball fireball) (move (eql :dissipate)))
(destroy-object fireball :dissipate))
Modified: the-feebs-war.asd
==============================================================================
--- the-feebs-war.asd (original)
+++ the-feebs-war.asd Sat Mar 15 13:56:01 2008
@@ -10,7 +10,7 @@
:version "0.1"
:author "Gustavo Henrique Milaré <gugamilare(a)gmail.com>"
:licence "GPL"
-; :depends-on (lispbuilder-sdl lispbuilder-sdl-image lispbuilder-sdl-gfx)
+; :depends-on (lispbuilder-sdl)
:components
((:cl-source-file "package")
@@ -18,6 +18,8 @@
(:cl-source-file "system" :depends-on ("utils"))
(:cl-source-file "images" :depends-on ("system"))
(:cl-source-file "main" :depends-on ("images"))
+ ;; GPL
+ (:doc-file "licence")
(:module "definitions"
:depends-on ("main")
@@ -27,15 +29,12 @@
(:cl-source-file "extra")
(:cl-source-file "brains")))
- (:module "graphics"
- :depends-on ("main")
- :components
- ((:file "graphics"))))
-
- ;; GPL
- (:doc-file "licence")
+ (:module "graphics"
+ :depends-on ("main")
+ :components
+ ((:file "graphics")))
- ;; documentation
- (:module "documentation"
- :components
- (:doc-file "feebs.tex")))
+ ;; documentation
+ (:module "documentation"
+ :components
+ ((:doc-file "feebs.tex")))))
1
0
Author: gmilare
Date: Sun Feb 17 15:29:26 2008
New Revision: 16
Added:
utils.lisp
Removed:
definitions/utils.lisp
Modified:
graphics/graphics.lisp
images.lisp
package.lisp
the-feebs-war.asd
Log:
Modified: graphics/graphics.lisp
==============================================================================
--- graphics/graphics.lisp (original)
+++ graphics/graphics.lisp Sun Feb 17 15:29:26 2008
@@ -18,8 +18,11 @@
along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
|#
+
(in-package :the-feebs-war)
+
+
(defun print-direction (dir)
(case dir
(0 #\N)
Modified: images.lisp
==============================================================================
--- images.lisp (original)
+++ images.lisp Sun Feb 17 15:29:26 2008
@@ -40,10 +40,6 @@
left-square
right-square)
-(defun rcurry (func &rest args)
- #'(lambda (x)
- (apply func x args)))
-
;;; Computes what the feeb is seeing
Modified: package.lisp
==============================================================================
--- package.lisp (original)
+++ package.lisp Sun Feb 17 15:29:26 2008
@@ -122,6 +122,7 @@
(in-package :the-feebs-war)
+
;;; Directions
(deftype direction ()
Modified: the-feebs-war.asd
==============================================================================
--- the-feebs-war.asd (original)
+++ the-feebs-war.asd Sun Feb 17 15:29:26 2008
@@ -13,22 +13,24 @@
; :depends-on (lispbuilder-sdl lispbuilder-sdl-image lispbuilder-sdl-gfx)
:components
- (:cl-source-file "package")
- (:cl-source-file "system" :depends-on ("package"))
- (:cl-source-file "images" :depends-on ("system"))
- (:cl-source-file "main" :depends-on ("images" "system"))
+ ((:cl-source-file "package")
+ (:cl-source-file "utils" :depends-on ("package"))
+ (:cl-source-file "system" :depends-on ("utils"))
+ (:cl-source-file "images" :depends-on ("system"))
+ (:cl-source-file "main" :depends-on ("images"))
- (:module "definitions"
- :components
- (:cl-source-file "utils")
- (:cl-source-file "rules" :depends-on ("main"))
- (:cl-source-file "mazes" :depends-on ("package" "utils"))
- (:cl-source-file "extra" :depends-on ("package"))
- (:cl-source-file "brains" :depends-on ("package")))
+ (:module "definitions"
+ :depends-on ("main")
+ :components
+ ((:cl-source-file "rules")
+ (:cl-source-file "mazes")
+ (:cl-source-file "extra")
+ (:cl-source-file "brains")))
(:module "graphics"
+ :depends-on ("main")
:components
- (:file "graphics" :depends-on ("main")))
+ ((:file "graphics"))))
;; GPL
(:doc-file "licence")
Added: utils.lisp
==============================================================================
--- (empty file)
+++ utils.lisp Sun Feb 17 15:29:26 2008
@@ -0,0 +1,55 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+
+(in-package :the-feebs-war)
+
+
+
+(defun bound-random (start min avg max)
+ (+ start
+ (* (expt -1 (random 2))
+ (let ((sort (random 2.0)))
+ (round
+ (if (< sort 1.0)
+ (+ min (* sort (- avg min)))
+ (+ avg (* (1- sort) (- max avg)))))))))
+
+(defun random-elt (seq)
+ (if seq
+ (elt seq (random (length seq)))))
+
+(defmacro ensure-bound (elt min max)
+ `(setf ,elt (bound ,elt ,min ,max)))
+
+(defun bound (elt min max)
+ (max min (min max elt)))
+
+(defmacro aif (test then &optional else)
+ `(let ((it ,test))
+ (if it ,then ,else)))
+
+(defmacro awhen (test &rest body)
+ `(let ((it ,test))
+ (when it ,@body)))
+
+(defun rcurry (func &rest args)
+ #'(lambda (x)
+ (apply func x args)))
1
0

16 Feb '08
Author: gmilare
Date: Sat Feb 16 15:01:42 2008
New Revision: 15
Added:
definitions/brains.lisp (contents, props changed)
definitions/extra.lisp (contents, props changed)
definitions/mazes.lisp (contents, props changed)
definitions/rules.lisp (contents, props changed)
definitions/utils.lisp
documentation/feebs.tex (contents, props changed)
graphics/graphics.lisp (contents, props changed)
Modified:
/ (props changed)
definitions/ (props changed)
Log:
Added: definitions/brains.lisp
==============================================================================
--- (empty file)
+++ definitions/brains.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,65 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+
+(in-package :the-feebs-war)
+
+
+;;; Modified from "cautious-brain"
+
+(defun auto-brain (status proximity vision vision-left vision-right)
+ (declare (ignore vision-left vision-right))
+ (let ((stuff (my-square proximity)))
+ (cond ((and (member :mushroom stuff :test #'eq)
+ (< (energy-reserve status)
+ (- (get-feeb-parm 'maximum-energy) 20)))
+ :eat-mushroom)
+ ((member :carcass stuff :test #'eq)
+ :eat-carcass)
+ ((and (ready-to-fire status)
+ (> (energy-reserve status) 30)
+ (dotimes (index (min (line-of-sight status) 5))
+ (let ((feeb (find-if #'feeb-image-p (svref vision index))))
+ (if (and feeb
+ (not (eq (feeb-image-facing feeb)
+ (facing status))))
+ (return t)))))
+ :flame)
+ ((and (not (wallp (left-square proximity)))
+ (or (member :mushroom (left-square proximity))
+ (> 3 (random 10))))
+ :turn-left)
+ ((and (not (wallp (right-square proximity)))
+ (or (member :mushroom (right-square proximity))
+ (> 3 (random 10))))
+ :turn-right)
+ ((and (> (line-of-sight status) 0)
+ (not (dotimes (index (min (line-of-sight status) 7))
+ (if (find #'fireball-image-p (svref vision index))
+ (return t)))))
+ :move-forward)
+ (t
+ :turn-around))))
+
+(defun make-auto-feebs (n)
+ (dotimes (i n)
+ (define-feeb
+ (format nil "System Feeb # ~d" i)
+ #'auto-brain)))
Added: definitions/extra.lisp
==============================================================================
--- (empty file)
+++ definitions/extra.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,128 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+
+;;; Usefull for creating a feeb
+;;; These are optimized so someone can use them without
+;;; complaining that they slow down your feeb !!!
+
+(in-package :the-feebs-war)
+
+(declaim (optimize (speed 3) (safety 0))
+
+ (inline left-of right-of behind
+ forward-dx forward-dy
+ left-dx left-dy
+ right-dx right-dy
+ behind-dx behind-dy
+
+ relative-facing
+
+ wallp chance)
+
+ ((function ((integer 0 3)) (integer 0 3))
+ left-of right-of behind
+ relative-facing)
+
+ ((function ((integer 0 3)) (integer -1 1))
+ forward-dx forward-dy
+ left-dx left-dy
+ right-dx right-dy
+ behind-dx behind-dy)
+
+ ((function (rational) boolean)
+ chance))
+
+;;; Directional arithmetic.
+
+(defun right-of (facing)
+ (mod (+ facing 3) 4))
+
+(defun left-of (facing)
+ (mod (+ facing 1) 4))
+
+(defun behind (facing)
+ (mod (+ facing 2) 4))
+
+(defun relative-facing (my-facing other-facing)
+ (mod (- my-facing other-facing) 4))
+
+(defun forward-dy (facing)
+ (if (oddp facing)
+ 0
+ (rem (1- facing) 4)))
+
+(defun forward-dx (facing)
+ (if (oddp facing)
+ (rem (- 2 facing) 4)
+ 0))
+
+(defun left-dy (facing)
+ (forward-dy (left-of facing)))
+
+(defun left-dx (facing)
+ (forward-dx (left-of facing)))
+
+(defun right-dy (facing)
+ (forward-dy (right-of facing)))
+
+(defun right-dx (facing)
+ (forward-dx (right-of facing)))
+
+(defun behind-dy (facing)
+ (forward-dy (behind facing)))
+
+(defun behind-dx (facing)
+ (forward-dx (behind facing)))
+
+;;; Tests
+
+(defun wallp (thing)
+ (the boolean
+ (eq :rock (car thing))))
+
+(defun chance (ratio)
+ (< (random (denominator ratio)) (numerator ratio)))
+
+#|
+;;; Handling the vision, vision-left and vision-right objects
+ (defmacro with-visible-elements ((count line-of-sight)
+ ((vis vision) &body vis-body)
+ ((vis-l vision-left) &body vis-l-body)
+ ((vis-r vision-right) &body vis-r-body)
+ &body finalize)
+ (let ((v (gensym))
+ (vl (gensym))
+ (vr (gensym)))
+ `(do* ((,count 1 (1+ ,count))
+ (,v (svref ,vision ,count))
+ (,vl (svref ,vision ,count))
+ (,vr (svref ,vision ,count)))
+ ((= ,count line-of-sight)
+ ,@finalize)
+ (declare (list ,v ,vl ,vr)
+ (fixnum ,count))
+ (dolist (,vis ,v)
+ ,@vis-body)
+ (dolist (,vis-l ,vl)
+ ,@vis-l-body)
+ (dolist (,vis-r ,vr)
+ ,@vis-r-body))))
+|#
\ No newline at end of file
Added: definitions/mazes.lisp
==============================================================================
--- (empty file)
+++ definitions/mazes.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,359 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+;;; The mazes were
+;;; Created by Jim Healy, July 1987.
+;;;
+;;; **************************************************
+;;; Maze guidelines:
+;;; X represents a wall.
+;;; * represents a mushroom patch.
+;;; e is a feeb entry point.
+;;;
+;;; The maze should be a rectangle bounded by walls
+;;; in each side.
+;;; These mazes are all 32x32, but you may build
+;;; a maze of any size you wish.
+;;; **************************************************
+
+;;; Maze1 has a good number of dead ends and little nooks.
+
+(in-package :the-feebs-war)
+
+(defparameter *maze-1*
+ '("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "XXX *eXXXX *e ** X"
+ "XXX XXXXX XXXX XXXXXXXXXXXX XX X"
+ "XXX XXX XXXXXX X X"
+ "XXXXX XXXXXXX XXXXXXX XXXXXXX XX"
+ "X * XXX XX * XeXX XX"
+ "X XXXXXXX XXX XXXXXXX X XXX XXXX"
+ "X XXXXXX XXX XX X *XX"
+ "X XXXXXXX XXX XXXXXXX XXXXXXXXXX"
+ "X XXXXXXX XXX* e XXXXXX XXX"
+ "X XXXXX XXXXXXXXX * XXX"
+ "X XXXXX XXXXXX XXXXXX XX XX"
+ "X eXXXX XXXXXX XXX XXXXX XX XXX"
+ "X XXXXX* XXXXe XXXX XX XX"
+ "X XXXXX XXXXXX XXXXX XXX XXX XX"
+ "X eXXXX e XXXXXX *XX XX XX"
+ "X XXXXX XXXXXX XXXXXXX X XXeXXX"
+ "X XXX XXXXXXXX XX XX"
+ "X XXXXX XXXXXX XXXXXXXXXX XXXXXX"
+ "X XXXXX * XXXXX XX"
+ "X* XXX XXXXXX XXXXX XXXXXX X XX"
+ "X XXXXX e XXXXX X e X XX"
+ "X XX XX XXXXXX XXXXX X XXXXXX XX"
+ "X *XXX XXXXX * XX"
+ "X XX XX XXXXXX XXXXXXXXXX XXXXXX"
+ "X XXXXX XXXXXX * * XX"
+ "X XXX XXXXXXXXXXXXXXXXXXXXX XX"
+ "X XXXX X X eX X XX"
+ "X XXX XX X XX X XX X XX X XX XX"
+ "X XXXX XX X XX X XX X XX*X XX XX"
+ "X e * XX XX * XX XX XXeXX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+
+;;; Maze2 doesn't have any really long corridors.
+
+(defparameter *maze-2*
+ '("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "X eXXXXX * X XXXXXX X e XXXXX"
+ "X XXXX X X XXXX X X XXXXX"
+ "X XX XXXX XXXX X* X X XXXXX"
+ "XX XX XXX XXXX XX XX X X"
+ "XX e XXX XXXXXXX XX XXXXXXXX*X"
+ "XXXX XXX XXXXX X e XXX XX X"
+ "XXXX XXX XXXXXXXX XXXX X X"
+ "XX * XX XXe XXXXXXXXXX XX XXX"
+ "XX XXXX X XX X XXX XXXXX XXX"
+ "XX XX XXX X XX XXXXX"
+ "XXXXX XXX *XXX X XXXXXXXX"
+ "XX* XXXXXX XXXX XXXX XXXXXXXX"
+ "XXXXX XX XXXX XXXXXXXXX XXXXXXXX"
+ "XXXXX e XXXX *XXXXXX eXXXXX"
+ "XXXXXXXX XXXXXXX XXXXXXXXX XXXXX"
+ "XXXXXX XXXXX eXXXXX XXXXX"
+ "XXXXXX XXX XXXXXXX XXXXX XXXXXXX"
+ "XX XXX X XXX XX X XX"
+ "XX XXX XXXXX XX XX XXX XX XX"
+ "XX XXXXX *X XX X XX XXXXXX*XX"
+ "X XXXXX XXXX X XX XX"
+ "X XX XXXXXXX XXXXX*X X Xe XXXX"
+ "X XXXX e X XXXXX*XX XX XXXX"
+ "X XX XXXXXX XX XXX*XXX XXX"
+ "XXXX eXXX XXXX XX XXXXX X X"
+ "XXXXXX XXXXXXXXX XX XXXX XXX X"
+ "XXX * X X XX XXXX XXX X X"
+ "XX XXXX X XX XXXX XXX X e X"
+ "XX XX * X * X XXXX XX XXX*X"
+ "XX XXX XXX XX eXXX XXX*X"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+
+;;; Maze3 has the minimum number of mushroom sites, most
+;;; of which are between a rock and a hard place. Those
+;;; poor feebs!
+
+(defparameter *maze-3*
+ '("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "X e XXXXXX XXXXXXX*XXXXXXXXX"
+ "X X XXX XXXXX e XXXX XXX e X"
+ "X XXX XXXXXX XX XX XXX XXX X"
+ "XXX XXX XXXXXX XX XX X X e X"
+ "Xe XXX*XXXX* XX XXeX X XXXXX X"
+ "X X XXX XXXXXX XX XX X XXXXX X"
+ "X XXX XXXXXX XX* XXXXXXXXX X"
+ "X XXXXX XX e XX XXXXXXXX XXX X"
+ "X X XXX XXX XXXXX XXXXXX XXX X"
+ "Xe XXX XXXX XXXX X X X"
+ "XXX XXXX XXXXXXXX X XXX XXX"
+ "XXX eXX XXXXXXXXX XXXXX XXXXX"
+ "XXXXX XXXXXXXXXXXX XXXXXX XXX"
+ "XXXXX * XX eXX XXX XX XXX"
+ "XX*XXXX XXXXXX XX XXX XXX XX XXX"
+ "XX X XXXXX X XXX eXX XXX"
+ "X XXXXXXXX XX XXXX XXX XX XXX"
+ "X XXXXeXXXXXX XXXX XXX XX XXX"
+ "X XX*XXXXX XXXXXXXXX XXX"
+ "XXXXXX XXX XXXX XXXXXX XXX"
+ "XXXXXXXXX XXX XXXXXX XXXXXX XXX"
+ "XXX XX e eX XXXX"
+ "XX XXXXX XXXX XXXX XXXX XXXX"
+ "XX XXXXX XX XXXX XXXX XXXX XX"
+ "XX eXXXX XX XXXX XXXX XXXXXX XX"
+ "XXX XX XXX * XXX XX"
+ "XX XX XXXX* XXXX XXXX XXXXXX XX"
+ "XXX X XXXXX XXXX XXXX X XX"
+ "XXXX e XXXX XXXX X XX X X"
+ "XXXXXXXXXXXX *e X e XX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+
+
+;;; Maze4 is symmetric about the vertical axis. (Wow...)
+
+(defparameter *maze-4*
+ '("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "X* eXXXXXXXXXXe *X"
+ "X XXXXXXXX XXXXXXXX X"
+ "X XX XXXXXXX XX XXXXXXX XX X"
+ "X XeXXXXXXX XX XXXXXXXeX X"
+ "XX X XXXXXXX eXXe XXXXXXX X XX"
+ "XX X XXXXXXX XXXXXX XXXXXXX X XX"
+ "XX * XXXXXXX XXXXXX XXXXXXX * XX"
+ "XX X XXXe eXXX X XX"
+ "XX X XXX XXXXXXXXXXXXXX XXX X XX"
+ "XX e XXX XXXXXXXX XXX e XX"
+ "XX X XXXXXX XXXXXXXX XXXXXX X XX"
+ "XX X XXXX XXXXXXXX XXXX X XX"
+ "XX XXXX XXXe eXXXX XXXX XX"
+ "XXX XXXXX XXX XXX XXXX XXXXX XXX"
+ "XXX XXXXX XXX XXX XXXXX XXX"
+ "X* XXXXX XXXX XXXXX *X"
+ "X XXXXX XX XX ** XX XX XXXXX X"
+ "X XXXXX XX XX XXXX XX XX XXXXX X"
+ "X XXX e XX XX XXXX XX XX e XXX X"
+ "X XXXXX XX XXXX XX XXXXX X"
+ "X XXXXX XXXXX XXXX XXXXX XXXXX X"
+ "X X XXXXX XXXX XXXXX X X"
+ "XXXXX * * XXXXX"
+ "XXXXX XXXXXXXX XX XXXXXXXX XXXXX"
+ "XXXXX XXXXXXXX XX XXXXXXXX XXXXX"
+ "XXXXX XXXXX XX XXXXX XXXXX"
+ "XXXX XX XXXXeXXeXXXX XX XXXX"
+ "XXX XXXX XXX XX XXX XXXX XXX"
+ "XXX XXXXXX XXX XX XXX XXXXXX XXX"
+ "XX* e XX e *XX"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+
+;;; Maze5 has a lot of long corridors good for feeb showdowns.
+;;; Furthermore, all the feeb entry-points are in the corridors.
+;;; You can run but you can't hide!
+
+(defparameter *maze-5*
+ '("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ "X e e X"
+ "X XXXXXXX*XXXXXXXXXXXX XXXXXXX X"
+ "X e X"
+ "X X XXXXX XXXXXXXXXXXX XXXXX X X"
+ "X * X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XXeXX X X"
+ "X X XX XX * XX XX X X"
+ "XeX XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX e XX XXeX X"
+ "X X XXeXX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX XeX"
+ "X*X XX XX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X XeXX XX XXXXXXXXXXXX*XX XX X X"
+ "X X XX XX * XX XX*X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX e XX XX*X X"
+ "X X XX*XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XX XXeX X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X X XX XX XXXXXXXXXXXX XX XX X X"
+ "X e X"
+ "X*X XXXXX XXXXXXXXXXXX XXXXX X*X"
+ "X e * X"
+ "X XXXXXXX XXXXXXXXXXXX XXXXXXX X"
+ "X e * X"
+ "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+
+;;; Use this function to create new mazes
+;;; of any size.
+
+(defun make-template (x-size y-size)
+ "Prints map template of the requested size.
+Use this to create new mazes."
+ (loop repeat y-size collect
+ (make-string x-size :initial-element #\X)))
+
+(defun density (maze xs ys)
+ (let ((sum 0))
+ (dotimes (x xs)
+ (dotimes (y ys)
+ (if (not (aref maze x y))
+ (incf sum))))
+ (float (/ sum (* xs ys)))))
+
+(defun horiz-corridor (map y x1 x2)
+ (do ((x x1 (if (< x1 x2) (1+ x) (1- x))))
+ ((= x x2))
+ ;; we need to guarantee that everything in map is
+ ;; corridors, that is, can't have something like
+ ;; XXXXXXXX
+ ;; XXX X
+ ;; X XXX
+ ;; XXXXXXXX
+ ;; that big blank square isn't good due
+ ;; to the limited vision of the feebs
+ (and (not (aref map x (1- y))) ; blank square up
+ (or (and (not (aref map (1+ x) y)) ; blank square to the right
+ (not (aref map (1+ x) (1- y)))) ; blank square up-right
+ (and (not (aref map (1- x) (1- y))) ; blank square up-left
+ (not (aref map (1- x) y)))) ; blank square to the left
+ (return)) ; can't make a blank square here, stop
+ (and (not (aref map x (1+ y))) ; blank square down
+ (or (and (not (aref map (1+ x) y)) ; blank square to the right
+ (not (aref map (1+ x) (1+ y)))) ; blank square down-right
+ (and (not (aref map (1- x) (1+ y))) ; blank square down-left
+ (not (aref map (1- x) y)))) ; blank square to the left
+ (return)) ; can't make a blank square here, stop
+ (setf (aref map x y) nil))
+ map)
+
+(defun vert-corridor (map x y1 y2)
+ (do ((y y1 (if (< y1 y2) (1+ y) (1- y))))
+ ((= y y2))
+ (and (not (aref map (1- x) y))
+ (or (and (not (aref map x (1+ y)))
+ (not (aref map (1- x) (1+ y))))
+ (and (not (aref map (1- x) (1- y)))
+ (not (aref map x (1- y)))))
+ (return))
+ (and (not (aref map (1+ x) y))
+ (if (or (and (not (aref map x (1+ y)))
+ (not (aref map (1+ x) (1+ y))))
+ (and (not (aref map (1+ x) (1- y)))
+ (not (aref map x (1- y)))))
+ (return)))
+ (setf (aref map x y) nil))
+ map)
+
+(defun translate (map xs ys)
+ (loop for y from (1- ys) downto 0 collect
+ (let ((str (make-string xs)))
+ (dotimes (x xs str)
+ (setf (aref str x)
+ (if (aref map x y)
+ #\X
+ #\Space))))))
+
+;;; This one generates an almost ready-to-use map
+
+(defun generate-maze (x-size y-size
+ &key (density 0.4)
+ (corridor-x-min 1)
+ (corridor-x-max (- x-size 2))
+ (corridor-x-avg (floor x-size 4))
+ (corridor-y-min 1)
+ (corridor-y-max (- y-size 2))
+ (corridor-y-avg (floor y-size 4)))
+ "Generates a maze of size X-SIZE x Y-SIZE (at least 10x10)
+with no entry points and no mushroom sites.
+DENSITY decides aproximatelly the ratio
+ (blank squares) / (total squares)
+recomended to be between 0.25 and 0.45.
+The horizontal corridors will be between CORRIDOR-X-MIN
+and CORRIDOR-X-MAX around CORRIDOR-X-AVG, when
+possible; similarly for vertical corridors.
+It returns two values, a layout like *maze-0* and its density."
+ (if (or (< x-size 10) (< y-size 10))
+ (error "Too small - should be at least 10x10."))
+ ;; Certifying the values to be acceptable
+ (ensure-bound corridor-x-avg
+ (ensure-bound corridor-x-min 1 (- x-size 2))
+ (ensure-bound corridor-x-max 3 (- x-size 2)))
+ (ensure-bound corridor-y-avg
+ (ensure-bound corridor-y-min 1 (- y-size 2))
+ (ensure-bound corridor-y-max 3 (- y-size 2)))
+ ;; Beginning with an array of walls
+ (let ((map (make-array (list x-size y-size)
+ :initial-element t
+ :element-type 'boolean)))
+ (do* ((i 1 (1+ i))
+ (y 1 y*) ; position of horizontal corridor
+ (y* (- y-size 2) (1+ (random (- y-size 2))))
+ (x1 (1+ (random (- x-size 2))) ; start position of horiz corridor
+ x1*)
+ (x1* (1+ (random (- x-size 2)))
+ (random-elt
+ (loop for x from 1 to (- x-size 2) ; any blank space
+ if (not (aref map x y)) collect x))) ; in line
+ (x2 (if x1 (bound-random x1 corridor-x-min
+ corridor-x-avg corridor-x-max))
+ (if x1 (bound-random x1 corridor-x-min
+ corridor-x-avg corridor-x-max)))
+ (x 1 x*) ; position of vertical corridor
+ (x* (- x-size 2) (1+ (random (- x-size 2))))
+ (y1 (1+ (random (- y-size 2)))
+ y1*)
+ (y1* (1+ (random (- y-size 2)))
+ (random-elt
+ (loop for y from 1 to (- y-size 2)
+ if (not (aref map x y)) collect y)))
+ (y2 (if y1 (bound-random y1 corridor-y-min
+ corridor-y-avg corridor-y-max))
+ (if y1 (bound-random y1 corridor-y-min
+ corridor-y-avg corridor-y-max)))
+ (real-dens (density map x-size y-size)))
+ ((or (>= real-dens density)
+ (> i (* density x-size y-size))) ; quits after trying TOO MUCH
+ (values (translate map x-size y-size) real-dens))
+ (if x1
+ (setf map (horiz-corridor map y x1
+ (bound x2 1 (- x-size 2)))))
+ (if y1
+ (setf map (vert-corridor map x y1
+ (bound y2 1 (- x-size 2))))))))
Added: definitions/rules.lisp
==============================================================================
--- (empty file)
+++ definitions/rules.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,247 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+
+(in-package :the-feebs-war)
+
+
+
+;;; -*- General Rules -*-
+
+(def-feeb-parm 'game-length 320
+ "Number of turns the game will last.")
+
+(def-feeb-parm 'number-of-mushrooms 3
+ "Maximum number of mushrooms created each turn.")
+
+(let (turn-number total-time)
+
+ (defun start-round ()
+ (setf turn-number 0))
+
+ (defun start-turn ()
+ (incf turn-number)
+ (setf total-time 0)
+ (number-of-mushrooms
+ (random (1+ (get-feeb-parm 'number-of-mushrooms)))))
+
+ (defun finish-game-p ()
+ (= (get-feeb-parm 'game-length) turn-number))
+
+ (defun inc-total-time (time)
+ (incf time total-time))
+
+ (defun total-time ()
+ total-time))
+
+;;; Detecting if feeb is playing
+
+(def-feeb-parm 'sense-location-p t
+ "If nil, x-position and y-position will return nil when
+ someone tries to invoke it. Otherwise return the position.")
+
+(defmethod x-position :around ((fb feeb))
+ (if (get-feeb-parm 'sense-location-p)
+ (call-next-method)))
+
+(defmethod y-position :around ((fb feeb))
+ (if (get-feeb-parm 'sense-location-p)
+ (call-next-method)))
+
+
+
+;;; -*- Being Born and Dying -*-
+
+;;; Being Born / Reincarnating
+
+(def-feeb-parm 'starting-energy 50
+ "Amount of energy a feeb will start with.")
+
+(defmethod create-object :before ((feeb feeb) x y)
+ (setf (feeb-energy-reserve feeb)
+ (get-feeb-parm 'starting-energy)
+ (feeb-ready-to-fire feeb) t))
+
+;;; Dying and Killing
+
+(def-feeb-parm 'points-for-dying -3
+ "How many points some feeb earn for dying (usually negative).")
+
+(defmethod destroy-object :before ((feeb feeb) cause)
+ (incf (feeb-score feeb) (get-feeb-parm 'points-for-dying)))
+
+(def-feeb-parm 'points-for-killing 5
+ "How many points some feeb earn for killing someone.")
+
+(defmethod destroy-object :before ((feeb feeb) (fireball fireball))
+ (let ((owner (fireball-owner fireball)))
+ (unless (eq owner feeb)
+ (incf (feeb-score owner) (get-feeb-parm 'points-for-killing))
+ (incf (feeb-kill-counter owner)))))
+
+;;; Carcasses:
+
+(def-feeb-parm 'carcass-guaranteed-lifetime 5
+ "Number of turns that a carcass will surely not rot.
+After these turns, it can rot, depending on probabilities.")
+
+(def-feeb-parm 'carcass-rot-probability 1/3
+ "Probability of the carcass to rot, after the apropriate time.")
+
+(defun rot-carcass-p (time)
+ (and (> time (get-feeb-parm 'carcass-guaranteed-lifetime))
+ (chance (get-feeb-parm 'carcass-rot-probability))))
+
+
+
+;;; -*- Movement Choice -*-
+
+;;; Fireballs:
+
+(def-feeb-parm 'fireball-dissipation-probability 1/5
+ "Probability of the flame to dissipate each turn after the
+apropriate time.")
+
+(def-feeb-parm 'fireball-reflection-probability 2/3
+ "Probability of the flame to reflect when encountering a wall.")
+
+(defmethod make-move-choice ((fireball fireball))
+ (cond
+ ((wallp (get-forward-pos fireball))
+ (if (chance (get-feeb-parm 'fireball-reflection-probability))
+ :turn-around
+ :dissipate))
+ ((chance (get-feeb-parm 'fireball-dissipation-probability))
+ :dissipate)
+ (t :move-forward)))
+
+
+;;; Feebs
+
+(def-feeb-parm 'flame-no-recovery-time 2
+ "Probability
+of the feeb to recover the hability to throw a flame, after the apropriate
+time.")
+
+(def-feeb-parm 'flame-recovery-probability 1/3
+ "Probability of the feeb to recover the hability to throw a flame,
+after the apropriate time.")
+
+(defmethod make-move-choice :around ((feeb feeb))
+ (unless (feeb-ready-to-fire feeb)
+ (and (> (feeb-turns-since-flamed feeb)
+ (get-feeb-parm 'flame-no-recovery-time))
+ (chance (get-feeb-parm 'flame-recovery-probability))
+ (setf (feeb-ready-to-fire feeb) t)))
+ (let (choice)
+ (inc-total-time
+ (setf (feeb-time feeb)
+ (+ (- (get-internal-real-time))
+ (progn
+ (setf choice (call-next-method))
+ (get-internal-real-time)))))
+ choice))
+
+
+
+;;; -*- Moving -*-
+
+;;; Fireball
+
+(defmethod make-move :before ((fireball fireball) (move (eql :move-forward)))
+ (multiple-value-bind (stuff x-pos y-pos)
+ (get-forward-pos fireball)
+ (dolist (thing stuff)
+ (typecase thing
+ (feeb (destroy-object thing fireball))
+ ((eql :mushroom)
+ (delete-object thing x-pos y-pos))))))
+
+
+;;; Feebs
+
+(def-feeb-parm 'slow-feeb-noop-switch nil
+ "If is non-nil, there is a possibility that the move
+of a feeb is aborted according to its function evaluation
+time.")
+
+(def-feeb-parm 'slow-feeb-noop-factor 1/4
+ "The probability of the feeb to abort will be this factor
+times the amount of time the feeb takes to have a decision,
+divided by the total time taken by all the feebs in the
+current turn, or divided by a reference time.")
+
+(def-feeb-parm 'reference-time nil
+ "Time taken by reference if non-nil. See slow-feeb-noop-factor.")
+
+(def-feeb-parm 'points-for-slow-down -1
+ "Points earned when a feeb's move is aborted due to slowness.")
+
+(defmethod make-move :around ((feeb feeb) move)
+ (if (get-feeb-parm 'slow-feeb-noop-switch)
+ (if (chance (* (get-feeb-parm 'slow-feeb-noop-factor)
+ (/ (feeb-time feeb)
+ (or (get-feeb-parm 'reference-time)
+ (total-time)))))
+ (prog1 nil ; in case that the move was eating something
+ (incf (feeb-score feeb) (get-feeb-parm 'points-for-slow-down)))
+ (call-next-method))
+ (call-next-method)))
+
+(defmethod make-move :around ((feeb feeb) (move (eql :move-forward)))
+ (let ((thing (find-if #'fireball-p (get-forward-pos feeb))))
+ (if thing
+ (destroy-object feeb thing)
+ (call-next-method))))
+
+
+;;; Eating
+
+(def-feeb-parm 'maximum-energy 100
+ "The most energy a feeb can accumulate.")
+
+(def-feeb-parm 'mushroom-energy 50
+ "Amount of energy recovered when the feeb eats a mushroom.")
+
+(defmethod make-move :around ((feeb feeb) (move (eql :eat-mushroom)))
+ (when (call-next-method) ; was eating successfull?
+ (setf (feeb-energy-reserve feeb)
+ (min (+ (feeb-energy-reserve feeb)
+ (get-feeb-parm 'mushroom-energy))
+ (get-feeb-parm 'maximum-energy)))))
+
+(def-feeb-parm 'carcass-energy 30
+ "Amount of energy recovered each turn that the feeb
+eats a carcass.")
+
+(defmethod make-move :around ((feeb feeb) (move (eql :eat-carcass)))
+ (when (call-next-method)
+ (setf (feeb-energy-reserve feeb)
+ (min (+ (feeb-energy-reserve feeb)
+ (get-feeb-parm 'carcass-energy))
+ (get-feeb-parm 'maximum-energy)))))
+
+(def-feeb-parm 'flame-energy 10
+ "Amount of energy lost after throwing a flame.")
+
+(defmethod make-move :around ((feeb feeb) (move (eql :flame)))
+ (when (>= (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
+ (decf (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
+ (call-next-method)))
Added: definitions/utils.lisp
==============================================================================
--- (empty file)
+++ definitions/utils.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,49 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+
+(in-package :the-feebs-war)
+
+(defun bound-random (start min avg max)
+ (+ start
+ (* (expt -1 (random 2))
+ (let ((sort (random 2.0)))
+ (round
+ (if (< sort 1.0)
+ (+ min (* sort (- avg min)))
+ (+ avg (* (1- sort) (- max avg)))))))))
+
+(defun random-elt (seq)
+ (if seq
+ (elt seq (random (length seq)))))
+
+(defmacro ensure-bound (elt min max)
+ `(setf ,elt (bound ,elt ,min ,max)))
+
+(defun bound (elt min max)
+ (max min (min max elt)))
+
+(defmacro aif (test then &optional else)
+ `(let ((it ,test))
+ (if it ,then ,else)))
+
+(defmacro awhen (test &rest body)
+ `(let ((it ,test))
+ (when it ,@body)))
Added: documentation/feebs.tex
==============================================================================
--- (empty file)
+++ documentation/feebs.tex Sat Feb 16 15:01:42 2008
@@ -0,0 +1,593 @@
+
+% Copyright (c) 2007,2008 Gustavo Henrique Milar�
+%
+% This file is part of The Feebs War.
+%
+% The Feebs War is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 3 of the License, or
+% (at your option) any later version.
+%
+% The Feebs War is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+
+\documentclass[english]{article}
+\usepackage[T1]{fontenc}
+\usepackage[latin1]{inputenc}
+\IfFileExists{url.sty}{\usepackage{url}}
+ {\newcommand{\url}{\texttt}}
+
+\makeatletter
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands.
+\newenvironment{lyxlist}[1]
+{\begin{list}{}
+{\settowidth{\labelwidth}{#1}
+ \setlength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}[1]{##1\hfil}}}
+{\end{list}}
+
+
+\IfFileExists{url.sty}{\usepackage{url}
+}
+ {\newcommand{\url}{\texttt}}
+
+\makeatletter
+
+
+
+
+\makeatother
+
+\usepackage{babel}
+\makeatother
+
+\begin{document}
+
+\title{\textbf{\huge The Feebs War}}
+
+
+\author{Gustavo Henrique Milar�}
+
+\maketitle
+\begin{abstract}
+\textit{The Feebs War} is a modified version of Planet of the Feebs
+\url{http://www.cliki.net/}, a game made for people learn and improve
+their lisp and code manipulation tecniques. The graphics are now displayed
+using Lispbuilder \url{http://lispbuilder.sourceforge.net}'s libraries,
+so the problems with portability from CMUCL and X Window Sistem do
+not exist anymore. Also the code is cleaner and more extensible.
+\end{abstract}
+\tableofcontents{}
+
+
+\section{Introduction}
+
+The Feebs are intelligent and hostile creatures that live inside maze
+tunnels. They also have no mercy with each other, so they frequently
+throw a letal flame from through their mouth, getting rid of their
+opponent and eatting the carcass left. But throwing flames have an
+energy cost, so they must keep tracking for food.
+
+This game is intended to help lisp newbies (or maybe a little more
+advanced lispers) to learn lisp. A player must create a function that
+receives what his/her feeb is seeing and feeling, and returns what
+it will do next. To create the better feeb, one can create variables
+to store data from previous moves (or not), and can also use all the
+power of lisp to improve his/her creature. But the most important
+is to make good choices and be aware of danger!
+
+
+\subsection{Changes from \emph{Planet of the Feebs}}
+
+Many changes were made from the original game, but, if you have any
+feeb definition and you want to use it, it should be easy to adapt
+the brain function to the new rules.
+
+The main reason of this project is that \textit{Planet of the Feebs}
+is really interesting for (not just) newbies to learn lisp, but the
+difficulties to install, unportability and the ausence of competitors
+make it difficult to someone to be interested in making a feeb. So,
+I hope that making these adjustments and maybe creating some contests
+over the web make people be more interested in learning lisp.
+
+So, these are (some of) the changes:
+
+\begin{itemize}
+\item The graphics are not based on X Window Sistem anymore, but on \textit{Lispbuilder},
+and there are no CMUCL's event handler. This way, the code is more
+portable and graphics can be improved. Just creating some image
+files of a feeb and your feeb is much more personalized!
+\item Every element of the map (including walls) is a list, so the brain of
+a feeb doesn't need to test all the time if the element is an atom
+or a list (wich, in my opinion, is really boring, unlispy and unnecessary
+in this case). That was only a reason to duplicate code and work,
+adding no results at all...
+\item Many functions and variables are changed and others were added
+\item Documentation is more objective than the one provided with \textit{Planet
+of the Feebs}, and is fully compatible with the code. This way it
+is easier to understand the game.
+\item Security is improved. Now it the behavior functions are allowed to store
+and change structures and vectors passed to it.
+The parameters can't be change by those functions while inside the game.
+\item It is possible now to extend the rules: the code is object oriented and
+new rules, special moves, change the behavior of flames, etc, can be done
+by adding new classes and/or methods. This manual is just the beginning!
+end{itemize}
+
+\section{The Game}
+
+
+\subsection{Overview}
+
+Your feeb's objective is to survive and kill other feebs. It is inside
+a maze of tunnels. Every turn, all feebs lose one unit of energy,
+and maybe starves. Your feeb is able to move forward, turn left, right
+or around, flame, peek around a corner, eat something or just wait.
+After all feebs move, the flames thrown before also move (or dissipate),
+carcasses may rot and mushrooms may grow, accordingly to some rules.
+
+The game rules are defined by parameters. These parameters can be read
+by the command \textsf{\textbf{(get-feeb-parm~}'parameter\textbf{)}}
+To see all parameters, values and also all the documentation, one can use
+\textsf{\textbf{(list-parameter-settings)}}. Using
+\textsf{\textbf{(change-feeb-parm}'parameter~value\textbf{)}}
+gives the possibility to change them (but not during the game) and
+\textsf{\textbf{(documentation~}'parameter~'feeb-parm\textbf{)}}
+can be used to know them. Just remember that every probability
+must be a rational number (like 1/2).
+
+But don't panic! These parameters are just for one to know how
+the game is going to be, but in the begining there is no need
+to explicitly use them when creating the brain of a feeb.
+The best way to create a feeb is watching a game (among system feebs),
+improving it (it is defined in file brains.lisp) a little more,
+testing the changes...
+
+These are some global parameters:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{'game-length}}}] Number of turns the game
+will last.
+\item [{\textsf{\textbf{'points-for-killing}}}] How many points some
+feeb earn for killing someone.
+\item [{\textsf{\textbf{'points-for-dying}}}] How many points some
+feeb earn for dying (usually negative).
+\item [{\textsf{\textbf{'maze-x-size}}}] Horizontal size of the maze.
+\item [{\textsf{\textbf{'maze-y-size}}}] Vertical size of the maze.
+\end{lyxlist}
+
+\subsection{Throwing flame}
+
+If a feeb decides to throw a flame, if it is prepared to and has
+enough energy, the next turn there will be a flame in the square
+in front of the feeb, and it will see it, so the feeb shouldn't move
+forward. For a few turns, the feeb will not be able to
+throw flames. Each turn, the flame moves forward destroing mushrooms and
+killing feebs it encounters, transforming them into carcass. If there
+is a wall, the flame can reflect, and, if so, it will turn 180 degrees.
+
+Once a feeb is killed (or starves), in it's place in the maze there will appear
+a carcass. The feeb goes to the end of the dead feebs line. When the
+carcass rots, the first feeb in line reincarnates. So, dying is not so terrible.
+
+These are the parameters related to flames:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{'flame-energy}}}] Amount of energy lost after
+throwing a flame.
+\item [{\textsf{\textbf{'fireball-guaranteed-lifetime}}}] Number of
+turns that a fireball is guaranteed not to dissipate, unless it encounters
+a wall.
+\item [{\textsf{\textbf{'fireball-dissipation-probability}}}] Probability
+of the flame to dissipate each turn after the apropriate time.
+\item [{\textsf{\textbf{'fireball-reflection-probability}}}] Probability
+of the flame to reflect when encountering a wall.
+\item [{\textsf{\textbf{'flame-no-recovery-time}}}] Number of turns
+that a feeb cannot fire.
+\item [{\textsf{\textbf{'flame-recovery-probability}}}] Probability
+of the feeb to recover the hability to throw a flame, after the apropriate
+time.
+\end{lyxlist}
+
+\subsection{Eating food}
+
+There are two kinds of food, carcasses and mushrooms. Carcasses usually
+give less energy than mushrooms, and may rot, but, while it does not
+rot, a feeb can feed as long as it wishes. Mushrooms disapear after
+being eaten. By eating food, the feeb
+will be able to recover energy, wich is important because, if a feeb
+stays with 0 or less units of energy, it starves.
+
+These are the quantities:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{'mushroom-energy}}}] Amount of energy recovered
+when the feeb eats a mushroom.
+\item [{\textsf{\textbf{'carcass-energy}}}] Amount of energy recovered
+each turn that the feeb eats a carcass.
+\item [{\textsf{\textbf{'carcass-guaranteed-lifetime}}}] Number of
+turns that a carcass will surely not rot. After these turns, it
+can rot, depending on probabilities.
+\item [{\textsf{\textbf{'carcass-rot-probability}}}] Probability of
+the carcass to rot, after the apropriate time.
+\item [{\textsf{\textbf{'maximum-energy}}}] Maximum amount of energy
+that a feeb can have eating.
+\item [{\textsf{\textbf{'starting-energy}}}] Amount of energy a feeb
+has when it reincarnates.
+\item [{\textsf{\textbf{'number-of-mushrooms}}}] Quantity of mushrooms
+that exist in the maze.
+\end{lyxlist}
+
+\section{The Feeb}
+
+A feeb needs four things: a name, a brain and a set of graphics (optional).
+
+\begin{itemize}
+\item The name, a string.
+\item The brain is a function that decides what the feeb will do next, based
+on what it is seeing and feeling.
+\item The set of graphics is an image file (of format BMP, JPEG, PNG, and
+any others that supported by SDL\_image).
+\end{itemize}
+One can create a feeb calling
+\textsf{\textbf{(define-feeb}~name~brain~\textbf{:graphics}~graphics\textbf{)}}.
+If name is already used, a warning will be signaled, and the old feeb
+will be substituted. Calling \textsf{\textbf{(list-of-feebs)}} will
+return the list of the feebs (names only) that will be defined when
+the game begins. \textsf{\textbf{(delete-feeb}}\textsf{~name}\textsf{\textbf{)}}
+will delete the feeb with this name from this list, and \textsf{\textbf{(delete-all-feebs)}}
+will clear it.
+
+
+\subsection{Possible decisions}
+
+After processing the information available, the brain will take a
+decision. If this decision is not one of the decisions listed down,
+a warning will be signaled, and the result will be like \textsf{\textbf{:wait}}.
+Then, if someone are testing a brain function, he or she will be able
+to know if something goes wrong.
+
+The possible values that the brain function can return are these:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{:move-forward}}}] Move one square forward, unless
+there is a wall in front of the feeb.
+\item [{\textsf{\textbf{:turn-left}}}] Turn 90 degrees to the left.
+\item [{\textsf{\textbf{:turn-right}}}] Turn 90 degrees to the right.
+\item [{\textsf{\textbf{:turn-around}}}] Turn 180 degrees.
+\item [{\textsf{\textbf{:flame}}}] Throw a flame. The flame will be created
+next turn in the front square of the feeb.
+\item [{\textsf{\textbf{:wait}}}] Do nothing in this turn.
+\item [{\textsf{\textbf{:peek-left}}}] Peek to the left around a corner.
+The creature does note actually move, but, in the next turn, the creature
+will have the same vision that it would have if he had moved one step
+foward and turned left (and one step back because the feeb needs to see
+what is actually in front of it). Peeking used so a feeb can analize a corridor
+before trespassing it.
+\item [{\textsf{\textbf{:peek-right}}}] Peek to the right around a corner,
+analogous to \textsf{\textbf{:peek-left}}.
+\item [{\textsf{\textbf{:eat-carcass}}}] Eat a carcass if there is any
+available in the feeb's square. The amount of the parameter
+\textsf{\textbf{'carcass-energy}} is restored to the feeb's energy.
+\item [{\textsf{\textbf{:eat-mushroom}}}] Eat a mushroom if there is any
+available in the feeb's square. The amount of the parameter
+\textsf{\textbf{'mushroom-energy}} is restored to the feeb's energy.
+\end{lyxlist}
+
+\subsection{Information available}
+
+The brain of a feeb must take five arguments; I'll call them \textsf{\emph{status}},
+\textsf{\emph{proximity}}, \textsf{\emph{vision}}, \textsf{\emph{vision-left}}
+and \textsf{\emph{vision-right}}.
+
+
+\subsubsection{Status}
+
+Every time the brain is called, it receives some useful information
+through \textsf{\textbf{status}}.
+
+The structure \textsf{\textbf{status}} keeps information about the
+feeb itself. Also it has information of the previous movement of the
+feeb. To access them, one must call:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{(name}}\textsf{\emph{~status}}\textsf{\textbf{)}}}] \begin{flushleft}
+The name of the feeb.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(facing}}\textsf{\emph{~status}}\textsf{\textbf{)}}}] \begin{flushleft}
+Where the feeb is facing to, one of the constants provided: \textsf{\textbf{north}},
+\textsf{\textbf{east}}, \textsf{\textbf{south}} or \textsf{\textbf{west}},
+wich are 0, 1, 2 and 3 respectivelly.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(x-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
+The horizontal position of the feeb, starting with 0 and increasing to east.
+If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(y-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
+The vertical position of the feeb, starting with 0 and increasing to south.
+If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(peeking}\emph{~status}\textbf{)}}}] \begin{flushleft}
+If it is \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}}, it means
+that the current \textsf{\emph{vision}} provided is result of a previous
+\textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}} command
+of the same feeb. Otherwise, it is \textsf{\textbf{nil}}. Note that
+\textsf{\emph{proximity}} is \emph{not} affected.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(line-of-sight}\emph{~status}\textbf{)}}}] \begin{flushleft}
+Indicates the amount of valid entries in \textsf{\emph{vision}}. It actually
+means that \textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
+will return \textsf{\textbf{'(:rock)}}.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(ready-to-fire}\emph{~status}\textbf{)}}}] \begin{flushleft}
+If \textsf{\textbf{T}} indicates that the feeb is ready to fire.
+If \textsf{\textbf{Nil}} indicates it is not.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(aborted}\emph{~status}\textbf{)}}}] \begin{flushleft}
+Related with timing. Returns \textsf{\textbf{T}} if the last move of feeb
+was aborted because of timing issues.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(last-move}\emph{~status}\textbf{)}}}] \begin{flushleft}
+The feeb's previous move, or \textsf{\textbf{:dead}} if it has just reincarnated.
+\par\end{flushleft}
+\end{lyxlist}
+
+\subsubsection{Proximity and vision}
+
+The brain receives also information about what is near the feeb and
+what the feeb sees. We note that, contrary to \emph{Planet of the Feebs},
+it is safe to change anything inside these structures, so you are
+alowed to keep them stored and to modify them as you wish.
+
+The structure \textsf{\emph{proximity}} has the contents of the squares
+near the feeb (not affected by peeking) with these fields:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
+Contents of the feeb's current square.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(left-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
+Contents of the right square of the feeb.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(right-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
+Contents of the left square of the feeb.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(rear-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}}] \begin{flushleft}
+Contents of the square behind the feeb.
+\par\end{flushleft}
+\item [{The}] vector \textsf{\emph{vision}} has the contents of the squares
+that are in front of the feeb. For example,
+\textsf{\textbf{(aref}\emph{~vision~}0\textbf{)}}
+will return the contents of the square in front of the feeb,
+\textsf{\textbf{(aref}\emph{~vision~}1\textbf{)}}
+will return the contents of the next square, and so on. As said before,
+\textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
+will be the first \textsf{\textbf{'(:rock)}} encountered. All subsequents square, like
+\textsf{\textbf{(aref}\emph{~vision~}\textbf{(+}~1~\textbf{(line-of-sight}\emph{~status}\textbf{)))}},
+will be garbage and should not be used.
+\end{lyxlist}
+The contents of one square returned by any of these calls is either
+a list of elements, a wall \textsf{\textbf{'(:rock)}} (i.e. a list with
+one element, a \textsf{\textbf{:rock}}) or \textsf{\textbf{()}} if the
+square is empty. Each element of the square is one of these:
+
+\begin{itemize}
+\item \textbf{Feeb image.} One can call \textsf{\textbf{(feeb-image-p}~element\textbf{)}}
+to see if element is a feeb image.
+\item \textbf{Fireball image.} One can call \textsf{\textbf{(fireball-image-p}~element\textbf{)}}
+to check if element is a fireball image.
+\item \textsf{\textbf{:carcass}}. If there is a \textsf{\textbf{:carcass}}
+in the square of the feeb (i.e. in \textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}),
+the call \textsf{\textbf{:eat-carcass}} will make the feeb eat it.
+\item \textsf{\textbf{:mushroom}}. Analogous to \textsf{\textbf{:carcass}}.
+A mushroom appears randomly in places previously marked in the map.
+\end{itemize}
+
+\subsubsection{Feebs and fireballs images}
+
+Both fireballs and feebs that are given to the brain function are
+not the real ones, but just images with contents that the brain function
+can access. It is allowed to keep and change its contents because they
+won't be used internally.
+
+These are the accessors available (they read and change the fiels):
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{(feeb-image-name}~feeb-image\textbf{)}}}] \begin{flushleft}
+The name of the feeb. (Maybe you know it's weakpoints?)
+\par\end{flushleft}
+\item [{\textsf{\textbf{(feeb-image-facing}~feeb-image\textbf{)}}}] \begin{flushleft}
+The facing of the feeb. This way the brain function can
+see if the feeb-image either sees the feeb which is playing or not.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(feeb-image-peeking}~feeb-image\textbf{)}}}] \begin{flushleft}
+Returns \textsf{\textbf{:peek-left}} or \textsf{\textbf{:peek-right}} if the
+feeb is peeking to (its) left or right, or \textsf{\textbf{nil}} if
+not.
+\par\end{flushleft}
+\item [{\textsf{\textbf{(fireball-image-direction}~fireball-image\textbf{)}}}] \begin{flushleft}
+The direction where the fireball image is going to.
+\par\end{flushleft}
+\end{lyxlist}
+
+\subsubsection{Vision-left and vision-right}
+
+\textsf{\emph{vision-left}} and \textsf{\emph{vision-right}} are vectors
+similar to vision, but they are less precise in the contents. Also
+their valid contents are limited by \textsf{\textbf{(line-of-sight}~\emph{status}\textbf{)}},
+so \textsf{\textbf{(aref}~\emph{vision-left}~\textbf{(line-of-sight}~\emph{status}\textbf{))}},
+for example, will return \textsf{\textbf{:unknown}}.
+
+Note that feebs that are not peeking, mushrooms and carcasses are
+\emph{not} be detected by these vectors. Also, if there is a feeb
+peeking to the opposite side, it won't be detected either. The
+elements in \textsf{\textbf{vision-left}} and \textsf{\textbf{vision-right}}
+are lists containing these elements:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{:peek-letf}}}] This means that in that square there
+is a feeb peeking to (its) left.
+\item [{\textsf{\textbf{:peek-right}}}] This means that in that square
+there is a feeb peeking to (its) right.
+\item [{\textsf{\textbf{:rock}}}] This square is just a wall. In this case,
+this is the only element in the square.
+\end{lyxlist}
+
+\subsection{Extra functions provided}
+
+Before making the brain of your feeb, you might want to take a look
+at the Extra functions that are available at the end of the feebs.lisp
+file. The only thing you need so you can use them is to see their
+code and know what they do.
+
+
+\subsection{Changing the map layout}
+
+It is possible to change the layout of the map by calling
+\textsf{\textbf{(change-layout}~new-layout\textbf{)}}.
+There are a few predefined mazes that are in variables \textsf{\textbf{{*}maze-0{*}}}
+(which is set by default) throw \textsf{\textbf{{*}maze-5{*}}}.
+In a layout, `X' represents a wall, `e' represents a feeb entry point
+(there will be as many entry points as feebs in the maze at the same time),
+`m' represents a mushroom site and ` ' is a blank space.
+
+If you want to create a new map, you can start by an empty template
+of any size that is provided by \textsf{\textbf{(make-template}~x-size~y-size\textbf{)}},
+or you can get a reandom map calling
+\textsf{\textbf{(generate-maze}~x-size~y-size~\textbf{:density}~density\textbf{)}}
+The density is a number, recomended to be between 0.25 and 0.45,
+which tells the portion of the maze should be blank spaces.
+The function quits after a while if it doesn't meet this portion. See
+its documentation for more details and options.
+
+
+\subsection{Graphics}
+
+With this version of the game, it's possible to choose the graphics
+of a feeb when creating it, so your feeb will be more personalized.
+
+The graphic of a feeb is defined by an image file, which should have
+three colunms by eight lines of pictures of the same size. The four
+first lines must be the animations of the feeb walking up, left, down
+and right, respectively. The next four lines must be the pictures
+of the feeb flaming up, left, down and right, respectively. To see
+an example, see {}``default-feeb.png''.
+
+After creating the image file, you must call \textsf{\textbf{(create-graphics}}\textsf{~path-to-image-file}\textsf{\textbf{)}}.
+If you now how to work with sdl surfaces in lispbuilder, you may use
+the function with a surface instead of a image file; or you can call
+\textsf{\textbf{(create-graphics}~path-to-image-file~nil\textbf{)}}
+if the surface should not be freed after the call. The result must
+be the third argument given to define-feeb.
+
+
+\subsection{Starting the game}
+
+The game loop is started by calling \textsf{\textbf{(simple-play)}}.
+
+
+
+\section{Contests}
+
+I sugest that you see this chapter only after you have created at
+least a basic brain feeb, which is better than the (simple) provided
+brain, or if you want to participate of a contest or a game with
+your friends.
+
+
+\subsection{\label{sub:Map}Map}
+
+It is possible to get the maze map during the game, but with only
+the corridors. Note that the function that gets the map is purposely
+a little slow, so, invoking it too many times in a contest that uses
+timing atributes is not a good idea; anyway, it is possible to invoke
+this function before defining the feeb, and store its value somewhere.
+Also note that the map returned does not have any information about
+what is really in the maze, but only the possible ways.
+
+To get the map, one can call \textsf{\textbf{(get-maze-map)}}. This
+function will return \textsf{\textbf{nil}} if parameter
+\textsf{\textbf{'may-get-maze-map-p}} is also \textsf{\textbf{nil}}.
+Otherwise, the map returned is an array, so that calling
+\textsf{\textbf{(aref}~map~x~y\textbf{)}} will get the contents
+in the position (x,y) (like euclidean but inverting the y axis).
+The contents of a cell could be one of these:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{:mushroom-place}}}] A mushroom patch, i.e. when
+a mushroom is reincarnate, it could reincarnate here.
+\item [{\textsf{\textbf{:feeb-entry-place}}}] A feeb entry, i.e. if a carcass
+rots a feeb can appear here.
+\item [{\textsf{\textbf{:rock}}}] A wall. Feebs cannot come to this place.
+\item [{\textsf{\textbf{nil}}}] An {}``empty'' place, i.e. neither of
+the previous.
+\end{lyxlist}
+
+This map can safelly be used since \textsf{\textbf{(get-maze-map)}} makes
+a new copy every time it is called.
+
+\subsection{Timing}
+
+There are also some timing atributes that can be given to the game.
+The more time the feeb takes make a decision, greater is the probability
+of its command to be aborted.
+
+To make this available, someone must set these parameters:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{'slow-feeb-noop-switch}}}] If is non-nil,
+there is a possibility that the move of a feeb is aborted according
+to its function time.
+\item [{\textsf{\textbf{'slow-feeb-noop-factor}}}] The probability
+of the feeb to abort will be this factor times the amount of time
+the feeb takes to have a decision, divided by the total time taken
+by all the feebs in the current turn or divided by a reference time.
+\item [{\textsf{\textbf{'reference-time}}}] Time taken by reference
+if non-nil.
+\item [{\textsf{\textbf{'points-for-slow-down}}}] Points earned when
+a feeb's move is aborted due to slowness.
+\end{lyxlist}
+
+\subsection{Sense of location}
+
+Some accessors related to position and orientation of the feeb can
+be turned off.
+
+These are the parameters:
+
+\begin{lyxlist}{00.00.0000}
+\item [{\textsf{\textbf{'sense-location-p}}}] If nil,
+\textsf{\textbf{x-position}} and \textsf{\textbf{y-position}}
+will return nil when someone tries to invoke it.
+Otherwise return the position.
+\end{lyxlist}
+
+\subsection{Changing the rules}
+
+To change the rules of the contest, they must be changed before the
+feebs are defined, because in a feeb definition it could use the values
+of the variables to make a global strategy.
+
+All the parameters, values and documentation that can be listed using
+\textsf{\textbf{(list-parameter-settings)}} can be changed using
+\textsf{\textbf{(change-feeb-parm name value)}}, which is deactivated
+during the game. Also, they all have documentation about themselves, so feel free to use
+\textsf{\textbf{(documentation~}}\textsf{'parameter~'feeb-parm}\textsf{\textbf{)}}
+and see what each parameter does. Documentation is available to external
+functions as well.
+
+
+\section{Reference}
+
+\begin{quote}
+Fahlman, S. E. \textbf{\emph{Planet of the Feebs -}} \emph{A Somewhat
+Educational Game.} \url{ftp://ftp.csl.sri.com/pub/users/gilham/feebs/feebs.tex}.
+\end{quote}
+
+\end{document}
Added: graphics/graphics.lisp
==============================================================================
--- (empty file)
+++ graphics/graphics.lisp Sat Feb 16 15:01:42 2008
@@ -0,0 +1,216 @@
+;;; -*- Common Lisp -*-
+
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
+
+ This file is part of The Feebs War.
+
+ The Feebs War is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ The Feebs War is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with The Feebs War. If not, see <http://www.gnu.org/licenses/>.
+|#
+
+(in-package :the-feebs-war)
+
+(defun print-direction (dir)
+ (case dir
+ (0 #\N)
+ (1 #\E)
+ (2 #\S)
+ (3 #\W)))
+
+(defun print-map ()
+ (dotimes (y *maze-y-size*)
+ (dotimes (x *maze-x-size*)
+ (let ((elt (aref *maze* x y)))
+ (apply 'format t
+ (cond
+ ((wallp elt)
+ (list " XX"))
+ ((feeb-p (car elt))
+ (list "F~1d~a"
+ (position (feeb-name (car elt)) *feebs* :key #'feeb-name)
+ (print-direction (feeb-facing (car elt)))))
+ ((fireball-p (car elt))
+ (list " *~a" (print-direction (fireball-direction (car elt)))))
+ ((eq (car elt) :mushroom)
+ (list " mm"))
+ ((eq (car elt) :carcass)
+ (list " cc"))
+ (t (list " "))))))
+ (format t "~%")))
+
+(defun simple-play (&optional layout)
+ (if layout
+ (change-layout layout))
+ (make-auto-feebs (- 10 (length *feebs-to-be*)))
+ (initialize-feebs)
+ (start-round)
+ (loop do
+ (play-one-turn)
+ (print-map)
+ (sleep 0.7)
+ (format t "~%~%")
+ (if (finish-game-p) (return)))
+ (format t "Game Over!!~%~%Scores:~%~%")
+ (dolist (feeb *feebs*)
+ (format t "~a: ~d~%" (feeb-name feeb) (feeb-score feeb))))
+
+
+#|
+
+
+(defconst *default-graphics*
+ (make-feeb-graphics
+ (load-and-convert-image "default-feeb.bmp")))
+
+(defvar *cell-width* 32)
+(defvar *cell-heigth* 32)
+
+(defstruct graphic
+ (walk (make-direction))
+ (flaming (make-direction)))
+
+(defstruct (direction (:conc-name nil))
+ (up (make-array 3))
+ (left (make-array 3))
+ (down (make-array 3))
+ (right (make-array 3)))
+
+(defun make-feeb-graphics (surface)
+
+ (let ((graphic (make-graphic)))
+ (progn
+ (loop for field in '(walk flaming)
+ and y0 from 0 by (* 4 *cell-heigth*) do
+ (loop for dir in '(up left right down)
+ and y from y0 by *cell-heigth* do
+ (loop for ind below 3
+ and x from 0 by *cell-width*
+ for aux = (surface :width *cell-width* :heigth *cell-heigth*) do
+ (set-cell :x x :y y :width *cell-width* :heigth *cell-heigth* :surface surface)
+ (draw-surface surface :surface aux)
+ (setf (svref (slot-value (slot-value graphic field)
+ dir)
+ ind)
+ aux))))
+ graphic)))
+
+(defgeneric create-graphics (feeb) &key (free-p t))
+
+(defmethod create-graphics ((feeb pathname))
+ (let ((surf (load-and-convert-image feeb)))
+ (make-feeb-grahpics surf)
+ (free-surface surf)))
+
+(defmethod create-graphics ((feeb surface) &key free-p)
+ (with-surface feeb
+ (make-feeb-graphics))
+ (if free-p
+ (fre-surface feeb)))
+
+
+(defvar *time* 0)
+
+(defun human-player (&rest args)
+ (declare (ignore args))
+ (sdl:with-events (:wait)
+ (:key-down-event (:key key)
+ (case key
+ (:sdl-key-up
+ (return-from human-player :move-forward))
+ (:sdl-key-left
+ (return-from human-player :turn-left))
+ (:sdl-key-right
+ (return-from human-player :turn-right))
+ (:sdl-key-up
+ (return-from human-player :turn-around))
+ (:sdl-key-space
+ (return-from human-player :flame))
+ (:sdl-key-return
+ (return-from human-player :wait))))
+ (:video-expose-event
+ (sdl:update-display))))
+
+
+(defun feebs (&key (delay 5) ; 4 min of game
+ human-player
+ files &aux (time 0))
+ "The main loop program. Single-step is no longer available.
+If human-player is supplied, it is taken as the name of human player,
+wich will controll a feeb with the keyboard. The end of the game
+only occurs if the player press ESC.
+If there is no human, *game-length* is used instead.
+A number of auto-feebs feebs are created by the system.
+Also, if there are more feebs supplied than places,
+the feeb wich is killed gives room to another feeb to be born."
+ (initialize-feebs)
+ (setf (sdl:frame-rate) 10)
+
+ (init-maze *layout*)
+
+ (dolist (file files)
+ (load file))
+ (if human-player
+ (define-feeb
+ human-player
+ #'human-player))
+
+ (sdl:with-init ()
+ (sdl:with-display ()
+ (sdl:with-events ()
+ (:idle ()
+ (sdl:update-display)
+ (if zerop time
+ (progn
+ (setf time delay)
+ (play-one-turn)
+ (when (not *continue*)
+ (return)))
+ (decf time)))
+ ))
+
+ (setf *feebs-to-be* nil))
+
+;;; Feeb creation.
+
+;; This a little better version of conservative-brain
+;; all others (stupid or redundant) brains of original
+;; feebs.lisp were eliminated
+(defun simple-brain (status proximity vision vision-left vision-right)
+ (declare (ignore vision-left vision-right))
+ (let ((stuff (my-square proximity)))
+ (cond ((and (consp stuff) (member :mushroom stuff :test #'eq))
+ :eat-mushroom)
+ ((and (consp stuff) (member :carcass stuff :test #'eq))
+ :eat-carcass)
+ ((and (ready-to-fire status)
+ (> (energy-reserve status) 30)
+ (dotimes (index (min (line-of-sight status) 5))
+ (if (find-if #'feeb-image-p (aref vision index))
+ (return t))))
+ :flame)
+ ((and (not (eq (left-square proximity) :rock))
+ (> 2 (random 10)))
+ :turn-left)
+ ((and (not (eq (right-square proximity) :rock))
+ (> 2 (random 10)))
+ :turn-right)
+ ((plusp (line-of-sight status))
+ :move-forward)
+ ((not (wallp (left-square proximity)))
+ :turn-left)
+ ((not (wallp (right-square proximity)))
+ :turn-right)
+ ((not (wallp (rear-square proximity)))
+ :turn-around))))
+
+|#
1
0

16 Feb '08
Author: gmilare
Date: Sat Feb 16 14:59:50 2008
New Revision: 14
Added:
definitions/
documentation/
graphics/
the-feebs-war.asd (contents, props changed)
Removed:
brains.lisp
extra.lisp
feebs.asd
feebs.tex
graphics.lisp
mazes.lisp
rules.lisp
Modified:
images.lisp
main.lisp
package.lisp
system.lisp
Log:
Modified: images.lisp
==============================================================================
--- images.lisp (original)
+++ images.lisp Sat Feb 16 14:59:50 2008
@@ -1,6 +1,6 @@
;;; -*- Common Lisp -*-
-#| Copyright (c) 2007 Gustavo Henrique Milar�
+#| Copyright (c) 2007,2008 Gustavo Henrique Milar�
This file is part of The Feebs War.
@@ -19,7 +19,7 @@
|#
-(in-package :feebs)
+(in-package :the-feebs-war)
;;; This file is an extension of system.lisp which handles vision
Modified: main.lisp
==============================================================================
--- main.lisp (original)
+++ main.lisp Sat Feb 16 14:59:50 2008
@@ -1,6 +1,6 @@
;;; -*- Common Lisp -*-
-#| Copyright (c) 2007 Gustavo Henrique Milar�
+#| Copyright (c) 2007,2008 Gustavo Henrique Milaré
This file is part of The Feebs War.
@@ -19,7 +19,7 @@
|#
-(in-package :feebs)
+(in-package :the-feebs-war)
Modified: package.lisp
==============================================================================
--- package.lisp (original)
+++ package.lisp Sat Feb 16 14:59:50 2008
@@ -1,6 +1,6 @@
;;; -*- Common Lisp -*-
-#| Copyright (c) 2007 Gustavo Henrique Milar��
+#| Copyright (c) 2007,2008 Gustavo Henrique Milaré
This file is part of The Feebs War.
@@ -30,95 +30,96 @@
;; Graphics ported to X11 by Fred Gilham 8-FEB-1998.
-(defpackage :feebs
+(defpackage :the-feebs-war
+ (:nicknames :feebs)
(:use :common-lisp)
;; Export everything we want the players to get their hands on.
(:export ;; Slots accessors
- name facing
- x-position y-position peeking line-of-sight
- energy-reserve
- score kills
- ready-to-fire
- aborted last-move
-
- my-square left-square right-square rear-square
-
- ;; Images
- feeb-image-p feeb-image-name
- feeb-image-facing feeb-image-peeking
- fireball-image-p fireball-image-direction
-
- ;; Parameters
- get-feeb-parm change-feeb-parm
- list-parameter-settings
-
- game-length
-
- ;; Pontuation
- points-for-killing points-for-dying
- points-for-slow-down
-
- ;; Energy
- flame-energy mushroom-energy carcass-energy
- maximum-energy
- starting-energy
- carcass-rot-probability
- carcass-guaranteed-lifetime
-
- ;; Game quantities
- maze-x-size
- maze-y-size
- number-of-mushrooms
-
- ;; Probabilities
- fireball-guaranteed-lifetime
- fireball-dissipation-probability
- fireball-reflection-probability
- flame-no-recovery-time
- flame-recovery-probability
-
- ;; Difficulty variables
- slow-feeb-noop-switch
- slow-feeb-noop-factor
- reference-time
- sense-location-p
- may-get-maze-map-p
-
- ;; Settings
- define-feeb delete-feeb
- feebs
- change-layout
- get-maze-map
-
- ;; Constants
- north south east west
-
- ;; Some layouts (can be find in mazes.lisp)
- *maze-0* *maze-1* *maze-2*
- *maze-3* *maze-4* *maze-5*
- make-template generate-maze
-
- ;; Graphics
- create-graphics
-
- ;; Extras
-
- ;; Directional arithmetic
- left-of right-of behind-of
- relative-facing
-
- forward-dx forward-dy
- left-dx left-dy
- right-dx right-dy
- behind-dx behind-dy
+ name facing
+ x-position y-position peeking line-of-sight
+ energy-reserve
+ score kills
+ ready-to-fire
+ aborted last-move
+
+ my-square left-square right-square rear-square
+
+ ;; Images
+ feeb-image-p feeb-image-name
+ feeb-image-facing feeb-image-peeking
+ fireball-image-p fireball-image-direction
+
+ ;; Parameters
+ get-feeb-parm change-feeb-parm
+ list-parameter-settings
+
+ game-length
+
+ ;; Pontuation
+ points-for-killing points-for-dying
+ points-for-slow-down
+
+ ;; Energy
+ flame-energy mushroom-energy carcass-energy
+ maximum-energy
+ starting-energy
+ carcass-rot-probability
+ carcass-guaranteed-lifetime
+
+ ;; Game quantities
+ maze-x-size
+ maze-y-size
+ number-of-mushrooms
+
+ ;; Probabilities
+ fireball-guaranteed-lifetime
+ fireball-dissipation-probability
+ fireball-reflection-probability
+ flame-no-recovery-time
+ flame-recovery-probability
+
+ ;; Difficulty variables
+ slow-feeb-noop-switch
+ slow-feeb-noop-factor
+ reference-time
+ sense-location-p
+ may-get-maze-map-p
+
+ ;; Settings
+ define-feeb delete-feeb
+ feebs
+ change-layout
+ get-maze-map
+
+ ;; Constants
+ north south east west
+
+ ;; Mazes
+ *maze-0* *maze-1* *maze-2*
+ *maze-3* *maze-4* *maze-5*
+ make-template generate-maze
+
+ ;; Graphics
+ create-graphics
+
+ ;; Extras
+
+ ;; Directional arithmetic
+ left-of right-of behind-of
+ relative-facing
+
+ forward-dx forward-dy
+ left-dx left-dy
+ right-dx right-dy
+ behind-dx behind-dy
+
+ ;; Others
+ wallp chance
+
+ ;; Graphics for alpha release
+ simple-play))
- ;; Others
- wallp chance
-
- ;; Graphics for alpha release
- simple-play))
-
-(in-package :feebs)
+(in-package :the-feebs-war)
;;; Directions
@@ -207,13 +208,6 @@
;;; Current feeb playing
+
(defvar *playing-feeb* nil)
(defvar *feebs-to-be* ())
-
-(defmacro aif (test then &optional else)
- `(let ((it ,test))
- (if it ,then ,else)))
-
-(defmacro awhen (test &rest body)
- `(let ((it ,test))
- (when it ,@body)))
Modified: system.lisp
==============================================================================
--- system.lisp (original)
+++ system.lisp Sat Feb 16 14:59:50 2008
@@ -1,6 +1,6 @@
;;; -*- Common Lisp -*-
-#| Copyright (c) 2007 Gustavo Henrique Milar�
+#| Copyright (c) 2007,2008 Gustavo Henrique Milaré
This file is part of The Feebs War.
@@ -19,7 +19,7 @@
|#
-(in-package :feebs)
+(in-package :the-feebs-war)
;;; We start defining the main system rules by defining the classes
@@ -39,13 +39,13 @@
(x-position :reader x-position :accessor feeb-x-position)
(y-position :reader y-position :accessor feeb-y-position)
(line-of-sight :accessor feeb-line-of-sight :reader line-of-sight
- :initform 0)
+ :initform 0)
(energy-reserve :accessor feeb-energy-reserve :reader energy-reserve)
(ready-to-fire :accessor feeb-ready-to-fire :reader ready-to-fire
- :initform t)
+ :initform t)
(aborted :accessor feeb-aborted :reader aborted)
(last-move :accessor feeb-last-move :reader last-move
- :initform :dead)
+ :initform :dead)
;; These are available for the system
(brain :accessor feeb-brain :initarg :brain)
@@ -57,11 +57,11 @@
(turns-since-flamed :accessor feeb-turns-since-flamed :initform 0)
(proximity :accessor feeb-proximity :initform (make-proximity))
(vision :accessor feeb-vision
- :initform (make-array (list (max *maze-y-size* *maze-x-size*))))
+ :initform (make-array (list (max *maze-y-size* *maze-x-size*))))
(vision-left :accessor feeb-vision-left
- :initform (make-array (list (max *maze-y-size* *maze-x-size*))))
+ :initform (make-array (list (max *maze-y-size* *maze-x-size*))))
(vision-right :accessor feeb-vision-right
- :initform (make-array (list (max *maze-y-size* *maze-x-size*))))))
+ :initform (make-array (list (max *maze-y-size* *maze-x-size*))))))
(defclass fireball (object)
((owner :accessor fireball-owner :initarg :owner)
@@ -89,23 +89,23 @@
(defun delete-object (thing x y)
(setf (aref *maze* x y)
- (delete thing (aref *maze* x y))))
+ (delete thing (aref *maze* x y))))
(defun place-object (thing x j)
(push thing (aref *maze* x j)))
(defun change-object-pos (obj x y)
(delete-object obj (object-x-position obj)
- (object-y-position obj))
+ (object-y-position obj))
(place-object obj x y)
(setf (object-x-position obj) x
- (object-y-position obj) y))
+ (object-y-position obj) y))
(defun get-forward-pos (object)
(let ((new-x (+ (forward-dx (object-direction object))
- (object-x-position object)))
- (new-y (+ (forward-dy (object-direction object))
- (object-y-position object))))
+ (object-x-position object)))
+ (new-y (+ (forward-dy (object-direction object))
+ (object-y-position object))))
(values (aref *maze* new-x new-y) new-x new-y)))
@@ -124,7 +124,7 @@
(:method (object x-pos y-pos)
(place-object object x-pos y-pos)
(setf (object-x-position object) x-pos
- (object-y-position object) y-pos))
+ (object-y-position object) y-pos))
(:method ((feeb feeb) x-pos y-pos)
(setf (feeb-last-move feeb) :dead)
@@ -134,7 +134,7 @@
(:method ((fireball fireball) x-pos y-pos)
(push fireball *fireballs-flying*)
(setf (object-x-position object) x-pos
- (object-y-position object) y-pos))) ; don't place it yet, only after first move
+ (object-y-position object) y-pos))) ; don't place it yet, only after first move
;;; Reincarnating
@@ -150,18 +150,18 @@
or :dissipate (for fireballs)."
(:method (object cause)
(delete-object object (object-x-position object)
- (object-y-position object)))
+ (object-y-position object)))
(:method ((fireball fireball) cause)
(setf *fireballs-flying*
- (delete fireball *fireballs-flying*))
+ (delete fireball *fireballs-flying*))
(call-next-method))
(:method ((feeb feeb) cause)
(setf *dead-feebs* (nconc *dead-feebs* (list feeb))
- *feebs* (delete feeb *feebs*))
+ *feebs* (delete feeb *feebs*))
(let* ((x (feeb-x-position feeb))
- (y (feeb-y-position feeb)))
+ (y (feeb-y-position feeb)))
(push (list 0 x y) *carcasses*)
(place-object :carcass x y))
(call-next-method)))
@@ -176,11 +176,11 @@
(:documentation "Lets object make its move choice.")
(:method ((feeb feeb))
(funcall (feeb-brain feeb)
- feeb
- (feeb-proximity feeb)
- (feeb-vision feeb)
- (feeb-vision-left feeb)
- (feeb-vision-right feeb))))
+ feeb
+ (feeb-proximity feeb)
+ (feeb-vision feeb)
+ (feeb-vision-left feeb)
+ (feeb-vision-right feeb))))
@@ -195,21 +195,21 @@
(:method (object (move (eql :turn-right)))
(setf (object-direction object)
- (right-of (object-direction object))))
+ (right-of (object-direction object))))
(:method (object (move (eql :turn-left)))
(setf (object-direction object)
- (left-of (object-direction object))))
+ (left-of (object-direction object))))
(:method (object (move (eql :turn-around)))
(setf (object-direction object)
- (behind (object-direction object))))
+ (behind (object-direction object))))
(:method (object (move (eql :move-forward)))
(multiple-value-bind (stuff new-x new-y)
- (get-forward-pos object)
+ (get-forward-pos object)
(unless (wallp stuff)
- (change-object-pos object new-x new-y))))
+ (change-object-pos object new-x new-y))))
(:method ((fireball fireball) (move (eql :dissipate)))
(destroy-object fireball :dissipate))
@@ -218,19 +218,19 @@
(setf (feeb-turns-since-flamed feeb) 0)
(create-object
(make-instance 'fireball :direction (feeb-facing feeb)
- :owner feeb)
+ :owner feeb)
(feeb-x-position feeb) (feeb-y-position feeb)))
(:method ((feeb feeb) (move (eql :eat-mushroom)))
(let ((x (feeb-x-position feeb))
- (y (feeb-y-position feeb)))
+ (y (feeb-y-position feeb)))
(when (find :mushroom (aref *maze* x y))
- (delete-object :mushroom x y)
- t)))
+ (delete-object :mushroom x y)
+ t)))
(:method ((feeb feeb) (move (eql :eat-carcass)))
(when (find :carcass (aref *maze* (feeb-x-position feeb)
- (feeb-y-position feeb)))
+ (feeb-y-position feeb)))
t))
(:method ((feeb feeb) (move (eql :peek-left)))
@@ -242,3 +242,4 @@
(setf (feeb-peeking feeb) move)))
) ; end of make-move generic function
+
Added: the-feebs-war.asd
==============================================================================
--- (empty file)
+++ the-feebs-war.asd Sat Feb 16 14:59:50 2008
@@ -0,0 +1,39 @@
+;;; -*- Common Lisp -*-
+
+(defpackage :feebs-system
+ (:use :cl :asdf))
+
+(in-package :feebs-system)
+
+(defsystem the-feebs-war
+ :description "The Feebs War is a continuation of Planet of the Feebs."
+ :version "0.1"
+ :author "Gustavo Henrique Milaré <gugamilare(a)gmail.com>"
+ :licence "GPL"
+; :depends-on (lispbuilder-sdl lispbuilder-sdl-image lispbuilder-sdl-gfx)
+
+ :components
+ (:cl-source-file "package")
+ (:cl-source-file "system" :depends-on ("package"))
+ (:cl-source-file "images" :depends-on ("system"))
+ (:cl-source-file "main" :depends-on ("images" "system"))
+
+ (:module "definitions"
+ :components
+ (:cl-source-file "utils")
+ (:cl-source-file "rules" :depends-on ("main"))
+ (:cl-source-file "mazes" :depends-on ("package" "utils"))
+ (:cl-source-file "extra" :depends-on ("package"))
+ (:cl-source-file "brains" :depends-on ("package")))
+
+ (:module "graphics"
+ :components
+ (:file "graphics" :depends-on ("main")))
+
+ ;; GPL
+ (:doc-file "licence")
+
+ ;; documentation
+ (:module "documentation"
+ :components
+ (:doc-file "feebs.tex")))
1
0
Author: gmilare
Date: Thu Jan 3 21:20:39 2008
New Revision: 13
Modified:
brains.lisp
extra.lisp
feebs.asd
feebs.tex
graphics.lisp
images.lisp
main.lisp
mazes.lisp
package.lisp
rules.lisp
system.lisp
Log:
Version 0.1.0
Documentation updated.
The program is object-oriented, so it is possible to add / change rules without changing
the internal code.
Parameters are not global variables anymore, but accessed by (get-feeb-parm) and (change-feeb-parm), for in-game-security reasons.
Created imagify function to transform feebs and fireballs into images. This way, if a feeb store the values given in vision and proximity, its contents won't represent the real state in game.
Modified: brains.lisp
==============================================================================
--- brains.lisp (original)
+++ brains.lisp Thu Jan 3 21:20:39 2008
@@ -29,30 +29,30 @@
(let ((stuff (my-square proximity)))
(cond ((and (member :mushroom stuff :test #'eq)
(< (energy-reserve status)
- (- *maximum-energy* 20)))
+ (- (get-feeb-parm 'maximum-energy) 20)))
:eat-mushroom)
((member :carcass stuff :test #'eq)
:eat-carcass)
((and (ready-to-fire status)
(> (energy-reserve status) 30)
(dotimes (index (min (line-of-sight status) 5))
- (let ((feeb (car (member-if #'feeb-image-p (svref vision index)))))
+ (let ((feeb (find-if #'feeb-image-p (svref vision index))))
(if (and feeb
(not (eq (feeb-image-facing feeb)
(facing status))))
(return t)))))
:flame)
- ((and (not (eq (left-square proximity) :rock))
+ ((and (not (wallp (left-square proximity)))
(or (member :mushroom (left-square proximity))
(> 3 (random 10))))
:turn-left)
- ((and (not (eq (right-square proximity) :rock))
+ ((and (not (wallp (right-square proximity)))
(or (member :mushroom (right-square proximity))
(> 3 (random 10))))
:turn-right)
((and (> (line-of-sight status) 0)
(not (dotimes (index (min (line-of-sight status) 7))
- (if (member-if #'fireball-image-p (svref vision index))
+ (if (find #'fireball-image-p (svref vision index))
(return t)))))
:move-forward)
(t
Modified: extra.lisp
==============================================================================
--- extra.lisp (original)
+++ extra.lisp Thu Jan 3 21:20:39 2008
@@ -52,10 +52,10 @@
;;; Directional arithmetic.
-(defun left-of (facing)
+(defun right-of (facing)
(mod (+ facing 3) 4))
-(defun right-of (facing)
+(defun left-of (facing)
(mod (+ facing 1) 4))
(defun behind (facing)
@@ -96,7 +96,7 @@
(defun wallp (thing)
(the boolean
- (eq :rock thing)))
+ (eq :rock (car thing))))
(defun chance (ratio)
(< (random (denominator ratio)) (numerator ratio)))
Modified: feebs.asd
==============================================================================
--- feebs.asd (original)
+++ feebs.asd Thu Jan 3 21:20:39 2008
@@ -7,20 +7,21 @@
(defsystem the-feebs-war
:description "The Feebs War is a continuation of Planet of the Feebs."
- :version "1.0"
+ :version "0.1"
:author "Gustavo Henrique Milar� <gugamilare(a)gmail.com>"
:licence "GPL"
-; :depends-on (pal)
+; :depends-on (lispbuilder-sdl lispbuilder-sdl-image lispbuilder-sdl-gfx)
:components
(;; source
(:cl-source-file "package")
- (:cl-source-file "system" :depends-on ("package"))
- (:cl-source-file "main" :depends-on ("system"))
+ (:cl-source-file "extra" :depends-on ("package"))
+ (:cl-source-file "system" :depends-on ("package" "extra"))
+ (:cl-source-file "images" :depends-on ("system"))
+ (:cl-source-file "main" :depends-on ("images" "system"))
(:cl-source-file "rules" :depends-on ("main"))
- (:cl-source-file "extra")
- (:cl-source-file "mazes")
+ (:cl-source-file "mazes" :depends-on ("package"))
(:cl-source-file "brains" :depends-on ("extra"))
(:file "graphics" :depends-on ("main"))
Modified: feebs.tex
==============================================================================
--- feebs.tex (original)
+++ feebs.tex Thu Jan 3 21:20:39 2008
@@ -103,7 +103,7 @@
and there are no CMUCL's event handler. This way, the code is more
portable and graphics can be improved. Just creating some image
files of a feeb and your feeb is much more personalized!
-\item Every element of the map (except walls) is a list, so the brain of
+\item Every element of the map (including walls) is a list, so the brain of
a feeb doesn't need to test all the time if the element is an atom
or a list (wich, in my opinion, is really boring, unlispy and unnecessary
in this case). That was only a reason to duplicate code and work,
@@ -118,7 +118,7 @@
\item It is possible now to extend the rules: the code is object oriented and
new rules, special moves, change the behavior of flames, etc, can be done
by adding new classes and/or methods. This manual is just the beginning!
-\end{itemize}
+end{itemize}
\section{The Game}
@@ -306,11 +306,11 @@
wich are 0, 1, 2 and 3 respectivelly.
\par\end{flushleft}
\item [{\textsf{\textbf{(x-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
-The horizontal position of the feeb, increasing to east.
+The horizontal position of the feeb, starting with 0 and increasing to east.
If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
\par\end{flushleft}
\item [{\textsf{\textbf{(y-position}\emph{~status}\textbf{)}}}] \begin{flushleft}
-The vertical position of the feeb, increasing to north.
+The vertical position of the feeb, starting with 0 and increasing to south.
If \textsf{\textbf{'sense-location-p}} is nil, it returns nil instead.
\par\end{flushleft}
\item [{\textsf{\textbf{(peeking}\emph{~status}\textbf{)}}}] \begin{flushleft}
@@ -323,7 +323,7 @@
\item [{\textsf{\textbf{(line-of-sight}\emph{~status}\textbf{)}}}] \begin{flushleft}
Indicates the amount of valid entries in \textsf{\emph{vision}}. It actually
means that \textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
-will return \textsf{\textbf{:rock}}.
+will return \textsf{\textbf{'(:rock)}}.
\par\end{flushleft}
\item [{\textsf{\textbf{(ready-to-fire}\emph{~status}\textbf{)}}}] \begin{flushleft}
If \textsf{\textbf{T}} indicates that the feeb is ready to fire.
@@ -368,12 +368,13 @@
\textsf{\textbf{(aref}\emph{~vision~}1\textbf{)}}
will return the contents of the next square, and so on. As said before,
\textsf{\textbf{(aref}\emph{~vision~}\textbf{(line-of-sight}\emph{~status}\textbf{))}}
-will be the first :rock encountered. All subsequents square, like
+will be the first \textsf{\textbf{'(:rock)}} encountered. All subsequents square, like
\textsf{\textbf{(aref}\emph{~vision~}\textbf{(+}~1~\textbf{(line-of-sight}\emph{~status}\textbf{)))}},
will be garbage and should not be used.
\end{lyxlist}
The contents of one square returned by any of these calls is either
-:rock or a list of elements, or \textsf{\textbf{()}} if the
+a list of elements, a wall \textsf{\textbf{'(:rock)}} (i.e. a list with
+one element, a \textsf{\textbf{:rock}}) or \textsf{\textbf{()}} if the
square is empty. Each element of the square is one of these:
\begin{itemize}
@@ -385,8 +386,7 @@
in the square of the feeb (i.e. in \textsf{\textbf{(my-square}}\textsf{\emph{~proximity}}\textsf{\textbf{)}}),
the call \textsf{\textbf{:eat-carcass}} will make the feeb eat it.
\item \textsf{\textbf{:mushroom}}. Analogous to \textsf{\textbf{:carcass}}.
-A mushroom appears randomly in places (mushroom patchs) previouly
-marked in the map.
+A mushroom appears randomly in places previously marked in the map.
\end{itemize}
\subsubsection{Feebs and fireballs images}
@@ -394,9 +394,9 @@
Both fireballs and feebs that are given to the brain function are
not the real ones, but just images with contents that the brain function
can access. It is allowed to keep and change its contents because they
-doesn't represent anything.
+won't be used internally.
-These are the fields available:
+These are the accessors available (they read and change the fiels):
\begin{lyxlist}{00.00.0000}
\item [{\textsf{\textbf{(feeb-image-name}~feeb-image\textbf{)}}}] \begin{flushleft}
@@ -412,7 +412,7 @@
not.
\par\end{flushleft}
\item [{\textsf{\textbf{(fireball-image-direction}~fireball-image\textbf{)}}}] \begin{flushleft}
-The direction that the fireball image is going to.
+The direction where the fireball image is going to.
\par\end{flushleft}
\end{lyxlist}
@@ -426,17 +426,17 @@
Note that feebs that are not peeking, mushrooms and carcasses are
\emph{not} be detected by these vectors. Also, if there is a feeb
-peeking to the opposite side, it won't be detected either. These are
-the possible returns of the elements in \textsf{\textbf{vision-left}}
-and \textsf{\textbf{vision-right}}:
+peeking to the opposite side, it won't be detected either. The
+elements in \textsf{\textbf{vision-left}} and \textsf{\textbf{vision-right}}
+are lists containing these elements:
\begin{lyxlist}{00.00.0000}
\item [{\textsf{\textbf{:peek-letf}}}] This means that in that square there
is a feeb peeking to (its) left.
\item [{\textsf{\textbf{:peek-right}}}] This means that in that square
there is a feeb peeking to (its) right.
-\item [{\textsf{\textbf{nil}}}] This square is empty.
-\item [{\textsf{\textbf{:rock}}}] This square is just a wall.
+\item [{\textsf{\textbf{:rock}}}] This square is just a wall. In this case,
+this is the only element in the square.
\end{lyxlist}
\subsection{Extra functions provided}
@@ -452,9 +452,15 @@
It is possible to change the layout of the map by calling
\textsf{\textbf{(change-layout}~new-layout\textbf{)}}.
There are a few predefined mazes that are in variables \textsf{\textbf{{*}maze-0{*}}}
-throw \textsf{\textbf{{*}maze-5{*}}}. If you want to create a new
-map, you can start by an empty template of any size provided by
-\textsf{\textbf{(make-template}~x-size~y-size~\textbf{:density}~density\textbf{)}}.
+(which is set by default) throw \textsf{\textbf{{*}maze-5{*}}}.
+In a layout, `X' represents a wall, `e' represents a feeb entry point
+(there will be as many entry points as feebs in the maze at the same time),
+`m' represents a mushroom site and ` ' is a blank space.
+
+If you want to create a new map, you can start by an empty template
+of any size that is provided by \textsf{\textbf{(make-template}~x-size~y-size\textbf{)}},
+or you can get a reandom map calling
+\textsf{\textbf{(generate-maze}~x-size~y-size~\textbf{:density}~density\textbf{)}}
The density is a number, recomended to be between 0.25 and 0.45,
which tells the portion of the maze should be blank spaces.
The function quits after a while if it doesn't meet this portion. See
@@ -483,7 +489,7 @@
\subsection{Starting the game}
-The game loop is started by calling (feebs).
+The game loop is started by calling \textsf{\textbf{(simple-play)}}.
@@ -506,11 +512,12 @@
what is really in the maze, but only the possible ways.
To get the map, one can call \textsf{\textbf{(get-maze-map)}}. This
-function will return \textsf{\textbf{nil}} if parameter \textsf{\textbf{'may-get-maze-map-p}}
-is also \textsf{\textbf{nil}}. Otherwise, the map returned is an array,
-so that calling \textsf{\textbf{(aref}~map~x~y\textbf{)}}
-will get the contents in the euclidean position (x,y) . The contents
-of a cell could be one of these:
+function will return \textsf{\textbf{nil}} if parameter
+\textsf{\textbf{'may-get-maze-map-p}} is also \textsf{\textbf{nil}}.
+Otherwise, the map returned is an array, so that calling
+\textsf{\textbf{(aref}~map~x~y\textbf{)}} will get the contents
+in the position (x,y) (like euclidean but inverting the y axis).
+The contents of a cell could be one of these:
\begin{lyxlist}{00.00.0000}
\item [{\textsf{\textbf{:mushroom-place}}}] A mushroom patch, i.e. when
@@ -522,6 +529,9 @@
the previous.
\end{lyxlist}
+This map can safelly be used since \textsf{\textbf{(get-maze-map)}} makes
+a new copy every time it is called.
+
\subsection{Timing}
There are also some timing atributes that can be given to the game.
@@ -537,7 +547,7 @@
\item [{\textsf{\textbf{'slow-feeb-noop-factor}}}] The probability
of the feeb to abort will be this factor times the amount of time
the feeb takes to have a decision, divided by the total time taken
-by all the feebs in the current turn or by a reference time.
+by all the feebs in the current turn or divided by a reference time.
\item [{\textsf{\textbf{'reference-time}}}] Time taken by reference
if non-nil.
\item [{\textsf{\textbf{'points-for-slow-down}}}] Points earned when
Modified: graphics.lisp
==============================================================================
--- graphics.lisp (original)
+++ graphics.lisp Thu Jan 3 21:20:39 2008
@@ -35,10 +35,11 @@
(cond
((wallp elt)
(list " XX"))
- ((feeb-image-p (car elt))
+ ((feeb-p (car elt))
(list "F~1d~a"
+ (position (feeb-name (car elt)) *feebs* :key #'feeb-name)
(print-direction (feeb-facing (car elt)))))
- ((fireball-image-p (car elt))
+ ((fireball-p (car elt))
(list " *~a" (print-direction (fireball-direction (car elt)))))
((eq (car elt) :mushroom)
(list " mm"))
@@ -52,11 +53,16 @@
(change-layout layout))
(make-auto-feebs (- 10 (length *feebs-to-be*)))
(initialize-feebs)
- (loop repeat *game-length* do
- (play-one-turn) (print-map) (sleep 0.7) (format t "~%~%"))
- (format t "Fim de jogo!!~%~%Pontua��es:~%~%")
+ (start-round)
+ (loop do
+ (play-one-turn)
+ (print-map)
+ (sleep 0.7)
+ (format t "~%~%")
+ (if (finish-game-p) (return)))
+ (format t "Game Over!!~%~%Scores:~%~%")
(dolist (feeb *feebs*)
- (format t "~a: ~d~%" (feeb-name feeb) (feeb-score feeb))))
+ (format t "~a: ~d~%" (feeb-name feeb) (feeb-score feeb))))
#|
Modified: images.lisp
==============================================================================
--- images.lisp (original)
+++ images.lisp Thu Jan 3 21:20:39 2008
@@ -27,6 +27,24 @@
;;; -*- Vision Calculation -*-
+(defstruct feeb-image
+ name facing peeking)
+
+(defstruct fireball-image
+ direction)
+
+(defstruct (proximity
+ (:conc-name nil))
+ my-square
+ rear-square
+ left-square
+ right-square)
+
+(defun rcurry (func &rest args)
+ #'(lambda (x)
+ (apply func x args)))
+
+
;;; Computes what the feeb is seeing
(defun compute-vision (feeb)
@@ -41,19 +59,17 @@
(y (feeb-y-position feeb)))
;; First fill in proximity info.
(setf (my-square proximity)
- (imagify feeb (aref *maze* x y) 'proximity)
+ (mapcar (rcurry #'imagify feeb :proximity)
+ (aref *maze* x y))
(left-square proximity)
- (imagify feeb
- (aref *maze* (+ x (left-dx facing)) (+ y (left-dy facing)))
- :proximity)
+ (mapcar (rcurry #'imagify feeb :proximity)
+ (aref *maze* (+ x (left-dx facing)) (+ y (left-dy facing))))
(right-square proximity)
- (imagify feeb
- (aref *maze* (+ x (right-dx facing)) (+ y (right-dy facing)))
- :proximity)
+ (mapcar (rcurry #'imagify feeb :proximity)
+ (aref *maze* (+ x (right-dx facing)) (+ y (right-dy facing))))
(rear-square proximity)
- (imagify feeb
- (aref *maze* (+ x (behind-dx facing)) (+ y (behind-dy facing)))
- :proximity))
+ (mapcar (rcurry #'imagify feeb :proximity)
+ (aref *maze* (+ x (behind-dx facing)) (+ y (behind-dy facing)))))
;; The vision vector starts in the square the feeb is facing.
(setf x (+ x (forward-dx facing))
y (+ y (forward-dy facing)))
@@ -72,50 +88,61 @@
(right-wall-y (+ y (right-dy facing)) (+ right-wall-y vision-dy))
(index 0 (1+ index)))
((wallp (aref *maze* x y))
- (setf (aref vision index) :rock
- (aref vision-left index) :unknown
- (aref vision-right index) :unknown
- (line-of-sight status) index))
- (setf (aref vision index) (imagify feeb (aref *maze* x y) :vision)
+ (setf (aref vision index) (list :rock)
+ (aref vision-left index) (list :unknown)
+ (aref vision-right index) (list :unknown)
+ (feeb-line-of-sight feeb) index))
+ (setf (aref vision index)
+ (mapcar (rcurry #'imagify feeb :vision)
+ (aref *maze* x y))
(aref vision-left index)
- (imagify feeb
- (aref *maze* left-wall-x left-wall-y)
- :left-vision)
+ (mapcar (rcurry #'imagify feeb :left-vision)
+ (aref *maze* left-wall-x left-wall-y))
(aref vision-right index)
- (imagify feeb
- (aref *maze* right-wall-x right-wall-y)
- :right-vision)))))
+ (mapcar (rcurry #'imagify feeb :right-vision)
+ (aref *maze* right-wall-x right-wall-y))))))
-(defstruct feeb-image
- name facing peeking)
-
-(defstruct fireball-image
- direction)
;;; This transforms what the feeb is seeing;
-(defgeneric imagify (feeb thing type)
+(defgeneric imagify (feeb type thing)
(:documentation "Defines how FEEB sees or feels THING.
TYPE could be :vision, :left-vision :right-vision or :proximity")
- (:method (feeb thing type)
+ (:method (thing feeb type)
thing)
- (:method (feeb (thing feeb)
- (type (or (eql :vision) (eql :proximity))))
+ (:method ((thing feeb) feeb (type (eql :vision)))
+ (make-feeb-image :name (feeb-name thing)
+ :facing (feeb-facing thing)
+ :peeking (feeb-peeking thing)))
+
+ (:method ((thing feeb) feeb (type (eql :proximity)))
(make-feeb-image :name (feeb-name thing)
- :facing (feeb-facing feeb)
- :peeking (feeb-peeking feeb)))
+ :facing (feeb-facing thing)
+ :peeking (feeb-peeking thing)))
- (:method (feeb (thing fireball)
- (type (or (eql :vision) (eql :proximity))))
+ (:method ((thing fireball) feeb (type (eql :vision)))
(make-fireball-image :direction (fireball-direction thing)))
- (:method (feeb thing
- (or (eql :left-vision) (eql :right-vision)))
- nil)
+ (:method ((thing fireball) feeb (type (eql :proximity)))
+ (make-fireball-image :direction (fireball-direction thing)))
+
+ (:method (thing feeb (type (eql :left-vision)))
+ (if (eq :rock thing)
+ :rock))
+
+ (:method (thing feeb (type (eql :right-vision)))
+ (if (eq :rock thing)
+ :rock))
- (:method (feeb (thing feeb)
- (or (eql :left-vision) (eql :right-vision)))
- (and (feeb-image-p thing)
- (= facing (feeb-image-facing thing))
- (feeb-image-peeking thing))))
+ (:method ((thing feeb) feeb (type (eql :left-vision)))
+ (and (feeb-p thing)
+ (= (feeb-facing feeb) (left-of (feeb-facing thing)))
+ (feeb-peeking thing)))
+
+ (:method ((thing feeb) feeb (type (eql :right-vision)))
+ (and (feeb-p thing)
+ (= (feeb-facing feeb) (right-of (feeb-facing thing)))
+ (feeb-peeking thing)))
+
+) ; end of imagify generic function
Modified: main.lisp
==============================================================================
--- main.lisp (original)
+++ main.lisp Thu Jan 3 21:20:39 2008
@@ -21,15 +21,6 @@
(in-package :feebs)
-;; These are defined provisorily here
-;; the definitive version is in rules.lisp
-
-(defun rot-carcass-p (time)
- t)
-
-(defun finish-game-p ()
- nil)
-
;;; Parameters
@@ -43,12 +34,13 @@
parameter already existed with value ~a." name value (car it))
(setf (gethash name parameters) (cons value (or doc (cdr it)))))
(setf (gethash name parameters) (cons value doc)))
+ (export name)
name)
(defun get-feeb-parm (name)
- (gethash name parameters))
+ (car (gethash name parameters)))
- (defun change-parameter (name value)
+ (defun change-feeb-parm (name value)
(unless *playing-feeb*
(setf (car (gethash name parameters)) value)))
@@ -65,29 +57,24 @@
;;; Characteristics of the maze:
+(def-feeb-parm 'maze-x-size *maze-x-size*
+ "Horizontal size of the maze.")
+
+(def-feeb-parm 'maze-y-size *maze-y-size*
+ "Vertical size of the maze.")
+
(def-feeb-parm 'may-get-maze-map-p t
"Tells if the function (get-maze-map) returns the map layout
instead of nil during the game.")
-;;; Tests that behavior functions might use
-
-;; (declare (inline feeb-image-p fireball-image-p))
-
-;; (defun feeb-image-p (thing)
-;; (typep thing 'feeb))
-
-;; (defun fireball-image-p (thing)
-;; (typep thing 'fireball))
-
-
;;; The maze
;;; Changing the maze
(defun change-layout (layout)
"Changes the layout of the map. See variables
-*maze-0* throw *maze-5* for examples (or options) of layouts"
+*maze-0* throw *maze-5* for examples (or options) of layouts."
(when *feebs-to-be*
(warn "There are some feebs that have already been defined.
They could have used (get-maze-map). Those are they:
@@ -127,48 +114,44 @@
*number-of-mushroom-sites* 0
*number-of-entry-points* 0)
(do ((rows *layout* (cdr rows))
- (i (1- *maze-y-size*) (1- i))) ; inverting the y axis
+ (y (1- *maze-y-size*) (1- y))) ; inverting the y axis
((null rows))
(let ((str (car rows)))
- (dotimes (j (length str))
- (setf (aref *maze* j i) nil
- (aref *fake-maze* j i) nil)
- (case (schar str j)
+ (dotimes (x (length str))
+ (setf (aref *maze* x y) nil
+ (aref *fake-maze* x y) nil)
+ (case (schar str x)
(#\X
- (setf (aref *fake-maze* j i) :rock
- (aref *maze* j i) :rock))
+ (setf (aref *fake-maze* x y) :rock
+ (aref *maze* x y) (list :rock)))
(#\*
- (setf (aref *fake-maze* j i) :mushroom-place)
+ (setf (aref *fake-maze* x y) :mushroom-place)
(incf *number-of-mushroom-sites*)
- (push (make-pos j i) *mushroom-sites*))
+ (push (cons x y) *mushroom-sites*))
(#\e
- (setf (aref *fake-maze* j i)
+ (setf (aref *fake-maze* x y)
:feeb-entry-place)
(incf *number-of-entry-points*)
- (push (make-pos j i) *entry-points*))
+ (push (cons x y) *entry-points*))
(#\space nil)
(t
- (error "Unknown spec in maze: ~C." (schar str j))))))))
+ (error "Unknown spec in maze: ~C." (schar str x))))))))
+
+(eval-when (:load-toplevel)
+ (init-maze))
(defun initialize-feebs ()
- (setf *mushrooms-alive* *number-of-mushrooms*
- *dead-feebs* nil
- *fireballs-flying* nil
- *continue* t
- *mushroom-sites* nil
- *entry-points* nil
- *carcasses* nil
- *static-parameters*
- (loop for (symbol . value) in (list-parameter-settings)
- collect value))
+ (setf *feebs* ()
+ *dead-feebs* ()
+ *fireballs-flying* ()
+ *mushroom-sites* ()
+ *carcasses* ()
+ *playing-feeb* nil)
+ (init-maze)
(create-feebs)) ; The feebs are defined here
-;;; Setting up the feebs.
-
-(defvar *feebs* nil)
-
;;; Define-Feeb builds a list of feebs to create. Create-Feebs actually
;;; builds the feebs on this list.
@@ -179,16 +162,19 @@
If there is another feeb with the same name, overwrites it
with a case sensitive test."
(when (find name *feebs-to-be* :key #'car
- :test #'string= (delete-feeb name))
- (warn "Feeb ~s already exists, deleting..." name))
- (push (list name brain graphics class) *feebs-to-be*))
+ :test #'string=)
+ (delete-feeb name)
+ (warn "Feeb ~s already exists, deleting..." name))
+ (push (list name brain graphics class) *feebs-to-be*)
+ name)
(defun delete-feeb (name)
"Deletes the feeb which has name NAME, causing it not to
be created when the game begins. Does not work for feebs
already in the game."
(setf *feebs-to-be*
- (remove name *feebs-to-be* :key #'car :test #'string=)))
+ (remove name *feebs-to-be* :key #'car :test #'string=))
+ nil)
(defun list-of-feebs ()
"Returns a copy of the list of feebs that will be created
@@ -208,18 +194,17 @@
:graphics graphs
:x-position x-pos
:y-position y-pos)))
- (push feeb *feebs*)
(if (and x-pos y-pos)
(create-object feeb x-pos y-pos)
(push feeb *dead-feebs*)))))
- (let ((entries (sort *entry-points* ; random positions
- #'(lambda (x y)
- (declare (ignore x y))
- (zerop (random 2))))))
- (setf *feebs* nil)
- (dolist (feeb-spec *feebs-to-be*)
- (let ((pos (pop entries))))
- (apply 'create-feeb (car pos) (cdr pos) feeb-spec)))))
+ (let ((entries (sort (copy-list *entry-points*) ; random positions
+ #'(lambda (x y)
+ (declare (ignore x y))
+ (zerop (random 2))))))
+ (setf *feebs* nil)
+ (dolist (feeb-spec *feebs-to-be*)
+ (let ((pos (pop entries)))
+ (apply #'create-feeb (car pos) (cdr pos) feeb-spec))))))
@@ -234,14 +219,15 @@
;; This is defined by rules:
(start-turn) ; possible call to number-of-mushrooms
;; Maybe grow up mushrooms:
- (let ((m-sites (sort *mushroom-sites*
+ (let ((m-sites (sort (copy-list *mushroom-sites*)
#'(lambda (x y)
(declare (ignore x y))
(zerop (random 2))))))
(dotimes (i mushrooms)
(let ((site (pop m-sites)))
- (unless (member #'fireball-p)
- (create-mushroom (car site) (cdr site))))))
+ (unless (find-if #'fireball-p
+ (aref *maze* (car site) (cdr site)))
+ (create-mushroom (car site) (cdr site))))))
;; Maybe rot some carcasses
(dolist (carc (prog1 *carcasses*
(setf *carcasses* nil)))
@@ -254,14 +240,15 @@
(push carc *carcasses*))))
;; Move some fireballs:
(dolist (fireball *fireballs-flying*)
- (move-object fireball (make-move-choice fireball)))
+ (make-move fireball (make-move-choice fireball)))
(dolist (feeb *feebs*)
;; Starve the feeb:
(when (<= (decf (feeb-energy-reserve feeb)) 0)
(destroy-object feeb :starve)))
(dolist (*playing-feeb* *feebs*)
;; Compute vision for the feeb:
- (compute-vision feeb)
+ (compute-vision *playing-feeb*)
+ (incf (feeb-turns-since-flamed *playing-feeb*))
;; Lets the feeb make a choice
(setf (feeb-last-move *playing-feeb*)
(make-move-choice *playing-feeb*)
@@ -269,6 +256,6 @@
;; binds the variable to the current playing feeb
(dolist (feeb *feebs*)
;; Collect the feeb's move
- (move-object feeb (feeb-last-move feeb))))
+ (make-move feeb (feeb-last-move feeb))))
) ; end of let ((mushrooms 1))
Modified: mazes.lisp
==============================================================================
--- mazes.lisp (original)
+++ mazes.lisp Thu Jan 3 21:20:39 2008
@@ -226,15 +226,8 @@
(defun make-template (x-size y-size)
"Prints map template of the requested size.
Use this to create new mazes."
- (dotimes (i y-size)
- (format t "~@?~a~@?~%"
- (if (zerop i)
- "~4t'(\""
- "~6t\"")
- (make-string x-size :initial-element #\X)
- (if (= i y-size)
- "\")"
- "\""))))
+ (loop repeat y-size collect
+ (make-string x-size :initial-element #\X)))
(defun density (maze xs ys)
(let ((sum 0))
@@ -373,8 +366,8 @@
corridor-y-avg corridor-y-max))
(if y1 (bound-random y1 corridor-y-min
corridor-y-avg corridor-y-max)))
- (real-dens ))
- ((or (>= real density)
+ (real-dens (density map x-size y-size)))
+ ((or (>= real-dens density)
(> i (* density x-size y-size))) ; quits after trying TOO MUCH
(values (translate map x-size y-size) real-dens))
(if x1
Modified: package.lisp
==============================================================================
--- package.lisp (original)
+++ package.lisp Thu Jan 3 21:20:39 2008
@@ -33,37 +33,7 @@
(defpackage :feebs
(:use :common-lisp)
;; Export everything we want the players to get their hands on.
- (:export *game-length*
-
- ;; Strategic quantities
- *points-for-killing* *points-for-dying*
- *flame-energy* *mushroom-energy* *carcass-energy*
- *maximum-energy*
- *starting-energy*
-
- ;; Game quantities
- *maze-x-size*
- *maze-y-size*
- *number-of-mushrooms*
-
- ;; Probabilities
- *fireball-guaranteed-lifetime*
- *fireball-dissipation-probability*
- *fireball-reflection-probability*
- *flame-no-recovery-time*
- *flame-recovery-probability*
-
- ;; Difficulty variables
- *slow-feeb-noop-switch*
- *slow-feeb-noop-factor*
- *sense-location-p*
-;; *sense-facing-p* ;; if this will be used, one must find a way to
-;; ;; a feeb detect other feeb's facing, and fireball's
-;; ;; direction, only relative to the feeb (in the brain call)
-;; ;; should not be so difficult
- *may-get-maze-map-p*
-
- ;; Slots accessors
+ (:export ;; Slots accessors
name facing
x-position y-position peeking line-of-sight
energy-reserve
@@ -82,6 +52,38 @@
get-feeb-parm change-feeb-parm
list-parameter-settings
+ game-length
+
+ ;; Pontuation
+ points-for-killing points-for-dying
+ points-for-slow-down
+
+ ;; Energy
+ flame-energy mushroom-energy carcass-energy
+ maximum-energy
+ starting-energy
+ carcass-rot-probability
+ carcass-guaranteed-lifetime
+
+ ;; Game quantities
+ maze-x-size
+ maze-y-size
+ number-of-mushrooms
+
+ ;; Probabilities
+ fireball-guaranteed-lifetime
+ fireball-dissipation-probability
+ fireball-reflection-probability
+ flame-no-recovery-time
+ flame-recovery-probability
+
+ ;; Difficulty variables
+ slow-feeb-noop-switch
+ slow-feeb-noop-factor
+ reference-time
+ sense-location-p
+ may-get-maze-map-p
+
;; Settings
define-feeb delete-feeb
feebs
@@ -92,7 +94,8 @@
north south east west
;; Some layouts (can be find in mazes.lisp)
- *maze-1* *maze-2* *maze-3* *maze-4* *maze-5*
+ *maze-0* *maze-1* *maze-2*
+ *maze-3* *maze-4* *maze-5*
make-template generate-maze
;; Graphics
@@ -117,6 +120,7 @@
(in-package :feebs)
+
;;; Directions
(deftype direction ()
@@ -133,9 +137,6 @@
(defvar *number-of-mushroom-sites* 0)
(defvar *feeb-parameters* nil)
-;;; These are for security
-
-(defvar *static-parameters* nil)
;;; Setting up the maze.
@@ -147,7 +148,7 @@
(defvar *maze* nil)
(defvar *fake-maze* nil)
-(defparameter *layout*
+(defparameter *maze-0*
'("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
"Xe * XXXXXXX XXXXXXXXXX"
"XXXXX XXXXXXX XXXXXXX * XXXXX"
@@ -181,35 +182,33 @@
"XXXXX XXXXXXXXXXXXX X"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"))
+(defparameter *layout* *maze-0*)
;;; Map size
-(def-feeb-parm 'maze-x-size 32
- "Horizontal size of the maze.")
-
-(def-feeb-parm 'maze-y-size 32
- "Vertical size of the maze.")
-
(defvar *maze-x-size* 32)
(defvar *maze-y-size* 32)
;;; Quantities during the game
-(defvar *mushroom-sites*)
-(defvar *entry-points*)
-(defvar *number-of-entry-points*)
-(defvar *mushrooms-alive*)
+(defvar *mushroom-sites* ())
+(defvar *entry-points* ())
+(defvar *number-of-entry-points* 0)
+
;;; Elements in the maze
-(defvar *fireballs-flying*)
-(defvar *dead-feebs*)
-(defvar *carcasses*)
+(defvar *feebs* ())
+(defvar *dead-feebs* ())
+(defvar *fireballs-flying* ())
+(defvar *carcasses* ())
+
;;; Current feeb playing
-(defvar *playing-feeb*)
+(defvar *playing-feeb* nil)
+(defvar *feebs-to-be* ())
(defmacro aif (test then &optional else)
`(let ((it ,test))
Modified: rules.lisp
==============================================================================
--- rules.lisp (original)
+++ rules.lisp Thu Jan 3 21:20:39 2008
@@ -32,7 +32,6 @@
"Maximum number of mushrooms created each turn.")
(let (turn-number total-time)
- ;; Function redefinitions
(defun start-round ()
(setf turn-number 0))
@@ -73,7 +72,7 @@
;;; Being Born / Reincarnating
(def-feeb-parm 'starting-energy 50
- "Smallest amount of energy a feeb will start with.")
+ "Amount of energy a feeb will start with.")
(defmethod create-object :before ((feeb feeb) x y)
(setf (feeb-energy-reserve feeb)
@@ -92,16 +91,16 @@
"How many points some feeb earn for killing someone.")
(defmethod destroy-object :before ((feeb feeb) (fireball fireball))
- (unless (eq (fireball-owner fireball) feeb)
- (incf (feeb-score (fireball-owner fireball))
- (get-feeb-parm 'points-for-killing))))
+ (let ((owner (fireball-owner fireball)))
+ (unless (eq owner feeb)
+ (incf (feeb-score owner) (get-feeb-parm 'points-for-killing))
+ (incf (feeb-kill-counter owner)))))
;;; Carcasses:
(def-feeb-parm 'carcass-guaranteed-lifetime 5
- "Number of
-turns that a carcass will surely not rot. After these turns, it
-can rot, depending on probabilities.")
+ "Number of turns that a carcass will surely not rot.
+After these turns, it can rot, depending on probabilities.")
(def-feeb-parm 'carcass-rot-probability 1/3
"Probability of the carcass to rot, after the apropriate time.")
@@ -136,7 +135,7 @@
;;; Feebs
-(deef-feeb-parm 'flame-no-recovery-time 2
+(def-feeb-parm 'flame-no-recovery-time 2
"Probability
of the feeb to recover the hability to throw a flame, after the apropriate
time.")
@@ -146,17 +145,19 @@
after the apropriate time.")
(defmethod make-move-choice :around ((feeb feeb))
- (inc-total-time
- (setf (feeb-time feeb)
- (+ (- (get-intenal-real-time))
- (progn
- (call-next-method)
- (get-intenal-real-time)))))
(unless (feeb-ready-to-fire feeb)
- (and (> (feeb-turns-since-flamed feebs)
+ (and (> (feeb-turns-since-flamed feeb)
(get-feeb-parm 'flame-no-recovery-time))
(chance (get-feeb-parm 'flame-recovery-probability))
- (setf (feeb-ready-to-fire feeb) t))))
+ (setf (feeb-ready-to-fire feeb) t)))
+ (let (choice)
+ (inc-total-time
+ (setf (feeb-time feeb)
+ (+ (- (get-internal-real-time))
+ (progn
+ (setf choice (call-next-method))
+ (get-internal-real-time)))))
+ choice))
@@ -242,5 +243,5 @@
(defmethod make-move :around ((feeb feeb) (move (eql :flame)))
(when (>= (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
- (decf (feeb-energy-reserve) (get-feeb-parm 'flame-energy))
+ (decf (feeb-energy-reserve feeb) (get-feeb-parm 'flame-energy))
(call-next-method)))
Modified: system.lisp
==============================================================================
--- system.lisp (original)
+++ system.lisp Thu Jan 3 21:20:39 2008
@@ -33,19 +33,14 @@
(defclass feeb (object)
(;; These are structures accessible from behavior functions.
- ;; These (whose :reader start with feeb-image)
- ;; are intended to be accessed by other feebs
(name :accessor feeb-name :reader name :initarg :name)
- (direction :reader facing :initform (random 4))
- (peeking :accessor feeb-peeking :reader peeking)
-
- ;; These are intended to be accessed only by the feeb itself
+ (direction :reader facing :initform (random 4) :accessor feeb-facing)
+ (peeking :accessor feeb-peeking :reader peeking :initform nil)
(x-position :reader x-position :accessor feeb-x-position)
(y-position :reader y-position :accessor feeb-y-position)
(line-of-sight :accessor feeb-line-of-sight :reader line-of-sight
:initform 0)
- (energy-reserve :accessor feeb-energy-reserve :reader energy-reserve
- :initform *starting-energy*)
+ (energy-reserve :accessor feeb-energy-reserve :reader energy-reserve)
(ready-to-fire :accessor feeb-ready-to-fire :reader ready-to-fire
:initform t)
(aborted :accessor feeb-aborted :reader aborted)
@@ -57,9 +52,8 @@
(graphics :accessor feeb-graphics :initarg :graphics)
(time :accessor feeb-time :initform 0)
(last-score :accessor feeb-last-score :initform 0)
- (last-kills :accessor feeb-last-kills :initform 0)
+ (kill-counter :accessor feeb-kill-counter :initform 0)
(score :accessor feeb-score :initform 0)
- (kills :accessor feeb-kills :initform 0)
(turns-since-flamed :accessor feeb-turns-since-flamed :initform 0)
(proximity :accessor feeb-proximity :initform (make-proximity))
(vision :accessor feeb-vision
@@ -94,14 +88,10 @@
t))
(defun delete-object (thing x y)
- (when (eq thing :mushroom)
- (decf *mushrooms-alive*))
(setf (aref *maze* x y)
(delete thing (aref *maze* x y))))
(defun place-object (thing x j)
- (when (eq thing :mushroom)
- (incf *mushrooms-alive*))
(push thing (aref *maze* x j)))
(defun change-object-pos (obj x y)
@@ -123,29 +113,28 @@
;;; --**-- System Rules --**--
-;;; -*- General Rules -*-
-
-;; These will be redefined by rules
-
-(defun start-turn ()
- t)
-
-(defun start-round ()
- t)
-
-
;;; -*- Being Born and Dying -*-
;;; Creating
-(defgeneric create-object (object x-pos y-pos &key &allow-other-keys)
+(defgeneric create-object (object x-pos y-pos)
+ (:documentation "Creates OBJECT and places it in position (X-POS,Y-POS)
+in the maze, except for fireballs, which are placed only the next turn.")
(:method (object x-pos y-pos)
- (change-object-pos object x-pos y-pos))
+ (place-object object x-pos y-pos)
+ (setf (object-x-position object) x-pos
+ (object-y-position object) y-pos))
+
(:method ((feeb feeb) x-pos y-pos)
- (setf (feeb-dead-p feeb) nil
- (feeb-last-move feeb) :dead)
- (pushnew feeb *feebs*)))
+ (setf (feeb-last-move feeb) :dead)
+ (push feeb *feebs*)
+ (call-next-method))
+
+ (:method ((fireball fireball) x-pos y-pos)
+ (push fireball *fireballs-flying*)
+ (setf (object-x-position object) x-pos
+ (object-y-position object) y-pos))) ; don't place it yet, only after first move
;;; Reincarnating
@@ -155,15 +144,25 @@
;;; Dying
-(defgeneric destroy-object (object cause &key &allow-other-keys)
+(defgeneric destroy-object (object cause)
+ (:documentation "Called when CAUSE destroys OBJECT.
+CAUSE could be :starve or a fireball (for feebs)
+or :dissipate (for fireballs)."
+ (:method (object cause)
+ (delete-object object (object-x-position object)
+ (object-y-position object)))
+
+ (:method ((fireball fireball) cause)
+ (setf *fireballs-flying*
+ (delete fireball *fireballs-flying*))
+ (call-next-method))
+
(:method ((feeb feeb) cause)
(setf *dead-feebs* (nconc *dead-feebs* (list feeb))
- (feeb-dead-p feeb) t
*feebs* (delete feeb *feebs*))
(let* ((x (feeb-x-position feeb))
(y (feeb-y-position feeb)))
(push (list 0 x y) *carcasses*)
- (delete-object (feeb-image feeb) x y)
(place-object :carcass x y))
(call-next-method)))
@@ -177,7 +176,7 @@
(:documentation "Lets object make its move choice.")
(:method ((feeb feeb))
(funcall (feeb-brain feeb)
- (feeb-status feeb)
+ feeb
(feeb-proximity feeb)
(feeb-vision feeb)
(feeb-vision-left feeb)
@@ -198,6 +197,10 @@
(setf (object-direction object)
(right-of (object-direction object))))
+ (:method (object (move (eql :turn-left)))
+ (setf (object-direction object)
+ (left-of (object-direction object))))
+
(:method (object (move (eql :turn-around)))
(setf (object-direction object)
(behind (object-direction object))))
@@ -205,21 +208,18 @@
(:method (object (move (eql :move-forward)))
(multiple-value-bind (stuff new-x new-y)
(get-forward-pos object)
- (when (wallp stuff)
- (return-from make-move nil))
- (change-object-pos object new-x new-y)))
+ (unless (wallp stuff)
+ (change-object-pos object new-x new-y))))
(:method ((fireball fireball) (move (eql :dissipate)))
- (destroy-object fireball))
+ (destroy-object fireball :dissipate))
(:method ((feeb feeb) (move (eql :flame)))
- (let ((x (feeb-x-position feeb))
- (y (feeb-y-position feeb))
- (fireball
- (make-instace 'fireball (feeb-facing feeb)
- feeb x y (forward-dx facing)
- (forward-dy facing))))
- (push fireball *fireballs-flying*)))
+ (setf (feeb-turns-since-flamed feeb) 0)
+ (create-object
+ (make-instance 'fireball :direction (feeb-facing feeb)
+ :owner feeb)
+ (feeb-x-position feeb) (feeb-y-position feeb)))
(:method ((feeb feeb) (move (eql :eat-mushroom)))
(let ((x (feeb-x-position feeb))
@@ -229,14 +229,16 @@
t)))
(:method ((feeb feeb) (move (eql :eat-carcass)))
- (when (find :carcass (aref *maze* (feeb-x-position feeb)
- (feeb-y-position feeb)))
- t))
-
- (:method ((feeb feeb) (move (or (eql :peek-left) (eql :peek-right))))
- (multiple-value-bind (x y stuff)
- (get-forward-pos feeb)
- (unless (wallp stuff)
- (setf (feeb-peeking feeb) move))))
+ (when (find :carcass (aref *maze* (feeb-x-position feeb)
+ (feeb-y-position feeb)))
+ t))
+
+ (:method ((feeb feeb) (move (eql :peek-left)))
+ (unless (wallp (get-forward-pos feeb))
+ (setf (feeb-peeking feeb) move)))
+
+ (:method ((feeb feeb) (move (eql :peek-right)))
+ (unless (wallp (get-forward-pos feeb))
+ (setf (feeb-peeking feeb) move)))
) ; end of make-move generic function
1
0