force use of pandoc version >= 3.1.12.2

The `bin/pandoc-wrapper.sh` tool will verify that the ssytem
has a recent enough version of `pandoc(1)`.

We explain why we insist on `pandoc(1)`. version >= 3.1.12.2
in comments where the $PANDOC_MIN_VERSION is set.

Added `--wrap=preserve` as a default argument to `pandoc(1)`.
While this change will impact every HTML file generated,
we believe this will improve the ability of someone to look
at the generated HTML and correlate with the original markdown.

Changed `bin/pandoc-wrapper.sh` VERSION from "1.4.2 2024-03-17"
to "1.4.3 2024-03-18".

Performed `make www` to achieve all of the above and to generate
HTML using the new  `--wrap=preserve` `pandoc(1)` mode.
This commit is contained in:
Landon Curt Noll committed 2024-03-18 01:26:39 -07:00
1 parent 9eb7a54e9f
commit b0b212acb1
402 files changed
+37061 -55132

No files matched your search

+45 -55
View File
@@ -120,58 +120,50 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<p>In order to successfully compile this you will need a C compiler that
supports C99+ and ncurses; note that for some platforms (e.g. Red Hat
based Linux) you will need two different packages: the library itself
but also the dev package that has the header files etc. If you use the
Makefile obviously you need <code>make</code> too.</p>
<p>In <a href="gameplay.md">gameplay.md</a> I show how to easily
customise the colours, set up different gameplay modes and various other
things. The troubleshooting.md and terminals.md as well as bugs.md
include a variety of information should you run into trouble.</p>
<p>In order to successfully compile this you will need a C compiler that supports
C99+ and ncurses; note that for some platforms (e.g. Red Hat based Linux) you
will need two different packages: the library itself but also the dev package
that has the header files etc. If you use the Makefile obviously you need <code>make</code>
too.</p>
<p>In <a href="gameplay.md">gameplay.md</a> I show how to easily customise the colours, set up
different gameplay modes and various other things. The troubleshooting.md
and terminals.md as well as bugs.md include a variety of information
should you run into trouble.</p>
<p>–</p>
<h1 id="portability">Portability</h1>
<p>I have tested this under macOS Catalina, macOS Ventura (and probably
between the two), Fedora (29 and also 31 - no that’s not a typo, I
upgraded from 29 to 31 as I had delayed upgrading to 30 due to a number
of issues and being busy) and CentOS 7.7.1908. It should work under any
modern linux system and maybe other Unices as well as macOS (as
noted).</p>
<p>It obviously requires ncurses but other than that nothing extra
should be needed. Note that the testing of Fedora 29 was earlier in the
development however (but then 29 is also EOL).</p>
<p>Furthermore I do not believe - but I cannot confirm either - that
endianness matters; I only have Intel CPUs and arm64 (MacBook Pro
M1).</p>
<p>I imagine that it works for 32-bit systems but I do not know for
sure.</p>
<p>I have tested this under macOS Catalina, macOS Ventura (and probably between the
two), Fedora (29 and also 31 - no that’s not a typo, I upgraded from 29 to 31 as
I had delayed upgrading to 30 due to a number of issues and being busy) and
CentOS 7.7.1908. It should work under any modern linux system and maybe other
Unices as well as macOS (as noted).</p>
<p>It obviously requires ncurses but other than that nothing extra should be
needed. Note that the testing of Fedora 29 was earlier in the development
however (but then 29 is also EOL).</p>
<p>Furthermore I do not believe - but I cannot confirm either - that endianness
matters; I only have Intel CPUs and arm64 (MacBook Pro M1).</p>
<p>I imagine that it works for 32-bit systems but I do not know for sure.</p>
<h1 id="portability-macos">Portability: macOS</h1>
<p>You should be able to get the compiler with:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> xcode-select <span class="at">--install</span></span></code></pre></div>
<p>You don’t need Xcode itself and it appears that the command line
tools (as above should install) already has ncurses so there shouldn’t
be anything else that needs to be done. But I’m not actually sure of
this - I’m seeing conflicting information and it’s been too long; anyway
there’s always <a href="https://www.macports.org">MacPorts</a> and also
Homebrew which should be sufficient; I do <em>NOT</em> recommend
Homebrew however: it takes ownership of /usr/local: as in the user you
run it as is the new owner so that you don’t need sudo because … Well
never mind.</p>
<p>You don’t need Xcode itself and it appears that the command line tools (as above
should install) already has ncurses so there shouldn’t be anything else that
needs to be done. But I’m not actually sure of this - I’m seeing conflicting
information and it’s been too long; anyway there’s always <a href="https://www.macports.org">MacPorts</a> and also
Homebrew which should be sufficient; I do <em>NOT</em> recommend Homebrew however:
it takes ownership of /usr/local: as in the user you run it as is the new owner
so that you don’t need sudo because … Well never mind.</p>
<h1 id="portability-fedora">Portability: Fedora</h1>
<p>You’ll need the packages <code>gcc</code>, <code>ncurses</code> and
<code>ncurses-devel</code> (plus <code>make</code> if you want to use
the Makefile) to compile and link this entry. With Fedora more recent
versions there’s the <code>dnf</code> package manager but I cannot help
with any of the GUI installers since I don’t use them. Something
like:</p>
<p>You’ll need the packages <code>gcc</code>, <code>ncurses</code> and <code>ncurses-devel</code> (plus <code>make</code> if
you want to use the Makefile) to compile and link this entry. With Fedora more
recent versions there’s the <code>dnf</code> package manager but I cannot help with any of
the GUI installers since I don’t use them. Something like:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> dnf install ncurses-devel ncurses make gcc</span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co"># dnf install ncurses-devel ncurses make gcc</span></span></code></pre></div>
<h1 id="portability-centos">Portability: CentOS</h1>
<p>Just like Fedora you will need <code>gcc</code>,
<code>ncurses</code>, <code>ncurses-devel</code> (and if you want to use
the Makefile <code>make</code>). CentOS uses <code>yum</code> and CentOS
8 uses <code>dnf</code>. So:</p>
<p>Just like Fedora you will need <code>gcc</code>, <code>ncurses</code>, <code>ncurses-devel</code> (and if you
want to use the Makefile <code>make</code>). CentOS uses <code>yum</code> and CentOS 8 uses <code>dnf</code>.
So:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> yum install ncurses-devel ncurses make gcc</span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co"># yum install ncurses-devel ncurses make gcc</span></span></code></pre></div>
@@ -179,20 +171,18 @@ the Makefile <code>make</code>). CentOS uses <code>yum</code> and CentOS
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sudo</span> dnf install ncurses-devel ncurses make gcc</span></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co"># dnf install ncurses-devel ncurses make gcc</span></span></code></pre></div>
<p>You can also use clang to compile (which is what gcc actually is
under macOS).</p>
<p>You can also use clang to compile (which is what gcc actually is under macOS).</p>
<h1 id="compilation-notes">Compilation notes</h1>
<p>As long as you have the dependencies above the only thing that comes
to mind is integer width problems.</p>
<p>If <code>size_t</code> does not equate to unsigned long: In this case
if say it’s an unsigned long long then theoretically you should be able
to change the <code>strtoul()</code> to be <code>strtoull()</code>
(after updating the typedef for unsigned long to be unsigned long long
maybe?). It appears to work from a quick test at least.</p>
<p>If it’s an unsigned int I believe you will have to opt for an
unsigned long (so <code>strtoul()</code> cast to an unsigned int).</p>
<p>Anything else I do not know other than just changing the typedef and
updating to the proper function (and/or cast to the right type).</p>
<p>As long as you have the dependencies above the only thing that comes to mind is
integer width problems.</p>
<p>If <code>size_t</code> does not equate to unsigned long: In this case if say it’s an
unsigned long long then theoretically you should be able to change the
<code>strtoul()</code> to be <code>strtoull()</code> (after updating the typedef for unsigned long to
be unsigned long long maybe?). It appears to work from a quick test at least.</p>
<p>If it’s an unsigned int I believe you will have to opt for an unsigned long (so
<code>strtoul()</code> cast to an unsigned int).</p>
<p>Anything else I do not know other than just changing the typedef and updating to
the proper function (and/or cast to the right type).</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+262 -308
View File
@@ -121,32 +121,26 @@
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1 id="about-this-document">About this document</h1>
<p>In this document I provide information to the herpetologist hackers
to help them modify certain things and add features for their studying
of snakes. Or if you prefer you can be the snake studying the
herpetologist. Whichever character you prefer to play doesn’t really
matter.</p>
<h1 id="warning-caveat-about-this-document">Warning / caveat about this
document</h1>
<p>WARNING: There are some things cited in this document that are no
longer correct, might be misleading or otherwise not clear. This is both
intentional and unintentional. This is especially true for claims that
something means something specific. Put another way just because the
table says something doesn’t mean it’s the whole truth: no misleading
comments but misleading document that talks about some parts of the
code!</p>
<p>Please do not assume that just because something is in this file
means that it’s complete or will work without any changes (see above).
As I have changed the game over development stages some features have
been dramatically changed and some of these ideas could be incompatible
now or otherwise impractical. Also you might find in fact that some of
these leave more questions than answers (e.g. some require making
decisions for specific problems one might encounter)!</p>
<p>With that said here’s the C sibilancy (the herpetologist programmer’s
and snake’s syllabary) for all snake and herpetologist programmers
alike.</p>
<h1 id="modifying-and-adding-additional-features-to-the-code">Modifying
and adding additional features to the code</h1>
<p>In this document I provide information to the herpetologist hackers to help them
modify certain things and add features for their studying of snakes. Or if
you prefer you can be the snake studying the herpetologist. Whichever character
you prefer to play doesn’t really matter.</p>
<h1 id="warning-caveat-about-this-document">Warning / caveat about this document</h1>
<p>WARNING: There are some things cited in this document that are no longer
correct, might be misleading or otherwise not clear. This is both intentional
and unintentional. This is especially true for claims that something means
something specific. Put another way just because the table says something
doesn’t mean it’s the whole truth: no misleading comments but misleading
document that talks about some parts of the code!</p>
<p>Please do not assume that just because something is in this file means that it’s
complete or will work without any changes (see above). As I have changed the
game over development stages some features have been dramatically changed and
some of these ideas could be incompatible now or otherwise impractical. Also you
might find in fact that some of these leave more questions than answers (e.g.
some require making decisions for specific problems one might encounter)!</p>
<p>With that said here’s the C sibilancy (the herpetologist programmer’s and
snake’s syllabary) for all snake and herpetologist programmers alike.</p>
<h1 id="modifying-and-adding-additional-features-to-the-code">Modifying and adding additional features to the code</h1>
<ul>
<li><p>Modifications</p>
<ul>
@@ -174,30 +168,28 @@ and adding additional features to the code</h1>
</ul></li>
</ul>
<h1 id="modifications">Modifications</h1>
<p>Here I include information on modifying the game in various ways
depending on the preference of the herpetologist (or if you prefer you
can be the snake studying the herpetologist).</p>
<p>Here I include information on modifying the game in various ways depending on
the preference of the herpetologist (or if you prefer you can be the snake
studying the herpetologist).</p>
<h2 id="modifying-the-colours">Modifying the colours</h2>
<p>As I already said I provided a script that prompts you for colours
and then compiles the game with those colours (default if invalid
input).</p>
<p>The parts of the game that are coloured are the WALL(s), the snake
HEAD and snake BODY. In the published alternate version (prog.alt.c) the
bug is also colourable. This means that there are a total of four
configurable colour pairs. It only supports the eight standard colours.
Each colour is a pair: foreground and background.</p>
<p>To change the colours use the snake-colours.sh or play.sh scripts.
Hit enter for defaults if you don’t want to change the colour.</p>
<h2 id="background-colour-of-the-game-field">Background colour of the
game field</h2>
<p>I prefer black backgrounds but this is the basic idea behind changing
it. You initialise a pair (make it 5 so as to not interfere with the
script customisability) and then you use the bkgd() function with the
colour pair. Something like this:</p>
<p>As I already said I provided a script that prompts you for colours and then
compiles the game with those colours (default if invalid input).</p>
<p>The parts of the game that are coloured are the WALL(s), the snake HEAD and
snake BODY. In the published alternate version (prog.alt.c) the bug is also
colourable. This means that there are a total of four configurable colour pairs.
It only supports the eight standard colours. Each colour is a pair: foreground
and background.</p>
<p>To change the colours use the snake-colours.sh or play.sh scripts. Hit enter for
defaults if you don’t want to change the colour.</p>
<h2 id="background-colour-of-the-game-field">Background colour of the game field</h2>
<p>I prefer black backgrounds but this is the basic idea behind changing it. You
initialise a pair (make it 5 so as to not interfere with the script
customisability) and then you use the bkgd() function with the colour pair.
Something like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>init_pair<span class="op">(</span><span class="dv">5</span><span class="op">,</span> COLOR_BLACK<span class="op">,</span> COLOR_WHITE<span class="op">);</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>bkgd<span class="op">(</span>COLOR_PAIR<span class="op">(</span><span class="dv">5</span><span class="op">));</span></span></code></pre></div>
<p>I played with this after winning and I came across some problems with
colours but that changes the background of the program anyway.</p>
<p>I played with this after winning and I came across some problems with colours
but that changes the background of the program anyway.</p>
<p>The standard colour identifiers are:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>COLOR_BLACK</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>COLOR_RED</span>
@@ -207,24 +199,20 @@ colours but that changes the background of the program anyway.</p>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>COLOR_MAGENTA</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>COLOR_CYAN</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>COLOR_WHITE</span></code></pre></div>
<p>See Linux Journal for more information article <a
href="https://www.linuxjournal.com/content/programming-color-ncurses"
class="uri">https://www.linuxjournal.com/content/programming-color-ncurses</a>
for more details.</p>
<h2 id="modifying-the-characters-for-the-wall-bug-and-snake">Modifying
the characters for the wall, bug and snake</h2>
<p>For the wall, bug and snake body characters you can replace the
following in the source code (<strong>include the single
quotes!</strong>) respectively:</p>
<p>See Linux Journal for more information article
<a href="https://www.linuxjournal.com/content/programming-color-ncurses" class="uri">https://www.linuxjournal.com/content/programming-color-ncurses</a> for more
details.</p>
<h2 id="modifying-the-characters-for-the-wall-bug-and-snake">Modifying the characters for the wall, bug and snake</h2>
<p>For the wall, bug and snake body characters you can replace the following in the
source code (<strong>include the single quotes!</strong>) respectively:</p>
<pre><code>&#39;#&#39;
&#39;*&#39;
&#39;o&#39;</code></pre>
<h2 id="modifying-input-keys">Modifying input keys</h2>
<p>Let’s say you don’t want to use arrow keys or you don’t have arrow
keys. Instead you might want the keys <code>l</code>, <code>r</code>,
<code>u</code> and <code>d</code> for the directions. Find the case
<p>Let’s say you don’t want to use arrow keys or you don’t have arrow keys. Instead
you might want the keys <code>l</code>, <code>r</code>, <code>u</code> and <code>d</code> for the directions. Find the case
statements:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> KEY_LEFT<span class="op">:</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> KEY_RIGHT<span class="op">:</span></span>
@@ -232,74 +220,63 @@ statements:</p>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> KEY_DOWN<span class="op">:</span></span></code></pre></div>
<p>Replace <code>KEY_LEFT</code> with:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ch">&#39;l&#39;</span></span></code></pre></div>
<p>and do the same thing for the other directions too. If you want more
than one key e.g. the arrow keys and the letters just add another case
statement e.g. for left it might be:</p>
<p>and do the same thing for the other directions too. If you want more than one
key e.g. the arrow keys and the letters just add another case statement e.g. for
left it might be:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> KEY_LEFT<span class="op">:</span> <span class="cf">case</span> <span class="ch">&#39;l&#39;</span><span class="op">:</span></span></code></pre></div>
<p>Yes the single quotes matter. You can do similar for the other input
keys. Please note that modifier keys like ctrl aren’t detectable or at
least I’m unaware of how to do so.</p>
<h2
id="modifying-the-statusscore-line-table-of-variablesstats-below">Modifying
the status/score line (table of variables/stats below)</h2>
<p>Yes the single quotes matter. You can do similar for the other input keys.
Please note that modifier keys like ctrl aren’t detectable or at least I’m
unaware of how to do so.</p>
<h2 id="modifying-the-statusscore-line-table-of-variablesstats-below">Modifying the status/score line (table of variables/stats below)</h2>
<h3 id="spoiler-warning">SPOILER WARNING</h3>
<p>Below I give a table of some variables/expressions along with the
data types and their respective format specifiers of the data.
Originally it was a lot more detailed but as I started obfuscating
things variables started to disappear and I decided to remove those
variables from the table outright. Again also remember that it’s
outdated.</p>
<p>Please note that this set of information is the same that will be
seen at the end of the game; I leave that as an exercise to the reader
to implement two different sets. Please also be aware that if you don’t
want any information you must set it to the below at the very least;
defining it without a value is not enough (it amounts to the parameters
to a printf call):</p>
<p>Below I give a table of some variables/expressions along with the data types and
their respective format specifiers of the data. Originally it was a lot more
detailed but as I started obfuscating things variables started to disappear and
I decided to remove those variables from the table outright. Again also remember
that it’s outdated.</p>
<p>Please note that this set of information is the same that will be seen at the
end of the game; I leave that as an exercise to the reader to implement two
different sets. Please also be aware that if you don’t want any information you
must set it to the below at the very least; defining it without a value is not
enough (it amounts to the parameters to a printf call):</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define J </span><span class="st">&quot; &quot;</span><span class="pp"> </span><span class="op">);</span></span></code></pre></div>
<p>If you don’t care about brief displays of ‘o’ at 0,0 you can just
have:</p>
<p>If you don’t care about brief displays of ‘o’ at 0,0 you can just have:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define J </span><span class="st">&quot;&quot;</span><span class="op">);</span></span></code></pre></div>
<p>That’s the bare minimum. Notice also that it’s been a long while
since I’ve tested this part but I think this is right.</p>
<p>Anyway as I said the score line has basic statistics that’s
relatively easy to change if you want more or less or different
information e.g. the location of the bug.</p>
<p>Initially there was no display of where the (head of the) snake was
at nor the maximum size (that is the size calculated by ncurses) -
though the astute hacker would notice that the maximum dimensions size
is not what the status line says: this has to do with the walls and the
status line - coordinates.</p>
<p>At that point the only time the top stats were updated is when the
snake got a bug. This however was something I didn’t quite like: I like
having the coordinates of where the snake is plus the other things that
are there (a number of which were added over time). Obviously this would
take many bug sized bytes (bites) even once let alone twice! Thus I made
it into a define:</p>
<p>That’s the bare minimum. Notice also that it’s been a long while since I’ve
tested this part but I think this is right.</p>
<p>Anyway as I said the score line has basic statistics that’s relatively easy to
change if you want more or less or different information e.g. the location of
the bug.</p>
<p>Initially there was no display of where the (head of the) snake was at nor the
maximum size (that is the size calculated by ncurses) - though the astute hacker
would notice that the maximum dimensions size is not what the status line says:
this has to do with the walls and the status line - coordinates.</p>
<p>At that point the only time the top stats were updated is when the snake got a
bug. This however was something I didn’t quite like: I like having the
coordinates of where the snake is plus the other things that are there (a number
of which were added over time). Obviously this would take many bug sized bytes
(bites) even once let alone twice! Thus I made it into a define:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define J Z</span><span class="op">(</span><span class="pp">X</span><span class="op">:%</span><span class="pp">d</span><span class="op">/%</span><span class="pp">d Y</span><span class="op">:%</span><span class="pp">d</span><span class="op">/%</span><span class="pp">d S</span><span class="op">:%</span><span class="pp">zu</span><span class="op">/%</span><span class="pp">zu B</span><span class="op">:%</span><span class="pp">zu\n</span><span class="op">),</span><span class="pp"> Y</span><span class="op">,</span><span class="pp"> y</span><span class="op">[-</span><span class="dv">2</span><span class="op">],</span><span class="pp"> X</span><span class="op">,*</span><span class="pp">y</span><span class="op">,</span><span class="pp">A</span><span class="op">,</span><span class="pp">g</span><span class="op">,</span><span class="pp"> c</span><span class="op">);</span></span></code></pre></div>
<p>With the table below you can show a variety of other
variables/statistics.</p>
<p>There’s another reason for changing this line though: depending on
the terminal width the line could cover the top wall; this can even
happen only part of the game because the line length is not constant:
most of the variables change throughout the game play and as these are
displayed the length of the line changes. Use <code>make test</code> to
get an estimate (it’s not perfect).</p>
<p>This is not the fault of my entry but rather how text wraps. But this
is another reason it’s easy to change: if the terminal size is too short
then you can update it; but if you want additional or different
information you can also update it. Remember that if you modify the
score data the termcaps algorithm might not remain as correct!</p>
<p>But the game needs to have the walls drawn and the score line is also
important; well it’s important in that the row number of the top wall is
in fact used and so if this line wasn’t there it would require changes
to make it work right.</p>
<p>For an example this would only include the size of the snake and the
number of bugs eaten (I think I have this correct; I’ve made many
changes to the point of not wanting to mess with anything that’s
unnecessary):</p>
<p>With the table below you can show a variety of other variables/statistics.</p>
<p>There’s another reason for changing this line though: depending on the terminal
width the line could cover the top wall; this can even happen only part of the
game because the line length is not constant: most of the variables change
throughout the game play and as these are displayed the length of the line
changes. Use <code>make test</code> to get an estimate (it’s not perfect).</p>
<p>This is not the fault of my entry but rather how text wraps. But this is another
reason it’s easy to change: if the terminal size is too short then you can
update it; but if you want additional or different information you can also
update it. Remember that if you modify the score data the termcaps algorithm
might not remain as correct!</p>
<p>But the game needs to have the walls drawn and the score line is also important;
well it’s important in that the row number of the top wall is in fact used and
so if this line wasn’t there it would require changes to make it work right.</p>
<p>For an example this would only include the size of the snake and the number of
bugs eaten (I think I have this correct; I’ve made many changes to the point of
not wanting to mess with anything that’s unnecessary):</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="pp">#define J Z</span><span class="op">(</span><span class="pp">SIZE</span><span class="op">:</span><span class="pp"> </span><span class="op">%</span><span class="pp">zu BUGS</span><span class="op">:</span><span class="pp"> </span><span class="op">%</span><span class="pp">zu\n</span><span class="op">),</span><span class="pp"> A</span><span class="op">,</span><span class="pp"> c</span><span class="op">);</span></span></code></pre></div>
<p>More generally the following expressions and data types (with format
specifiers) come to mind as information that might be of interest.</p>
<p>More generally the following expressions and data types (with format specifiers)
come to mind as information that might be of interest.</p>
<pre><code> DESCRIPTION EXPRESSION TYPE FORMAT SPECIFIER
Snake size A size_t %zu
@@ -322,122 +299,108 @@ specifiers) come to mind as information that might be of interest.</p>
Growth size (per N size_t %zu
bug)</code></pre>
<h2 id="make-it-so-the-snake-starts-at-a-random-location">Make it so the
snake starts at a random location</h2>
<h2 id="make-it-so-the-snake-starts-at-a-random-location">Make it so the snake starts at a random location</h2>
<p>Quite simply change:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>X <span class="op">=</span> H <span class="op">/</span> <span class="dv">2</span><span class="op">;</span> Y <span class="op">=</span> <span class="op">*</span>x <span class="op">/</span> <span class="dv">2</span><span class="op">;</span></span></code></pre></div>
<p>To be something like:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>X <span class="op">=</span> R<span class="op">(</span><span class="dv">1</span><span class="op">,</span>H<span class="op">-</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>Y <span class="op">=</span> R<span class="op">(</span><span class="dv">2</span><span class="op">,*</span>x<span class="op">-</span><span class="dv">1</span><span class="op">);</span></span></code></pre></div>
<p>Or whatever you might want it to be… (question to answer: will this
work at all? You decide!)</p>
<p>Or whatever you might want it to be… (question to answer: will this work at
all? You decide!)</p>
<h1 id="additions">Additions (+)</h1>
<p>Here are some things you could add (including a bit of code).</p>
<h2 id="health-andor-lives">Health (and/or Lives)</h2>
<p>This was something I thought of a number of times but I opted for
other features instead. Here are some ideas on how one might choose to
implement something like this. Or maybe it’s more like what sorts of
things do you have to consider and answer?</p>
<p>This was something I thought of a number of times but I opted for other features
instead. Here are some ideas on how one might choose to implement something like
this. Or maybe it’s more like what sorts of things do you have to consider and
answer?</p>
<ol start="0" type="1">
<li><p>If the snake runs back into itself - thus dying - the snake would
actually be slithering inside itself (a rather creepy thought - though
they sort of do when they shed their skin). How then would the lives be
of any value? If that would constitute as running into itself wouldn’t
it very quickly lose all lives?</p>
<li><p>If the snake runs back into itself - thus dying - the snake would actually be
slithering inside itself (a rather creepy thought - though they sort of do when
they shed their skin). How then would the lives be of any value? If that would
constitute as running into itself wouldn’t it very quickly lose all lives?</p>
<p>I can think of a number of ways to answer this question: by defining
specific rules (as in what would be allowed and what wouldn’t be) and
also by when to decrement the lives.</p></li>
<li><p>If the snake hits a wall and it’s not allowed to where would the
snake be placed? This is similar to (1) but maybe not as many things to
consider.</p></li>
<li><p>Should the snake lose its size? WHAT does having another life
even MEAN?</p></li>
<li><p>Do you want (you do not necessarily need) a new variable that
says how many lives you want? Either way probably be good that it can be
specified by the player.</p></li>
specific rules (as in what would be allowed and what wouldn’t be) and also
by when to decrement the lives.</p></li>
<li><p>If the snake hits a wall and it’s not allowed to where would the snake be
placed? This is similar to (1) but maybe not as many things to consider.</p></li>
<li><p>Should the snake lose its size? WHAT does having another life even MEAN?</p></li>
<li><p>Do you want (you do not necessarily need) a new variable that says how many
lives you want? Either way probably be good that it can be specified by the
player.</p></li>
</ol>
<p>The simplest rules I can think of off the top of my head is that the
snake loses its size but it keeps the bugs count. So if the lives are
three and the snake has three lives, has eaten 15 bugs and then runs
into itself it will start out again at the original size (remember
there’s a fair bit more than just changing the size of the snake to do
in order for it to be of use!) but it then the next bug it eats will be
the 16th bug.</p>
<p>Of course you could also say that the first time the snake eats a bug
(on the next life) it grows to the size it once was. This would actually
be one way to deal with some issues that I sort of alluded to above. Of
course it also has some other complications.</p>
<p>You could do similar for health only maybe the size of the snake
decreases or you use the variable you would have used for lives to be
health instead.</p>
<p>Vital issue to resolve: where is the snake? And if the snake size is
decreased will you be careful enough that you don’t run into the snake
where it actually isn’t?</p>
<p>The simplest rules I can think of off the top of my head is that the snake loses
its size but it keeps the bugs count. So if the lives are three and the snake
has three lives, has eaten 15 bugs and then runs into itself it will start out
again at the original size (remember there’s a fair bit more than just changing
the size of the snake to do in order for it to be of use!) but it then the next
bug it eats will be the 16th bug.</p>
<p>Of course you could also say that the first time the snake eats a bug (on the
next life) it grows to the size it once was. This would actually be one way to
deal with some issues that I sort of alluded to above. Of course it also has
some other complications.</p>
<p>You could do similar for health only maybe the size of the snake decreases or
you use the variable you would have used for lives to be health instead.</p>
<p>Vital issue to resolve: where is the snake? And if the snake size is decreased
will you be careful enough that you don’t run into the snake where it actually
isn’t?</p>
<h2 id="saving-the-game">Saving the game</h2>
<p>A few things would have to be done to do this. Maybe more than a few:
some decisions and some code.</p>
<p>First obviously is you would need a hook to save the game: that is
what if you don’t want to save? You could save every time the snake
moves so that you keep the highest size (though this could theoretically
slow the game down more as the snake gets bigger and bigger). Or you
could say that hitting the key ‘s’ saves the game by calling a save
function.</p>
<p>Second is you need a save function. You would need to save the
dimensions of the game, all the coordinates the snake is currently at
(from head to tail), where the bug is, decide whether or not to save the
direction (if it’s 0 the snake isn’t moving which would mean the player
could decide when to resume) and the number of bugs eaten so far.
Alternatively you could have the bug simply be placed somewhere where
the snake isn’t after replacing (can you replace something with itself?)
the snake.</p>
<p>Question: do you have to save the WALLS and other environmental
variables? You wouldn’t have to but you could: if you didn’t it would
mean that the player could change the growth size on another run for
example, or they could disable or enable a feature.</p>
<p>Of course you would also need a restore routine. This would mean you
would want to parse the command line so as to know which file should be
read in (easiest way would be if the first arg is some value then it
tries to load in whatever you decided to name the save file). How would
this work?</p>
<p>You would have to make sure that the dimensions of the terminal are
valid for what was saved and you would have to compensate that maybe the
dimensions have to be slightly adjusted for the screen (I have given
more than enough information on this elsewhere as to why this is).
Obviously you have to initialise ncurses, allocate the arrays, draw the
walls, snake, bug etc. You wouldn’t initialise ncurses or its features
more than once (i.e. keep track of whether or not you have initialised
these things due to a file being read or starting anew). Clearly you
would have to come up with a file format and have error detection too. I
can think of an easier way to make sure you don’t initialise the ncurses
twice however. It would do the same things only with a bit less code and
maybe simpler logic.</p>
<p>It might seem like a difficult task but it’s actually not that
difficult. It didn’t take much time for me to do something like this: as
far as saving and loading the values and even setting up ncurses: I just
didn’t go beyond that.</p>
<p>Tip: <strong>DON’T TRY</strong>
<code>scr_dump()</code>/<code>scr_restore()</code>/<code>scr_init()</code>/<code>scr_set()</code>.
After a quick test in the way I have things set up it seems to cause
some problems (also <code>scr_dump()</code> quits the program).</p>
<p>You would have to instead identify that restoring is requested, then
read in the file (including the coordinates) and then populate the snake
arrays, drawing it on screen.</p>
<p>A few things would have to be done to do this. Maybe more than a few: some
decisions and some code.</p>
<p>First obviously is you would need a hook to save the game: that is what if you
don’t want to save? You could save every time the snake moves so that you keep
the highest size (though this could theoretically slow the game down more as the
snake gets bigger and bigger). Or you could say that hitting the key ‘s’ saves
the game by calling a save function.</p>
<p>Second is you need a save function. You would need to save the dimensions of
the game, all the coordinates the snake is currently at (from head to tail),
where the bug is, decide whether or not to save the direction (if it’s 0 the
snake isn’t moving which would mean the player could decide when to resume) and
the number of bugs eaten so far. Alternatively you could have the bug simply be
placed somewhere where the snake isn’t after replacing (can you replace
something with itself?) the snake.</p>
<p>Question: do you have to save the WALLS and other environmental variables?
You wouldn’t have to but you could: if you didn’t it would mean that the player
could change the growth size on another run for example, or they could disable
or enable a feature.</p>
<p>Of course you would also need a restore routine. This would mean you would want
to parse the command line so as to know which file should be read in (easiest
way would be if the first arg is some value then it tries to load in whatever
you decided to name the save file). How would this work?</p>
<p>You would have to make sure that the dimensions of the terminal are valid for
what was saved and you would have to compensate that maybe the dimensions have
to be slightly adjusted for the screen (I have given more than enough
information on this elsewhere as to why this is). Obviously you have to
initialise ncurses, allocate the arrays, draw the walls, snake, bug etc. You
wouldn’t initialise ncurses or its features more than once (i.e. keep track of
whether or not you have initialised these things due to a file being read or
starting anew). Clearly you would have to come up with a file format and have
error detection too. I can think of an easier way to make sure you don’t
initialise the ncurses twice however. It would do the same things only with a
bit less code and maybe simpler logic.</p>
<p>It might seem like a difficult task but it’s actually not that difficult. It
didn’t take much time for me to do something like this: as far as saving and
loading the values and even setting up ncurses: I just didn’t go beyond that.</p>
<p>Tip: <strong>DON’T TRY</strong> <code>scr_dump()</code>/<code>scr_restore()</code>/<code>scr_init()</code>/<code>scr_set()</code>. After a quick
test in the way I have things set up it seems to cause some problems (also
<code>scr_dump()</code> quits the program).</p>
<p>You would have to instead identify that restoring is requested, then read in the
file (including the coordinates) and then populate the snake arrays, drawing it
on screen.</p>
<h2 id="different-types-of-walls">Different types of walls</h2>
<p>The game has two modes with walls: if you run into it the game is
over (you die) OR you go through it and come out on the opposite side.
There certainly are other possibilities though. Here I give some ideas
that could be implemented (and one I have some code for).</p>
<h3 id="different-types-of-walls-blockades">Different types of walls:
Blockades</h3>
<p>I did this once before as an experiment so it can work fine: let’s
say instead of the snake either dying or going through and out on the
other side what if it’s just that the snake is momentarily dazed and
unable to move again until it comes round sort of like what happens with
some people who pay more attention to their ruddy phone instead of where
they’re walking (even when crossing a busy street!).</p>
<p>If you look at the walls code you will see a ternary operator for
both <code>X</code> and <code>Y</code> coordinates. This of course is
very different now but the idea remains the same:</p>
<p>The game has two modes with walls: if you run into it the game is over (you
die) OR you go through it and come out on the opposite side. There certainly are
other possibilities though. Here I give some ideas that could be implemented
(and one I have some code for).</p>
<h3 id="different-types-of-walls-blockades">Different types of walls: Blockades</h3>
<p>I did this once before as an experiment so it can work fine: let’s say instead
of the snake either dying or going through and out on the other side what if
it’s just that the snake is momentarily dazed and unable to move again until it
comes round sort of like what happens with some people who pay more attention to
their ruddy phone instead of where they’re walking (even when crossing a busy
street!).</p>
<p>If you look at the walls code you will see a ternary operator for both <code>X</code> and <code>Y</code>
coordinates. This of course is very different now but the idea remains the same:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(</span>p <span class="op">&amp;&amp;</span> <span class="op">!(*</span>O<span class="op">&gt;=</span>O<span class="op">[</span><span class="dv">1</span><span class="op">]||</span>H<span class="op">&gt;=</span>M<span class="op">(</span><span class="dv">1</span><span class="op">)))</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>X<span class="op">&lt;</span><span class="dv">1</span><span class="op">||</span>X<span class="op">&gt;=</span>H<span class="op">)</span></span>
@@ -445,100 +408,91 @@ very different now but the idea remains the same:</p>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a> <span class="cf">if</span> <span class="op">(</span>Y<span class="op">&lt;</span><span class="dv">2</span><span class="op">||</span>Y<span class="op">&gt;=*</span>O<span class="op">)</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a> Y <span class="op">=</span> Y<span class="op">&lt;</span><span class="dv">2</span><span class="op">?*</span>O<span class="op">-</span><span class="dv">1</span><span class="op">:</span><span class="dv">2</span><span class="op">;</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>You can ignore the first if if you like; I’m not going to explain
that part. The inner if statements however are testing if the new snake
coordinates are beyond the walls (off screen). Depending on where the
snake is it will set the coordinates to the correct new location.</p>
<p>If however you wanted the walls to act as a barrier you could do
something like this instead (omitting the inner if statements here):</p>
<p>You can ignore the first if if you like; I’m not going to explain that part. The
inner if statements however are testing if the new snake coordinates are beyond
the walls (off screen). Depending on where the snake is it will set the
coordinates to the correct new location.</p>
<p>If however you wanted the walls to act as a barrier you could do something like
this instead (omitting the inner if statements here):</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>X<span class="op">=</span>X<span class="op">&lt;</span><span class="dv">1</span><span class="op">?</span><span class="dv">1</span><span class="op">:*</span>H<span class="op">-</span><span class="dv">1</span><span class="op">;</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>Y<span class="op">=</span>Y<span class="op">&lt;</span><span class="dv">2</span><span class="op">?</span><span class="dv">2</span><span class="op">:*</span>O<span class="op">-</span><span class="dv">1</span><span class="op">;</span></span></code></pre></div>
<p>Again though that’s just the idea; the code is dramatically
different. The above incidentally is not even complete.</p>
<p>You could also have it so depending on the WALLS value have it go
through walls, end game or act as a blockade. If you really wanted you
could have some walls you can go through and some you can’t (maybe
different colours would be needed?).</p>
<p>Oh and yes you might find it can look a bit funny this way. For
instance if you’re slithering left along top wall and you hit up the
snake will still be horizontal (after the thing I warned about is
resolved of course! - And that’s a very important one unless you want
negative coordinates - and you don’t!) since it’ll have stopped. If you
were to then hit the direction you had been going you will see that it
continues going that way in a straight horizontal line. In other words
the snake will just appear to be not moving as if the game had been
<p>Again though that’s just the idea; the code is dramatically different. The above
incidentally is not even complete.</p>
<p>You could also have it so depending on the WALLS value have it go through
walls, end game or act as a blockade. If you really wanted you could have some
walls you can go through and some you can’t (maybe different colours would be
needed?).</p>
<p>Oh and yes you might find it can look a bit funny this way. For instance if
you’re slithering left along top wall and you hit up the snake will still be
horizontal (after the thing I warned about is resolved of course! - And that’s a
very important one unless you want negative coordinates - and you don’t!) since
it’ll have stopped. If you were to then hit the direction you had been going you
will see that it continues going that way in a straight horizontal line. In
other words the snake will just appear to be not moving as if the game had been
paused.</p>
<h2 id="diagonal-movement">Diagonal movement</h2>
<p>I said this is impractical so how could it be done? Well you have to
decide which keys would take you up and right, up and left, down and
right or down and left. The trouble is ncurses can’t detect both right
and up at the same time. Besides that though it would only be a matter
of updating both <code>Y</code> and <code>X</code> coordinates rather
than just one or the other. That’s easy enough to do. The only
impractical part of this is deciding the keys and unfortunately rule 2b
(and probably 2b) would have been broken and so have no chance of
winning (now that I won it’s too much effort and I’ve forgotten most of
the stuff too to say nothing of getting the format right).</p>
<p>Anyway it’s just a matter of updating both <code>X</code> and
<code>Y</code>. But what about going through walls mode? Does it matter?
I’ll let you figure it out!</p>
<p>Looking back at the missing features, this is the feature I wanted
more than any other.</p>
<p>I said this is impractical so how could it be done? Well you have to decide
which keys would take you up and right, up and left, down and right or down and
left. The trouble is ncurses can’t detect both right and up at the same time.
Besides that though it would only be a matter of updating both <code>Y</code> and <code>X</code>
coordinates rather than just one or the other. That’s easy enough to do. The
only impractical part of this is deciding the keys and unfortunately rule 2b
(and probably 2b) would have been broken and so have no chance of winning (now
that I won it’s too much effort and I’ve forgotten most of the stuff too to say
nothing of getting the format right).</p>
<p>Anyway it’s just a matter of updating both <code>X</code> and <code>Y</code>. But what about going
through walls mode? Does it matter? I’ll let you figure it out!</p>
<p>Looking back at the missing features, this is the feature I wanted more than any
other.</p>
<h2 id="special-abilities">Special abilities</h2>
<p>Could the snake jump over itself if it wanted to? How would this be
implemented? The head would simply be moved one beyond but then you
would have to keep track of where the part that was jumped over is and
what part of the snake has to do the same thing. I can think of a much
easier way though. This very paragraph actually includes it! Then it
would only be a matter of deciding what key does what.</p>
<p>Could the snake jump over itself if it wanted to? How would this be implemented?
The head would simply be moved one beyond but then you would have to keep track
of where the part that was jumped over is and what part of the snake has to do
the same thing. I can think of a much easier way though. This very paragraph
actually includes it! Then it would only be a matter of deciding what key does
what.</p>
<h2 id="obstacles">Obstacles</h2>
<p>Similar to walls only that it’s inside the field. You would have to
consider the behaviour of running into the obstacles: should the snake
die? Should it lose health/lives (if implemented)? Can it go through
them? And also: the bug placement would have to be updated too. You
would also need to figure out what character to use for the obstacles: I
personally would just reuse the wall character. Also to make it simpler
if the walls are passable then so too would be the obstacles; else you
would die (or if you had health/lives then those would apply).</p>
<p>Similar to walls only that it’s inside the field. You would have to consider
the behaviour of running into the obstacles: should the snake die? Should it
lose health/lives (if implemented)? Can it go through them? And also: the bug
placement would have to be updated too. You would also need to figure out what
character to use for the obstacles: I personally would just reuse the wall
character. Also to make it simpler if the walls are passable then so too would
be the obstacles; else you would die (or if you had health/lives then those
would apply).</p>
<h2 id="more-than-one-bug">More than one bug</h2>
<p>The main thing to consider would be the test if the snake has eaten a
bug would have to check an array (and: how big? Where does the size come
from?) as well as the placement routine (though I guess you could have a
value for each array meaning that if you run into a bug spot that has
more than one bug you would eat that many bugs).</p>
<p>The main thing to consider would be the test if the snake has eaten a bug would
have to check an array (and: how big? Where does the size come from?) as well as
the placement routine (though I guess you could have a value for each array
meaning that if you run into a bug spot that has more than one bug you would eat
that many bugs).</p>
<h2 id="power-ups">Power-ups</h2>
<p>You would need to decide what power-ups exist, what they do, how many
can there be (and how many can the snake have at one time), what makes
them show up plus you would have to add code to handle the
power-ups.</p>
<h2 id="snakeskin-shedding-becoming-an-obstacle">Snakeskin shedding
(becoming an obstacle)</h2>
<p>I.e. at some point the snake would split back to some (arbitrary)
size but then the snakeskin left would act as the snake in the sense
that if the snake runs into it it’s the same as running into the snake.
More realistically the snakeskin would be the same size the snake was
and the snake would grow as it slithered out. But that would fill the
screen very quickly of course. Maybe the snakeskin has some other
purpose?</p>
<p>You would need to decide what power-ups exist, what they do, how many can there
be (and how many can the snake have at one time), what makes them show up plus
you would have to add code to handle the power-ups.</p>
<h2 id="snakeskin-shedding-becoming-an-obstacle">Snakeskin shedding (becoming an obstacle)</h2>
<p>I.e. at some point the snake would split back to some (arbitrary) size but then
the snakeskin left would act as the snake in the sense that if the snake runs
into it it’s the same as running into the snake. More realistically the
snakeskin would be the same size the snake was and the snake would grow as it
slithered out. But that would fill the screen very quickly of course. Maybe the
snakeskin has some other purpose?</p>
<h2 id="snake-moves-faster-over-time">Snake moves faster over time</h2>
<p>In the game
[Surround](https://en.wikipedia.org/wiki/Surround_(video_game) you have
no control over the speed. I believe there are five different speed
levels but the player has no control over it except the drawing mode. It
would be possible to make it so the snake moves faster over time. How
often and by what amount would probably vary but importantly it would
need to not go so fast there’s no controlling - or go below 0 which puts
it in blocking mode. Probably it would be that it gets faster up to a
certain per cent of the original speed so that it doesn’t get too fast.
But even that would have to be customisable.</p>
<h2 id="max-times-the-bug-evades-before-game-over">Max times the bug
evades before game over</h2>
<p>Basically so that the player is on a time schedule of sorts. The same
could be done for maximum number of movements before game over. These
would both be rather easy to implement but personally I would only
consider the max number of evasions (I just don’t have many more bytes
left!) - unless maybe that there is no default limit on max moves.</p>
<p>In the game [Surround](https://en.wikipedia.org/wiki/Surround_(video_game) you
have no control over the speed. I believe there are five different speed levels
but the player has no control over it except the drawing mode. It would be
possible to make it so the snake moves faster over time. How often and by what
amount would probably vary but importantly it would need to not go so fast
there’s no controlling - or go below 0 which puts it in blocking mode. Probably
it would be that it gets faster up to a certain per cent of the original speed
so that it doesn’t get too fast. But even that would have to be customisable.</p>
<h2 id="max-times-the-bug-evades-before-game-over">Max times the bug evades before game over</h2>
<p>Basically so that the player is on a time schedule of sorts. The same could be
done for maximum number of movements before game over. These would both be
rather easy to implement but personally I would only consider the max number of
evasions (I just don’t have many more bytes left!) - unless maybe that there is
no default limit on max moves.</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+164 -223
View File
@@ -120,113 +120,82 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<p>Current bugs and things that look like bugs but are not, as of 12
September 2020.</p>
<p>Current bugs and things that look like bugs but are not, as of 12 September 2020.</p>
<p><a name="toc"></a></p>
<ul>
<li><p><a href="#builtin-test-unit">Built-in test unit for some
features!</a></p></li>
<li><p><a href="#stillsnake">The snake doesn’t seem to be
moving</a></p></li>
<li><p><a href="#getch">getch() also accepts input from some input
hardware other than keyboards</a></p></li>
<li><p><a href="#size">SIZE=0 is the same as SIZE=1 and other
oddities</a></p></li>
<li><p><a href="#bitetail">‘I was a few places behind my tail and I ran
into it!’</a></p></li>
<li><p><a href="#middleofsnake">With negative growth the snake drops
from the middle of the body</a></p></li>
<li><p><a href="#buginsnake">It looks like the bug is in the
snake</a></p></li>
<li><p><a href="#bugplacement">On the safety of the bug placement
loop</a></p></li>
<li><p><a href="#verticalsnake">Vertical snake has more space between
snake char than horizontal</a></p></li>
<li><p><a href="#builtin-test-unit">Built-in test unit for some features!</a></p></li>
<li><p><a href="#stillsnake">The snake doesn’t seem to be moving</a></p></li>
<li><p><a href="#getch">getch() also accepts input from some input hardware other than keyboards</a></p></li>
<li><p><a href="#size">SIZE=0 is the same as SIZE=1 and other oddities</a></p></li>
<li><p><a href="#bitetail">‘I was a few places behind my tail and I ran into it!’</a></p></li>
<li><p><a href="#middleofsnake">With negative growth the snake drops from the middle of the body</a></p></li>
<li><p><a href="#buginsnake">It looks like the bug is in the snake</a></p></li>
<li><p><a href="#bugplacement">On the safety of the bug placement loop</a></p></li>
<li><p><a href="#verticalsnake">Vertical snake has more space between snake char than horizontal</a></p></li>
</ul>
<h1
id="built-in-test-unit-for-some-features"><a name="builtin-test-unit" href="#toc">Built-in
test unit for some features!</a></h1>
<p>Fun fact: There’s something of a built-in test unit for some
features; much like some of the other features this was not
intentionally designed but is simply a fun consequence of the features I
did implement.</p>
<p>Let’s say you want to verify that the evade mode is at the right
count. How can you verify it without modifying the code? Try:</p>
<h1 id="built-in-test-unit-for-some-features"><a name="builtin-test-unit" href="#toc">Built-in test unit for some features!</a></h1>
<p>Fun fact: There’s something of a built-in test unit for some features; much
like some of the other features this was not intentionally designed but is
simply a fun consequence of the features I did implement.</p>
<p>Let’s say you want to verify that the evade mode is at the right count. How
can you verify it without modifying the code? Try:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>0 <span class="va">SHED</span><span class="op">=</span>1 <span class="va">SHEDS</span><span class="op">=</span>1 <span class="va">EVADE</span><span class="op">=</span>10 <span class="ex">./prog</span></span></code></pre></div>
<p>Since you start out at size 0 and you shed every movement then when
you’re size 10 (as long as you don’t eat a bug of course!) the bug
should evade.</p>
<p>If you set it to <code>SIZE=10</code> there would be a difference of
10. Now every move you will see the size the snake is. But then…Why is
it that it doesn’t seem to move until the snake is of size 20? Because
you start out at size 10 of course (but in fact if you observe the snake
won’t appear to be of size 20 yet).</p>
<p>There probably are combinations that can test these types of things I
just don’t at this time remember any I might have done.</p>
<h1
id="the-snake-doesnt-seem-to-be-moving"><a name="stillsnake" href="#toc">The
snake doesn’t seem to be moving</a></h1>
<p>One way to show this is in full is to set the initial size and growth
size to a high value; then try each one individually. For example:</p>
<p>Since you start out at size 0 and you shed every movement then when you’re
size 10 (as long as you don’t eat a bug of course!) the bug should evade.</p>
<p>If you set it to <code>SIZE=10</code> there would be a difference of 10. Now every
move you will see the size the snake is. But then…Why is it that it
doesn’t seem to move until the snake is of size 20? Because you start out at
size 10 of course (but in fact if you observe the snake won’t appear to be
of size 20 yet).</p>
<p>There probably are combinations that can test these types of things I just
don’t at this time remember any I might have done.</p>
<h1 id="the-snake-doesnt-seem-to-be-moving"><a name="stillsnake" href="#toc">The snake doesn’t seem to be moving</a></h1>
<p>One way to show this is in full is to set the initial size and growth size to a
high value; then try each one individually. For example:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="ex">./prog</span></span></code></pre></div>
<p>In this case after you make the first move the snake will keep
growing and so the snake tail stays in the same spot until after it’s
the ‘full size’. When it has reached the full size then the entire body
of the snake will start to move too (i.e. if the tail isn’t moving it is
growing or else paused).</p>
<p>In several tests I set the initial size to a high value, the max to a
higher value still and enabled cannibalism and much of the screen was
full of the snake before it started to move. The <a
href="cannibalism.log.md">cannibalism.log.md</a> has some examples of
both cannibalism and a long snake that didn’t move for most of the
game.</p>
<p>If however you let the snake get to the full size then eat a bug
there can be a moment of lingering where it appears the snake moves for
a few places before it then stops moving and just grows until it’s the
full size.</p>
<p>It can also appear to be not moving when the snake is extraordinarily
long and more so when the snake has just eaten: which of course is when
it would grow (just like when shedding). Even so sometimes it takes a
moment for the snake tail to catch up with the body (so to speak) so
that it could for a few moments be difficult to know if where you’re
going is going to be occupied or not.</p>
<p>Basically if the snake head is moving you can consider the snake to
be moving or growing and that’s the important point (if you have the
default status line you can also see the coordinates being updated to
show this).</p>
<h1
id="getch-also-accepts-input-from-some-input-hardware-other-than-keyboards"><a name="getch" href="#toc">getch()
also accepts input from some input hardware other than
keyboards</a></h1>
<p>On my MacBook Pro the trackpad has actually triggered directions; if
I were to swipe up and then down the snake would run into itself. I
believe this has to do with the function call <code>keypad(v, 1);</code>
which enables arrow keys.</p>
<h1
id="size0-is-the-same-as-size1-and-other-oddities"><a name="size" href="#toc">SIZE=0
is the same as SIZE=1 and other oddities</a></h1>
<p>What this means is that for both you will only have the snake head.
At this point you can safely go back on yourself even without
cannibalism enabled. This is intentional; a snake size of 0 is pointless
but why should it not be playable anyway?</p>
<p>If <code>SIZE &lt; 0</code> you’ll likely win straight away since
it’s unsigned and it’ll wrap back to the maximum so you will win
automatically (this is the same as the second mode the judges suggested
with <code>SIZE=-1 ./prog</code>).</p>
<p>As for the growth sizes (including shedding) if it’s &lt; 0: the
snake will still lose its length and display will still be odd: because
the snake size is decreased any element beyond the reduced size isn’t
touched so the snake characters will remain on the screen; only the
moving snake is what matters. But it’s likely the game will be won
fairly quickly because once it’s -1 in size it’ll be at the maximum
size.</p>
<p>For example if I say <code>SIZE=3 GROW=-2</code> at two bugs the game
is won.</p>
<p>As for growing: anything &gt; 0 it will grow that many; 0 it will not
grow (which I show as a gameplay mode); and &lt; 0 it will ‘shrink’ as I
explained above. You could say that it’s defying physics by growing and
shrinking simultaneously but either way negative size will force a
win.</p>
<p>In this case after you make the first move the snake will keep growing and
so the snake tail stays in the same spot until after it’s the ‘full size’.
When it has reached the full size then the entire body of the snake will
start to move too (i.e. if the tail isn’t moving it is growing or else paused).</p>
<p>In several tests I set the initial size to a high value, the max to a higher
value still and enabled cannibalism and much of the screen was full of the snake
before it started to move. The <a href="cannibalism.log.md">cannibalism.log.md</a> has some examples of both
cannibalism and a long snake that didn’t move for most of the game.</p>
<p>If however you let the snake get to the full size then eat a bug there can
be a moment of lingering where it appears the snake moves for a few places
before it then stops moving and just grows until it’s the full size.</p>
<p>It can also appear to be not moving when the snake is extraordinarily long
and more so when the snake has just eaten: which of course is when it would
grow (just like when shedding). Even so sometimes it takes a moment for the
snake tail to catch up with the body (so to speak) so that it could for a
few moments be difficult to know if where you’re going is going to be
occupied or not.</p>
<p>Basically if the snake head is moving you can consider the snake to be
moving or growing and that’s the important point (if you have the default
status line you can also see the coordinates being updated to show this).</p>
<h1 id="getch-also-accepts-input-from-some-input-hardware-other-than-keyboards"><a name="getch" href="#toc">getch() also accepts input from some input hardware other than keyboards</a></h1>
<p>On my MacBook Pro the trackpad has actually triggered directions; if I were to
swipe up and then down the snake would run into itself. I believe this has to do
with the function call <code>keypad(v, 1);</code> which enables arrow keys.</p>
<h1 id="size0-is-the-same-as-size1-and-other-oddities"><a name="size" href="#toc">SIZE=0 is the same as SIZE=1 and other oddities</a></h1>
<p>What this means is that for both you will only have the snake head. At this point
you can safely go back on yourself even without cannibalism enabled. This is
intentional; a snake size of 0 is pointless but why should it not be playable
anyway?</p>
<p>If <code>SIZE &lt; 0</code> you’ll likely win straight away since it’s unsigned and it’ll wrap
back to the maximum so you will win automatically (this is the same as the
second mode the judges suggested with <code>SIZE=-1 ./prog</code>).</p>
<p>As for the growth sizes (including shedding) if it’s &lt; 0: the snake will still
lose its length and display will still be odd: because the snake size is
decreased any element beyond the reduced size isn’t touched so the snake
characters will remain on the screen; only the moving snake is what matters.
But it’s likely the game will be won fairly quickly because once it’s -1 in size
it’ll be at the maximum size.</p>
<p>For example if I say <code>SIZE=3 GROW=-2</code> at two bugs the game is won.</p>
<p>As for growing: anything &gt; 0 it will grow that many; 0 it will not grow (which I
show as a gameplay mode); and &lt; 0 it will ‘shrink’ as I explained above. You could
say that it’s defying physics by growing and shrinking simultaneously but either
way negative size will force a win.</p>
<p>Here’s a fun output:</p>
<pre><code>&lt; &lt;&lt;&lt;+</code></pre>
<p>That’s from:</p>
@@ -236,88 +205,71 @@ win.</p>
X:72/156 Y:20/41 S:997/997 B:0</code></pre>
<p>Try this though:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="va">SHEDS</span><span class="op">=</span>-1 <span class="va">SHED</span><span class="op">=</span>25 <span class="ex">./prog</span></span></code></pre></div>
<p>And you’ll see that you start to be the normal size but then you
leave your head several places until you end up getting to the max size
(by way of it being unsigned). This isn’t a bug even if it might seem
like one. In fact this is the basis of the grow/shrink mode of play that
I talk about in the <a href="gameplay.html">gameplay.html</a> (<a
href="gameplay.md">gameplay.md</a> on GitHub) file.</p>
<p>And you’ll see that you start to be the normal size but then you leave your
head several places until you end up getting to the max size (by way of it
being unsigned). This isn’t a bug even if it might seem like one. In fact
this is the basis of the grow/shrink mode of play that I talk about in the
<a href="gameplay.html">gameplay.html</a> (<a href="gameplay.md">gameplay.md</a> on GitHub) file.</p>
<p>Here’s another thing to be aware of. Let’s say you do:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>1 <span class="va">GROW</span><span class="op">=</span>-1 <span class="ex">./prog</span></span></code></pre></div>
<p>How many bugs will it take before you win? In fact it’s two: you
would see the head twice: the second time once you ‘shrink’ down to size
0; it would then be that if you get another bug you will be at the ‘max
size’:</p>
<p>How many bugs will it take before you win? In fact it’s two: you would see the
head twice: the second time once you ‘shrink’ down to size 0; it would then be
that if you get another bug you will be at the ‘max size’:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ex">YOU</span> WIN!</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="ex">X:81/156</span> Y:35/41 S:997/997 B:2</span></code></pre></div>
<h1
id="i-was-a-few-places-behind-my-tail-and-i-ran-into-it"><a name="bitetail" href="#toc">‘I
was a few places behind my tail and I ran into it!’</a></h1>
<p>I.e. what happens if you’re growing - for example after just eating a
bug - and you’re racing towards your tail? If you’re behind it should be
fine since you’re going the same speed as the snake is, right? Not
quite. Because you’re growing you might end up running into your tail
(depending on how much you’ve left to grow and how far away from your
tail)! This happened to me once and it surprised me and I figured I
better note it.</p>
<p><strong>Remember: the tail at that point isn’t moving yet; the snake
is growing!</strong></p>
<h1
id="with-negative-growth-the-snake-drops-from-the-middle-of-the-body"><a name="middleofsnake" href="#toc">With
negative growth the snake drops from the middle of the body</a></h1>
<p>For instance it might look like this (the first line is as it
happens, the second pointing to where it happens and the third being
what’s left after the rest of the snake has gone through). Doing
<code>SHED=100 SHEDS=-1</code>:</p>
<h1 id="i-was-a-few-places-behind-my-tail-and-i-ran-into-it"><a name="bitetail" href="#toc">‘I was a few places behind my tail and I ran into it!’</a></h1>
<p>I.e. what happens if you’re growing - for example after just eating a bug - and
you’re racing towards your tail? If you’re behind it should be fine since you’re
going the same speed as the snake is, right? Not quite. Because you’re growing
you might end up running into your tail (depending on how much you’ve left to
grow and how far away from your tail)! This happened to me once and it surprised
me and I figured I better note it.</p>
<p><strong>Remember: the tail at that point isn’t moving yet; the snake is growing!</strong></p>
<h1 id="with-negative-growth-the-snake-drops-from-the-middle-of-the-body"><a name="middleofsnake" href="#toc">With negative growth the snake drops from the middle of the body</a></h1>
<p>For instance it might look like this (the first line is as it happens, the
second pointing to where it happens and the third being what’s left after the
rest of the snake has gone through). Doing <code>SHED=100 SHEDS=-1</code>:</p>
<pre><code>ooooooooo&gt;ooo&gt;
^
&gt;</code></pre>
<p>The <code>^</code> points to the part that’s split from the snake and
which will be there on its own after the snake passes through it. Here’s
an example with it being <code>SHEDS=-3</code>:</p>
<p>The <code>^</code> points to the part that’s split from the snake and which will be
there on its own after the snake passes through it. Here’s an example with
it being <code>SHEDS=-3</code>:</p>
<pre><code>&lt;ooo&lt;ooooo
^^^
&lt;oo</code></pre>
<p>If you go through the part that has split (which for some might be
difficult to see whilst the snake has not fully left its skin) you won’t
run into yourself; if you run into another part though you do. This
might be a bit confusing I know but what kind of animal shrinks in size
by leaving its head behind only to sprout up a new head? Actually…on
second thought, I won’t go there! :)</p>
<p>Anyway it’s an odd idea for the snake to shrink by leaving part of
its skin: that’s how they grow in the wild so it’s a misnomer. The
shrinking was only ‘discovered’ because it’s an unsigned number but
happily it allows for different gameplay modes.</p>
<h1
id="it-looks-like-the-bug-is-in-the-snake"><a name="buginsnake" href="#toc">It
looks like the bug is in the snake</a></h1>
<p>I show a different example in the <a
href="crazy.log.md">crazy.log.md</a> file but what defines a coordinate
<p>If you go through the part that has split (which for some might be difficult
to see whilst the snake has not fully left its skin) you won’t run into
yourself; if you run into another part though you do. This might be a bit
confusing I know but what kind of animal shrinks in size by leaving its head
behind only to sprout up a new head? Actually…on second thought, I won’t
go there! :)</p>
<p>Anyway it’s an odd idea for the snake to shrink by leaving part of its skin:
that’s how they grow in the wild so it’s a misnomer. The shrinking was only
‘discovered’ because it’s an unsigned number but happily it allows for different
gameplay modes.</p>
<h1 id="it-looks-like-the-bug-is-in-the-snake"><a name="buginsnake" href="#toc">It looks like the bug is in the snake</a></h1>
<p>I show a different example in the <a href="crazy.log.md">crazy.log.md</a> file but what defines a coordinate
which the snake occupies? If the snake breaks apart then the only part
of the screen the snake is occupying is the place which is actually
moving: if the snake decreases in size by 3 then the three respective
characters you can go through safely. But this also means that a bug can
go there! So you might see something like:</p>
of the screen the snake is occupying is the place which is actually moving: if
the snake decreases in size by 3 then the three respective characters you can go
through safely. But this also means that a bug can go there! So you might see
something like:</p>
<pre><code>&lt;*oooooooo</code></pre>
<p>This is because the snake is no longer there: in fact in this run the
snake was quite a bit lower on the screen and 25 in length.</p>
<h1
id="on-the-safety-of-the-bug-placement-loop"><a name="bugplacement" href="#toc">On
the safety of the bug placement loop</a></h1>
<p>Ilya Kurdyukov shared concern for the loop in the bug placement
routine: is it safe? What he refers to is that it’s a potential infinite
loop. But is it? I understand the concern and it’s something I played
with a lot to be sure that it doesn’t happen. This is how it works.</p>
<p>To explain it I will go back to the make test program
<code>termcaps</code> (which is imperfect for the recommended terminal
size but the max snake size is exactly how it’s done in Snake and works
well). The minimum terminal size I require in the game is 10 x 10. This
includes the walls and score line.</p>
<p>Now the default max snake size is 997 but when the terminal is too
small it adjusts the max snake size. For 10 lines and 10 columns you
would see:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> make test</span>
<p>This is because the snake is no longer there: in fact in this run the snake was
quite a bit lower on the screen and 25 in length.</p>
<h1 id="on-the-safety-of-the-bug-placement-loop"><a name="bugplacement" href="#toc">On the safety of the bug placement loop</a></h1>
<p>Ilya Kurdyukov shared concern for the loop in the bug placement routine: is it
safe? What he refers to is that it’s a potential infinite loop. But is it? I
understand the concern and it’s something I played with a lot to be sure that it
doesn’t happen. This is how it works.</p>
<p>To explain it I will go back to the make test program <code>termcaps</code> (which is
imperfect for the recommended terminal size but the max snake size is exactly
how it’s done in Snake and works well). The minimum terminal size I require in
the game is 10 x 10. This includes the walls and score line.</p>
<p>Now the default max snake size is 997 but when the terminal is too small it
adjusts the max snake size. For 10 lines and 10 columns you would see:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> make test</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports cursor movement</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports making cursor invisible</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports bold</span>
@@ -334,34 +286,27 @@ class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a><span class="ex">1</span> problem detected <span class="er">(</span><span class="ex">0</span> fatal<span class="kw">)</span><span class="bu">.</span></span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a><span class="ex">make:</span> <span class="pp">***</span> <span class="pp">[</span><span class="ss">test</span><span class="pp">]</span> Error 1</span></code></pre></div>
<p>First: what’s the problem? It’s just a warning that for the snake
size of 49 the recommended size of columns is 28. However this is just
for the score text; with only 10 columns it will overflow and wrap to
the next line(s). But if you observe that 49 is the max snake size. How
is this derived and why?</p>
<p>With 10 rows and columns it’s calculated as <code>7 * 7</code>
(i.e. it’s <code>(cols-3)*(rows-3)</code>. However the number of
playable locations is in this case 56
(<code>playable_rows * playable_columns</code>). I have played with this
many times and I do not believe there should be a problem. If there is
it’s from a very poor implementation of rand() and I discuss this in <a
href="troubleshooting.html">troubleshooting.html</a> (<a
href="troubleshooting.md">troubleshooting.md</a> on GitHub).</p>
<p>There I also give some test outputs without the cap in place to give
an idea of when it became a problem (or would have). In short this is
known but I do not think it will be a problem and I have given
resolutions. In any event without cannibal mode it’s even less likely
that you’ll ever run into this problem.</p>
<p>The obvious question is why didn’t I put in a break? Because of the
IOCCC size rule 2 and what would it do anyway? I guess it would win but
to my mind that is a bug and I prefer putting in restrictions to try and
make it very unlikely.</p>
<h1
id="vertical-snake-has-more-space-between-snake-char-than-horizontal-snake"><a name="verticalsnake" href="#toc">Vertical
snake has more space between snake char than horizontal snake</a></h1>
<p>Ilya Kurdyukov also pointed out that depending on orientation of the
snake there are different amount of spaces between the snake char ‘o’.
This is what he had to say on it:</p>
<p>First: what’s the problem? It’s just a warning that for the snake size of 49 the
recommended size of columns is 28. However this is just for the score text; with
only 10 columns it will overflow and wrap to the next line(s). But if you observe
that 49 is the max snake size. How is this derived and why?</p>
<p>With 10 rows and columns it’s calculated as <code>7 * 7</code> (i.e. it’s
<code>(cols-3)*(rows-3)</code>. However the number of playable locations is in this case 56
(<code>playable_rows * playable_columns</code>). I have played with this many
times and I do not believe there should be a problem. If there is it’s from a
very poor implementation of rand() and I discuss this in
<a href="troubleshooting.html">troubleshooting.html</a> (<a href="troubleshooting.md">troubleshooting.md</a> on GitHub).</p>
<p>There I also give some test outputs without the cap in place to give an idea of
when it became a problem (or would have). In short this is known but I do not
think it will be a problem and I have given resolutions. In any event without
cannibal mode it’s even less likely that you’ll ever run into this problem.</p>
<p>The obvious question is why didn’t I put in a break? Because of the IOCCC size
rule 2 and what would it do anyway? I guess it would win but to my mind that is
a bug and I prefer putting in restrictions to try and make it very unlikely.</p>
<h1 id="vertical-snake-has-more-space-between-snake-char-than-horizontal-snake"><a name="verticalsnake" href="#toc">Vertical snake has more space between snake char than horizontal snake</a></h1>
<p>Ilya Kurdyukov also pointed out that depending on orientation of the snake there
are different amount of spaces between the snake char ‘o’. This is what he
had to say on it:</p>
<blockquote>
<p>Yes, it is the problem, space in character terminal is not isotropic
from a viewer (gamer) perspective so one step up look like two steps
@@ -371,40 +316,36 @@ right.</p>
character tiles are not square (except for Japanese/Chinese, Japanese
even have so called full-width English characters in their encoding,
presented in UTF too).</p>
<p><a
href="https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms">https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms</a></p>
<p><a href="https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms">https://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms</a></p>
<p>So the typical fonts are Half-width or close to it.</p>
<p><img src="halfwidth_vs_fullwidth.png"></p>
</blockquote>
<p>However the function <code>mvaddch()</code> takes a
<code>chtype</code> which amounts to a C char with additional
information and so the full width <code>O</code>is too big for the
function call. He reminded me of the old DOS box chars but even if this
was easily duplicable (and it might be and I don’t remember) the logic
would have to be changed for drawing the snake and in such a way that
would change the source code layout too much - to say nothing else of
the fact I have also forgotten some of what I did obfuscation wise (and
the <a href="spoilers.markdown">spoilers</a> aren’t enough here!).</p>
<p>That being said the font and font size does seem to have somewhat of
an effect on it since his screenshots have wider gaps than mine.</p>
<p>Once again thank you mate for bringing this to my attention and also
playing with it and providing the resources! Much appreciated! (And
although you suggested it is bugging me I once again here say it’s not
at all bugging me but it is very much appreciated and it means a great
deal to me. Cheers.)</p>
<p>However the function <code>mvaddch()</code> takes a <code>chtype</code> which amounts to a C char
with additional information and so the full width <code>O</code>is too big for the
function call. He reminded me of the old DOS box chars but even if this was
easily duplicable (and it might be and I don’t remember) the logic would
have to be changed for drawing the snake and in such a way that would change
the source code layout too much - to say nothing else of the fact I have
also forgotten some of what I did obfuscation wise (and the
<a href="spoilers.markdown">spoilers</a> aren’t enough here!).</p>
<p>That being said the font and font size does seem to have somewhat of an
effect on it since his screenshots have wider gaps than mine.</p>
<p>Once again thank you mate for bringing this to my attention and also playing
with it and providing the resources! Much appreciated! (And although you
suggested it is bugging me I once again here say it’s not at all bugging me
but it is very much appreciated and it means a great deal to me. Cheers.)</p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr class="odd">
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt
Noll][judges] - All rights reserved This work is licensed under a
[Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
</tr>
<tr class="even">
<td>[judges]: https://www.ioccc.org/judges.html [cc]:
http://creativecommons.org/licenses/by-sa/3.0/</td>
<td>[judges]: https://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/</td>
</tr>
</tbody>
</table>
+17 -24
View File
@@ -120,25 +120,20 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1
id="extreme-cannibalism-in-2020-ioccc-dont-tread-on-me-snake-game">Extreme
cannibalism in <a href="/2020/ferguson1/prog.c">2020 IOCCC ‘Don’t tread
on me’ Snake game</a></h1>
<p>To give an idea what cannibalism can look like (it’s I believe a
unique feature to any other version of Snake), this file shows just how
extreme cannibalism can get with a long snake. I made a few changes,
described below, to make it easier to distinguish what is what.</p>
<h1 id="extreme-cannibalism-in-2020-ioccc-dont-tread-on-me-snake-game">Extreme cannibalism in <a href="/2020/ferguson1/prog.c">2020 IOCCC ‘Don’t tread on me’ Snake game</a></h1>
<p>To give an idea what cannibalism can look like (it’s I believe a unique feature
to any other version of Snake), this file shows just how extreme cannibalism can
get with a long snake. I made a few changes, described below, to make it easier
to distinguish what is what.</p>
<h1 id="examples">Examples</h1>
<p>In the below game dumps I have replaced the bug with
<strong><code>B</code></strong>, the head with
<strong><code>H</code></strong> and where it is known, the tail with
<strong><code>T</code></strong>, in order to help distinguish where they
are. Since the head is replaced with <strong><code>H</code></strong> I
have noted the direction it was moving above each dump as well as at the
right of the line; each line with a bug, the head or tail is marked with
upper case text at the right to make it easier to find.</p>
<p>The first run I include several dumps but there isn’t much
information about most of them.</p>
<p>In the below game dumps I have replaced the bug with <strong><code>B</code></strong>, the head with
<strong><code>H</code></strong> and where it is known, the tail with <strong><code>T</code></strong>, in order to help
distinguish where they are. Since the head is replaced with <strong><code>H</code></strong> I have noted
the direction it was moving above each dump as well as at the right of the line;
each line with a bug, the head or tail is marked with upper case text at the
right to make it easier to find.</p>
<p>The first run I include several dumps but there isn’t much information about
most of them.</p>
<h2 id="example-0-snake-moving-right">Example 0: snake moving right</h2>
<pre><code>X:45/89 Y:22/25 S:1675/2001 B:35
##########################################################################################
@@ -274,10 +269,9 @@ information about most of them.</p>
#ooooooooo ooooooooooooooooooooooooooooooooooooooooooooo ooooooo#
# #
##########################################################################################</code></pre>
<h2 id="example-5-snake-moving-left-with-snake-inside-itsself">Example
5: snake moving left with snake inside itsself</h2>
<p>Another example invocation where the snake head is in the snake and
where the snake hadn’t yet moved (that is it was still growing):</p>
<h2 id="example-5-snake-moving-left-with-snake-inside-itsself">Example 5: snake moving left with snake inside itsself</h2>
<p>Another example invocation where the snake head is in the snake and where the snake
hadn’t yet moved (that is it was still growing):</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">SIZE</span><span class="op">=</span>1500 <span class="va">GROW</span><span class="op">=</span>2 <span class="va">MAXSIZE</span><span class="op">=</span>1600 <span class="ex">./prog</span></span></code></pre></div>
<p>It looked like:</p>
<pre><code>X:55/89 Y:11/25 S:1564/1600 B:32
@@ -306,8 +300,7 @@ where the snake hadn’t yet moved (that is it was still growing):</p>
# oooooooooooooooooooooooooooooooooooooooooooooooooooo ooo o #
# ooooooooooo ooooooooooooo o oooooooooo #
##########################################################################################</code></pre>
<p>…and no <strong><em>Preciouss</em></strong>: the <em>itsself</em> was
not a typo but intentional sibilance!</p>
<p>…and no <strong><em>Preciouss</em></strong>: the <em>itsself</em> was not a typo but intentional sibilance!</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+99 -133
View File
@@ -120,92 +120,74 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1 id="double-layered-chocolate-fudge-cake">Double-layered Chocolate
Fudge Cake</h1>
<h1 id="double-layered-chocolate-fudge-cake">Double-layered Chocolate Fudge Cake</h1>
<p>Here’s a delicious double-layered chocolate fudge cake that is
something of my mum’s speciality. It’s complicated and I should warn
that nobody has seemed to get it down as well as she has but it’s well
worth the effort if you love chocolate and have the time and
patience.</p>
<p>My late stepmum who only liked white ‘chocolate’ loved this cake! The
picture below is after it’s been iced. The image <a
href="ioccc-cake.jpg">ioccc-cake.jpg</a> was a feeble attempt at drawing
<code>IOCCC</code> into the cake before icing, a different time. The
picture below was taken for my birthday (14 February) in 2022 as it’s
the best one I have:</p>
something of my mum’s speciality. It’s complicated and I should warn that nobody
has seemed to get it down as well as she has but it’s well worth the effort if
you love chocolate and have the time and patience.</p>
<p>My late stepmum who only liked white ‘chocolate’ loved this cake! The picture
below is after it’s been iced. The image <a href="ioccc-cake.jpg">ioccc-cake.jpg</a> was a
feeble attempt at drawing <code>IOCCC</code> into the cake before icing, a different time.
The picture below was taken for my birthday (14 February) in 2022 as it’s the
best one I have:</p>
<figure>
<img src="cake.jpg"
alt="picture of the Double-layered chocolate fudge cake" />
<figcaption aria-hidden="true">picture of the Double-layered chocolate
fudge cake</figcaption>
<img src="cake.jpg" alt="picture of the Double-layered chocolate fudge cake" />
<figcaption aria-hidden="true">picture of the Double-layered chocolate fudge cake</figcaption>
</figure>
<p>There are two sets of ingredients and instructions; the cake and the
icing. In addition there are some <strong>VERY IMPORTANT NOTES</strong>
to pay attention to; some will be repeated because they’re
<strong>VITALLY IMPORTANT</strong> for the quality of the cake. That
cannot be overstated.</p>
<p>Below I have included the ingredients separately but I include them
within the instructions as well and in bold. Also in bold are some of
the special notes.</p>
<p>Finally note that depending on where you are in the world this might
not work in the warmer months of the year and for the icing in
particular.</p>
<p>There are two sets of ingredients and instructions; the cake and the icing. In
addition there are some <strong>VERY IMPORTANT NOTES</strong> to pay attention to; some will
be repeated because they’re <strong>VITALLY IMPORTANT</strong> for the quality of the cake.
That cannot be overstated.</p>
<p>Below I have included the ingredients separately but I include them within the
instructions as well and in bold. Also in bold are some of the special notes.</p>
<p>Finally note that depending on where you are in the world this might not work in
the warmer months of the year and for the icing in particular.</p>
<h2 id="measurements">Measurements</h2>
<p>This was originally taken from an American magazine for women so the
measurements are in the US standards. A nice resource (that has much
more than just cooking) is <a
href="http://www.onlineconversion.com/cooking.htm"
class="uri">http://www.onlineconversion.com/cooking.htm</a>. This will
measurements are in the US standards. A nice resource (that has much more than
just cooking) is <a href="http://www.onlineconversion.com/cooking.htm" class="uri">http://www.onlineconversion.com/cooking.htm</a>. This will
particularly matter for cups, teaspoons, tablespoons and ounces.</p>
<h2 id="bakers-chocolate">Baker’s chocolate</h2>
<p>Baker’s chocolate is a brand name and the product in question is
unsweetened chocolate bars used for baking. According to a <a
href="https://www.davidlebovitz.com/chocolate-faqs/">chocolates FAQ</a>
it might be called different things:</p>
<p>Baker’s chocolate is a brand name and the product in question is unsweetened
chocolate bars used for baking. According to a <a href="https://www.davidlebovitz.com/chocolate-faqs/">chocolates FAQ</a> it might be
called different things:</p>
<blockquote>
<p>Bitter chocolate contains no sugar and is often called ‘unsweetened’
or ‘baking’ chocolate. In some countries it’s called 100% cacao since
it’s composed only of ground up cocoa beans, and nothing else.</p>
<p>Bitter chocolate contains no sugar and is often called ‘unsweetened’ or
‘baking’ chocolate. In some countries it’s called 100% cacao since it’s composed
only of ground up cocoa beans, and nothing else.</p>
</blockquote>
<p>The FAQ suggests that you might have to look for a baking supply shop
but I cannot offer any specific advice other than it’s unsweetened
chocolate bars for baking. The FAQ talks about what looks like
substitutes but I have no idea what that would turn out as; I somehow
suspect it wouldn’t be good.</p>
<p>Either way <strong>PLEASE STILL PAY ATTENTION TO ALL THE NOTES on the
chocolate IN THE RECIPE and RECIPE NOTES BECAUSE THEY’RE <em>EXTREMELY
IMPORTANT!</em></strong></p>
<p>The FAQ suggests that you might have to look for a baking supply shop but I
cannot offer any specific advice other than it’s unsweetened chocolate bars for
baking. The FAQ talks about what looks like substitutes but I have no idea what
that would turn out as; I somehow suspect it wouldn’t be good.</p>
<p>Either way <strong>PLEASE STILL PAY ATTENTION TO ALL THE NOTES on the chocolate IN THE RECIPE and
RECIPE NOTES BECAUSE THEY’RE <em>EXTREMELY IMPORTANT!</em></strong></p>
<h2 id="special-notes-for-the-cake">Special notes for the cake</h2>
<p><strong>PAY CLOSE ATTENTION TO THESE:</strong></p>
<ul>
<li><p><strong>USE <em>MARGARINE</em>! DO <em>NOT</em> USE
BUTTER!</strong> Butter does not work well. If you think it will come
out better by using butter you’re very mistaken; it will come out badly!
People have come back saying it didn’t come out well and they are asked
if they used butter or margarine. They had used butter because they
‘know better’ but they were very wrong and it is why the cake was
ruined.</p></li>
<li><p>Over the years they changed the size of the unsweetened chocolate
squares; they used to be one ounce each; now they are 1/4 ounce each
square so be sure to remember that <strong>THE AMOUNT IS BY OUNCE
<em>NOT SQUARES</em> AS LISTED</strong>. See the measurements link if
there’s any doubt.</p></li>
<li><p>Pay careful attention to the <strong>COOK FOR ONLY THE INDICATED
TIME</strong> part. Note that if your oven cooks a bit hotter you might
have to adjust the timing a bit. This is likely the case if the cake
comes out a little bit dry.</p></li>
<li><p><strong>REMOVE THE CAKE FROM THE PANS <em>2 MINUTES AFTER
REMOVING FROM OVEN</em></strong> and then allow to <strong>FULLY COOL
<em>ON RACKS!</em></strong> The important point is to <strong>MAKE SURE
<li><p><strong>USE <em>MARGARINE</em>! DO <em>NOT</em> USE BUTTER!</strong> Butter does not work well. If you
think it will come out better by using butter you’re very mistaken; it will
come out badly! People have come back saying it didn’t come out well and
they are asked if they used butter or margarine. They had used butter
because they ‘know better’ but they were very wrong and it is why the cake
was ruined.</p></li>
<li><p>Over the years they changed the size of the unsweetened chocolate squares;
they used to be one ounce each; now they are 1/4 ounce each square so be sure to
remember that <strong>THE AMOUNT IS BY OUNCE <em>NOT SQUARES</em> AS LISTED</strong>. See the
measurements link if there’s any doubt.</p></li>
<li><p>Pay careful attention to the <strong>COOK FOR ONLY THE INDICATED TIME</strong> part. Note
that if your oven cooks a bit hotter you might have to adjust the timing a
bit. This is likely the case if the cake comes out a little bit dry.</p></li>
<li><p><strong>REMOVE THE CAKE FROM THE PANS <em>2 MINUTES AFTER REMOVING FROM OVEN</em></strong> and
then allow to <strong>FULLY COOL <em>ON RACKS!</em></strong> The important point is to <strong>MAKE SURE
THAT THEY <em>DON’T OVERCOOK</em></strong>.</p></li>
<li><p>When the recipe was first written they sold powdered sugar in a
box; now it’s confectionery sugar in a bag. My mum experimented with the
amount and found that 4 cups seems about right.</p></li>
<li><p><strong>USE <em>WHOLE MILK!</em></strong> Don’t try skim milk or
whatever per cent of fat milk you have.</p></li>
<li><p>Use <strong>ONLY <em>PURE</em> VANILLA EXTRACT!</strong>
<strong>DO <em>NOT USE IMITATION VANILLA!</em></strong> Not following
this rule will lead to a worse outcome.</p></li>
<li><p>When the recipe was first written they sold powdered sugar in a box; now
it’s confectionery sugar in a bag. My mum experimented with the amount and
found that 4 cups seems about right.</p></li>
<li><p><strong>USE <em>WHOLE MILK!</em></strong> Don’t try skim milk or whatever per cent of fat milk you
have.</p></li>
<li><p>Use <strong>ONLY <em>PURE</em> VANILLA EXTRACT!</strong> <strong>DO <em>NOT USE IMITATION VANILLA!</em></strong> Not
following this rule will lead to a worse outcome.</p></li>
</ul>
<h2 id="cake-ingredients">Cake Ingredients</h2>
<ul>
@@ -215,42 +197,35 @@ this rule will lead to a worse outcome.</p></li>
<li>1/2 tsp salt</li>
<li>2 and 1/4 cups packed brown sugar</li>
<li>3 eggs</li>
<li>1 and 1/2 tsp <strong>PURE VANILLA EXTRACT (<em>NOT IMITATION
VANILLA!</em>)</strong></li>
<li>1 and 1/2 tsp <strong>PURE VANILLA EXTRACT (<em>NOT IMITATION VANILLA!</em>)</strong></li>
<li>1/2 cup <strong>MARGARINE (<em>NOT BUTTER!</em>)</strong></li>
<li>1 cup (boiling) water</li>
<li>1 cup sour cream</li>
</ul>
<h2 id="cake-preparation">Cake Preparation</h2>
<ol type="1">
<li><p>Lightly grease <strong>TWO 9 x 1.5 INCH ROUND PANS</strong>;
lightly dust with flour.</p></li>
<li><p>Lightly grease <strong>TWO 9 x 1.5 INCH ROUND PANS</strong>; lightly dust with flour.</p></li>
<li><p>Preheat oven to <strong>350 F / 176.67 C</strong>.</p></li>
</ol>
<h2 id="cake-directions">Cake Directions</h2>
<ol type="1">
<li><p>Melt <strong>3 OZ UNSWEETENED CHOCOLATE</strong> in double boiler
or small bowl over <strong>hot (<em>BUT NOT BOILING</em>)
water</strong>; let cool whilst proceeding.</p></li>
<li><p>Sift <strong>2 and 1/4 CUPS FLOUR</strong>, <strong>2 TSP BAKING
SODA</strong>, and <strong>1/2 TSP SALT</strong></p></li>
<li><p>Beat <strong>1 STICK MARGARINE (<em>NOT BUTTER!</em>)</strong> in
large bowl <em>until soft</em>. Again <strong>MARGARINE, <em>NOT
BUTTER!</em></strong></p></li>
<li><p>Add <strong>2 and 1/4 CUPS PACKED BROWN SUGAR</strong> and
<strong>3 EGGS</strong>. Beat until light and fluffy.</p></li>
<li><p>Beat in <strong>1 1/2 TSP <em>PURE</em> VANILLA EXTRACT (<em>NOT
IMITATION VANILLA!</em>)</strong> and <strong><em>COOLED</em> MELTED
CHOCOLATE</strong>.</p></li>
<li><p>Stir in dry ingredients alternately with <strong>1 CUP SOUR
CREAM</strong>; always beat until smooth.</p></li>
<li><p>Melt <strong>3 OZ UNSWEETENED CHOCOLATE</strong> in double boiler or small bowl over
<strong>hot (<em>BUT NOT BOILING</em>) water</strong>; let cool whilst proceeding.</p></li>
<li><p>Sift <strong>2 and 1/4 CUPS FLOUR</strong>, <strong>2 TSP BAKING SODA</strong>, and <strong>1/2 TSP SALT</strong></p></li>
<li><p>Beat <strong>1 STICK MARGARINE (<em>NOT BUTTER!</em>)</strong> in large bowl <em>until soft</em>. Again
<strong>MARGARINE, <em>NOT BUTTER!</em></strong></p></li>
<li><p>Add <strong>2 and 1/4 CUPS PACKED BROWN SUGAR</strong> and <strong>3 EGGS</strong>. Beat until light and
fluffy.</p></li>
<li><p>Beat in <strong>1 1/2 TSP <em>PURE</em> VANILLA EXTRACT (<em>NOT IMITATION VANILLA!</em>)</strong> and
<strong><em>COOLED</em> MELTED CHOCOLATE</strong>.</p></li>
<li><p>Stir in dry ingredients alternately with <strong>1 CUP SOUR CREAM</strong>; always beat
until smooth.</p></li>
<li><p>Stir in <strong>1 CUP <em>BOILING</em> WATER</strong>.</p></li>
<li><p>Pour into prepared pans.</p></li>
<li><p>Bake for <strong>ONLY 35 MINUTES</strong> (<strong>NO
LONGER!</strong>) at <strong>350 F / 176.67 C</strong>.</p></li>
<li><p>When you take the cake out put the cake pans on a cooling rack
for **_ONLY TWO MINUTES AND THEN <em>IMMEDIATELY TURN CAKES OUT ON TO
RACK</em><strong>. Let </strong>COOL <em>COMPLETELY!</em>**</p></li>
<li><p>Bake for <strong>ONLY 35 MINUTES</strong> (<strong>NO LONGER!</strong>) at <strong>350 F / 176.67 C</strong>.</p></li>
<li><p>When you take the cake out put the cake pans on a cooling rack for **_ONLY
TWO MINUTES AND THEN <em>IMMEDIATELY TURN CAKES OUT ON TO RACK</em><strong>. Let </strong>COOL
<em>COMPLETELY!</em>**</p></li>
</ol>
<h2 id="icing-ingredients">Icing Ingredients</h2>
<ul>
@@ -258,47 +233,39 @@ RACK</em><strong>. Let </strong>COOL <em>COMPLETELY!</em>**</p></li>
<li>1/2 cup <strong>MARGARINE (<em>NOT BUTTER!</em>)</strong></li>
<li>4 cups powdered sugar</li>
<li>1/2 cup whole milk</li>
<li>2 tsp <strong><em>PURE</em> VANILLA EXTRACT (<em>NOT IMITATION
VANILLA!</em>)</strong></li>
<li>2 tsp <strong><em>PURE</em> VANILLA EXTRACT (<em>NOT IMITATION VANILLA!</em>)</strong></li>
</ul>
<p>You will also need a bigger pan or bowl that can have ice water that
the icing bowl can sit in.</p>
<p>You will also need a bigger pan or bowl that can have ice water that the icing
bowl can sit in.</p>
<h2 id="special-notes-for-the-icing">Special notes for the icing</h2>
<p><strong>PAY CLOSE ATTENTION TO THESE:</strong></p>
<ul>
<li><p><strong>MAKE SURE</strong> that the melted chocolate and
<strong>MARGARINE (<em>NOT BUTTER!</em>)</strong> do not get
solid.</p></li>
<li><p>For step #4 put <strong>8 to 10 ICE CUBES</strong> in a pan or
big bowl (that’s big enough that another bowl can fit in it).
<strong>ADD AN INCH OF WATER</strong> and <strong>SET THE BOWL WITH THE
ICING IN THE PAN OR BOWL</strong> of ice water. <strong>DO NOT LET THE
<li><p><strong>MAKE SURE</strong> that the melted chocolate and <strong>MARGARINE (<em>NOT BUTTER!</em>)</strong>
do not get solid.</p></li>
<li><p>For step #4 put <strong>8 to 10 ICE CUBES</strong> in a pan or big bowl (that’s big
enough that another bowl can fit in it). <strong>ADD AN INCH OF WATER</strong> and <strong>SET
THE BOWL WITH THE ICING IN THE PAN OR BOWL</strong> of ice water. <strong>DO NOT LET THE
ICING GET WET!</strong></p></li>
<li><p><strong>DO NOT LET ICING GET TOO THICK.</strong></p></li>
<li><p><strong>USE <em>WHOLE MILK!</em></strong> Don’t try skim milk or
whatever per cent of fat milk you have.</p></li>
<li><p>Use <strong>ONLY PURE VANILLA EXTRACT</strong>! <strong>DO NOT
USE IMITATION VANILLA!</strong> Not following this rule will lead to a
worse outcome. As I recall the icing was quite a bit worse (but still
chocolaty at least) the times we had imitation vanilla (simply because
we couldn’t get pure vanilla at the time we needed it). Just don’t do
it.</p></li>
<li><p><strong>USE <em>WHOLE MILK!</em></strong> Don’t try skim milk or whatever per cent of fat milk you
have.</p></li>
<li><p>Use <strong>ONLY PURE VANILLA EXTRACT</strong>! <strong>DO NOT USE IMITATION VANILLA!</strong> Not
following this rule will lead to a worse outcome. As I recall the icing was
quite a bit worse (but still chocolaty at least) the times we had imitation
vanilla (simply because we couldn’t get pure vanilla at the time we needed
it). Just don’t do it.</p></li>
</ul>
<h2 id="icing-directions">Icing Directions</h2>
<ol type="1">
<li><p>Combine <strong>4 OZ UNSWEETENED CHOCOLATE</strong> and
<strong>1/2 CUP <em>MARGARINE (NOT BUTTER!)</em></strong> in pan. Melt
and remove from heat. <strong>DO NOT LET IT GET SOLID!</strong></p></li>
<li><p>Combine <strong>3 1/4 CUPS POWDERED SUGAR</strong>, <strong>1/2
CUPS WHOLE MILK</strong> and <strong>2 TSP </strong><em>PURE</em>
VANILLA EXTRACT (<em>NOT IMITATION VANILLA!</em>)** into a bowl.
<strong>STIR UNTIL SMOOTH</strong>.</p></li>
<li><p>Combine <strong>4 OZ UNSWEETENED CHOCOLATE</strong> and <strong>1/2 CUP <em>MARGARINE (NOT
BUTTER!)</em></strong> in pan. Melt and remove from heat. <strong>DO NOT LET IT GET SOLID!</strong></p></li>
<li><p>Combine <strong>3 1/4 CUPS POWDERED SUGAR</strong>, <strong>1/2 CUPS WHOLE MILK</strong> and <strong>2 TSP
</strong><em>PURE</em> VANILLA EXTRACT (<em>NOT IMITATION VANILLA!</em>)** into a bowl. <strong>STIR
UNTIL SMOOTH</strong>.</p></li>
<li><p>Add chocolate mixture.</p></li>
<li><p>Set bowl in pan/bowl of ice and water. Beat with spoon/mixer
until it’s thick BUT not too thick. <strong>Make <em>SURE</em> ICING
DOES <em>NOT</em> GET WET!</strong> The idea is to <strong>MAKE THE BOWL
IT’S IN COLD <em>BUT TO NOT LET THE ICING GET
WET!</em></strong></p></li>
<li><p>Set bowl in pan/bowl of ice and water. Beat with spoon/mixer until it’s
thick BUT not too thick. <strong>Make <em>SURE</em> ICING DOES <em>NOT</em> GET WET!</strong> The idea is to
<strong>MAKE THE BOWL IT’S IN COLD <em>BUT TO NOT LET THE ICING GET WET!</em></strong></p></li>
</ol>
<table>
<colgroup>
@@ -306,13 +273,12 @@ WET!</em></strong></p></li>
</colgroup>
<tbody>
<tr class="odd">
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt
Noll][judges] - All rights reserved This work is licensed under a
[Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
</tr>
<tr class="even">
<td>[judges]: https://www.ioccc.org/judges.html [cc]:
http://creativecommons.org/licenses/by-sa/3.0/</td>
<td>[judges]: https://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/</td>
</tr>
</tbody>
</table>
+15 -19
View File
@@ -122,16 +122,15 @@
<p>The following are a few screen dumps of:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="va">SHEDS</span><span class="op">=</span>5 <span class="va">GROW</span><span class="op">=</span>-10 <span class="va">SHED</span><span class="op">=</span>50 <span class="va">MAXSIZE</span><span class="op">=</span>250 <span class="ex">./prog</span></span></code></pre></div>
<p>As you will see it took 17 bugs to get down to below 0. Notice how I
had to get down to 0 more than once: because I moved enough times before
I got the last bug that I grew by 5 in size. I then however moved a bit
more and ate a bug which brought me down to -5 therefore winning at the
max size of 250. This then showed:</p>
<p>As you will see it took 17 bugs to get down to below 0. Notice how I had to get
down to 0 more than once: because I moved enough times before I got the last
bug that I grew by 5 in size. I then however moved a bit more and ate a bug
which brought me down to -5 therefore winning at the max size of 250. This then
showed:</p>
<pre><code>YOU WIN!
X:62/89 Y:5/25 S:250/250 B:17</code></pre>
<p>Observe all the arrows on the screen; that’s where a bug was that I
ate and then I split off losing 10 in size. The first dump I’m already
at 15/250:</p>
<p>Observe all the arrows on the screen; that’s where a bug was that I ate and
then I split off losing 10 in size. The first dump I’m already at 15/250:</p>
<pre><code>X:17/89 Y:15/25 S:15/250 B:13
##########################################################################################
# &lt;ooooooooo o &lt;ooooooooo* #
@@ -158,8 +157,7 @@ at 15/250:</p>
# o o&gt; #
# oooooo #
##########################################################################################</code></pre>
<p>But here now I’m at 0; the head is marked <code>H</code> and it’s
moving left.</p>
<p>But here now I’m at 0; the head is marked <code>H</code> and it’s moving left.</p>
<pre><code>X:19/89 Y:12/25 S:0/250 B:16
##########################################################################################
# &lt;ooooooooo o &lt;oooooooo &lt;ooooooo #
@@ -187,10 +185,9 @@ moving left.</p>
# oooooo #
##########################################################################################</code></pre>
<p>I ended up moving enough times where my size went back up to 5.</p>
<p>Below the snake is moving right and its head is indicated by a
<code>H</code> with the line marked at the right; the bug is marked as
<code>B</code> and is also marked at the right. Notice how it’s in the
body of the snake (but see below)!</p>
<p>Below the snake is moving right and its head is indicated by a <code>H</code> with the line
marked at the right; the bug is marked as <code>B</code> and is also marked at the right.
Notice how it’s in the body of the snake (but see below)!</p>
<pre><code>X:55/89 Y:4/25 S:5/250 B:16
##########################################################################################
# &lt;ooooooooo o &lt;oooooooo &lt;ooooooo #
@@ -217,11 +214,10 @@ body of the snake (but see below)!</p>
# o o&gt; #
# oooooo #
##########################################################################################</code></pre>
<p>But did you see anything strange? The bug is on the fourth line below
the upper wall. However it appears to be inside the body of the snake!
But actually that’s just where the snake split off at some point: the
snake no longer occupies that place and indeed I could safely go through
that part of the screen.</p>
<p>But did you see anything strange? The bug is on the fourth line below the upper wall.
However it appears to be inside the body of the snake! But actually that’s just where
the snake split off at some point: the snake no longer occupies that place and indeed I
could safely go through that part of the screen.</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+327 -464
View File
@@ -120,14 +120,13 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<p>Playing the game is very simple but because there are many different
modes I have included much more than just the input keys and a few
printouts of the game. For normal play you probably don’t even need this
file at all unless it be for the input keys.</p>
<p>Playing the game is very simple but because there are many different modes I
have included much more than just the input keys and a few printouts of the
game. For normal play you probably don’t even need this file at all unless it be
for the input keys.</p>
<p><a name="toc"></a></p>
<ol type="1">
<li><p><a href="#support">Testing terminal
environment/capabilities</a></p></li>
<li><p><a href="#support">Testing terminal environment/capabilities</a></p></li>
<li><p><a href="#input">Input keys</a></p></li>
<li><p><a href="#gameplay">Gameplay</a></p>
<ul>
@@ -141,20 +140,14 @@ environment/capabilities</a></p></li>
</ul></li>
<li><p><a href="#modes">Gameplay modes</a></p>
<ul>
<li><p><a href="#warning"><strong>Photosensitive epilepsy/Stimulation
overload trigger warnings</strong></a></p></li>
<li><p><a href="#warning"><strong>Photosensitive epilepsy/Stimulation overload trigger warnings</strong></a></p></li>
<li><p><a href="#drawing">Drawing / Practice mode</a></p></li>
<li><p><a href="#auto">Computer playing / Automatic mode
(<strong>Photosensitive epilepsy/Stimulation overload
trigger</strong>)</a></p>
<li><p><a href="#auto">Computer playing / Automatic mode (<strong>Photosensitive epilepsy/Stimulation overload trigger</strong>)</a></p>
<ul>
<li><a href="#auto-variations">Variations</a></li>
</ul></li>
<li><p><a href="#grow-shrink">Grow-Shrink (Positive/Negative Winning)
mode</a></p></li>
<li><p><a href="#hypnotic">Hypnotic / Sleepy mode
(<strong>Photosensitive epilepsy/Stimulation overload
trigger</strong>)</a></p></li>
<li><p><a href="#grow-shrink">Grow-Shrink (Positive/Negative Winning) mode</a></p></li>
<li><p><a href="#hypnotic">Hypnotic / Sleepy mode (<strong>Photosensitive epilepsy/Stimulation overload trigger</strong>)</a></p></li>
<li><p><a href="#stim">Stimulation / Calming mode</a></p></li>
<li><p><a href="#other-ideas">Other ideas</a></p></li>
</ul></li>
@@ -167,55 +160,40 @@ trigger</strong>)</a></p></li>
<ul>
<li><p><a href="#wait">WAIT - Snake speed</a></p></li>
<li><p><a href="#evade">EVADE - Bug evasion frequency</a></p></li>
<li><p><a href="#sizes">SIZE / MAXSIZE - Initial snake / max
sizes</a></p></li>
<li><p><a href="#growth">GROW / SHEDS - Growth / Shedding
sizes</a></p></li>
<li><p><a href="#sizes">SIZE / MAXSIZE - Initial snake / max sizes</a></p></li>
<li><p><a href="#growth">GROW / SHEDS - Growth / Shedding sizes</a></p></li>
</ul></li>
<li><p><a href="#conclusions">Conclusion (and inspirational words for
everyone)</a></p></li>
<li><p><a href="#conclusions">Conclusion (and inspirational words for everyone)</a></p></li>
</ol>
<h1 id="testing-terminal-environmentcapabilities">1.
<a name="support" href="#toc">Testing terminal
environment/capabilities</a></h1>
<p>Most people probably won’t have any issue at all but for those who
have any problems with the terminal see the <a
href="terminals.html">terminals.html</a> (<a
href="terminals.md">terminals.md</a> on GitHub) file for more
information on the terminal capabilities testing utility I include.</p>
<p>For troubleshooting other problems see <a
href="troubleshooting.html">troubleshooting.html</a> (<a
href="troubleshooting.md">troubleshooting.md</a> on GitHub) and <a
href="bugs.html">bugs.html</a> (<a href="bugs.md">bugs.md</a> on
GitHub).</p>
<h1 id="testing-terminal-environmentcapabilities">1. <a name="support" href="#toc">Testing terminal environment/capabilities</a></h1>
<p>Most people probably won’t have any issue at all but for those who have any
problems with the terminal see the <a href="terminals.html">terminals.html</a> (<a href="terminals.md">terminals.md</a> on
GitHub) file for more information on the terminal capabilities testing utility I
include.</p>
<p>For troubleshooting other problems see <a href="troubleshooting.html">troubleshooting.html</a>
(<a href="troubleshooting.md">troubleshooting.md</a> on GitHub) and <a href="bugs.html">bugs.html</a> (<a href="bugs.md">bugs.md</a> on GitHub).</p>
<h1 id="input-keys">2. <a name="input" href="#toc">Input keys</a></h1>
<ul>
<li><p>Left, right, up and down <strong>arrow keys</strong>: move that
direction.</p></li>
<li><p>Left, right, up and down <strong>arrow keys</strong>: move that direction.</p></li>
<li><p><code>q</code> (and <code>Q</code>): quit the game.</p></li>
<li><p>Space: pause/resume the game (direction keys will also resume).
Note that no other keys will resume the game; however if you press a key
that <code>getch()</code> picks up on and the game is not paused then it
will be as if you pressed the current direction key (assuming you
already moved the snake).</p></li>
that <code>getch()</code> picks up on and the game is not paused then it will be as if
you pressed the current direction key (assuming you already moved the snake).</p></li>
</ul>
<h1 id="gameplay">3. <a name="gameplay" href="#toc">Gameplay</a></h1>
<p>Here I will show the initial screen as well as what a few things look
like. If you don’t feel you need this but you want to configure colours
jump to <a href="#colours">colour selection</a>. You can also jump to <a
href="#modes">gameplay modes</a> or <a href="#variables">game
<p>Here I will show the initial screen as well as what a few things look like. If
you don’t feel you need this but you want to configure colours jump to <a href="#colours">colour
selection</a>. You can also jump to <a href="#modes">gameplay modes</a> or <a href="#variables">game
variables</a>.</p>
<p>The bug colour by default is white; the snake head colour is red and
the snake body colour is green. The walls are cyan.</p>
<h2
id="gameplay-the-initial-screen"><a name="initial" href="#toc">Gameplay:
The initial screen</a></h2>
<p>When you load the game you will see a screen that looks something
like the below. Note that the top line is the score/status line: the top
wall is at line 1 and the left wall is column 0. Below I use the
coordinates in the X/Y order (ncurses is the opposite: Y/X). I will
parenthesise the numbers below to refer to the number in the
diagram:</p>
<p>The bug colour by default is white; the snake head colour is red and the snake
body colour is green. The walls are cyan.</p>
<h2 id="gameplay-the-initial-screen"><a name="initial" href="#toc">Gameplay: The initial screen</a></h2>
<p>When you load the game you will see a screen that looks something like the
below. Note that the top line is the score/status line: the top wall is at line
1 and the left wall is column 0. Below I use the coordinates in the X/Y order
(ncurses is the opposite: Y/X). I will parenthesise the numbers below to refer
to the number in the diagram:</p>
<pre><code>X:24/49 Y:8/16 S:5/658 B:0
##################################################
# #
@@ -235,28 +213,23 @@ diagram:</p>
##################################################
</code></pre>
<ul>
<li><p>The snake (<code>+</code>) is at (24),(8). The bug char is
<code>*</code> and the wall char is <code>#</code>. When the snake moves
the head will be an arrow facing the direction it is moving; the body is
‘o’.</p></li>
<li><p>The top wall is always line (1), the left wall is always column
(0), the bottom wall is line (16) and the right wall is column (49). If
walls are impassable and you run into any of these the game is over (you
can slither at the edge of the wall); else you’ll come out the opposite
side.</p></li>
<li><p>The snake size is (5): but until you start to move it’s
technically 1 (even if you set <strong>SIZE=0</strong> this applies).
This is so that you can decide which direction from the centre of the
screen. By default the head colour is red; the body is green. The snake
will grow by one until it reaches the right size.</p></li>
<li><p>The maximum snake size is (997): this is the default; it can be
changed but it will always have an upper limit depending on the terminal
<li><p>The snake (<code>+</code>) is at (24),(8). The bug char is <code>*</code> and the wall char is
<code>#</code>. When the snake moves the head will be an arrow facing the direction it
is moving; the body is ‘o’.</p></li>
<li><p>The top wall is always line (1), the left wall is always column (0), the
bottom wall is line (16) and the right wall is column (49). If walls are
impassable and you run into any of these the game is over (you can slither
at the edge of the wall); else you’ll come out the opposite side.</p></li>
<li><p>The snake size is (5): but until you start to move it’s technically 1 (even
if you set <strong>SIZE=0</strong> this applies). This is so that you can decide which
direction from the centre of the screen. By default the head colour is red;
the body is green. The snake will grow by one until it reaches the right
size.</p></li>
<li><p>The maximum snake size is (997): this is the default; it can be changed but
it will always have an upper limit depending on the terminal size.</p></li>
<li><p>The number of bugs eaten so far is 0.</p></li>
</ul>
<h2
id="gameplay-playing-the-game"><a name="playing" href="#toc">Gameplay:
Playing the game</a></h2>
<h2 id="gameplay-playing-the-game"><a name="playing" href="#toc">Gameplay: Playing the game</a></h2>
<pre><code>X:39/49 Y:8/16 S:5/658 B:0
##################################################
# #
@@ -274,8 +247,8 @@ Playing the game</a></h2>
# #
# #
##################################################</code></pre>
<p>I let the snake grow to its full size (with the head at (39),(8)) and
I’m two places above the bug so let’s go down:</p>
<p>I let the snake grow to its full size (with the head at (39),(8)) and I’m two
places above the bug so let’s go down:</p>
<pre><code>X:39/49 Y:9/16 S:5/658 B:0
##################################################
# #
@@ -293,8 +266,8 @@ I’m two places above the bug so let’s go down:</p>
# #
# #
##################################################</code></pre>
<p>Now you see that the snake is going down and in one move the bug will
be eaten. Let’s do that:</p>
<p>Now you see that the snake is going down and in one move the bug will be eaten.
Let’s do that:</p>
<pre><code>X:36/49 Y:10/16 S:10/658 B:1
##################################################
# #
@@ -312,12 +285,11 @@ be eaten. Let’s do that:</p>
# #
# #
##################################################</code></pre>
<p>Observe that the bug was eaten and a new bug spawned elsewhere. I
went left three and then up one and could slither on to the bug.</p>
<h1 id="gameplay-walls"><a name="walls" href="#toc">Gameplay:
Walls</a></h1>
<p>By default walls are passable (<strong>WALLS=1</strong>). Let’s get
to full size and go through the top wall:</p>
<p>Observe that the bug was eaten and a new bug spawned elsewhere. I went left
three and then up one and could slither on to the bug.</p>
<h1 id="gameplay-walls"><a name="walls" href="#toc">Gameplay: Walls</a></h1>
<p>By default walls are passable (<strong>WALLS=1</strong>). Let’s get to full size and go
through the top wall:</p>
<pre><code>X:36/49 Y:15/16 S:10/658 B:1
##################################################
# o #
@@ -335,8 +307,8 @@ to full size and go through the top wall:</p>
# #
# ^ #
##################################################</code></pre>
<p>There you can see I have grown to the full size and went through the
top wall; the head is now at the opposite wall. Continuing:</p>
<p>There you can see I have grown to the full size and went through the top wall;
the head is now at the opposite wall. Continuing:</p>
<pre><code>X:36/49 Y:11/16 S:10/658 B:1
##################################################
# o #
@@ -354,11 +326,10 @@ top wall; the head is now at the opposite wall. Continuing:</p>
# o #
# o #
##################################################</code></pre>
<p>I might then have turned to the left and then shortly go up to get
the bug. This goes on until you lose, quit or win the game.</p>
<p>When you specify <strong>WALLS=0</strong> the walls become an
obstacle that end the game. It might look like (I set the starting size
to 150 and had only just started):</p>
<p>I might then have turned to the left and then shortly go up to get the bug. This
goes on until you lose, quit or win the game.</p>
<p>When you specify <strong>WALLS=0</strong> the walls become an obstacle that end the game. It
might look like (I set the starting size to 150 and had only just started):</p>
<pre><code>X:20/49 Y:2/16 S:150/658 B:0
##################################################
# ^ #
@@ -379,11 +350,9 @@ to 150 and had only just started):</p>
<p>If I continue going up I will see:</p>
<pre><code>OUCH!
X:20/49 Y:1/16 S:150/658 B:0</code></pre>
<h1
id="gameplay-cannibalism"><a name="cannibalism" href="#toc">Gameplay:
Cannibalism</a></h1>
<p>By default cannibalism is disabled (<strong>CANNIBAL=0</strong>) so
if you run into yourself it might look something like:</p>
<h1 id="gameplay-cannibalism"><a name="cannibalism" href="#toc">Gameplay: Cannibalism</a></h1>
<p>By default cannibalism is disabled (<strong>CANNIBAL=0</strong>) so if you run into yourself it might look
something like:</p>
<pre><code>X:45/49 Y:10/16 S:10/658 B:1
##################################################
# #
@@ -401,14 +370,13 @@ if you run into yourself it might look something like:</p>
# #
# #
##################################################</code></pre>
<p>If I were to do any movement but turn to the left I would run into
myself. I’ll go to the right two spaces:</p>
<p>If I were to do any movement but turn to the left I would run into myself. I’ll
go to the right two spaces:</p>
<pre><code>OW!
X:47/49 Y:10/16 S:10/658 B:1</code></pre>
<p>But <strong>CANNIBAL=1</strong> can look very funny both in movement
and still especially when you go through yourself several times when the
snake is rather long. For example going through walls and the snake a
few times:</p>
<p>But <strong>CANNIBAL=1</strong> can look very funny both in movement and still especially
when you go through yourself several times when the snake is rather long. For
example going through walls and the snake a few times:</p>
<pre><code>X:4/49 Y:12/16 S:165/658 B:3
##################################################
#oo o ooooo o o o#
@@ -444,8 +412,8 @@ few times:</p>
#ooooo&gt;oooooooo o oooo oooooooo#
# o o o o o #
##################################################</code></pre>
<p>If you note that the head is at (6),(14) I will go one more to the
right and you will see that the arrow has moved over:</p>
<p>If you note that the head is at (6),(14) I will go one more to the right and you
will see that the arrow has moved over:</p>
<pre><code>X:7/49 Y:14/16 S:165/658 B:3
##################################################
#oo o ooooo o o o#
@@ -463,397 +431,292 @@ right and you will see that the arrow has moved over:</p>
#oooooo&gt;ooooooo o oooo oooooooo#
# o o o o o #
##################################################</code></pre>
<p>Try this: get a reasonable length and then go back on yourself (if
you’re going left go right etc.) and then after some length (but before
you get beyond the snake) turn (so that you go perpendicular) and then
watch as the snake starts unwinding at one place and then suddenly
unwinds another direction.</p>
<p>An example of extreme cannibalism is in the <a
href="cannibalism.log.html">cannibalism.log.html</a> (<a
href="cannibalism.log.md">cannibalism.log.md</a> on GitHub) file. It
explains information about the file including how to find the bug, head
and tail of the snake, at least where it was documented. The first run
has several dumps. The final example has the snake inside itself.</p>
<h1
id="gameplay-shedding-stretching"><a name="shedding" href="#toc">Gameplay:
Shedding (stretching)</a></h1>
<p>This feature will make you grow by the value of
<strong><code>SHEDS</code></strong> for every
<strong><code>SHED</code></strong> movements (the counter isn’t
incremented when you eat a bug). Basically growing without eating a bug
(stretching would be better name here).</p>
<h1 id="gameplay-winning"><a name="winning" href="#toc">Gameplay:
Winning</a></h1>
<p>If you ever get to the <strong><code>MAXSIZE</code></strong> the game
is won. You can force a win by setting the max size to a smaller value
than the size you specify (or the default) or setting the size to higher
than the default (or &lt; 0 which will end up being &gt; the max size
though I suppose there might be some value that makes it less than again
- I’m not going to try and figure that out however). Anyway:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>-1 <span class="ex">./prog</span></span>
<p>Try this: get a reasonable length and then go back on yourself (if you’re going
left go right etc.) and then after some length (but before you get beyond the
snake) turn (so that you go perpendicular) and then watch as the snake starts
unwinding at one place and then suddenly unwinds another direction.</p>
<p>An example of extreme cannibalism is in the <a href="cannibalism.log.html">cannibalism.log.html</a>
(<a href="cannibalism.log.md">cannibalism.log.md</a> on GitHub) file. It explains information about the file
including how to find the bug, head and tail of the snake, at least where it was
documented. The first run has several dumps. The final example has the snake
inside itself.</p>
<h1 id="gameplay-shedding-stretching"><a name="shedding" href="#toc">Gameplay: Shedding (stretching)</a></h1>
<p>This feature will make you grow by the value of <strong><code>SHEDS</code></strong> for every <strong><code>SHED</code></strong>
movements (the counter isn’t incremented when you eat a bug). Basically growing
without eating a bug (stretching would be better name here).</p>
<h1 id="gameplay-winning"><a name="winning" href="#toc">Gameplay: Winning</a></h1>
<p>If you ever get to the <strong><code>MAXSIZE</code></strong> the game is won. You can force a win by
setting the max size to a smaller value than the size you specify (or the
default) or setting the size to higher than the default (or &lt; 0 which will end
up being &gt; the max size though I suppose there might be some value that makes it
less than again - I’m not going to try and figure that out however). Anyway:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>-1 <span class="ex">./prog</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="ex">YOU</span> WIN!</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="ex">X:24/49</span> Y:8/16 S:658/658 B:0</span></code></pre></div>
<p>Observe that the size isn’t the default 997: because the screen size
is too small for that value (see <a
href="terminals.md">terminals.md</a>).</p>
<p>The reason I chose 997 is that it leaves a bit of a challenge for
some (maybe most) people but it’s still winnable. Previously even I
couldn’t have won unless maybe a much bigger screen, if both cheat modes
were disabled. I probably could win without any cheat mode enabled on my
24” monitor but I probably would need at least one cheat mode on my 16”
laptop (I don’t need both enabled). I don’t think I need either for
997.</p>
<p>The beauty though is the game can be winnable by anyone since you can
define the max size to win. Games are meant to be fun: who enjoys games
that can never be won? Very few probably do and those who do enjoy them
it probably are games that are relaxing and stimulating (which
admittedly this game can be - but still I want it to be winnable
too).</p>
<p>Another reason I chose 997: it’s prime and the judges love prime
numbers. Actually, this is the main reason for the number: I had changed
it down to 1000 but then it occurred to me that there are prime numbers
close to 1000 so why not choose one instead (that was less than 1000)?
And so I did. Another fun fact: at the default starting size and growth
size of 5 the number of bugs needed before the game is won is 199 - also
a prime!</p>
<h1 id="gameplay-quitting"><a name="quitting" href="#toc">Gameplay:
Quitting</a></h1>
<p>If you wish to quit you can hit ‘q’ (case-insensitive). For
example:</p>
<p>Observe that the size isn’t the default 997: because the screen size is too
small for that value (see <a href="terminals.md">terminals.md</a>).</p>
<p>The reason I chose 997 is that it leaves a bit of a challenge for some (maybe
most) people but it’s still winnable. Previously even I couldn’t have won unless
maybe a much bigger screen, if both cheat modes were disabled. I probably could
win without any cheat mode enabled on my 24” monitor but I probably would need
at least one cheat mode on my 16” laptop (I don’t need both enabled). I don’t
think I need either for 997.</p>
<p>The beauty though is the game can be winnable by anyone since you can define the
max size to win. Games are meant to be fun: who enjoys games that can never be
won? Very few probably do and those who do enjoy them it probably are games that
are relaxing and stimulating (which admittedly this game can be - but still I
want it to be winnable too).</p>
<p>Another reason I chose 997: it’s prime and the judges love prime numbers.
Actually, this is the main reason for the number: I had changed it down to 1000
but then it occurred to me that there are prime numbers close to 1000 so why not
choose one instead (that was less than 1000)? And so I did. Another fun fact: at
the default starting size and growth size of 5 the number of bugs needed before
the game is won is 199 - also a prime!</p>
<h1 id="gameplay-quitting"><a name="quitting" href="#toc">Gameplay: Quitting</a></h1>
<p>If you wish to quit you can hit ‘q’ (case-insensitive). For example:</p>
<pre><code>X:24/49 Y:8/16 S:5/658 B:0</code></pre>
<h1 id="gameplay-modes">4. <a name="modes" href="#toc">Gameplay
modes</a></h1>
<p>Here I list a number of different modes of play. In the <a
href="bugs.html">bugs.html</a> (<a href="bugs.md">bugs.md</a> on GitHub)
file I even show how there’s a built-in test unit for some modes! There
are certainly other modes that could be imagined: the modes below
happened over time and some were simply an accidental discovery or
something I thought of by a chance; others were thought out from the
beginning but were improved over time.</p>
<p>The <a href="play.sh">play.sh</a> script sets up some of these
automatically; I describe it after the modes below.</p>
<h2
id="photosensitive-epilepsystimulation-overload-trigger-warnings"><a name="warning" href="#toc">Photosensitive
epilepsy/Stimulation overload trigger warnings</a></h2>
<p>If you have <strong>photosensitive epilepsy please be
careful</strong> especially with low values for both
<strong><code>WAIT</code></strong> and
<strong><code>EVADE</code></strong>. It appears that the <a
href="https://www.epilepsysociety.org.uk/photosensitive-epilepsy#.Xjgpwi2ZOgQ">number
of hertz (flashes) per second triggering seizures</a> is wide but
depending on the variables it easily can be in the range.</p>
<p>There are different patterns and lights flashing at different speeds
so please exercise caution. This could trigger seizures and <strong>it
might also be too much stimulation for some people.</strong></p>
<p><strong>Please be careful of these if these types of things have ever
affected you or if you have any form of epilepsy. Thank
you.</strong></p>
<h2
id="gameplay-mode-drawing-practice-mode"><a name="drawing" href="#toc">Gameplay
mode: Drawing / Practice mode</a></h2>
<p>If you want to draw the snake wherever you like on the screen you can
do this by modifying the wait time (for input) to -1 (or any value &lt;
0): then the snake does not move until you press a movement key. For
example:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>-1 <span class="ex">./prog</span></span></code></pre></div>
<p>When you eat a bug the snake will grow and you can draw more. If you
want to make it so you can go through yourself:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>-1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>If you don’t want to start out so small (i.e. you want to be able to
draw more quickly) you can just set the size to a bigger number (and you
could do the same with growth and moult/shed):</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>50 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>-1 <span class="ex">./prog</span></span></code></pre></div>
<p>Do note that although you’re a bigger size you still grow one
movement at a time.</p>
<p>Okay but then if you get too many bugs the drawing will be over. If
this proves to be a problem simply do:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>-1 <span class="va">GROW</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>Or something like that (maybe make the size bigger but that’s up to
you). You could also set the max size to be the highest possible by
saying</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="va">MAXSIZE</span><span class="op">=</span>-1</span></code></pre></div>
<h1 id="gameplay-modes">4. <a name="modes" href="#toc">Gameplay modes</a></h1>
<p>Here I list a number of different modes of play. In the <a href="bugs.html">bugs.html</a>
(<a href="bugs.md">bugs.md</a> on GitHub) file I even show how there’s a built-in test unit for some
modes! There are certainly other modes that could be imagined: the modes below
happened over time and some were simply an accidental discovery or something I
thought of by a chance; others were thought out from the beginning but were
improved over time.</p>
<p>The <a href="play.sh">play.sh</a> script sets up some of these automatically; I describe it after
the modes below.</p>
<h2 id="photosensitive-epilepsystimulation-overload-trigger-warnings"><a name="warning" href="#toc">Photosensitive epilepsy/Stimulation overload trigger warnings</a></h2>
<p>If you have <strong>photosensitive epilepsy please be careful</strong> especially with low values
for both <strong><code>WAIT</code></strong> and <strong><code>EVADE</code></strong>. It appears that the <a href="https://www.epilepsysociety.org.uk/photosensitive-epilepsy#.Xjgpwi2ZOgQ">number of hertz (flashes)
per second triggering seizures</a> is wide but depending on the variables it
easily can be in the range.</p>
<p>There are different patterns and lights flashing at different speeds so please
exercise caution. This could trigger seizures and <strong>it might also be too much
stimulation for some people.</strong></p>
<p><strong>Please be careful of these if these types of things have ever affected you or if
you have any form of epilepsy. Thank you.</strong></p>
<h2 id="gameplay-mode-drawing-practice-mode"><a name="drawing" href="#toc">Gameplay mode: Drawing / Practice mode</a></h2>
<p>If you want to draw the snake wherever you like on the screen you can do this by
modifying the wait time (for input) to -1 (or any value &lt; 0): then the snake
does not move until you press a movement key. For example:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>-1 <span class="ex">./prog</span></span></code></pre></div>
<p>When you eat a bug the snake will grow and you can draw more. If you want to
make it so you can go through yourself:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>-1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>If you don’t want to start out so small (i.e. you want to be able to draw more
quickly) you can just set the size to a bigger number (and you could do the same
with growth and moult/shed):</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>50 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>-1 <span class="ex">./prog</span></span></code></pre></div>
<p>Do note that although you’re a bigger size you still grow one movement at a
time.</p>
<p>Okay but then if you get too many bugs the drawing will be over. If this proves
to be a problem simply do:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>-1 <span class="va">GROW</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>Or something like that (maybe make the size bigger but that’s up to you). You
could also set the max size to be the highest possible by saying</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="va">MAXSIZE</span><span class="op">=</span>-1</span></code></pre></div>
<p>Which I’ve done in the <a href="play.sh">play.sh</a> script.</p>
<p>I discuss how this mode works in [spoilers.markdown][].</p>
<p>Here’s an example run where I spelt ‘SNAKE’. As you can see it’s far
from perfect: the snake after all does not leave gaps and the game does
not support diagonal movement and I also made a mistake and had to
modify what I was aiming for. But you can consider this mode drawing or
practice mode.</p>
<p>Here’s an example run where I spelt ‘SNAKE’. As you can see it’s far from
perfect: the snake after all does not leave gaps and the game does not support
diagonal movement and I also made a mistake and had to modify what I was aiming
for. But you can consider this mode drawing or practice mode.</p>
<pre><code> oooooooooo ooooo o oo ooooo
o o oo o oo o ooo o
oooo o oo ooooooo oooo ooooo
o o ooo oo o ooo o
oooo o oo ooo oooooooo&gt;</code></pre>
<h2
id="gameplay-mode-computer-playing-automatic-mode-photosensitive-epilepsystimulation-overload-trigger"><a name="auto" href="#toc">Gameplay
mode: Computer playing / Automatic mode (Photosensitive
epilepsy/Stimulation overload trigger)</a></h2>
<p><strong>Photosensitive epilepsy/stimulation overload trigger
warning:</strong> For those who have epilepsy or are susceptible to
stimulation overload from flashing lights please do be careful with this
mode. Depending on your susceptibility this could very well trigger
seizures or other discomforts and I wouldn’t want that to happen to
anyone. This mode has a lot of flashing of different colours and
depending on the exact parameters you specify it could easily be in the
trigger range for epilepsy but potentially stimulation overload too.</p>
<h2 id="gameplay-mode-computer-playing-automatic-mode-photosensitive-epilepsystimulation-overload-trigger"><a name="auto" href="#toc">Gameplay mode: Computer playing / Automatic mode (Photosensitive epilepsy/Stimulation overload trigger)</a></h2>
<p><strong>Photosensitive epilepsy/stimulation overload trigger warning:</strong>
For those who have epilepsy or are susceptible to stimulation overload from
flashing lights please do be careful with this mode. Depending on your
susceptibility this could very well trigger seizures or other discomforts and I
wouldn’t want that to happen to anyone. This mode has a lot of flashing of
different colours and depending on the exact parameters you specify it could
easily be in the trigger range for epilepsy but potentially stimulation overload
too.</p>
<p>If you’re still here you can create this effect like:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>As long as the bug evades you’ll find that the snake is growing
because it’s actually eating bugs; the computer is actually playing the
game by itself! You can still move the snake though it won’t seem like
you have much control over it. If you pause the game you can see that
it’s bigger (you probably will be able to even without pausing it).</p>
<p>Basically the snake is moving so fast that because the bug evades the
bug will inevitably move in the snake path’s and therefore be eaten.</p>
<p>You might find it goes quicker if you set the evade count to a lower
value for example 1. Or you might not. But as long as the bug moves the
computer can play by itself.</p>
<p>Quick tests suggest that bigger dimensions it gets bigger quicker.
But it also seems to take longer for it to get a bug as it gets longer.
I believe these happen because the bug has to find a X and Y coordinate
that’s not occupied and so with fewer available it has a harder time
finding a place in that one line.</p>
<h3
id="computer-player-variations"><a name="auto-variations" href="#toc">Computer
player variations</a></h3>
<div class="sourceCode" id="cb22"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>As long as the bug evades you’ll find that the snake is growing because it’s
actually eating bugs; the computer is actually playing the game by itself! You
can still move the snake though it won’t seem like you have much control over
it. If you pause the game you can see that it’s bigger (you probably will be
able to even without pausing it).</p>
<p>Basically the snake is moving so fast that because the bug evades the bug will
inevitably move in the snake path’s and therefore be eaten.</p>
<p>You might find it goes quicker if you set the evade count to a lower value for
example 1. Or you might not. But as long as the bug moves the computer can play
by itself.</p>
<p>Quick tests suggest that bigger dimensions it gets bigger quicker. But it also
seems to take longer for it to get a bug as it gets longer. I believe these
happen because the bug has to find a X and Y coordinate that’s not occupied and
so with fewer available it has a harder time finding a place in that one line.</p>
<h3 id="computer-player-variations"><a name="auto-variations" href="#toc">Computer player variations</a></h3>
<p>Here’s how to make the bug move every time the snake moves:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<h4 id="help-the-computer-win-fairly-quickly">Help the computer win
fairly quickly</h4>
<div class="sourceCode" id="cb23"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<h4 id="help-the-computer-win-fairly-quickly">Help the computer win fairly quickly</h4>
<p>If you want to see the game ‘win’ try something like:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="va">MAXSIZE</span><span class="op">=</span>10 <span class="ex">./prog</span></span></code></pre></div>
<h4 id="negative-growth-shrink-automatic-mode">Negative growth (Shrink)
Automatic mode</h4>
<p>Here’s a fun one I just thought of (a long time after these other
modes were thought of):</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="va">GROW</span><span class="op">=</span>-1 <span class="va">SIZE</span><span class="op">=</span>9 <span class="va">MAXSIZE</span><span class="op">=</span>10 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>What you’ll see is that first the snake will get to the size of 9 -
whether it shows to be 10 characters depends on whether or not it gets a
bug before it can get to that length - and then it’ll start shrinking
until it’s just the head then the head again (i.e. 1 then 0 in size) and
then win! This is also in the <a href="play.sh">play.sh</a> script.</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="va">MAXSIZE</span><span class="op">=</span>10 <span class="ex">./prog</span></span></code></pre></div>
<h4 id="negative-growth-shrink-automatic-mode">Negative growth (Shrink) Automatic mode</h4>
<p>Here’s a fun one I just thought of (a long time after these other modes were
thought of):</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="va">EVADE</span><span class="op">=</span>1 <span class="va">GROW</span><span class="op">=</span>-1 <span class="va">SIZE</span><span class="op">=</span>9 <span class="va">MAXSIZE</span><span class="op">=</span>10 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>What you’ll see is that first the snake will get to the size of 9 - whether it
shows to be 10 characters depends on whether or not it gets a bug before it can
get to that length - and then it’ll start shrinking until it’s just the head
then the head again (i.e. 1 then 0 in size) and then win! This is also in the
<a href="play.sh">play.sh</a> script.</p>
<h4 id="adjusting-the-timespeed">Adjusting the time/speed</h4>
<p>Of course you can also do something like:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>5 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<div class="sourceCode" id="cb26"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>5 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>Which although might not seem like it is significantly slower.</p>
<h4 id="moving-the-snake-about-to-create-patterns">Moving the snake
about to create patterns</h4>
<p>If you press different direction keys in some pattern you will see a
pattern form too (entirely dependent on how fast you react, what keys
you press and I suppose also how much the bug moves and the chance of
being eaten also).</p>
<h4 id="moving-the-snake-about-to-create-patterns">Moving the snake about to create patterns</h4>
<p>If you press different direction keys in some pattern you will see a pattern
form too (entirely dependent on how fast you react, what keys you press and I
suppose also how much the bug moves and the chance of being eaten also).</p>
<h4 id="other-ideas">Other ideas</h4>
<p>Here’s an idea: how many moves is needed to make it possible to have
some sort of success in catching bugs? Obviously the dimensions will
affect this value.</p>
<p>How long will it take for the snake to run into itself? For instance
by doing:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>On my 13” MacBook Pro (replaced later by a 16”) at the default
settings going horizontally the snake ran into itself at:</p>
<p>Here’s an idea: how many moves is needed to make it possible to have some sort
of success in catching bugs? Obviously the dimensions will affect this value.</p>
<p>How long will it take for the snake to run into itself? For instance by doing:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="va">WAIT</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>On my 13” MacBook Pro (replaced later by a 16”) at the default settings going
horizontally the snake ran into itself at:</p>
<pre><code>OW!
X:57/156 Y:20/41 S:155/997 B:30</code></pre>
<p>What if you set the size to a high value? The lowest? There are bound
to be other games to play with this feature!</p>
<h2
id="gameplay-mode-grow-shrink-mode-positive-and-negative-winning"><a name="grow-shrink" href="#toc">Gameplay
mode: Grow-Shrink mode (Positive and Negative Winning)</a></h2>
<p>In this mode you’re simultaneously growing and shrinking but because
the max size is unsigned you can win both by shrinking to the point of
losing your body or growing to the full size directly. This is how it
works:</p>
<p>You have a negative shedding growth and a positive growth size:
negative and positive winning. Depending on the parameters specified it
might go one way over the other. Try:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>150 <span class="va">SHEDS</span><span class="op">=</span>-5 <span class="va">GROW</span><span class="op">=</span>10 <span class="va">SHED</span><span class="op">=</span>50 <span class="va">MAXSIZE</span><span class="op">=</span>250 <span class="ex">./prog</span></span></code></pre></div>
<p>What this does is set the size to 150 (to make it not go down so
quickly) and then for each bug you eat it adds 5 to the size; for every
50 moves (that you don’t get the bug) you shrink by 5. You will find
that at times you might only decrease in size but then at other times -
depending on size of screen and how lucky you are with where the bug is
relative to where it last was - you might be growing. Combining this
with the drawing mode could be interesting but I never actually tried
it.</p>
<p>The parameters above were chosen after playing with the mode a bit to
find a value that wouldn’t take that much time but still would pose a
challenge. One could reverse it so that one shrinks more than
growing.</p>
<p>The <a href="crazy.log.html">crazy.log.html</a> (<a
href="crazy.log.md">crazy.log.md</a> on GitHub) file has several screen
<p>What if you set the size to a high value? The lowest? There are bound to be
other games to play with this feature!</p>
<h2 id="gameplay-mode-grow-shrink-mode-positive-and-negative-winning"><a name="grow-shrink" href="#toc">Gameplay mode: Grow-Shrink mode (Positive and Negative Winning)</a></h2>
<p>In this mode you’re simultaneously growing and shrinking but because the max
size is unsigned you can win both by shrinking to the point of losing your body
or growing to the full size directly. This is how it works:</p>
<p>You have a negative shedding growth and a positive growth size: negative and
positive winning. Depending on the parameters specified it might go one way over
the other. Try:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>150 <span class="va">SHEDS</span><span class="op">=</span>-5 <span class="va">GROW</span><span class="op">=</span>10 <span class="va">SHED</span><span class="op">=</span>50 <span class="va">MAXSIZE</span><span class="op">=</span>250 <span class="ex">./prog</span></span></code></pre></div>
<p>What this does is set the size to 150 (to make it not go down so quickly) and
then for each bug you eat it adds 5 to the size; for every 50 moves (that you
don’t get the bug) you shrink by 5. You will find that at times you might only
decrease in size but then at other times - depending on size of screen and how
lucky you are with where the bug is relative to where it last was - you might be
growing. Combining this with the drawing mode could be interesting but I never
actually tried it.</p>
<p>The parameters above were chosen after playing with the mode a bit to find a
value that wouldn’t take that much time but still would pose a challenge. One
could reverse it so that one shrinks more than growing.</p>
<p>The <a href="crazy.log.html">crazy.log.html</a> (<a href="crazy.log.md">crazy.log.md</a> on GitHub) file has several screen
dumps with this idea.</p>
<p>You could also have it so that eating a bug makes you shrink and
moving so many moves you grow. I tried this and for me it was far more
fun. The <a href="play.sh">play.sh</a> also has this mode:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="va">SHEDS</span><span class="op">=</span>5 <span class="va">GROW</span><span class="op">=</span>-10 <span class="va">SHED</span><span class="op">=</span>50 <span class="va">MAXSIZE</span><span class="op">=</span>250 <span class="ex">./prog</span></span></code></pre></div>
<p>Obviously there are many other variations. The <a
href="play.sh">play.sh</a> script has some of them (the above is option
5; others are 4, 15 and 16 but only options 4 and 5 are called Grow /
Shrink).</p>
<h2
id="hypnotic-sleepy-mode-photosensitive-epilepsystimulation-overload-trigger"><a name="hypnotic" href="#toc">Hypnotic
/ Sleepy mode (<strong>Photosensitive epilepsy/Stimulation overload
trigger</strong>)</a></h2>
<p><strong>Photosensitive epilepsy/stimulation overload trigger
warning:</strong> For those who have epilepsy or are susceptible to
stimulation overload from flashing lights and patterns please do be
careful with this mode. Depending on your susceptibility this could very
well trigger seizures or other discomforts and I wouldn’t want that to
happen to anyone. The default wait time is 231ms, the typical range of
seizures is 3 to 30 flashes per seconds (but can be higher) and that
means that at <strong>EVADE=1</strong> every 231ms there will be a flash
in addition to the snake moving too.</p>
<p>Anyway this might sound absurd but it can be somewhat hypnotic by
doing:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="va">EVADE</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>And just moving the snake about not trying to catch any bugs - just
let whatever happens happen.</p>
<h2
id="gameplay-mode-stimulation-calming-mode"><a name="stim" href="#toc">Gameplay
mode: Stimulation / Calming mode</a></h2>
<p>If you just need something to stimulate your mind to keep you calm or
simply you want to play a game without having to worry about winning or
losing you can set the growth size to 0 and then just move the snake
round and round eating bugs until you want to quit. You can enable
cannibalism so that you don’t have to worry about even running into
yourself and losing:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="va">GROW</span><span class="op">=</span>0 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<h2
id="gameplay-mode-expansibility"><a name="expansibility" href="#toc">Gameplay
mode: Expansibility</a></h2>
<p>As I was writing this document and the game modes I have thought of
other game modes (they were added) and I have come back to this document
to add more modes. That’s the beauty of the variables I have
implemented: together with the imagination and even just chance
different modes of play can be devised. The drawing mode was a happy
chance of how the <code>timeout()</code> function works for example.</p>
<p>As a person who was heavily involved in MUD development and design I
know very well how games need to be fun and have different options, not
be too easy but not be too hard either. And a game developer who does
not play their games is a game developer who is detached from their
player base and the wants and needs are therefore disregarded if even
heard. I have played this game a lot for this reason as well as I simply
enjoy it and thinking up new modes.</p>
<p>You could also have it so that eating a bug makes you shrink and moving so many
moves you grow. I tried this and for me it was far more fun. The <a href="play.sh">play.sh</a>
also has this mode:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>100 <span class="va">SHEDS</span><span class="op">=</span>5 <span class="va">GROW</span><span class="op">=</span>-10 <span class="va">SHED</span><span class="op">=</span>50 <span class="va">MAXSIZE</span><span class="op">=</span>250 <span class="ex">./prog</span></span></code></pre></div>
<p>Obviously there are many other variations. The <a href="play.sh">play.sh</a> script has some
of them (the above is option 5; others are 4, 15 and 16 but only options 4 and 5
are called Grow / Shrink).</p>
<h2 id="hypnotic-sleepy-mode-photosensitive-epilepsystimulation-overload-trigger"><a name="hypnotic" href="#toc">Hypnotic / Sleepy mode (<strong>Photosensitive epilepsy/Stimulation overload trigger</strong>)</a></h2>
<p><strong>Photosensitive epilepsy/stimulation overload trigger warning:</strong>
For those who have epilepsy or are susceptible to stimulation overload from
flashing lights and patterns please do be careful with this mode. Depending on your
susceptibility this could very well trigger seizures or other discomforts and I
wouldn’t want that to happen to anyone. The default wait time is 231ms, the
typical range of seizures is 3 to 30 flashes per seconds (but can be higher) and
that means that at <strong>EVADE=1</strong> every 231ms there will be a flash in addition to the
snake moving too.</p>
<p>Anyway this might sound absurd but it can be somewhat hypnotic by doing:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="va">EVADE</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<p>And just moving the snake about not trying to catch any bugs - just let whatever
happens happen.</p>
<h2 id="gameplay-mode-stimulation-calming-mode"><a name="stim" href="#toc">Gameplay mode: Stimulation / Calming mode</a></h2>
<p>If you just need something to stimulate your mind to keep you calm or simply you
want to play a game without having to worry about winning or losing you can set
the growth size to 0 and then just move the snake round and round eating bugs
until you want to quit. You can enable cannibalism so that you don’t have to
worry about even running into yourself and losing:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="va">GROW</span><span class="op">=</span>0 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./prog</span></span></code></pre></div>
<h2 id="gameplay-mode-expansibility"><a name="expansibility" href="#toc">Gameplay mode: Expansibility</a></h2>
<p>As I was writing this document and the game modes I have thought of other game
modes (they were added) and I have come back to this document to add more modes.
That’s the beauty of the variables I have implemented: together with the
imagination and even just chance different modes of play can be devised. The
drawing mode was a happy chance of how the <code>timeout()</code> function works for
example.</p>
<p>As a person who was heavily involved in MUD development and design I know very
well how games need to be fun and have different options, not be too easy but
not be too hard either. And a game developer who does not play their games is a
game developer who is detached from their player base and the wants and needs
are therefore disregarded if even heard. I have played this game a lot for this
reason as well as I simply enjoy it and thinking up new modes.</p>
<h1 id="scripts">5. <a name="scripts" href="#toc">Scripts</a></h1>
<p>The following scripts are provided to simplify and automate some of
the things this file discusses as well as allowing to easily change the
colours.</p>
<h2
id="colours-selection-snake-colours"><a name="colours" href="#toc">Colours
selection: snake-colours</a></h2>
<p>To do this use the <a href="snake-colours">snake-colours</a> script
like so:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./snake-colours</span></span></code></pre></div>
<p>If you want to pass in specific variables you can do that too
e.g.:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./snake-colours</span></span></code></pre></div>
<p>The script will prompt you for the colour of the walls, snake head,
body and the bug.</p>
<h2
id="automate-the-above-gameplay-modes"><a name="preset" href="#toc">Automate
the above gameplay modes</a></h2>
<p>The <a href="play.sh">play.sh</a> script has the gameplay modes
described in this file and is menu based (there might be differences and
some of the modes I include a variation). The script tests the terminal
(allowing you to continue even if problems are detected), prompts you if
you want to select colours (like those in snake-colours above) and then
gives you a list of game modes to play. You can pass in the game
variables but note that if you pass in a variable that the mode you
choose uses then the script will override what you pass in.</p>
<p>The following scripts are provided to simplify and automate some of the things
this file discusses as well as allowing to easily change the colours.</p>
<h2 id="colours-selection-snake-colours"><a name="colours" href="#toc">Colours selection: snake-colours</a></h2>
<p>To do this use the <a href="snake-colours">snake-colours</a> script like so:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./snake-colours</span></span></code></pre></div>
<p>If you want to pass in specific variables you can do that too e.g.:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="ex">./snake-colours</span></span></code></pre></div>
<p>The script will prompt you for the colour of the walls, snake head, body and the
bug.</p>
<h2 id="automate-the-above-gameplay-modes"><a name="preset" href="#toc">Automate the above gameplay modes</a></h2>
<p>The <a href="play.sh">play.sh</a> script has the gameplay modes described in this file and is menu
based (there might be differences and some of the modes I include a variation).
The script tests the terminal (allowing you to continue even if problems are
detected), prompts you if you want to select colours (like those in
snake-colours above) and then gives you a list of game modes to play. You can
pass in the game variables but note that if you pass in a variable that the mode
you choose uses then the script will override what you pass in.</p>
<p>To use you can do something like:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./play.sh</span></span></code></pre></div>
<div class="sourceCode" id="cb35"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./play.sh</span></span></code></pre></div>
<p>Or to make it so walls are an obstacle:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>0 <span class="ex">./play.sh</span></span></code></pre></div>
<h1 id="notes-about-some-of-the-game-variables">6.
<a name="variables" href="#toc">Notes about some of the game
variables</a></h1>
<p>The game variables can be used for a variety of things including
different gameplay modes (as shown above) but here are some general
notes about a few of them.</p>
<h2 id="wait-snake-speed"><a name="wait" href="#toc">WAIT: Snake
speed</a></h2>
<p>Besides the different game modes, if you find it too fast/slow you
can change it to a value that’s better for you. Remember it’s a wait
time so if you want the snake to move slower you have to increase the
wait time!</p>
<h2 id="evade-bug-evasion-frequency"><a name="evade" href="#toc">EVADE:
Bug evasion frequency</a></h2>
<p>For every <strong><code>EVADE</code></strong> snake movements the bug
will try and find a new place to occupy. It might be very close to it
and I do not ensure it’s a new place at all.</p>
<p>Each time the bug is placed the counter will be reset whether from
eating the bug or not reaching it in time. Default 300 moves.</p>
<p>This can help you get out of a trap but it can also sometimes make it
harder.</p>
<h2
id="size-maxsize-initial-max-snake-sizes"><a name="sizes" href="#toc">SIZE
/ MAXSIZE: Initial / Max snake sizes</a></h2>
<p>997 might be a bit high for many people. Or maybe you don’t have
enough time. Or you’re not in the mood to lose. Or you want to get close
to a size you were last time but quickly. It might be in conjunction
with drawing mode.</p>
<p>Note on snake size: there’s a stated size (in the score line) which
is what the snake will ‘populate’ in the snake arrays and the visible
size: as I have discussed here and there the snake doesn’t grow
immediately so it takes time before the snake is visibly that many
characters. In other words just because it says SIZE 29 doesn’t mean it
will instantly be 29 characters on the screen.</p>
<h2
id="grow-sheds-growth-shedding-sizes"><a name="growth" href="#toc">GROW
/ SHEDS : Growth / Shedding sizes</a></h2>
<p>Similar to the initial size. Notice that the above point on size
applies here: it will take the number of movements before it is ‘its
full size’.</p>
<h1 id="conclusion-and-inspirational-words-for-everyone">7.
<a name="conclusions" href="#toc">Conclusion (and inspirational words
for everyone)</a></h1>
<p>I believe that this file has given more than enough information for
anyone to get an idea of what is possible with my implementation of
Snake. I realise also that most people won’t have read this far and
that’s quite all right; I’m very thorough and pay attention to details
obsessively. Creating this game was a delight and I am quite proud of
what I have done.</p>
<p>Thank you for whatever level of attention you felt you could or
wanted to give and enjoy it in whatever way you see fit!</p>
<p><strong>Much more importantly is that Snake aside I hope I have
demonstrated how with the imagination and creativity almost anything is
possible.</strong> This is something <strong>that applies in our world
in every way and <em>everyone</em> can do something amazing if they
believe in themselves!</strong> I would have never thought this the case
for me years ago but I know it’s true now. <strong>Believe in yourself.
Always.</strong></p>
<div class="sourceCode" id="cb36"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>0 <span class="ex">./play.sh</span></span></code></pre></div>
<h1 id="notes-about-some-of-the-game-variables">6. <a name="variables" href="#toc">Notes about some of the game variables</a></h1>
<p>The game variables can be used for a variety of things including different
gameplay modes (as shown above) but here are some general notes about a few of them.</p>
<h2 id="wait-snake-speed"><a name="wait" href="#toc">WAIT: Snake speed</a></h2>
<p>Besides the different game modes, if you find it too fast/slow you can change it
to a value that’s better for you. Remember it’s a wait time so if you want the
snake to move slower you have to increase the wait time!</p>
<h2 id="evade-bug-evasion-frequency"><a name="evade" href="#toc">EVADE: Bug evasion frequency</a></h2>
<p>For every <strong><code>EVADE</code></strong> snake movements the bug will try and find a new place to
occupy. It might be very close to it and I do not ensure it’s a new place at
all.</p>
<p>Each time the bug is placed the counter will be reset whether from eating the
bug or not reaching it in time. Default 300 moves.</p>
<p>This can help you get out of a trap but it can also sometimes make it harder.</p>
<h2 id="size-maxsize-initial-max-snake-sizes"><a name="sizes" href="#toc">SIZE / MAXSIZE: Initial / Max snake sizes</a></h2>
<p>997 might be a bit high for many people. Or maybe you don’t have enough time. Or
you’re not in the mood to lose. Or you want to get close to a size you were last
time but quickly. It might be in conjunction with drawing mode.</p>
<p>Note on snake size: there’s a stated size (in the score line) which is what
the snake will ‘populate’ in the snake arrays and the visible size: as I have
discussed here and there the snake doesn’t grow immediately so it takes time
before the snake is visibly that many characters. In other words just because it
says SIZE 29 doesn’t mean it will instantly be 29 characters on the screen.</p>
<h2 id="grow-sheds-growth-shedding-sizes"><a name="growth" href="#toc">GROW / SHEDS : Growth / Shedding sizes</a></h2>
<p>Similar to the initial size. Notice that the above point on size applies here:
it will take the number of movements before it is ‘its full size’.</p>
<h1 id="conclusion-and-inspirational-words-for-everyone">7. <a name="conclusions" href="#toc">Conclusion (and inspirational words for everyone)</a></h1>
<p>I believe that this file has given more than enough information for anyone to
get an idea of what is possible with my implementation of Snake. I realise also
that most people won’t have read this far and that’s quite all right; I’m very
thorough and pay attention to details obsessively. Creating this game was a
delight and I am quite proud of what I have done.</p>
<p>Thank you for whatever level of attention you felt you could or wanted to give
and enjoy it in whatever way you see fit!</p>
<p><strong>Much more importantly is that Snake aside I hope I have demonstrated how with
the imagination and creativity almost anything is possible.</strong> This is something
<strong>that applies in our world in every way and <em>everyone</em> can do something amazing if
they believe in themselves!</strong> I would have never thought this the case for me
years ago but I know it’s true now. <strong>Believe in yourself. Always.</strong></p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr class="odd">
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt
Noll][judges] - All rights reserved This work is licensed under a
[Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
</tr>
<tr class="even">
<td>[judges]: https://www.ioccc.org/judges.html [cc]:
http://creativecommons.org/licenses/by-sa/3.0/</td>
<td>[judges]: https://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/</td>
</tr>
</tbody>
</table>
+390 -572
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+146 -193
View File
@@ -121,18 +121,15 @@
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1 id="terminals">Terminals</h1>
<p>Terminals are very easy to mess up and for that reason they deserve
their own file. I discuss terminal capabilities, dimensions (setting and
how to restore sanity if it causes any problems) as well as colours
(limitations etc.).</p>
<p>Terminals are very easy to mess up and for that reason they deserve their own
file. I discuss terminal capabilities, dimensions (setting and how to restore
sanity if it causes any problems) as well as colours (limitations etc.).</p>
<p><a name="toc"></a></p>
<ul>
<li><p><a href="#termcaps">Capabilities support testing
program</a></p></li>
<li><p><a href="#termcaps">Capabilities support testing program</a></p></li>
<li><p><a href="#dimensions">Setting the game dimensions</a></p>
<ul>
<li><p><a href="#linescolumns">The LINES and COLUMNS environmental
variables</a></p></li>
<li><p><a href="#linescolumns">The LINES and COLUMNS environmental variables</a></p></li>
<li><p><a href="#insanity">Terminal insanity</a></p></li>
<li><p><a href="#restore">Restoring the terminal</a></p></li>
<li><p><a href="#abuse">Terminal size abuse</a></p></li>
@@ -146,18 +143,14 @@ variables</a></p></li>
<li><p><a href="#disablecolour">Disabling colour</a></p></li>
</ul></li>
</ul>
<h1
id="capabilities-support-testing-program"><a name="termcaps" href="#toc">Capabilities
support testing program</a></h1>
<p>Although it should be playable without the features I use (except
that cursor movement is required) I have provided a source file that can
test your terminal for the capabilities I use in the entry.</p>
<p>It also tries to determine the minimum number of columns to play
without the status line overflowing - even with the dynamic length.
Try:</p>
<h1 id="capabilities-support-testing-program"><a name="termcaps" href="#toc">Capabilities support testing program</a></h1>
<p>Although it should be playable without the features I use (except that cursor
movement is required) I have provided a source file that can test your terminal
for the capabilities I use in the entry.</p>
<p>It also tries to determine the minimum number of columns to play without the
status line overflowing - even with the dynamic length. Try:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> make test</span></code></pre></div>
<p>This compiles the program <a href="termcaps.c">termcaps.c</a> and
runs it; you should see something like:</p>
<p>This compiles the program <a href="termcaps.c">termcaps.c</a> and runs it; you should see something like:</p>
<pre><code>terminal supports cursor movement
terminal supports making cursor invisible
terminal supports bold
@@ -173,20 +166,16 @@ at least 34 columns (currently 155) recommended for snake size 997
at least 37 columns (currently 155) recommended for capped snake size 5776
No problems detected.</code></pre>
<p>Terminal rows and cols are the current values (the number of columns
shown later as well). The snake size is the default size to win (based
on the variables, see below). The <code>max size: 5776</code> is the
capped size (or ‘capsize’). The 199 bugs is approximately the
<code>snake_size / growth_size</code> i.e. how many bugs it will take to
win the game. The max bugs in the <code>bugs</code> line is
approximately <code>max_snake_size / growth_size</code> i.e. how many
bugs it’ll take to win at the maximum (capped) snake size.</p>
<p>If I pass in any of the variables <strong><code>GROW</code></strong>,
<strong><code>MAXSIZE</code></strong>,
<strong><code>SIZE</code></strong> and/or
<strong><code>LINES</code></strong> or
<strong><code>COLUMNS</code></strong> it bases its calculations on those
variables. For example:</p>
<p>Terminal rows and cols are the current values (the number of columns shown later
as well). The snake size is the default size to win (based on the variables, see
below). The <code>max size: 5776</code> is the capped size (or ‘capsize’). The 199 bugs is
approximately the <code>snake_size / growth_size</code> i.e. how many bugs it
will take to win the game. The max bugs in the <code>bugs</code> line is approximately
<code>max_snake_size / growth_size</code> i.e. how many bugs it’ll take to win at the
maximum (capped) snake size.</p>
<p>If I pass in any of the variables <strong><code>GROW</code></strong>, <strong><code>MAXSIZE</code></strong>, <strong><code>SIZE</code></strong> and/or
<strong><code>LINES</code></strong> or <strong><code>COLUMNS</code></strong> it bases its calculations on those variables. For
example:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports cursor movement</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports making cursor invisible</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ex">terminal</span> supports bold</span>
@@ -202,76 +191,64 @@ variables. For example:</p>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="ex">at</span> least 37 columns <span class="er">(</span><span class="ex">currently</span> 155<span class="kw">)</span> <span class="ex">recommended</span> for capped snake size 5776</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="ex">No</span> problems detected.</span></code></pre></div>
<p>As you can see it tells you the max size (the ‘capsized’ snake) as
well as the requested max size (if the requested size is bigger than the
capped size then it will be set to that value instead) of the snake. The
capped size is like in the Snake game itself but the suggested minimum
number of columns is based on a number of variables.</p>
<p>If I were to do the above but set columns to less &lt; 35 then there
would be a problem. But why if the utility recommends at least 37? This
is because the max size of the snake also depends on the terminal size.
This utility is not perfect: I don’t consider shedding; I set growth to
5 if it’s 0 (since it would be indeterminate how many bugs are possible
before ‘winning’ since there would be no ‘winning’); and there are
probably other things too.</p>
<p>As for capabilities: besides cursor movement the others are just nice
to have. From my tests keeping the cursor visible doesn’t ruin gameplay
but it is less distracting if nothing else to have it invisible (in fact
due to the sequence of function calls the cursor would mostly appear to
be not in the game field itself - from memory at least).</p>
<p>Maybe there are other capabilities I should check for that I’m
unaware of but this should give you an idea.</p>
<p>If there are any problems it will say how many (fatal and otherwise).
The fatal problems are if curses fails to initialise or if movement of
cursor cannot be done (both seem unlikely to happen nowadays).</p>
<p>As you can see it tells you the max size (the ‘capsized’ snake) as well as the
requested max size (if the requested size is bigger than the capped size then it
will be set to that value instead) of the snake. The capped size is like in the
Snake game itself but the suggested minimum number of columns is based on a
number of variables.</p>
<p>If I were to do the above but set columns to less &lt; 35 then there would be a
problem. But why if the utility recommends at least 37? This is because the
max size of the snake also depends on the terminal size. This utility is not
perfect: I don’t consider shedding; I set growth to 5 if it’s 0 (since it would
be indeterminate how many bugs are possible before ‘winning’ since there would
be no ‘winning’); and there are probably other things too.</p>
<p>As for capabilities: besides cursor movement the others are just nice to have.
From my tests keeping the cursor visible doesn’t ruin gameplay but it is less
distracting if nothing else to have it invisible (in fact due to the sequence of
function calls the cursor would mostly appear to be not in the game field itself -
from memory at least).</p>
<p>Maybe there are other capabilities I should check for that I’m unaware of but
this should give you an idea.</p>
<p>If there are any problems it will say how many (fatal and otherwise). The fatal
problems are if curses fails to initialise or if movement of cursor cannot be
done (both seem unlikely to happen nowadays).</p>
<p>Both scripts run this utility and prompt if there are any problems;
you can continue either way.</p>
<h1
id="setting-the-game-dimensions"><a name="dimensions" href="#toc">Setting
the game dimensions</a></h1>
<p>There are a number of ways to do this and only one will keep the
terminal sane all the time but that’s by running it under a terminal
emulator that you can resize the window with first. But what if you want
exacts?</p>
<h2
id="the-lines-and-columns-environmental-variables"><a name="linescolumns" href="#toc">The
LINES and COLUMNS environmental variables</a></h2>
<p>To specify the lines/columns of curses program per instance use the
<code>LINES</code> and <code>COLUMNS</code> environmental variables.</p>
<h1 id="setting-the-game-dimensions"><a name="dimensions" href="#toc">Setting the game dimensions</a></h1>
<p>There are a number of ways to do this and only one will keep the terminal sane
all the time but that’s by running it under a terminal emulator that you can
resize the window with first. But what if you want exacts?</p>
<h2 id="the-lines-and-columns-environmental-variables"><a name="linescolumns" href="#toc">The LINES and COLUMNS environmental variables</a></h2>
<p>To specify the lines/columns of curses program per instance use the <code>LINES</code> and
<code>COLUMNS</code> environmental variables.</p>
<p>For demonstration consider the following:</p>
<pre><code> $ echo $LINES $COLUMNS
42 157</code></pre>
<p>Note: I subtract 1 from the max y/x and the max coords in the game
output include the walls and score line but these values are for the
terminal itself.</p>
<p>Note: I subtract 1 from the max y/x and the max coords in the game output
include the walls and score line but these values are for the terminal itself.</p>
<p>Say you want 55 columns:</p>
<pre><code> $ COLUMNS=55 ./prog</code></pre>
<p>This will force curses to detect the max columns (X) of your terminal
(for the game dimensions) - to be 55; it might look like this
instead:</p>
<p>This will force curses to detect the max columns (X) of your terminal (for the
game dimensions) - to be 55; it might look like this instead:</p>
<pre><code> X:27/54 Y:20/41 S:5/997 B:0</code></pre>
<p>But problems can arise with messing with dimensions: in my tests this
held only to lines.</p>
<h2 id="terminal-insanity"><a name="insanity" href="#toc">Terminal
insanity</a></h2>
<p>Terminal sanity can be compromised and it can cause all sorts of
output problems; it might not appear right away but it will show its
ugly head eventually if you use it. For example pager output might be
screwy, echo might be turned off, output of commands might overwrite the
input of those commands, etc. For the game you might not see the final
score.</p>
<h3 id="restoring-the-terminal"><a name="restore" href="#toc">Restoring
the terminal</a></h3>
<p>In my tests there is one thing that at least allows you to see the
final score and that is by running <code>clear</code> before running the
program. That’s what the prog.alt version does. You might run it as one
of:</p>
<p>But problems can arise with messing with dimensions: in my tests this held only
to lines.</p>
<h2 id="terminal-insanity"><a name="insanity" href="#toc">Terminal insanity</a></h2>
<p>Terminal sanity can be compromised and it can cause all sorts of output
problems; it might not appear right away but it will show its ugly head
eventually if you use it. For example pager output might be screwy, echo might
be turned off, output of commands might overwrite the input of those commands,
etc. For the game you might not see the final score.</p>
<h3 id="restoring-the-terminal"><a name="restore" href="#toc">Restoring the terminal</a></h3>
<p>In my tests there is one thing that at least allows you to see the final score
and that is by running <code>clear</code> before running the program. That’s what the
prog.alt version does. You might run it as one of:</p>
<pre><code> LINES=20 ./prog.alt
LINES=20 ./snake.alt</code></pre>
<p>Even if the final score is visible though the terminal may very well
still be messed up. There are numerous things you might try but probably
the easiest is to run the game again without modifying the dimensions
(and then just quit) or even just the <code>reset</code> command.</p>
<p>Even if the final score is visible though the terminal may very well still be
messed up. There are numerous things you might try but probably the easiest is
to run the game again without modifying the dimensions (and then just quit) or
even just the <code>reset</code> command.</p>
<p>The Linux man page says:</p>
<pre><code>You might have to run the `reset` tool like:
@@ -281,77 +258,59 @@ the easiest is to run the game again without modifying the dimensions
to work, as carriage-return may no longer work in the abnormal state.</code></pre>
<p>If you don’t have the reset utility you can try:</p>
<pre><code> echo -e \\033c</code></pre>
<p>Otherwise try <code>clear; stty sane</code> (that will turn on echo
also) or if all else fails log out and back in.</p>
<p>For more information on this subject generally see the <a
href="https://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO.html">Linux
keyboard and console HOWTO</a> (specifically <a
href="https://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-4.html">Linux
keyboard and console HOWTO section 4</a>). Yes this works under macOS
(at least it did for me).</p>
<h3 id="terminal-size-abuse"><a name="abuse" href="#toc">Terminal size
abuse</a></h3>
<p>So players 1, 2 and 3 are content with not meddling with the terminal
sizes outside what’s actually possible with their screen. But then
player 4 comes along and thinks he/she will be clever and mess with the
dimensions a bit. Let’s say they have a 13” monitor and they think it’d
be funny to see how 997 lines would work; they might try something
like:</p>
<p>Otherwise try <code>clear; stty sane</code> (that will turn on echo also) or if all else
fails log out and back in.</p>
<p>For more information on this subject generally see the <a href="https://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO.html">Linux keyboard and
console HOWTO</a> (specifically <a href="https://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-4.html">Linux keyboard and console HOWTO section 4</a>).
Yes this works under macOS (at least it did for me).</p>
<h3 id="terminal-size-abuse"><a name="abuse" href="#toc">Terminal size abuse</a></h3>
<p>So players 1, 2 and 3 are content with not meddling with the terminal sizes
outside what’s actually possible with their screen. But then player 4 comes
along and thinks he/she will be clever and mess with the dimensions a bit. Let’s
say they have a 13” monitor and they think it’d be funny to see how 997 lines
would work; they might try something like:</p>
<pre><code> LINES=997 ./prog</code></pre>
<p>What then? Well expect trouble; curses will not know any better and
the max number of lines will be 997. If they were to do:</p>
<p>What then? Well expect trouble; curses will not know any better and the max
number of lines will be 997. If they were to do:</p>
<pre><code> COLUMNS=997 ./prog</code></pre>
<p>Then they will see a different effect. Again the same reason: the
player trying to be funny.</p>
<p>The game will try and be funny in return and you can expect it to not
function properly. Because that’s what funny means in this context.</p>
<h1
id="terminal-limitations"><a name="termlimitations" href="#toc">Terminal
limitations</a></h1>
<p>It’d be nice if curses could detect hitting more than one arrow key
at the same time so that diagonal directions would be possible but
unfortunately it’s not (<code>cat -v</code> confirms this). Even if I
were to define four extra keys what would they be? And what about the
head character? The <a href="HACKING.html">HACKING.html</a> (<a
href="HACKING.md">HACKING</a> on GitHub) file has information on
this.</p>
<p>I also limit the terminal size to 10 lines/columns but most likely it
would require the cheat modes to win and in any event allowing certain
low values causes problems e.g. <strong>LINES=6 COLUMNS=6</strong> and
<strong>LINES=3 COLUMNS=3</strong> caused some nasty issues.</p>
<h1 id="terminal-colours"><a name="colours" href="#toc">Terminal
colours</a></h1>
<p>N.B.: If all you’re after is wanting to change the colours see the
script <a href="snake-colours.sh">snake-colours.sh</a> instead. The rest
of this file was mostly notes for the judges; here I discuss the
background, foreground as well as limitations (in particular runtime
limitations).</p>
<h2 id="curses-background"><a name="background" href="#toc">Curses
background</a></h2>
<p>The documentation I have seen says that the background will always be
black and from a quick test this holds even with a terminal that has a
white background. There is a way to force the background to remain white
though that’s by way of monochrome (so no colours); I discuss that and
another related terminal specific in the troubleshooting guide (there’s
another way but it would take me over the iocccsize; I talk about it in
the <a href="HACKING.html">HACKING.html</a> (<a
href="HACKING.md">HACKING</a> on GitHub) file).</p>
<h2
id="monochrome-terminals"><a name="monochrome" href="#toc">Monochrome
terminals</a></h2>
<p>According to my tests for monochrome terminals the screen has the
white and black background; if terminal is configured to be black
background white foreground that is the order it is too. You can try
that like:</p>
<p>Then they will see a different effect. Again the same reason: the player trying
to be funny.</p>
<p>The game will try and be funny in return and you can expect it to not function
properly. Because that’s what funny means in this context.</p>
<h1 id="terminal-limitations"><a name="termlimitations" href="#toc">Terminal limitations</a></h1>
<p>It’d be nice if curses could detect hitting more than one arrow key at the
same time so that diagonal directions would be possible but unfortunately it’s
not (<code>cat -v</code> confirms this). Even if I were to define four extra keys what
would they be? And what about the head character? The <a href="HACKING.html">HACKING.html</a>
(<a href="HACKING.md">HACKING</a> on GitHub) file has information on this.</p>
<p>I also limit the terminal size to 10 lines/columns but most likely it would
require the cheat modes to win and in any event allowing certain low values
causes problems e.g. <strong>LINES=6 COLUMNS=6</strong> and <strong>LINES=3 COLUMNS=3</strong> caused some
nasty issues.</p>
<h1 id="terminal-colours"><a name="colours" href="#toc">Terminal colours</a></h1>
<p>N.B.: If all you’re after is wanting to change the colours see the script
<a href="snake-colours.sh">snake-colours.sh</a> instead. The rest of this file was mostly notes for the
judges; here I discuss the background, foreground as well as limitations (in
particular runtime limitations).</p>
<h2 id="curses-background"><a name="background" href="#toc">Curses background</a></h2>
<p>The documentation I have seen says that the background will always be black and
from a quick test this holds even with a terminal that has a white background.
There is a way to force the background to remain white though that’s by way of
monochrome (so no colours); I discuss that and another related terminal specific
in the troubleshooting guide (there’s another way but it would take me over the
iocccsize; I talk about it in the <a href="HACKING.html">HACKING.html</a> (<a href="HACKING.md">HACKING</a> on
GitHub) file).</p>
<h2 id="monochrome-terminals"><a name="monochrome" href="#toc">Monochrome terminals</a></h2>
<p>According to my tests for monochrome terminals the screen has the white and
black background; if terminal is configured to be black background white
foreground that is the order it is too. You can try that like:</p>
<pre><code> TERM=linux-m ./prog</code></pre>
<p>But I do not specifically check if the terminal has colours. Is there
a curses implementation that has a problem here? Below I explain what to
comment out should you need colours to be disabled but I personally have
not run into any problems even with monochrome terminals. Later I say
what to do to remove colour support in the source code itself.</p>
<h2
id="colour-limitations"><a name="colourlimitations" href="#toc">Colour
limitations</a></h2>
<p>But I do not specifically check if the terminal has colours. Is there a curses
implementation that has a problem here? Below I explain what to comment out
should you need colours to be disabled but I personally have not run into any
problems even with monochrome terminals. Later I say what to do to remove colour
support in the source code itself.</p>
<h2 id="colour-limitations"><a name="colourlimitations" href="#toc">Colour limitations</a></h2>
<p>According to X/Open Curses, Issue 7 (pg. 57):</p>
<pre><code>With init_pair() and pair_content(), the value of pair must be in a range
from 0 to and including COLOR_PAIRS-1. (There may be an
@@ -364,10 +323,9 @@ including COLORS-1.</code></pre>
[...]
COLOR_PAIRS corresponds to the terminal database&#39;s max_pairs capability, (see terminfo(5)).</code></pre>
<p>Based on the two as well as the fact that monochrome terminals (I’ve
tried under both Linux and macOS) seem to work fine I believe I am fine
here too. And to confirm this I wrote the following code with the output
below:</p>
<p>Based on the two as well as the fact that monochrome terminals (I’ve tried under
both Linux and macOS) seem to work fine I believe I am fine here too. And to
confirm this I wrote the following code with the output below:</p>
<pre><code> #include &lt;curses.h&gt;
int main()
@@ -385,11 +343,10 @@ below:</p>
<p>Without specifying the TERM I get:</p>
<pre><code> COLORS: 256
COLOR_PAIRS: 32767</code></pre>
<p>In the case that colour is supported the standard states that there
will be more possible colour pairs than I have used so that’s not a
problem either. Perhaps even it would only be a runtime error if the
colours are supported and the number is out of the range? To try and
figure this out I did another test:</p>
<p>In the case that colour is supported the standard states that there will be more
possible colour pairs than I have used so that’s not a problem either. Perhaps
even it would only be a runtime error if the colours are supported and the
number is out of the range? To try and figure this out I did another test:</p>
<pre><code> int main()
{
initscr();
@@ -406,39 +363,35 @@ figure this out I did another test:</p>
}</code></pre>
<p>Running it like</p>
<pre><code> TERM=linux-m ./colour_pairs</code></pre>
<p>I got the output as if colours weren’t used: 0 and 0. With coloured
terminals however it was not visible. If I however comment out the call
to <code>bkgd()</code> I get instead:</p>
<p>I got the output as if colours weren’t used: 0 and 0. With coloured terminals
however it was not visible. If I however comment out the call to <code>bkgd()</code> I get
instead:</p>
<pre><code> COLORS: 256
COLOR_PAIRS: 32767</code></pre>
<p>Which leads me to believe that if you try using a value outside the
range it won’t work for a colour-capable terminal but it doesn’t matter
for monochrome terminals one way or another. And since I don’t go beyond
the ranges (as I cited earlier) there shouldn’t be any problem here.</p>
<h2 id="disabling-colour"><a name="disablecolour" href="#toc">Disabling
colour</a></h2>
<p>Nevertheless if it is a problem and you don’t want to use a
monochrome terminal (or can’t):</p>
<p>First comment out the code that has <code>start_color();</code> and
then add <code>return;</code> to the top of the <code>C()</code>
function (the rest of the code won’t be reached). If necessary you can
also comment out the <code>init_pair()</code> calls.</p>
<p>Perhaps you only need to add the <code>return;</code> to
<code>C()</code>. My guess is that’s the case but I do not know for
certain.</p>
<p>Which leads me to believe that if you try using a value outside the range it
won’t work for a colour-capable terminal but it doesn’t matter for monochrome
terminals one way or another. And since I don’t go beyond the ranges (as I cited
earlier) there shouldn’t be any problem here.</p>
<h2 id="disabling-colour"><a name="disablecolour" href="#toc">Disabling colour</a></h2>
<p>Nevertheless if it is a problem and you don’t want to use a monochrome terminal
(or can’t):</p>
<p>First comment out the code that has <code>start_color();</code> and then add <code>return;</code> to the
top of the <code>C()</code> function (the rest of the code won’t be reached). If necessary
you can also comment out the <code>init_pair()</code> calls.</p>
<p>Perhaps you only need to add the <code>return;</code> to <code>C()</code>. My guess is that’s the case
but I do not know for certain.</p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr class="odd">
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt
Noll][judges] - All rights reserved This work is licensed under a
[Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
</tr>
<tr class="even">
<td>[judges]: https://www.ioccc.org/judges.html [cc]:
http://creativecommons.org/licenses/by-sa/3.0/</td>
<td>[judges]: https://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/</td>
</tr>
</tbody>
</table>
+239 -318
View File
@@ -121,183 +121,149 @@
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1 id="troubleshooting-snake">Troubleshooting Snake</h1>
<p>In this file I have a list of a number of possible problems that
could show up under some situations as well as some things that might
appear to be happening or be a problem but actually are not. For each
one I have included a summary, a more thorough description and any
resolutions (from easiest to hardest). For anything that can cause more
than one issue I will list those separately to keep it as structured as
possible/easiest to find.</p>
<p><a name="toc"></a> - <a href="#topwall">The top wall isn’t (all/some
of the time) visible!</a></p>
<p>In this file I have a list of a number of possible problems that could show up
under some situations as well as some things that might appear to be happening
or be a problem but actually are not. For each one I have included a summary, a
more thorough description and any resolutions (from easiest to hardest). For
anything that can cause more than one issue I will list those separately to keep
it as structured as possible/easiest to find.</p>
<p><a name="toc"></a>
- <a href="#topwall">The top wall isn’t (all/some of the time) visible!</a></p>
<ul>
<li><p><a href="#notmoving">The snake isn’t moving!</a></p></li>
<li><p><a href="#invisiblehead">I can’t see the snake head (or other
part of the snake)!</a></p></li>
<li><p><a href="#invisiblehead">I can’t see the snake head (or other part of the snake)!</a></p></li>
<li><p><a href="#invisiblebug">I can’t see the bug!</a></p></li>
<li><p><a href="#froze">The game froze!</a></p></li>
<li><p><a href="#bigsnake">The game gets slower as the snake gets
bigger!</a></p></li>
<li><p><a href="#headonly">I set SIZE=0 GROW=1, ate a bug but still only
the head was visible! Why?</a></p></li>
<li><p><a href="#monochrome">I like black text on a white background but
even with a white background terminal it ends up black!</a></p></li>
<li><p><a href="#toodark">The text is hard to see (not bright
enough)!</a></p></li>
<li><p><a href="#movefaster">Can I move the snake faster temporarily
without having to modify the wait time?</a></p></li>
<li><p><a href="#envvars">On environmental variables more generally and
string to int conversions</a></p></li>
<li><p><a href="#bigsnake">The game gets slower as the snake gets bigger!</a></p></li>
<li><p><a href="#headonly">I set SIZE=0 GROW=1, ate a bug but still only the head was visible! Why?</a></p></li>
<li><p><a href="#monochrome">I like black text on a white background but even with a white background terminal it ends up black!</a></p></li>
<li><p><a href="#toodark">The text is hard to see (not bright enough)!</a></p></li>
<li><p><a href="#movefaster">Can I move the snake faster temporarily without having to modify the wait time?</a></p></li>
<li><p><a href="#envvars">On environmental variables more generally and string to int conversions</a></p></li>
<li><p><a href="#errors">Errors and error reporting</a></p></li>
</ul>
<h2
id="the-top-wall-isnt-allsome-of-the-time-visible"><a name="topwall" href="#toc">The
top wall isn’t (all/some of the time) visible!</a></h2>
<p>Because the score line is dynamic in length depending on the terminal
size it can happen that the score/status wraps to the next line(s). This
can be fixed by modifying the status line (see <a
href="HACKING.html">HACKING.html</a> or on GitHub <a
href="HACKING.md">HACKING.md</a>) but you shouldn’t need it to be very
wide.</p>
<h2 id="the-top-wall-isnt-allsome-of-the-time-visible"><a name="topwall" href="#toc">The top wall isn’t (all/some of the time) visible!</a></h2>
<p>Because the score line is dynamic in length depending on the terminal size it
can happen that the score/status wraps to the next line(s). This can be fixed by
modifying the status line (see <a href="HACKING.html">HACKING.html</a> or on GitHub <a href="HACKING.md">HACKING.md</a>) but
you shouldn’t need it to be very wide.</p>
<ul>
<li><p>RESOLUTION #0: Use a bigger screen (it doesn’t take that many
columns)</p>
<p><strong>Tip:</strong> try running <code>make test</code> to get an
estimate of the minimum number of columns needed. This won’t work right
if you change the score line!</p>
<p>Note that this utility is not perfect; I describe this elsewhere.
Either way a small screen will make it harder to play esp without the
cheat modes enabled (but they can still be fun with large
screens).</p></li>
<li><p>RESOLUTION #1: Open the <a href="prog.c">prog.c</a> and change
the line</p>
<li><p>RESOLUTION #0: Use a bigger screen (it doesn’t take that many columns)</p>
<p><strong>Tip:</strong> try running <code>make test</code> to get an estimate of the minimum number of columns
needed. This won’t work right if you change the score line!</p>
<p>Note that this utility is not perfect; I describe this elsewhere. Either way a
small screen will make it harder to play esp without the cheat modes enabled
(but they can still be fun with large screens).</p></li>
<li><p>RESOLUTION #1: Open the <a href="prog.c">prog.c</a> and change the line</p>
<pre><code> #define J Z(X:%d/%d Y:%d/%d S:%zu/%zu B:%zu\n),Y,y[-2],X, *y, A, g, c );</code></pre>
<p>To be something like:</p>
<pre><code> #define J Z(B:%zu\n), c);</code></pre>
<p>Recompile and try again. That will then show only the number of bugs
eaten. See the <a href="HACKING.html">HACKING.html</a> (<a
href="HACKING.md">HACKING.md</a> on GitHub) file for other data you can
include (though there are some discrepancies here and there as you’ll
<p>Recompile and try again. That will then show only the number of bugs eaten.
See the <a href="HACKING.html">HACKING.html</a> (<a href="HACKING.md">HACKING.md</a> on GitHub) file for other data you
can include (though there are some discrepancies here and there as you’ll
see).</p></li>
</ul>
<h2 id="the-snake-isnt-moving"><a name="notmoving" href="#toc">The snake
isn’t moving!</a></h2>
<p>Unless the game is paused this should not be happening. It can appear
sometimes that there isn’t movement and sometimes it might have to take
a moment to ‘unwind’ but as long as the head is moving then everything
is fine.</p>
<p>The tail might not always be moving which could make it seem like the
snake isn’t moving but as long as the head is moving then the snake can
be assumed to be moving.</p>
<h2 id="the-snake-isnt-moving"><a name="notmoving" href="#toc">The snake isn’t moving!</a></h2>
<p>Unless the game is paused this should not be happening. It can appear sometimes
that there isn’t movement and sometimes it might have to take a moment to
‘unwind’ but as long as the head is moving then everything is fine.</p>
<p>The tail might not always be moving which could make it seem like the snake
isn’t moving but as long as the head is moving then the snake can be assumed to
be moving.</p>
<ul>
<li><p>RESOLUTION #0: Unless the game is paused as long as the snake
head is moving everything is fine even if it seems sometimes that the
snake tail is still: this is normal and there are a few conditions that
this might especially show itself e.g. when the snake is growing.</p>
<li><p>RESOLUTION #0: Unless the game is paused as long as the snake head is moving
everything is fine even if it seems sometimes that the snake tail is still: this
is normal and there are a few conditions that this might especially show itself
e.g. when the snake is growing.</p>
<p>If you want to see this in action try:</p>
<pre><code> SIZE=150 SHEDS=10 SHED=1 ./prog</code></pre>
<p>Once you start moving you’ll see that the tail stays still for a
while and when it does move you’ll see it doesn’t move for long.</p>
<p>Sometimes also it might appear that the movement is delayed but there
are numerous causes for this some of which are a busy computer but
ultimately it’ll catch up; just give it the time it needs.</p></li>
<li><p>BOTTOM LINE: If you want more information then see the <a
href="bugs.html">bugs.html</a> (<a href="bugs.md">bugs.md</a> on GitHub)
file.</p></li>
<p>Once you start moving you’ll see that the tail stays still for a while and
when it does move you’ll see it doesn’t move for long.</p>
<p>Sometimes also it might appear that the movement is delayed but there are
numerous causes for this some of which are a busy computer but ultimately
it’ll catch up; just give it the time it needs.</p></li>
<li><p>BOTTOM LINE: If you want more information then see the <a href="bugs.html">bugs.html</a>
(<a href="bugs.md">bugs.md</a> on GitHub) file.</p></li>
</ul>
<h2
id="i-cant-see-the-snake-head-or-other-part-of-the-snake"><a name="invisiblehead" href="#toc">I
can’t see the snake head (or other part of the snake)!</a></h2>
<p>Possibly this could happen with too long a score line which I already
discussed. It also used to be possible during cannibal mode whilst
cannibalising: you would just have to continue moving on and you’d
eventually find your head (assuming the rest of the screen isn’t covered
with your body!). And what else could you expect if you decided to shove
your head up your …. ? :))</p>
<h2 id="i-cant-see-the-snake-head-or-other-part-of-the-snake"><a name="invisiblehead" href="#toc">I can’t see the snake head (or other part of the snake)!</a></h2>
<p>Possibly this could happen with too long a score line which I already discussed.
It also used to be possible during cannibal mode whilst cannibalising: you would
just have to continue moving on and you’d eventually find your head (assuming
the rest of the screen isn’t covered with your body!). And what else could you
expect if you decided to shove your head up your …. ? :))</p>
<ul>
<li><p>RESOLUTION #0: Actually I thought it would look better that you
could see the head even when cannibalising so you should be able to lose
your head and at the same time see it!</p></li>
<li><p>RESOLUTION #1: If the terminal width is too small then it could
be that the score line is covering the wall, snake and even bug; I gave
two resolutions to that earlier in this file. To get a recommended
number of columns use <code>make test</code>.</p></li>
<li><p>RESOLUTION #0: Actually I thought it would look better that you could see the
head even when cannibalising so you should be able to lose your head and at the
same time see it!</p></li>
<li><p>RESOLUTION #1: If the terminal width is too small then it could be that the
score line is covering the wall, snake and even bug; I gave two resolutions to
that earlier in this file. To get a recommended number of columns use <code>make test</code>.</p></li>
</ul>
<h2 id="i-cant-see-the-bug"><a name="invisiblebug" href="#toc">I can’t
see the bug!</a></h2>
<p>This has happened to me a number of times and early in development
there were times that I could swear I even saw it beyond the walls but
this should not be a problem now if it ever was.</p>
<p>However I have made a lot of effort to think of situations that might
make the bug location calculation and placement be a problem and even
did some debug output and wrote another test program to calculate the
maximum number of places the bug could be put etc.</p>
<p>One of the reasons I have the terminal dimensions have a minimum and
also a maximum has to do with the way the bug placement and max size of
the snake (and so arrays) are calculated: it could happen that because
of it being unsigned without there being restrictions it could end up
being a bad value that causes the bug placement loop to never end (in
this case the snake would also stop moving).</p>
<h2 id="i-cant-see-the-bug"><a name="invisiblebug" href="#toc">I can’t see the bug!</a></h2>
<p>This has happened to me a number of times and early in development there were
times that I could swear I even saw it beyond the walls but this should not be a
problem now if it ever was.</p>
<p>However I have made a lot of effort to think of situations that might make the
bug location calculation and placement be a problem and even did some debug
output and wrote another test program to calculate the maximum number of places
the bug could be put etc.</p>
<p>One of the reasons I have the terminal dimensions have a minimum and also a
maximum has to do with the way the bug placement and max size of the snake (and
so arrays) are calculated: it could happen that because of it being unsigned
without there being restrictions it could end up being a bad value that causes
the bug placement loop to never end (in this case the snake would also stop
moving).</p>
<ul>
<li><p>RESOLUTION #0: If evasion mode is enabled (default after 300
moves) just wait it out and the bug will move to a new place and it
might be easier to see in the new place.</p></li>
<li><p>RESOLUTION #1: The terminal size is too small for the score line.
See the earlier problem for how to resolve this if that’s the
case.</p></li>
<li><p>RESOLUTION #2: Sometimes you have to look closely for it can be
easy to miss. If it’s against the wall and the screen is <a
href="https://www.hp-lexicon.org/character/gaunt-family/morfin-gaunt/">Snakey</a>
or you’re tired or the colour contrast isn’t right for you or something
like that it might be harder to see. Try pausing the game (space) and
scan the screen for it. If you really are desperate copy and paste the
entire file into a document and search for the bug char (if it’s an
editor like vi/vim you will have to be sure to escape the char since
<code>*</code> is a regexp metacharacter). This has happened to me
numerous times.</p></li>
<li><p>RESOLUTION #3: If the colour contrast is not good for your eyes
use the <a href="snake-colours">snake-colours</a> script to select a
different colour scheme.</p></li>
<li><p>RESOLUTION #0: If evasion mode is enabled (default after 300 moves) just wait
it out and the bug will move to a new place and it might be easier to see in the
new place.</p></li>
<li><p>RESOLUTION #1: The terminal size is too small for the score line. See the
earlier problem for how to resolve this if that’s the case.</p></li>
<li><p>RESOLUTION #2: Sometimes you have to look closely for it can be easy to miss.
If it’s against the wall and the screen is <a href="https://www.hp-lexicon.org/character/gaunt-family/morfin-gaunt/">Snakey</a> or you’re tired or the colour
contrast isn’t right for you or something like that it might be harder to see.
Try pausing the game (space) and scan the screen for it. If you really are
desperate copy and paste the entire file into a document and search for the bug
char (if it’s an editor like vi/vim you will have to be sure to escape the char
since <code>*</code> is a regexp metacharacter). This has happened to me numerous times.</p></li>
<li><p>RESOLUTION #3: If the colour contrast is not good for your eyes use the
<a href="snake-colours">snake-colours</a> script to select a different colour scheme.</p></li>
</ul>
<h2 id="the-game-froze"><a name="froze" href="#toc">The game
froze!</a></h2>
<p>This should not be possible either but without certain safety checks
in place I have caused this (and I did this deliberately in development
to find all the conditions I could to resolve them).</p>
<h2 id="the-game-froze"><a name="froze" href="#toc">The game froze!</a></h2>
<p>This should not be possible either but without certain safety checks in place I
have caused this (and I did this deliberately in development to find all the
conditions I could to resolve them).</p>
<ul>
<li><p>RESOLUTION #0: If this does happen it likely is to do with
placement of the bug; that is why I have the max size of the snake
capped a fair bit below the maximum number of coordinates in the game
field: because the bug isn’t to be at a place the snake already
occupies.</p></li>
<li><p>RESOLUTION #1: If the system <code>rand()</code> implementation
is really bad maybe it’s having a problem finding a location to place
the bug. The best I can think of is to try increasing the screen size or
decrease the max size of the snake.</p></li>
<li><p>BOTTOM LINE: If the bug cannot find a place to be this will
likely cause the game to freeze because the game loops until it finds an
available place for the bug to be; if the pRNG is so bad wrt where the
snake occupies it could theoretically happen. If this happens you will
have to kill the game by e.g. ctrl-c. Try increasing the screen size
and/or decreasing the max size of the snake. See below for some
tests.</p>
<li><p>RESOLUTION #0: If this does happen it likely is to do with placement of the
bug; that is why I have the max size of the snake capped a fair bit below the
maximum number of coordinates in the game field: because the bug isn’t to be at
a place the snake already occupies.</p></li>
<li><p>RESOLUTION #1: If the system <code>rand()</code> implementation is really bad maybe it’s
having a problem finding a location to place the bug. The best I can think of is
to try increasing the screen size or decrease the max size of the snake.</p></li>
<li><p>BOTTOM LINE: If the bug cannot find a place to be this will likely cause the
game to freeze because the game loops until it finds an available place for the
bug to be; if the pRNG is so bad wrt where the snake occupies it could
theoretically happen. If this happens you will have to kill the game by e.g.
ctrl-c. Try increasing the screen size and/or decreasing the max size of the
snake. See below for some tests.</p>
<p>I removed caps in a test and then:</p>
<pre><code> GROW=1 COLUMNS=30 LINES=10 CANNIBAL=1 MAXSIZE=10000 ./prog</code></pre>
<p>It froze at this point:</p>
<pre><code> X:14/29 Y:5/9 S:323/10000 B:318</code></pre>
<p>This is because there was only one place for the bug - where the
snake head was to be. With these parameters the limit is actually 189!
This could perhaps be increased but the calculation I have used is easy
and although I certainly could make it so it’s one less than the max
that takes more bytes and I don’t see it actually mattering.</p>
<p>This is because there was only one place for the bug - where the snake head
was to be. With these parameters the limit is actually 189! This could
perhaps be increased but the calculation I have used is easy and although I
certainly could make it so it’s one less than the max that takes more bytes
and I don’t see it actually mattering.</p>
<p>Another time I tried:</p>
<pre><code> LINES=6 COLUMNS=6</code></pre>
<p>And it also froze (as noted I impose a minimum of &gt;= 10 for both
LINES and COLUMNS).</p>
<p>Ultimately I had to kill the program due to the game being stuck in
the bug placement routine. I could have put in a maximum number of loops
but what good would that do? It would use more bytes and what would it
do anyway, win? Well that’s what the max size is for.</p></li>
<p>And it also froze (as noted I impose a minimum of &gt;= 10 for both LINES and
COLUMNS).</p>
<p>Ultimately I had to kill the program due to the game being stuck in the bug
placement routine. I could have put in a maximum number of loops but what
good would that do? It would use more bytes and what would it do anyway,
win? Well that’s what the max size is for.</p></li>
<li><p>TERMINAL SIZE TO MAX SNAKE SIZE CALCULATION ETC.</p>
<p>For this information and more use the termcaps utility:</p>
<pre><code> make test</code></pre>
@@ -317,154 +283,120 @@ do anyway, win? Well that’s what the max size is for.</p></li>
at least 37 columns (currently 154) recommended for capped snake size 5738
No problems detected.</code></pre>
<p>Why are there only 38 playable lines for 41 rows? The first row is
the score line, the second is the top wall, the last is the bottom wall.
For columns you have the left and rightmost columns for the walls.</p>
<p>The calculation for max size takes place after decrementing the max
y/x; then it’s <code>(maxy - 2) * (maxx - 2)</code>; above that would
be:</p>
<p>Why are there only 38 playable lines for 41 rows? The first row is the score
line, the second is the top wall, the last is the bottom wall. For columns
you have the left and rightmost columns for the walls.</p>
<p>The calculation for max size takes place after decrementing the max y/x;
then it’s <code>(maxy - 2) * (maxx - 2)</code>; above that would be:</p>
<pre><code> (41 - 2) * (156 - 2) == 6006</code></pre>
<p>If for some reason the game were to stall for this purpose you would
have to kill the game by e.g. ctrl-c since the bug placement is stuck in
a loop. This shouldn’t happen though.</p></li>
<p>If for some reason the game were to stall for this purpose you would have to
kill the game by e.g. ctrl-c since the bug placement is stuck in a loop.
This shouldn’t happen though.</p></li>
</ul>
<h2
id="the-game-gets-slower-as-the-snake-gets-bigger"><a name="bigsnake" href="#toc">The
game gets slower as the snake gets bigger!</a></h2>
<p>Realistically the game shouldn’t take that much memory but maybe in
some very busy systems it would have a problem.</p>
<h2 id="the-game-gets-slower-as-the-snake-gets-bigger"><a name="bigsnake" href="#toc">The game gets slower as the snake gets bigger!</a></h2>
<p>Realistically the game shouldn’t take that much memory but maybe in some very
busy systems it would have a problem.</p>
<ul>
<li><p>RESOLUTION #0: If the rand() implementation is particularly poor
then it might be that the bug placement is taking more time.</p></li>
<li><p>RESOLUTION #1: It could also be the arrays being updated as the
snake gets bigger.</p></li>
<li><p>BOTTOM LINE: I find it unlikely that either of these happen and I
don’t know what to say; you can try decreasing the max size to see if it
doesn’t reach this problem. Otherwise it would be good to see if you can
find a pattern: is it when the snake is bigger i.e. the screen is rather
fuller than when you first begin? Or is the system rather busy?</p></li>
<li><p>RESOLUTION #0: If the rand() implementation is particularly poor then it might
be that the bug placement is taking more time.</p></li>
<li><p>RESOLUTION #1: It could also be the arrays being updated as the snake gets
bigger.</p></li>
<li><p>BOTTOM LINE: I find it unlikely that either of these happen and I don’t know
what to say; you can try decreasing the max size to see if it doesn’t reach this
problem. Otherwise it would be good to see if you can find a pattern: is it when
the snake is bigger i.e. the screen is rather fuller than when you first begin?
Or is the system rather busy?</p></li>
</ul>
<h2
id="i-set-size0-grow1-ate-a-bug-but-still-only-the-head-was-visible-why"><a name="headonly" href="#toc">I
set <code>SIZE=0 GROW=1</code>, ate a bug but still only the head was
visible! Why?</a></h2>
<h2 id="i-set-size0-grow1-ate-a-bug-but-still-only-the-head-was-visible-why"><a name="headonly" href="#toc">I set <code>SIZE=0 GROW=1</code>, ate a bug but still only the head was visible! Why?</a></h2>
<ul>
<li><p>RESOLUTION #0: The size includes the head but what should it show
if the size is 0? The head is the obvious choice so once you do get to
size 1 you will still only have the head. When you get to size 2 you’ll
have part of the body too. Try:</p>
<li><p>RESOLUTION #0: The size includes the head but what should it show if the size
is 0? The head is the obvious choice so once you do get to size 1 you will still
only have the head. When you get to size 2 you’ll have part of the body too.
Try:</p>
<pre><code> SIZE=1 GROW=1</code></pre>
<p>And you will see that at one bug you’ll have size two and just as if
you had two bugs with the previous invocation.</p>
<p>BTW: When you are size 1 you can go back on yourself even if
cannibalism is disabled because there really isn’t anything to go back
through: it’s just you moving the head until you find a body to use!
Once you have size &gt;= 2 then cannibalism mode counts.</p></li>
<li><p>BOTTOM LINE: In some senses SIZE=0 and SIZE=1 are the same
thing.</p></li>
<p>And you will see that at one bug you’ll have size two and just as if you had
two bugs with the previous invocation.</p>
<p>BTW: When you are size 1 you can go back on yourself even if cannibalism is
disabled because there really isn’t anything to go back through: it’s just
you moving the head until you find a body to use! Once you have size &gt;= 2
then cannibalism mode counts.</p></li>
<li><p>BOTTOM LINE: In some senses SIZE=0 and SIZE=1 are the same thing.</p></li>
</ul>
<h2
id="i-like-black-text-on-a-white-background-but-even-with-a-white-background-terminal-it-ends-up-black"><a name="monochrome" href="#toc">I
like black text on a white background but even with a white background
terminal it ends up black!</a></h2>
<p>This is a curses thing but fortunately it should be easy enough to
solve.</p>
<h2 id="i-like-black-text-on-a-white-background-but-even-with-a-white-background-terminal-it-ends-up-black"><a name="monochrome" href="#toc">I like black text on a white background but even with a white background terminal it ends up black!</a></h2>
<p>This is a curses thing but fortunately it should be easy enough to solve.</p>
<ul>
<li><p>RESOLUTION #0: Try setting the terminal to monochrome for the
invocation of the game. Depending on what is installed on your system
you might not have a monochrome terminal but you can certainly get them.
In Red Hat systems these can be found in the package ncurses-term but
maybe that will vary on others. I don’t recall having to install it
under macOS nor Fedora but those systems have GUIs so that’s probably
why; in CentOS I did have to install it specially.</p>
<p>The <code>-m</code> suffix to terminal names means monochrome. Under
Linux this terminal is under <code>/usr/share/terminfo/l/linux-m</code>
and under macOS (Catalina at least) it’s at
<code>/usr/share/terminfo/6c/linux-m</code> (for macOS Ventura it’s
<li><p>RESOLUTION #0: Try setting the terminal to monochrome for the invocation of
the game. Depending on what is installed on your system you might not have a
monochrome terminal but you can certainly get them. In Red Hat systems these can
be found in the package ncurses-term but maybe that will vary on others. I don’t
recall having to install it under macOS nor Fedora but those systems have GUIs
so that’s probably why; in CentOS I did have to install it specially.</p>
<p>The <code>-m</code> suffix to terminal names means monochrome. Under Linux this
terminal is under <code>/usr/share/terminfo/l/linux-m</code> and under macOS (Catalina
at least) it’s at <code>/usr/share/terminfo/6c/linux-m</code> (for macOS Ventura it’s
<code>/usr/share/terminfo/6c/linux-m</code>).</p></li>
<li><p>BOTTOM LINE: Try using a monochrome terminal for the game by
e.g.:</p>
<li><p>BOTTOM LINE: Try using a monochrome terminal for the game by e.g.:</p>
<pre><code> TERM=linux-m ./prog</code></pre>
<p>And then on your white background terminal the game should keep the
background white and the foreground black. This will of course mean you
have no colour but unfortunately changing the background colour of
curses would eat too many bytes in the entry (I cite the functions in
the <a href="HACKING.html">HACKING.html</a> (<a
href="HACKING.md">HACKING.md</a> on GitHub) file).</p>
<p>I discuss colours and terminals in much more detail in <a
href="terminals.html">terminals.html</a> (<a
href="terminals.md">terminals.md</a> on GitHub).</p></li>
background white and the foreground black. This will of course mean you have
no colour but unfortunately changing the background colour of curses would
eat too many bytes in the entry (I cite the functions in the
<a href="HACKING.html">HACKING.html</a> (<a href="HACKING.md">HACKING.md</a> on GitHub) file).</p>
<p>I discuss colours and terminals in much more detail in
<a href="terminals.html">terminals.html</a> (<a href="terminals.md">terminals.md</a> on GitHub).</p></li>
</ul>
<h2
id="the-text-is-hard-to-see-not-bright-enough"><a name="toodark" href="#toc">The
text is hard to see (not bright enough)!</a></h2>
<h2 id="the-text-is-hard-to-see-not-bright-enough"><a name="toodark" href="#toc">The text is hard to see (not bright enough)!</a></h2>
<ul>
<li><p>RESOLUTION #0: Make sure that your terminal settings have for
bold text a brighter font. The way I have my terminal profiles set up is
to use bright colours for bold text. I specifically enable bold in the
program so try and find out if enabling brighter colours is
possible.</p>
<p>If it’s already set at brighter colours I do not know what to say.
Try playing with the colours in your terminal, maybe the font size or
various other settings. Probably better to make a new profile for this
first in case you mess up your old one. FWIW I haven’t had this problem
on consoles only and in my systems I have the option to enable brighter
colours for bold - it was only in testing that I came across this
problem.</p></li>
<li><p>RESOLUTION #0: Make sure that your terminal settings have for bold text a
brighter font. The way I have my terminal profiles set up is to use bright
colours for bold text. I specifically enable bold in the program so try and find
out if enabling brighter colours is possible.</p>
<p>If it’s already set at brighter colours I do not know what to say. Try
playing with the colours in your terminal, maybe the font size or various
other settings. Probably better to make a new profile for this first in case
you mess up your old one. FWIW I haven’t had this problem on consoles only
and in my systems I have the option to enable brighter colours for bold - it
was only in testing that I came across this problem.</p></li>
</ul>
<h2
id="can-i-move-the-snake-faster-temporarily-without-having-to-modify-the-wait-time"><a name="movefaster" href="#toc">Can
I move the snake faster temporarily without having to modify the wait
time?</a></h2>
<p>Yes. The <code>getch()</code> call is non-blocking when the timeout
value is positive so it’s up to that number of milliseconds.</p>
<h2 id="can-i-move-the-snake-faster-temporarily-without-having-to-modify-the-wait-time"><a name="movefaster" href="#toc">Can I move the snake faster temporarily without having to modify the wait time?</a></h2>
<p>Yes. The <code>getch()</code> call is non-blocking when the timeout value is positive so
it’s up to that number of milliseconds.</p>
<ul>
<li><p>RESOLUTION #0: All you need to do then is hold down the direction
key (or for that matter any other key that <code>getch()</code> will
pick up on). You can also rapidly push the key instead of holding it
down.</p></li>
<li><p>BOTTOM LINE: Depending on the key repeat rate and/or how fast you
repeatedly hit the key you can have more control over the speed - as
long as it is quicker than the regular wait time. For negative wait time
(drawing mode) you have to hit a key every time to move because it is
blocking.</p></li>
<li><p>RESOLUTION #0: All you need to do then is hold down the direction key (or for
that matter any other key that <code>getch()</code> will pick up on). You can also rapidly
push the key instead of holding it down.</p></li>
<li><p>BOTTOM LINE: Depending on the key repeat rate and/or how fast you repeatedly
hit the key you can have more control over the speed - as long as it is quicker
than the regular wait time. For negative wait time (drawing mode) you have to
hit a key every time to move because it is blocking.</p></li>
</ul>
<h2
id="on-environmental-variables-more-generally-and-string-to-int-conversions"><a name="envvars" href="#toc">On
environmental variables more generally and string to int
conversions</a></h2>
<h2 id="on-environmental-variables-more-generally-and-string-to-int-conversions"><a name="envvars" href="#toc">On environmental variables more generally and string to int conversions</a></h2>
<p>What happens if you do:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span> <span class="ex">./prog</span></span></code></pre></div>
<p>Can you run into the wall since you didn’t specify a value and the
default is 1? No. That’s not the way it works. By saying WALLS= you have
told the system that there is that environmental variable. However the
way the <code>strtoul()</code> functions work is that if there’s no
valid input it returns 0. This can be detected but it’s wasteful
(iocccsize wise) and I have never felt that having invalid input for a
number could have a better value than 0.</p>
<p>If however you were to give valid input followed by invalid input the
valid input would be parsed. For example:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>1test <span class="ex">./prog</span></span></code></pre></div>
<div class="sourceCode" id="cb12"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span> <span class="ex">./prog</span></span></code></pre></div>
<p>Can you run into the wall since you didn’t specify a value and the default is 1?
No. That’s not the way it works. By saying WALLS= you have told the system that
there is that environmental variable. However the way the <code>strtoul()</code> functions
work is that if there’s no valid input it returns 0. This can be detected but
it’s wasteful (iocccsize wise) and I have never felt that having invalid input
for a number could have a better value than 0.</p>
<p>If however you were to give valid input followed by invalid input the valid
input would be parsed. For example:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>1test <span class="ex">./prog</span></span></code></pre></div>
<p>would let you go through the walls. On the other hand</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>test1 <span class="ex">./prog</span></span></code></pre></div>
<p>would not. Furthermore if you specify the same variable more than
once it’s the last one that counts. For example:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>0 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>would allow you to go through walls but you could not
cannibalise.</p>
<p>Also note that I specify base 0 which means that you can also have it
in hex and octal. These are all the same:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>test1 <span class="ex">./prog</span></span></code></pre></div>
<p>would not. Furthermore if you specify the same variable more than once it’s the
last one that counts. For example:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="va">WALLS</span><span class="op">=</span>0 <span class="va">WALLS</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>1 <span class="va">CANNIBAL</span><span class="op">=</span>0 <span class="ex">./prog</span></span></code></pre></div>
<p>would allow you to go through walls but you could not cannibalise.</p>
<p>Also note that I specify base 0 which means that you can also have it in hex and
octal. These are all the same:</p>
<pre><code>SIZE=0x3
SIZE=3
SIZE=03</code></pre>
<p>The way the functions work is if 0x (or 0X) it’s considered hex; if
prefixed with a 0 it’s octal and otherwise it’s decimal. If you specify
invalid data (even if only at the beginning of the string) the functions
return 0. For example:</p>
<p>The way the functions work is if 0x (or 0X) it’s considered hex; if prefixed
with a 0 it’s octal and otherwise it’s decimal. If you specify invalid data
(even if only at the beginning of the string) the functions return 0. For
example:</p>
<pre><code>SIZE=0
SIZE=f
SIZE=-
@@ -472,59 +404,48 @@ SIZE=f1</code></pre>
<p>are all equivalent.</p>
<p>Observe that:</p>
<pre><code>SIZE=08</code></pre>
<p>is invalid input because octal only has digits 0 - 7: the resulting
size will be 0.</p>
<p>I discuss the signed/unsigned issue to do with curses and sizes in C
being unsigned in <a href="bugs.html">bugs.html</a> (<a
href="bugs.md">bugs.md</a> on GitHub) but probably there isn’t anything
more to say here.</p>
<h2 id="errors-and-error-reporting"><a name="errors" href="#toc">Errors
and error reporting</a></h2>
<p>If curses fails to initialise you should get an error that says
‘curses error’ and you have every right to curse it to hell if that’s
what you so wish. Apparently curses will report an error itself if that
function fails but that escaped my notice until later on so you might
get two errors in that case.</p>
<p>Assuming it succeeds the game obtains the maximum y/x of the
terminal. The screen size must be at least 10 lines/columns (though in
code the number will not be 10); if either is smaller you will get
‘screen too small’ and the game will end (yes things that haven’t begun
can be ended).</p>
<p>If <code>calloc()</code> fails to obtain the needed memory you’ll see
something like (here it was before I added proper - to make the perfect
and obvious pun - capsizing so that by setting the size to -1 it went to
the max unsigned value):</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> MAXSIZE=-1 ./prog</span>
<p>is invalid input because octal only has digits 0 - 7: the resulting size will be
0.</p>
<p>I discuss the signed/unsigned issue to do with curses and sizes in C being
unsigned in <a href="bugs.html">bugs.html</a> (<a href="bugs.md">bugs.md</a> on GitHub) but probably there isn’t
anything more to say here.</p>
<h2 id="errors-and-error-reporting"><a name="errors" href="#toc">Errors and error reporting</a></h2>
<p>If curses fails to initialise you should get an error that says ‘curses error’
and you have every right to curse it to hell if that’s what you so wish.
Apparently curses will report an error itself if that function fails but that
escaped my notice until later on so you might get two errors in that case.</p>
<p>Assuming it succeeds the game obtains the maximum y/x of the terminal. The
screen size must be at least 10 lines/columns (though in code the number will
not be 10); if either is smaller you will get ‘screen too small’ and the game
will end (yes things that haven’t begun can be ended).</p>
<p>If <code>calloc()</code> fails to obtain the needed memory you’ll see something like (here it
was before I added proper - to make the perfect and obvious pun - capsizing
so that by setting the size to -1 it went to the max unsigned value):</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> MAXSIZE=-1 ./prog</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="ex">memory</span> error</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="ex">X:0/157</span> Y:0/42 S:3/18446744073709551614 B:0</span></code></pre></div>
<p>BTW: There are two arrays that have to be
<strong><code>MAXSIZE</code></strong> (technically + 1).</p>
<p>Is it possible that some value specified by the user could mess this
up? I do not know but what I do know is that because it’s unsigned it
can’t be negative; if the max size is 0 then the array size will be 1
but it won’t matter because the snake size will be &gt;= that max
anyway. But here’s a curious output:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>1 <span class="va">MAXSIZE</span><span class="op">=</span>0 <span class="ex">./prog</span></span>
<p>BTW: There are two arrays that have to be <strong><code>MAXSIZE</code></strong> (technically + 1).</p>
<p>Is it possible that some value specified by the user could mess this up? I do
not know but what I do know is that because it’s unsigned it can’t be negative;
if the max size is 0 then the array size will be 1 but it won’t matter because
the snake size will be &gt;= that max anyway. But here’s a curious output:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="va">SIZE</span><span class="op">=</span>1 <span class="va">MAXSIZE</span><span class="op">=</span>0 <span class="ex">./prog</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="ex">YOU</span> WIN!</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="ex">X:78/156</span> Y:20/41 S:0/0 B:0</span></code></pre></div>
<p>Why does it show snake size as 0 when I specified 1? It’s because the
max size is 0 and I limit the size to be no bigger than the max
size.</p>
<p>Why does it show snake size as 0 when I specified 1? It’s because the max size
is 0 and I limit the size to be no bigger than the max size.</p>
<table>
<colgroup>
<col style="width: 100%" />
</colgroup>
<tbody>
<tr class="odd">
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt
Noll][judges] - All rights reserved This work is licensed under a
[Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
<td>(c) Copyright 1984-2020, [Leo Broukhis, Simon Cooper, Landon Curt Noll][judges] - All rights reserved
This work is licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License][cc].</td>
</tr>
<tr class="even">
<td>[judges]: https://www.ioccc.org/judges.html [cc]:
http://creativecommons.org/licenses/by-sa/3.0/</td>
<td>[judges]: https://www.ioccc.org/judges.html
[cc]: http://creativecommons.org/licenses/by-sa/3.0/</td>
</tr>
</tbody>
</table>