build missing HTML files for entries

Setup a simple topnav for missing HTML files for entries.

Added `bin/gen-other-html.sh` to build entry HTML files from
markdown other than README.md to index.html HTML files.

Fixed duplicate link text in `2020/ferguson1/gameplay.md`.

Improved `inc/md2html.cfg` to support building the missing HTML
files for entries.

Added `make gen_other_html` to top level Makefile.
Added `make gen_other_html` to `make quick_www` and `make www`.

Fixed inventory links for year level index.html files.
Changed `bin/output-year-index.sh` VERSION from "1.0.1 2024-02-23"
to "1.1 2024-02-27".

Added missing lines in `manifest.numbers`.  Update the affected
`.entry.json` files.

The manifest (in both `manifest.numbers` and the collection of
manifests from of all entry `.entry.json` files) now match.  Errors
from `make verify_entry_files` will now abort both `make quick_www`
and `make www` rules in the top level `Makefile`.

Changed markdown files in manifest to have an _inventory_order_ of
_2000000000_ so that the `index.html` file will usually appear at
the start of the _Secondary files_ set for the "#inventory" section
of an entry's `index.html` file.

Changed compressed tar files (files that end in _.tar.bz2_) in
manifest to have an _inventory_order_ of _100000_ so that these
files will usually appear at the end of the _Primary files_ set for
the "#inventory" section of an entry's `index.html` file.

Added 'Jump to top` link above the _Primary files_ section.
Changed `bin/output-index-inventory.sh` VERSION from "1.1.1 2024-02-23"
to "1.2 2024-02-27".

Updated HTML files to perform the above via `make www`.
This commit is contained in:
Landon Curt Noll committed 2024-02-27 22:36:20 -08:00
1 parent 7babf792e4
commit 9d3438fb88
718 files changed
+17515 -4084

No files matched your search

+561
View File
@@ -0,0 +1,561 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- START: two lines up starts content from: inc/top.default.html -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- -->
<!-- The original markdown content was formed by the tool: bin/gen-other-html.sh -->
<!-- The HTML was converted from markdown by the tool: bin/md2html.sh -->
<!-- -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>The International Obfuscated C Code Contest</title>
<meta name="description" content="HACKING.md for 2020/ferguson1">
<meta name="keywords" content="IOCCC, 2020/ferguson1, HACKING.md">
</head>
<!-- END: this line ends content from: inc/head.default.html -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<img src="../../png/ioccc.png" alt="IOCCC image by Matt Zucker" width=300 height=110>
<h1>The International Obfuscated C Code Contest</h1>
<h2>HACKING.md for 2020/ferguson1</h2>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/topnav.up2index.html -->
<div class="topnav">
<a class="Left" href="index.html">&uarr; jump to index.html &uarr;</a>
</div>
<!-- END: this line ends content from: inc/topnav.up2index.html -->
<!-- START: this line starts content from: inc/begin-row.default.html -->
<div class="row">
<!-- END: this line ends content from: inc/begin-row.default.html -->
<!-- START: this line starts content from: inc/begin-leftcolumn.default.html -->
<div class="leftcolumn">
<!-- END: this line ends content from: inc/begin-leftcolumn.default.html -->
<!-- START: this line starts content from: inc/sidenav.default.html -->
<div class="sidenav">
<a href="#content">Jump to contents</a>
</div>
<hr>
<div class="sidenav">
<a href="../../index.html">IOCCC Home</a>
<a href="../../years.html">Winning Entries</a>
<a href="../../authors.html">People who have won</a>
</div>
<hr>
<div class="sidenav">
<a href="../../news.html">IOCCC News</a>
<a href="../../faq.html#submit">How to enter the IOCCC</a>
<a href="../../faq.html">FAQ</a>
</div>
<hr>
<div class="sidenav">
<a href="../../bugs.html">Bugs &amp; (mis)features</a>
<a href="../../faq.html#fix_an_entry">Fixing IOCCC entries</a>
<a href="../../faq.html#fix_web_site">Fixing the web site</a>
<a href="../../faq.html#fix_author">Fixing author info</a>
<a href="../../thanks-for-help.html">Thanks for the help</a>
</div>
<hr>
<div class="sidenav">
<a href="../../judges.html">The IOCCC Judges</a>
<a href="../../contact.html">Contacting the IOCCC</a>
</div>
<hr>
<div class="sidenav">
<a href="#top">Jump to top</a>
</div>
<!-- END: this line ends content from: inc/sidenav.default.html -->
<!-- START: this line starts content from: inc/end-leftcolumn.default.html -->
</div>
<!-- END: this line ends content from: inc/end-leftcolumn.default.html -->
<!-- START: this line starts content from: inc/begin-rightcolumn.default.html -->
<div class="rightcolumn">
<!-- END: this line ends content from: inc/begin-rightcolumn.default.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<a name="content"></a>
<!-- 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="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>
<ul>
<li><p>Modifications</p>
<ul>
<li><p>Modifying the colours</p></li>
<li><p>Background colour</p></li>
<li><p>Modifying the characters for the wall, bug and snake</p></li>
<li><p>Modifying input keys</p></li>
<li><p>Modifying the status/score line</p></li>
<li><p>Make it so the snake starts at a random location</p></li>
</ul></li>
<li><p>Additions</p>
<ul>
<li><p>Health (and/or Lives)</p></li>
<li><p>Saving the game</p></li>
<li><p>Different types of walls</p></li>
<li><p>Blockades</p></li>
<li><p>Diagonal movement</p></li>
<li><p>Special abilities</p></li>
<li><p>Obstacles</p></li>
<li><p>More than one bug</p></li>
<li><p>Power-ups</p></li>
<li><p>Snakeskin shedding (becoming an obstacle)</p></li>
<li><p>Snake moves faster over time</p></li>
<li><p>Max times the bug evades before game over</p></li>
</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>
<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>
<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>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>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>COLOR_GREEN</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>COLOR_YELLOW</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>COLOR_BLUE</span>
<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>
<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
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>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> KEY_UP<span class="op">:</span></span>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<pre><code> DESCRIPTION EXPRESSION TYPE FORMAT SPECIFIER
Snake size A size_t %zu
Y coordinate Y int %d
of snake head
X coordinate X int %d
of snake head
Max snake size g size_t %zu
Bugs eaten c size_t %zu
Bug line (Y) *U int %d
Bug column (X) *V int %d
Snake size A size_t %zu
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>
<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>
<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>
<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>
<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>
</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>
<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>
<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>
<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>
<span id="cb14-4"><a href="#cb14-4" 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>H<span class="op">-</span><span class="dv">1</span><span class="op">:</span><span class="dv">1</span><span class="op">;</span></span>
<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>
<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
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>
<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>
<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>
<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>
<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>
<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>
<!-- 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 -->
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/end-rightcolumn.default.html -->
</div>
<!-- END: this line ends content from: inc/end-rightcolumn.default.html -->
<!-- START: this line starts content from: inc/end-row.default.html -->
</div>
<!-- END: this line ends content from: inc/end-row.default.html -->
<!-- START: this line starts content from: inc/footer.default.html -->
<div class="footer">
<hr>
<h2>Coda</h2>
<p><a href="https://validator.w3.org/nu/?doc=#">Nu HTML check this web page</a></p>
<p><a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a></p>
</div>
<!-- END: this line ends content from: inc/footer.default.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->