Files
Landon Curt Noll f29b37e49a improve HTML menus, add social.html, prep for IOCCC28 winners
Prepare for the winners of **IOCCC28**.

> However these are not the 2024 droids you are looking for.  :-)

The HTML menu (both JavaScript and non-JavaScript) has been updated.

The `Status -> Rules and guidelines' have been replaced with two
separate menus `Status -> IOCCC rules` and `Status -> IOCCC guidelines`.

Added a new top level `social.html` page: built from a new `social.md`.

Sorted rules for building specific web pages in the top level `Makefile`.
Added `make social` to make the `social.html` page from `social.md`.

The `bin/gen-top-html.sh` now is able to process a argument of **social**
to process the new top level `social.html` page.

Changed `bin/gen-top-html.sh` VERSION from "2.0.0 2025-03-13"
to "2.0.1 2025-07-25".

Below `About -> Home page` a new `About -> IOCCC social media` menu item
as added.

Because the menu change touched every HTML file, we changed the general
copyright date range for HTML files from "1984-2024" to "1984-2025"
due to the extensive changes made for **IOCCC28**.

Those markdown files that were modified in 2025 had their copyright date
range also changed from "1984-2024" to "1984-2025".

Rebuilt tarballs and sitemap due to the extensive HTML rebuilding.

Ran `make update` to perform the above.
2025-07-26 13:06:29 -07:00

924 lines
39 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
<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>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="HACKING.md for 2020/ferguson1">
<meta name="keywords" content="IOCCC, 2020/ferguson1, HACKING.md">
</head>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! 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/head.default.html -->
<!-- -->
<!-- This web page was formed via the tool: bin/gen-other-html.sh -->
<!-- The content of main section of this web page came from: 2020/ferguson1/HACKING.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2020/ferguson1/HACKING.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2020/ferguson1/HACKING.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2020/ferguson1/HACKING.md !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
<!-- 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/topbar.default.html -->
<div class="theader">
<nav class="topbar">
<div class="container">
<div class="logo">
<a href="../../index.html" class="logo-link">
IOCCC
</a>
</div>
<div class="topbar-items">
<div class="item">
<span class="item-header">
Entries
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../years.html" class="sub-item-link">
Winning entries
</a>
</div>
<div class="outfit-font">
<a href="../../authors.html" class="sub-item-link">
Winning authors
</a>
</div>
<div class="outfit-font">
<a href="../../location.html" class="sub-item-link">
Location of authors
</a>
</div>
<div class="outfit-font">
<a href="../../bugs.html" class="sub-item-link">
Bugs and (mis)features
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
Fixing entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_author" class="sub-item-link">
Updating author info
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
Status
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../news.html" class="sub-item-link">
News
</a>
</div>
<div class="outfit-font">
<a href="../../status.html" class="sub-item-link">
Contest status
</a>
</div>
<div class="outfit-font">
<a href="../../next/rules.html" class="sub-item-link">
IOCCC rules
</a>
</div>
<div class="outfit-font">
<a href="../../next/guidelines.html" class="sub-item-link">
IOCCC guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../markdown.html" class="sub-item-link">
Markdown guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../SECURITY.html" class="sub-item-link">
Security policy
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
FAQ
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../faq.html" class="sub-item-link">
Frequently asked questions
</a>
</div>
<div class="outfit-font">
<a href="../../quick-start.html#enter" class="sub-item-link">
Enter the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#compiling" class="sub-item-link">
Compiling entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#running_entries" class="sub-item-link">
Running entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#help" class="sub-item-link">
How to help
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
About
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../index.html" class="sub-item-link">
Home page
</a>
</div>
<div class="outfit-font">
<a href="../../social.html" class="sub-item-link">
IOCCC social media
</a>
</div>
<div class="outfit-font">
<a href="../../about.html" class="sub-item-link">
About the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../judges.html" class="sub-item-link">
The judges
</a>
</div>
<div class="outfit-font">
<a href="../../thanks-for-help.html" class="sub-item-link">
Thanks for the help
</a>
</div>
<div class="outfit-font">
<a href="../../contact.html" class="sub-item-link">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="header-mobile-menu">
<noscript>
<a href="../../nojs-menu.html" class="topbar-js-label">
Please Enable JavaScript
</a>
</noscript>
<button id="header-open-menu-button" class="topbar-mobile-menu">
<img
src="../../png/hamburger-icon-open.png"
alt="hamburger style menu icon - open state"
width=48
height=48>
</button>
<button id="header-close-menu-button" class="hide-content">
<img
src="../../png/hamburger-icon-closed.png"
alt="hamburger style menu icon - closed state"
width=48
height=48>
</button>
<div id="mobile-menu-panel" class="hide-content">
<div class="mobile-menu-container">
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Entries
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../years.html">
Winning entries
</a>
<a class="mobile-submenu-item" href="../../authors.html">
Winning authors
</a>
<a class="mobile-submenu-item" href="../../location.html">
Location of authors
</a>
<a class="mobile-submenu-item" href="../../bugs.html">
Bugs and (mis)features
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
Fixing entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
Updating author info
</a>
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
Thanks for the help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Status
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../news.html">
News
</a>
<a class="mobile-submenu-item" href="../../status.html">
Contest status
</a>
<a class="mobile-submenu-item" href="../../next/rules.html">
IOCCC rules
</a>
<a class="mobile-submenu-item" href="../../next/guidelines.html">
IOCCC guidelines
</a>
<a class="mobile-submenu-item" href="../../markdown.html">
Markdown guidelines
</a>
<a class="mobile-submenu-item" href="../../SECURITY.html">
Security policy
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
FAQ
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../faq.html">
Frequently asked questions
</a>
<a class="mobile-submenu-item" href="../../quick-start.html#enter">
Enter the IOCCC
</a>
<a class="mobile-submenu-item" href="../../faq.html#compiling">
Compiling entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#running_entries">
Running entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#help">
How to help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
About
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../index.html">
Home page
</a>
<a class="mobile-submenu-item" href="../../social.html">
IOCCC social media
</a>
<a class="mobile-submenu-item" href="../../about.html">
About the IOCCC
</a>
<a class="mobile-submenu-item" href="../../judges.html">
The judges
</a>
<a class="mobile-submenu-item" href="../../contact.html">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
headerOpenMenuButton.addEventListener("click", () => {
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
headerOpenMenuButton.classList.add("hide-content");
headerCloseMenuButton.classList.remove("hide-content");
headerCloseMenuButton.classList.add("topbar-mobile-menu");
mobileMenuPanel.classList.remove("hide-content");
mobileMenuPanel.classList.add("topbar-mobile-panel");
});
headerCloseMenuButton.addEventListener("click", () => {
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
headerCloseMenuButton.classList.add("hide-content");
mobileMenuPanel.classList.add("hide-content");
mobileMenuPanel.classList.remove("topbar-mobile-panel");
headerOpenMenuButton.classList.add("topbar-mobile-menu");
headerOpenMenuButton.classList.remove("hide-content");
});
</script>
<!-- END: this line ends content from: inc/topbar.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<a href="../../2011/zucker/index.html">
<img src="../../png/ioccc.png"
alt="IOCCC image by Matt Zucker"
width=300
height=110>
</a>
<h1>The International Obfuscated C Code Contest</h1>
<h2>HACKING.html for 2020/ferguson1</h2>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/navbar.up2index.html -->
<div class="navbar">
<a class="Left" href="index.html">&uarr; jump to 2020/ferguson1/index.html &uarr;</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2020%2Fferguson1%2FHACKING.html">&#x2713;</a>
</div>
<!-- END: this line ends content from: inc/navbar.up2index.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<div class="content" id="content">
<!-- 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 -->
<!-- BEFORE: 1st line of markdown file: 2020/ferguson1/HACKING.md -->
<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>Modifying the colours
<ul>
<li>Background colour</li>
</ul></li>
<li>Modifying the characters for the wall, bug and snake</li>
<li>Modifying input keys</li>
<li>Modifying the status/score line</li>
<li>Make it so the snake starts at a random location</li>
</ul></li>
<li><p>Additions</p>
<ul>
<li>Health (and/or Lives)</li>
<li>Saving the game</li>
<li>Different types of walls
<ul>
<li>Blockades</li>
</ul></li>
<li>Diagonal movement</li>
<li>Special abilities</li>
<li>Obstacles</li>
<li>More than one bug</li>
<li>Power-ups</li>
<li>Snakeskin shedding (becoming an obstacle)</li>
<li>Snake moves faster over time</li>
<li>Max times the bug evades before game over</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>
<pre><code> init_pair(5, COLOR_BLACK, COLOR_WHITE);
bkgd(COLOR_PAIR(5));</code></pre>
<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>
<pre><code> COLOR_BLACK
COLOR_RED
COLOR_GREEN
COLOR_YELLOW
COLOR_BLUE
COLOR_MAGENTA
COLOR_CYAN
COLOR_WHITE</code></pre>
<p>See <a href="https://www.linuxjournal.com/content/programming-color-ncurses">Linux Journal for more information
article</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>
<pre><code> case KEY_LEFT:
case KEY_RIGHT:
case KEY_UP:
case KEY_DOWN:</code></pre>
<p>Replace <code>KEY_LEFT</code> with:</p>
<pre><code> &#39;l&#39;</code></pre>
<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>
<pre><code> case KEY_LEFT: case &#39;l&#39;:</code></pre>
<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="obfuscation-notice">OBFUSCATION NOTICE</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>
<pre><code> #define J &quot; &quot; );</code></pre>
<p>If you don’t care about brief displays of ‘<code>o</code>’ at <code>0,0</code> you can just have:</p>
<pre><code> #define J &quot;&quot;);</code></pre>
<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>
<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>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>
<pre><code> #define J Z(SIZE: %zu BUGS: %zu\n), A, c);</code></pre>
<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>
<pre><code> X = H / 2; Y = *x / 2;</code></pre>
<p>To be something like:</p>
<pre><code> X = R(1,H-1);
Y = R(2,*x-1);</code></pre>
<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 (at least without
<code>CANNIBAL=1</code>) - 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 (<code>WALLS=0</code>) 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 <code>WALLS</code> 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>
<pre><code> if (p &amp;&amp; !(*O&gt;=O[1]||H&gt;=M(1)))
{
if (X&lt;1||X&gt;=H)
X = X&lt;1?H-1:1;
if (Y&lt;2||Y&gt;=*O)
Y = Y&lt;2?*O-1:2;
}</code></pre>
<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>
<pre><code> X=X&lt;1?1:*H-1;
Y=Y&lt;2?2:*O-1;</code></pre>
<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 <code>WALLS</code> 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 <a href="https://en.wikipedia.org/wiki/Surround_(video_game)">Surround</a> 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>
<hr style="width:10%;text-align:left;margin-left:0">
<p>Jump to: <a href="#">top</a></p>
<!--
Copyright © 1984-2024 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<!-- AFTER: last line of markdown file: 2020/ferguson1/HACKING.md -->
<!-- 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 -->
</div>
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/footer.default.html -->
<!--
Copyright © 1984-2025 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<div class="footer">
<div id="copyright"><h3>Copyright &copy; 1984-2025 by Landon Curt Noll:
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
target="_blank"
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
<p>
This work is <b>licensed by Landon Curt Noll</b> under
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
target="_blank"
rel="license noopener noreferrer"
style="display:inline-block;">CC BY-SA 4.0</a></b>.
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/cc.png"
alt="cc inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/by.png"
alt="person inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/sa.png"
alt="arrow looping back on itself inside circle symbol"><br>
You should <b>carefully review</b> the
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
target="_blank"
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
before using the licensed material.<br>
You may wish to review the
<b><a href="../../license.html"
target="_blank"
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
of <b>CC BY-SA 4.0</b>.<br>
</p>
</div>
<div id="coda"><h3>Coda</h3>
<p>
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2020%2Fferguson1%2FHACKING.html" rel="nofollow">Nu HTML check this web page</a><br>
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a>
</p>
</div>
</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 -->