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:
1 parent
9eb7a54e9f
commit
b0b212acb1
402 files changed
+37061
-55132
No files matched your search
+102
-156
@@ -129,9 +129,9 @@
|
||||
|
||||
<h2 id="author"><a name="author"></a>Author:</h2>
|
||||
<ul>
|
||||
<li>Name: <a href="../../authors.html#Nicholas_Carlini">Nicholas
|
||||
Carlini</a><br> Location: <a href="../../location.html#US">US</a> -
|
||||
<em>United States of America</em> (<em>United States</em>) <br><br></li>
|
||||
<li>Name: <a href="../../authors.html#Nicholas_Carlini">Nicholas Carlini</a><br>
|
||||
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
|
||||
<br><br></li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
|
||||
@@ -144,8 +144,7 @@ Carlini</a><br> Location: <a href="../../location.html#US">US</a> -
|
||||
<h3 id="bugs-and-misfeatures">Bugs and (Mis)features:</h3>
|
||||
<p>The current status of this entry is:</p>
|
||||
<pre><code>STATUS: INABIAF - please **DO NOT** fix</code></pre>
|
||||
<p>For more detailed information see <a
|
||||
href="../../bugs.html#2020_carlini">2020 carlini bugs</a>.</p>
|
||||
<p>For more detailed information see <a href="../../bugs.html#2020_carlini">2020 carlini bugs</a>.</p>
|
||||
<h2 id="to-use">To use:</h2>
|
||||
<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">./prog</span></span></code></pre></div>
|
||||
<h2 id="try">Try:</h2>
|
||||
@@ -154,11 +153,10 @@ href="../../bugs.html#2020_carlini">2020 carlini bugs</a>.</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"># Play with a friend, real or imagined, P1 and P2, squares are numbered 1..9</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ex">./prog</span></span></code></pre></div>
|
||||
<h2 id="judges-remarks">Judges’ remarks:</h2>
|
||||
<p>This program consists of a single <code>printf(3)</code> statement
|
||||
wrapped in a <code>while</code> loop. You would not think that this
|
||||
would amount to much, but you would be very, very wrong. A clue to what
|
||||
is happening and how this works is encoded in the ASCII art of the
|
||||
program source.</p>
|
||||
<p>This program consists of a single <code>printf(3)</code> statement wrapped in a <code>while</code>
|
||||
loop. You would not think that this would amount to much, but you would be very,
|
||||
very wrong. A clue to what is happening and how this works is encoded in the
|
||||
ASCII art of the program source.</p>
|
||||
<h2 id="authors-remarks">Author’s remarks:</h2>
|
||||
<p>HOW ABOUT A NICE GAME OF <strike>CHESS</strike>TIC-TAC-TOE?</p>
|
||||
<h3 id="usage">USAGE</h3>
|
||||
@@ -177,145 +175,116 @@ program source.</p>
|
||||
<li>A player makes an illegal move; their opponent wins.</li>
|
||||
</ul>
|
||||
<h3 id="limitations">LIMITATIONS</h3>
|
||||
<p>Bad things may happen if the entered move is outside of the range
|
||||
[1..9]</p>
|
||||
<p>While the game will stop if one player tries to overwrite another
|
||||
player’s move, it will happily allow a player to move on top of
|
||||
themself. However, given that this is an effective no-op and guarantees
|
||||
a loss to a competent opponent, if you do this you probably deserve to
|
||||
lose.</p>
|
||||
<p>Your terminal may beep at you every turn. We’ll call this a feature
|
||||
that … the program … is hard at work processing your move! That is!
|
||||
Please be patient.</p>
|
||||
<p>After macro expansion the format string is roughly 100K. This makes
|
||||
some compilers unhappy, and others slow. (For example, passing GCC the
|
||||
flags <code>-Wall -Wextra -pedantic</code> will result in a warning
|
||||
about oversized strings.)</p>
|
||||
<p>Under some terminals the program may exit early. The following should
|
||||
always work:</p>
|
||||
<p>Bad things may happen if the entered move is outside of the range [1..9]</p>
|
||||
<p>While the game will stop if one player tries to overwrite another player’s move,
|
||||
it will happily allow a player to move on top of themself. However, given that
|
||||
this is an effective no-op and guarantees a loss to a competent opponent, if you
|
||||
do this you probably deserve to lose.</p>
|
||||
<p>Your terminal may beep at you every turn. We’ll call this a feature that …
|
||||
the program … is hard at work processing your move! That is! Please be
|
||||
patient.</p>
|
||||
<p>After macro expansion the format string is roughly 100K. This makes some
|
||||
compilers unhappy, and others slow. (For example, passing GCC the flags <code>-Wall -Wextra -pedantic</code> will result in a warning about oversized strings.)</p>
|
||||
<p>Under some terminals the program may exit early. The following should always work:</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="bu">echo</span> <span class="st">"1 2 3 4 5 6 7"</span> <span class="kw">|</span> <span class="ex">./prog</span></span></code></pre></div>
|
||||
<h3 id="obfuscation">OBFUSCATION</h3>
|
||||
<p>The entirety of the program consists of a single iterated call to
|
||||
<code>printf(3)</code>.</p>
|
||||
<p>The entirety of the program consists of a single iterated call to <code>printf(3)</code>.</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="dt">int</span> main<span class="op">()</span> <span class="op">{</span></span>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a> <span class="cf">while</span><span class="op">(*</span>d<span class="op">)</span> printf<span class="op">(</span>fmt<span class="op">,</span> arg<span class="op">);</span></span>
|
||||
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||||
<p>Here, <code>fmt</code> is a single string, and <code>arg</code> is a
|
||||
series of arguments to <code>printf(3)</code>.</p>
|
||||
<p>While its primary purpose is to serve as The One True Debugger,
|
||||
<code>printf(3)</code> also happens to be Turing complete. (See
|
||||
“Control-Flow Bending: On the Effectiveness of Control-Flow Integrity”
|
||||
where we introduced this in an actual, published, academic paper. The
|
||||
<p>Here, <code>fmt</code> is a single string, and <code>arg</code> is a series of arguments to
|
||||
<code>printf(3)</code>.</p>
|
||||
<p>While its primary purpose is to serve as The One True Debugger, <code>printf(3)</code> also happens
|
||||
to be Turing complete. (See “Control-Flow Bending: On the Effectiveness of Control-Flow
|
||||
Integrity” where we introduced this in an actual, published, academic paper. The
|
||||
things you can get away with sometimes.)</p>
|
||||
<p>We <strike>ab</strike>use this fact to implement the logic of
|
||||
tic-tac-toe entirely within this one <code>printf(3)</code> call (and a
|
||||
call to <code>scanf(3)</code> to read user input).</p>
|
||||
<p>We <strike>ab</strike>use this fact to implement the logic of tic-tac-toe entirely within
|
||||
this one <code>printf(3)</code> call (and a call to <code>scanf(3)</code> to read user input).</p>
|
||||
<p>Here’s (briefly) how it works.</p>
|
||||
<h4 id="preliminaries">Preliminaries</h4>
|
||||
<p>This program uses three <code>printf(3)</code> format specifiers.</p>
|
||||
<ul>
|
||||
<li><p><code>%d</code> takes an integer argument and prints it.</p></li>
|
||||
<li><p><code>%s</code> takes a string argument and prints it.</p></li>
|
||||
<li><p><code>%n</code> takes a pointer and writes (!!) the number of
|
||||
bytes printed so far.</p></li>
|
||||
<li><p><code>%n</code> takes a pointer and writes (!!) the number of bytes printed so far.</p></li>
|
||||
</ul>
|
||||
<p>Okay, everyone probably knows this. Let’s get a bit more
|
||||
advanced.</p>
|
||||
<p>Okay, everyone probably knows this. Let’s get a bit more advanced.</p>
|
||||
<p>Format specifiers can take extra “arguments”.</p>
|
||||
<ul>
|
||||
<li><p><code>"%hhn"</code>: store the number of bytes written mod 256 to
|
||||
the <code>char</code> pointer.</p></li>
|
||||
<li><p><code>"%2$d"</code>: print argument 2 to <code>printf(3)</code>
|
||||
(and not the sequentially next argument).</p></li>
|
||||
<li><p><code>"%8d"</code>: pad the printed integer to 8
|
||||
characters.</p></li>
|
||||
<li><p><code>"%3$.*4$d"</code>: print argument 3 to
|
||||
<code>printf(3)</code> with as many zeros as in argument 4.</p></li>
|
||||
<li><p><code>"%hhn"</code>: store the number of bytes written mod 256 to the <code>char</code> pointer.</p></li>
|
||||
<li><p><code>"%2$d"</code>: print argument 2 to <code>printf(3)</code> (and not the sequentially next argument).</p></li>
|
||||
<li><p><code>"%8d"</code>: pad the printed integer to 8 characters.</p></li>
|
||||
<li><p><code>"%3$.*4$d"</code>: print argument 3 to <code>printf(3)</code> with as many zeros as in argument 4.</p></li>
|
||||
</ul>
|
||||
<p>For example, the following expression</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>printf<span class="op">(</span><span class="st">"%1$.*2$d%3$hhn"</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">10</span><span class="op">,</span> <span class="op">&</span>x<span class="op">)</span></span></code></pre></div>
|
||||
<p>will have the same effect as if we had written</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>x <span class="op">=</span> <span class="dv">10</span><span class="op">;</span></span></code></pre></div>
|
||||
<p>because it will print out <code>0000000005</code> (5 padded to size
|
||||
10) and then write the number of bytes written to <code>x</code>.</p>
|
||||
<h4 id="printf3-oriented-programming"><code>printf(3)</code> Oriented
|
||||
Programming</h4>
|
||||
<p>because it will print out <code>0000000005</code> (5 padded to size 10) and then write the
|
||||
number of bytes written to <code>x</code>.</p>
|
||||
<h4 id="printf3-oriented-programming"><code>printf(3)</code> Oriented Programming</h4>
|
||||
<p>Alright, now we can get to the real fun.</p>
|
||||
<p>We perform arbitrary computation with <code>printf(3)</code> treating
|
||||
memory as a binary array–one bit per pair of bytes:</p>
|
||||
<p>We perform arbitrary computation with <code>printf(3)</code> treating memory as a binary
|
||||
array–one bit per pair of bytes:</p>
|
||||
<ul>
|
||||
<li><p>The zero bit is represented by the sequence
|
||||
<code>00 00</code>.</p></li>
|
||||
<li><p>The one-bit is represented by the sequence <code>xx 00</code>
|
||||
where <code>xx</code> is any non-zero byte.</p></li>
|
||||
<li><p>The zero bit is represented by the sequence <code>00 00</code>.</p></li>
|
||||
<li><p>The one-bit is represented by the sequence <code>xx 00</code> where <code>xx</code> is any non-zero byte.</p></li>
|
||||
</ul>
|
||||
<p>We can use format strings to compute the OR/NOT of arbitrary
|
||||
“bits”.</p>
|
||||
<p>We can use format strings to compute the OR/NOT of arbitrary “bits”.</p>
|
||||
<p>We’ll start with the simplest, OR:</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>printf<span class="op">(</span><span class="st">"%1$s%2$s%3$hhn"</span><span class="op">,</span> a<span class="op">,</span> b<span class="op">,</span> c<span class="op">)</span></span></code></pre></div>
|
||||
<p>will compute</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><span class="op">*</span>c <span class="op">=</span> strlen<span class="op">(</span>a<span class="op">)</span> <span class="op">+</span> strlen<span class="op">(</span>b<span class="op">)</span></span></code></pre></div>
|
||||
<p>but given that <code>strlen(x)</code> is <code>1</code> for a 1-bit
|
||||
and <code>0</code> for a 0-bit, we have</p>
|
||||
<p>but given that <code>strlen(x)</code> is <code>1</code> for a 1-bit and <code>0</code> for a 0-bit, we have</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="op">*</span>c <span class="op">=</span> a <span class="op">|</span> b</span></code></pre></div>
|
||||
<p>Computing the NOT of a single value is also easy:</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>printf<span class="op">(</span><span class="st">"%1$255d%1$s</span><span class="sc">%hhn</span><span class="st">"</span><span class="op">,</span> a<span class="op">,</span> b<span class="op">)</span></span></code></pre></div>
|
||||
<p>will compute</p>
|
||||
<div class="sourceCode" id="cb16"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="op">*</span>b <span class="op">=</span> <span class="op">(</span>strlen<span class="op">(</span>a<span class="op">)+</span><span class="dv">255</span><span class="op">)%</span><span class="dv">256</span> <span class="op">=</span> strlen<span class="op">(</span>a<span class="op">)-</span><span class="dv">1</span></span></code></pre></div>
|
||||
<p>and again, because <code>strlen(x)</code> is either <code>1</code> or
|
||||
<code>0</code> we have</p>
|
||||
<p>and again, because <code>strlen(x)</code> is either <code>1</code> or <code>0</code> we have</p>
|
||||
<div class="sourceCode" id="cb17"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="op">*</span>c <span class="op">=</span> <span class="op">!</span>b</span></code></pre></div>
|
||||
<p>From here we can compute any binary circuit. Doing something
|
||||
efficient, though, still takes work.</p>
|
||||
<p>From here we can compute any binary circuit. Doing something efficient,
|
||||
though, still takes work.</p>
|
||||
<h4 id="tic-tac-toe">Tic-Tac-Toe</h4>
|
||||
<p>The game itself is represented as a board of 18 bits, 9 bits per
|
||||
player, along with a turn counter that alternates between player 1 and
|
||||
player 2.</p>
|
||||
<p>To detect who has won, we implement the following logic. Let
|
||||
<code>A</code>, <code>B</code>, and <code>C</code> be pointers to three
|
||||
squares in a row to test, and <code>D</code> be where to save if there
|
||||
is a win or not.</p>
|
||||
<p>The game itself is represented as a board of 18 bits, 9 bits per player, along
|
||||
with a turn counter that alternates between player 1 and player 2.</p>
|
||||
<p>To detect who has won, we implement the following logic. Let <code>A</code>, <code>B</code>, and <code>C</code> be
|
||||
pointers to three squares in a row to test, and <code>D</code> be where to save if there is a
|
||||
win or not.</p>
|
||||
<div class="sourceCode" id="cb18"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="st">"</span><span class="sc">%A</span><span class="st">$s%B$s%C$s%1$253d%11$hhn"</span> <span class="co">// r11 = !(*A & *B & *C)</span></span>
|
||||
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>ZERO</span>
|
||||
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="st">"%11$s%1$255d</span><span class="sc">%11hhn</span><span class="st">"</span> <span class="co">// r11 = !r11</span></span>
|
||||
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>ZERO</span>
|
||||
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="st">"%11$s%D$s%D$hhn"</span> <span class="co">// *D = *D | r11</span></span></code></pre></div>
|
||||
<p>That is, we set <code>*D</code> to <code>1</code> if there is a
|
||||
three-in-a-row. We repeat this for all possible three-in-a-row
|
||||
configurations, for both players.</p>
|
||||
<p>The ZERO macro ensures that the number of bytes written out is 0 mod
|
||||
256 with the following expression</p>
|
||||
<p>That is, we set <code>*D</code> to <code>1</code> if there is a three-in-a-row. We repeat this for all
|
||||
possible three-in-a-row configurations, for both players.</p>
|
||||
<p>The ZERO macro ensures that the number of bytes written out is 0 mod 256 with
|
||||
the following expression</p>
|
||||
<div class="sourceCode" id="cb19"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="st">"%1$hhn%1$s"</span> <span class="op">(</span>repeated <span class="dv">256</span> times<span class="op">)</span></span></code></pre></div>
|
||||
<p>where argument 1 is a pointer to a temporary variable followed by a
|
||||
NUL byte.</p>
|
||||
<p>This works because if the current count is 0 mod 256, then
|
||||
<code>"%1$hhn"</code> will write zero to argument 1 and then
|
||||
<code>"%1$s"</code> will never emit any text. If, on the other hand, the
|
||||
count is not 0 mod 256, a length-1 string will be written to argument 1,
|
||||
and then <code>"%1$s"</code> will increment the count by one. By
|
||||
repeating this 256 times we’re eventually going to reach 0 mod 256.</p>
|
||||
<p>where argument 1 is a pointer to a temporary variable followed by a NUL byte.</p>
|
||||
<p>This works because if the current count is 0 mod 256, then <code>"%1$hhn"</code> will write
|
||||
zero to argument 1 and then <code>"%1$s"</code> will never emit any text. If, on the other
|
||||
hand, the count is not 0 mod 256, a length-1 string will be written to argument
|
||||
1, and then <code>"%1$s"</code> will increment the count by one. By repeating this 256
|
||||
times we’re eventually going to reach 0 mod 256.</p>
|
||||
<p>Checking if there has been an invalid move is achieved similarly.</p>
|
||||
<p>In order to decide what to print out, we have to cast the “in-memory”
|
||||
array of bits to Xs and Os to print out. This is actually rather
|
||||
straightforward. Given in <code>1$</code> the pointer to player 1’s
|
||||
square, and <code>2$</code> the pointer to player 2’s, and in
|
||||
<code>3$</code> the pointer to the board string, we can compute</p>
|
||||
<p>In order to decide what to print out, we have to cast the “in-memory” array of
|
||||
bits to Xs and Os to print out. This is actually rather straightforward. Given
|
||||
in <code>1$</code> the pointer to player 1’s square, and <code>2$</code> the pointer to player 2’s, and
|
||||
in <code>3$</code> the pointer to the board string, we can compute</p>
|
||||
<div class="sourceCode" id="cb20"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="st">"%1$s"</span> <span class="op">(</span>repeated <span class="dv">47</span> times<span class="op">)</span> <span class="st">"%2$s"</span> <span class="op">(</span>repeated <span class="dv">56</span> times<span class="op">)</span> <span class="op">%</span><span class="dv">1</span>$<span class="dv">32</span><span class="er">d</span><span class="op">%</span><span class="dv">3</span>$hhn<span class="st">"</span></span></code></pre></div>
|
||||
<p>which will, in effect, compute</p>
|
||||
<div class="sourceCode" id="cb21"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="op">*</span>r3 <span class="op">=</span> <span class="op">(*</span>r1<span class="op">)</span> <span class="op">*</span> <span class="dv">47</span> <span class="op">+</span> <span class="op">(*</span>r2<span class="op">)</span> <span class="op">*</span> <span class="dv">56</span> <span class="op">+</span> <span class="dv">32</span></span></code></pre></div>
|
||||
<p>which will output <code>' '</code> if neither are true,
|
||||
<code>'X'</code> if <code>r1</code> is true, or <code>'O'</code> if
|
||||
<p>which will output <code>' '</code> if neither are true, <code>'X'</code> if <code>r1</code> is true, or <code>'O'</code> if
|
||||
<code>r2</code> is true.</p>
|
||||
<h4 id="further-obfuscations">Further Obfuscations</h4>
|
||||
<p>In order to be able to finally display the board, while still only
|
||||
using one <code>printf(3)</code> statement, we finish the statement
|
||||
with</p>
|
||||
<p>In order to be able to finally display the board, while still only using one
|
||||
<code>printf(3)</code> statement, we finish the statement with</p>
|
||||
<div class="sourceCode" id="cb22"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="st">"</span><span class="sc">\n\033</span><span class="st">[2J</span><span class="sc">\n</span><span class="st">%26$s"</span></span></code></pre></div>
|
||||
<p>which is the escape sequence to clear the screen, and then prints
|
||||
argument 26. Argument 26 is a pointer to a <code>char*</code> in memory,
|
||||
that initially is undefined, but within the <code>printf(3)</code>
|
||||
statement we will construct this string to look like a tic-tac-toe
|
||||
board.</p>
|
||||
<p>which is the escape sequence to clear the screen, and then prints argument 26.
|
||||
Argument 26 is a pointer to a <code>char*</code> in memory, that initially is undefined,
|
||||
but within the <code>printf(3)</code> statement we will construct this string to look like a
|
||||
tic-tac-toe board.</p>
|
||||
<p>After the board, we need to print one of the following strings:</p>
|
||||
<pre><code>P1>_
|
||||
P2>_
|
||||
@@ -323,86 +292,63 @@ P1 WINS
|
||||
P2 WINS
|
||||
P1 TIES
|
||||
P2 TIES</code></pre>
|
||||
<p>Depending on if it’s P1 or P2’s turn to move, the game is over and
|
||||
someone won, or the game is over and it is a draw.</p>
|
||||
<p>This turns out not to be as hard as it might look. Using the same
|
||||
trick as before, we set byte four to be</p>
|
||||
<p>Depending on if it’s P1 or P2’s turn to move, the game is over and someone
|
||||
won, or the game is over and it is a draw.</p>
|
||||
<p>This turns out not to be as hard as it might look. Using the same trick as
|
||||
before, we set byte four to be</p>
|
||||
<div class="sourceCode" id="cb24"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="op">*</span>byte4 <span class="op">=</span> is_win <span class="op">*</span> <span class="ch">'W'</span> <span class="op">+</span> is_tie <span class="op">*</span> <span class="ch">'T'</span></span></code></pre></div>
|
||||
<p>The byte <code>'I'</code> and <code>'S'</code> can always be the
|
||||
same, and we do the same for <code>'E'</code>/<code>'N'</code>.</p>
|
||||
<p>We do this same on-the-fly creation of the <code>scanf(3)</code>
|
||||
format string, but for a different reason. We first want to run
|
||||
<code>printf(3)</code> to show the first board, and then alternate
|
||||
between runs to <code>scanf(3)</code> and <code>printf(3)</code> reading
|
||||
and then displaying moves. Importantly, we <em>do not</em> want a final
|
||||
<code>scanf(3)</code> when the game ends. It should just exit.</p>
|
||||
<p>The byte <code>'I'</code> and <code>'S'</code> can always be the same, and we do the same for <code>'E'</code>/<code>'N'</code>.</p>
|
||||
<p>We do this same on-the-fly creation of the <code>scanf(3)</code> format string, but for a
|
||||
different reason. We first want to run <code>printf(3)</code> to show the first board, and
|
||||
then alternate between runs to <code>scanf(3)</code> and <code>printf(3)</code> reading and then
|
||||
displaying moves. Importantly, we <em>do not</em> want a final <code>scanf(3)</code> when the game
|
||||
ends. It should just exit.</p>
|
||||
<p>One option would be to implement the logic as</p>
|
||||
<div class="sourceCode" id="cb25"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>printf<span class="op">()</span></span>
|
||||
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="op">(*</span>ok<span class="op">)</span> <span class="op">{</span></span>
|
||||
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a> scanf<span class="op">();</span></span>
|
||||
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a> printf<span class="op">();</span></span>
|
||||
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||||
<p>but this would DOUBLE the number of calls to <code>printf(3)</code>
|
||||
we require. So instead we implement it like this</p>
|
||||
<p>but this would DOUBLE the number of calls to <code>printf(3)</code> we require. So instead we
|
||||
implement it like this</p>
|
||||
<div class="sourceCode" id="cb26"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="cf">while</span> <span class="op">(*</span>ok<span class="op">)</span> <span class="op">{</span></span>
|
||||
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a> scanf<span class="op">();</span></span>
|
||||
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a> printf<span class="op">();</span></span>
|
||||
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
|
||||
<p>(In reality we actually pass <code>scanf(3)</code> as an argument to
|
||||
avoid the extra statement, but it has the same effect.)</p>
|
||||
<p>Notice there is now no initial <code>printf(3)</code>. In order make
|
||||
sure the program doesn’t block before the first <code>printf(3)</code>,
|
||||
we initialize the <code>scanf(3)</code> format to the NUL string so that
|
||||
it returns right away without blocking. The first time the
|
||||
<code>printf(3)</code> call runs, it writes out <code>"%hhd"</code> to
|
||||
create the <code>scanf(3)</code> format string.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
|
||||
License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
|
||||
Reserved. You are free to share and adapt this file under the terms of
|
||||
this license:</p>
|
||||
<p>(In reality we actually pass <code>scanf(3)</code> as an argument to avoid the extra
|
||||
statement, but it has the same effect.)</p>
|
||||
<p>Notice there is now no initial <code>printf(3)</code>. In order make sure the program doesn’t
|
||||
block before the first <code>printf(3)</code>, we initialize the <code>scanf(3)</code> format to the NUL
|
||||
string so that it returns right away without blocking. The first time the
|
||||
<code>printf(3)</code> call runs, it writes out <code>"%hhd"</code> to create the <code>scanf(3)</code> format string.</p>
|
||||
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
|
||||
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
|
||||
You are free to share and adapt this file under the terms of this license:</p>
|
||||
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
|
||||
<p>For more information, see:
|
||||
https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
|
||||
|
||||
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
|
||||
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
|
||||
|
||||
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
<h1 id="inventory-for-2020carlini"><a name="inventory"></a>Inventory for
|
||||
2020/carlini</h1>
|
||||
<h1 id="inventory-for-2020carlini"><a name="inventory"></a>Inventory for 2020/carlini</h1>
|
||||
<p><a href="#top">Jump to top</a></p>
|
||||
<h2 id="primary-files">Primary files</h2>
|
||||
<ul>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/prog.c">prog.c</a>
|
||||
- entry source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/Makefile">Makefile</a>
|
||||
- entry Makefile</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/prog.orig.c">prog.orig.c</a>
|
||||
- original source</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/try.sh">try.sh</a>
|
||||
- how to run</li>
|
||||
<li><a href="2020_carlini.tar.bz2">2020_carlini.tar.bz2</a> - download
|
||||
entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/prog.c">prog.c</a> - entry source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/Makefile">Makefile</a> - entry Makefile</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/prog.orig.c">prog.orig.c</a> - original source</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/try.sh">try.sh</a> - how to run</li>
|
||||
<li><a href="2020_carlini.tar.bz2">2020_carlini.tar.bz2</a> - download entry source</li>
|
||||
</ul>
|
||||
<h2 id="secondary-files">Secondary files</h2>
|
||||
<ul>
|
||||
<li><a href="index.html">index.html</a> - entry home page</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/.entry.json">.entry.json</a>
|
||||
- description of entry in JSON</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/.gitignore">.gitignore</a>
|
||||
- list of files that should not be committed under git</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/.entry.json">.entry.json</a> - description of entry in JSON</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
|
||||
<li><a href=".path">.path</a> - directory path from top directory</li>
|
||||
<li><a
|
||||
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/README.md">README.md</a>
|
||||
- markdown source for index.html</li>
|
||||
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2020/carlini/README.md">README.md</a> - markdown source for index.html</li>
|
||||
</ul>
|
||||
|
||||
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
|
||||
|
||||
Reference in new issue
Block a user