1 <!DOCTYPE html>
  2 <html lang="en-US">  <!-- Set language of this page to USA English. -->
  3 
  4 <!-- ===================================================================
  5 |
  6 | NAME
  7 | 
  8 |     Life.html
  9 |
 10 | DESCRIPTION
 11 |
 12 |     This is the game of life web page.
 13 |     It is a hand-crafted HTML 5 W3C validated document.
 14 |
 15 | AUTHOR
 16 |
 17 |    Sean Erik O'Connor
 18 |
 19 =================================================================== -->
 20 
 21     <head>
 22         <!-- This page uses Unicode characters. -->
 23         <meta charset="utf-8">
 24 
 25         <!-- Set viewport to actual device width.  Any other settings makes the web page initially appear zoomed-in on mobile devices. -->
 26         <meta name="viewport" content="width=device-width" />
 27 
 28         <!-- Titles appear in the web browser and the browser's bookmarks. -->
 29        <title>Game of Life</title>
 30 
 31         <!-- Search engines will show this description below the title. -->
 32         <meta name="description"
 33               content="Game of Life implemented in Javascript and Windows --- free software." />
 34 
 35         <meta name="author"
 36               content="Sean Erik O'Connor" >
 37 
 38         <meta name="copyright"
 39              content="Copyright (C) 1999-2024 by Sean Erik O'Connor.  All Rights Reserved." />
 40 
 41         <!-- Point to the Javascript Game of Life -->
 42         <script src="Scripts/gameOfLife.js"></script>
 43 
 44         <!-- Cascading style sheet for this document. -->
 45         <link rel="stylesheet" href="../../../StyleSheet.css" type="text/css" />
 46 
 47         <!-- Favicons are 32x32 or 16x16, 8 or 24 bit PNG Images which show up left of the web page title in a browser.  -->
 48         <link rel="icon" type="image/png" href="../../../Images/favicon.png" >
 49     </head>
 50 
 51     <body>
 52         <!-- This wraps the whole body in a CSS grid. -->
 53         <div class="wrapper titlePage">
 54 
 55             <!-- Title page at the top.  -->
 56             <header class="title">
 57                 <h1>GAME OF LIFE</h1>
 58                 <hr>
 59             </header>
 60 
 61             <!-- Horizontal navigation bar to all top level pages. -->
 62             <header class="navigation">
 63                 <a href="../../../index.html">
 64                     <img src="../../../Images/home.png" alt="Home Page Button." width="32" height="32" />
 65                      <em>Home</em>
 66                  </a>
 67 
 68                  <a href="../../../Mathematics/mathematicalSoftware.html">
 69                      <img src="../../../Images/compactDisk.png" alt="Mathematical Software Button." width="32" height="32" />
 70                       <em>Mathematical Software</em>
 71                  </a>
 72 
 73                  <a href="../../../Art/Art.html">
 74                      <img src="../../../Images/sampleArtLowRes.png" alt="Art Button." width="32" height="32" />
 75                       <em>Fine Arts</em>
 76                  </a>
 77 
 78                  <a href="../../../WebPageDesign/webPageDesign.html">
 79                      <img src="../../../Images/home.png" alt="Web Design Button." width="32" height="32" />
 80                       <em>Web Page Design</em>
 81                  </a>
 82 
 83                  <a href="../../../Electronics/Electronics.html">
 84                      <img src="../../../Images/sparkCoil.png" alt="Hobby Electronics Button." width="32" height="32" />
 85                       <em>Hobby Electronics</em>
 86                  </a>
 87 
 88                  <a href="../../../ReadingList/readingList.html">
 89                       <img src="../../../Images/terraApollo17NASALowRes.png"
 90                            alt="Reading List Button."
 91                            width="32" height="32" />
 92                       <em>Reading list</em>
 93                 </a>
 94             </header>
 95 
 96             <!-- A decorative border at the left side of the page. -->
 97             <aside class=border>
 98                   <img class="border"
 99                        src="../../../Images/sinXYPlot.png"
100                        alt="Sin( x y ) Image Border." />
101             </aside>
102 
103             <!-- The main content of this page. -->
104             <article class="content">
105                 <section>
106                     <h3>Game of Life in Javascript</h3>
107 
108                     <p>
109                     This is an implementation of J. H. Conway's cellular automata
110                     <a href="http://conwaylife.com/wiki/Main_Page">game of life</a>
111                     in Javascript where the game board is a topologically a torus.  See my
112                     <a href="theory.html">design notes</a>
113                     for a description of the game and how it is designed.
114                     </p>
115 
116                     <!-- Game of Life canvas -->
117                     <p>
118                         <canvas id="GameOfLifeCanvas" 
119                                 width="1000" height="1000" 
120                                 style="background-color:  rgb( 170, 235, 245 ) ;">
121                             <em>Your browser does not support the canvas API so I can't show game of life!</em>
122                         </canvas>
123                     </p>
124 
125                     <!-- Game of Life form controls -->
126                     <form id="LifePatternsForm">
127                         <ul>
128                             <li>
129                                 <!-- Buttons to start/stop, single step and reset the game.  
130                                      Upon click, call the Javascript functions runStopGame(), singleStepGame() and clearGame(). 
131                                   -->
132                                   <fieldset>
133                                       <legend>Game Controls</legend>
134 
135                                       <input type="button" onclick="gameOfLife.runStopGame()"    value="Run/Stop" />
136                                       <input type="button" onclick="gameOfLife.singleStepGame()" value="Single Step" />
137                                       <input type="button" onclick="gameOfLife.clearGame()"      value="Clear" />
138                                  </fieldset>
139                             </li>
140 
141                             <li>
142                                 <!-- Check box buttons to select number of neighbors for survival and birth.  
143                                      If the user toggles the button, call the Javascript function changeRules( flag ) 
144                                      where flag = true for survival or false for birth.
145                                      Default to the Conway rules. 
146                                   -->
147                                <fieldset>
148                                    <legend>Neighbors to survive</legend>
149 
150                                    <label> 1 <input type="checkbox" name="SurvivalRules" value="1"         onchange="gameOfLife.changeRules( true )"> </label>
151                                    <label> 2 <input type="checkbox" name="SurvivalRules" value="2" checked onchange="gameOfLife.changeRules( true )"> </label>
152                                    <label> 3 <input type="checkbox" name="SurvivalRules" value="3" checked onchange="gameOfLife.changeRules( true )"> </label>
153                                    <label> 4 <input type="checkbox" name="SurvivalRules" value="4"         onchange="gameOfLife.changeRules( true )"> </label>
154                                    <label> 5 <input type="checkbox" name="SurvivalRules" value="5"         onchange="gameOfLife.changeRules( true )"> </label>
155                                    <label> 6 <input type="checkbox" name="SurvivalRules" value="6"         onchange="gameOfLife.changeRules( true )"> </label>
156                                    <label> 7 <input type="checkbox" name="SurvivalRules" value="7"         onchange="gameOfLife.changeRules( true )"> </label>
157                                    <label> 8 <input type="checkbox" name="SurvivalRules" value="8"         onchange="gameOfLife.changeRules( true )"> </label>
158                                </fieldset>
159                             </li>
160 
161                             <li>
162                                 <fieldset>
163                                      <legend>Neighbors for birth</legend>
164 
165                                      <label> 1 <input type="checkbox" name="BirthRules" value="1"            onchange="gameOfLife.changeRules( false )"> </label>
166                                      <label> 2 <input type="checkbox" name="BirthRules" value="2"            onchange="gameOfLife.changeRules( false )"> </label>
167                                      <label> 3 <input type="checkbox" name="BirthRules" value="3" checked    onchange="gameOfLife.changeRules( false )"> </label>
168                                      <label> 4 <input type="checkbox" name="BirthRules" value="4"            onchange="gameOfLife.changeRules( false )"> </label>
169                                      <label> 5 <input type="checkbox" name="BirthRules" value="5"            onchange="gameOfLife.changeRules( false )"> </label>
170                                      <label> 6 <input type="checkbox" name="BirthRules" value="6"            onchange="gameOfLife.changeRules( false )"> </label>
171                                      <label> 7 <input type="checkbox" name="BirthRules" value="7"            onchange="gameOfLife.changeRules( false )"> </label>
172                                      <label> 8 <input type="checkbox" name="BirthRules" value="8"            onchange="gameOfLife.changeRules( false )"> </label>
173                                  </fieldset>
174                             </li>
175 
176                             <li>
177                                 <!-- Game of Life File I/O -->
178                                 <fieldset>
179                                     <legend>File I/O</legend>
180 
181                                     <!-- Tag the input form with unique id GameOfLifeLoadFile.
182                                          Get the element by its id in the Javascript function initializeGameOfLife().
183                                          Add an event listener to the element which responds to changes by calling a function make_fileSelectForReading(). 
184                                          The function argument is an event which is the list of files.
185                                      -->
186                                     <input type="file"   id="GameOfLifeLoadFile"  name="files[]" multiple />
187                                 </fieldset>
188                             </li>
189 
190                             <li>
191                                 <!-- Game of Life clipboard controls -->
192                                 <fieldset>
193                                     <legend>Clipboard</legend>
194 
195                                     <input type="button" onclick="gameOfLife.writeGameToClipboard()"  value="Write" />
196                                     <input type="button" onclick="gameOfLife.readGameFromClipboard()" value="Read" />
197                                 </fieldset>
198                             </li>
199 
200                             <li>
201                                 <!-- Radio buttons for loading sample life patterns. 
202                                      Call the Javascript function loadSampleLifePattern(). 
203                                 -->
204                                 <fieldset>
205                                     <legend>Life Pattern</legend>
206 
207                                     <!-- Tag the selection in the form with unique id LifePatterns.
208                                      Get the element by its id in the Javascript function initializeGameOfLife().
209                                      Add an event listener to the element which responds to changes by calling a function make_loadSampleLifePattern().
210                                      The function argument is an event which is the option selected. 
211                                     -->
212                                     <select id="LifePatterns">
213                                         <option selected value="glidergun">Glider Gun</option>
214                                         <option value="replicator">Replicator</option>
215                                         <option value="crab">Crab</option>
216                                         <option value="shickengine">Schick Engine</option>
217                                         <option value="trafficcircle">Traffic Circle</option>
218                                         <option value="highlifeglidergun">High Life Glider Gun</option>
219                                     </select>
220                                 </fieldset>
221                             </li>
222 
223                             <li>
224                                 <!-- Game of life status.  Javascript accesses the span by its id and rewrites its contents.  -->
225                                 <span style="color: navy;  font-size: 0.8em;" id="GameOfLifeState"> --- Game State --- </span>
226                             </li>
227                         </ul>
228                     </form>
229 
230                         <!-- Clipboard form for Game of Life files. -->
231                         <form>
232                             <ul>
233                                 <li>
234                                     Game of Life Clipboard
235                                     <fieldset>
236                                         <textarea id="GameOfLifeClipboard" rows="10">
237                                         ---Life file---
238                                         </textarea>
239                                     </fieldset>
240                                 </li>
241 
242                                 <li>
243                                     <!-- Game of life cell state -->
244                                     <span style="color: navy;  font-size: 0.6em ; clear: both;" id="GameOfLifeCellState"> --- Cell State --- </span>
245                                 </li>
246                             </ul>
247                         </form>
248 
249                     <!-- Output window for game of life. -->
250                     <div class="scrollBoxHuge"> <div class="scrollBoxContent" id="GameOfLifeDebug">
251                             --- Life Counter States Go Here ---
252                     </div> </div>
253 
254                     <!-- Initialize the Game of Life application after all HTML elements have been defined. -->
255                     <script>
256                         gameOfLife.init() ;
257                     </script>
258                 </section>
259 
260                 <section>
261                     <h3>Software Architecture</h3>
262 
263                     <p>
264                     It's in two parts, HTML/CSS for the user interface and the Javascript for the actions.
265                     </p>
266 
267                     <h4>Preloading the JavaScript</h4>
268                     <p>
269                     In this HTML file, <em>life.html</em>, we preload the Javascript program <em>gameOfLife.js</em> in the head section.
270                     </p>
271 
272                     <h4>Canvas, Forms and Controls</h4>
273 
274                     <p>
275                     First, we set up a page wide canvas for the game board.
276                     </p>
277 
278                     <p>
279                     Game controls and status buttons are HTML forms.  Their styles defined by CSS.  The controls have types and ID's to tie
280                     them to the Javascript.
281                     </p>
282 
283                         <ul>
284                             <li>Some fields of the form have their actions call Javascript functions directly.  Example:  birth and death rule checkboxes.</li>
285                             <li>Other fields send their handles to into the Javascript upon initialization where they are linked to event listeners.  Example: file name box, mouse click on the canvas.</li>
286                             <li>Still other fields have their contents rewritten by Javascript functions as internal states change.  Example:  clipboard.</li>
287                         </ul>
288 
289                     <h4>JavaScript Objects</h4>
290 
291                     <p>
292                     First we create a <strong>Game of Life Base Object</strong>.  It contains the settings and links to DOM elements.
293                     Next we create a <strong>Game of Life Object</strong> from the base object.  This object has most of the functions.
294                     Due to delegation along the prototype chain, we have access to the base object data and methods.
295                     Finally we initialize the Game of Life object as the last step.
296                     </p>
297 
298                     <ul>
299                         <li>Using the unique id's in the HTML form controls, it gets handles to the canvas, game state, cell state, debug scrollbox, file input form,
300                             clipboard, and other HTML elements.</li>
301                         <li>Creates callback functions, some using closures, tied to form actions, events, etc.</li>
302                         <li>Creates a timer and registers a single step game function with it.</li>
303                         <li>There's a bit of minor cleanup where upon loading the body section, we call a function to initialize checkmarks in the game state form.</li>
304                     </ul>
305 
306                     <figure>
307                         <img src="Images/GameOfLifeObjects01.jpg" alt="Game of Life Objects" >
308                         <img src="Images/GameOfLifeObjects02.jpg" alt="Game of Life Objects" >
309 
310                        <figcaption>
311                            Game of Life Objects and the Prototype Chain.
312                        </figcaption>
313                     </figure>
314                 </section>
315 
316                 <section>
317                     <h3>Download</h3>
318 
319                     <p>
320                         Source code <em>Version 3.4</em> is distributed under the terms of the
321                         <a href="http://www.gnu.org/licenses/">GNU General Public License</a>.
322                     </p>
323 
324                     <table class="download">
325                         <tr>
326                             <td>
327                                 <em>gameOfLife.js</em>
328                             </td>
329 
330                             <td>
331                             Game of Life implemented in <i>Javascript</i>
332                             </td>
333 
334                             <td>
335                                 <a href="Scripts/gameOfLife.js.html">
336                                    <img src="../../../Images/eye.png" 
337                                         alt="Eye icon for source code viewing." 
338                                         width="30" height="30" />
339                                 View</a>
340 
341                                 &nbsp; &nbsp;
342 
343                                 <a href="Scripts/gameOfLife.js" download="gameOfLife.js">
344                                    <img src="../../../Images/compactDisk.png" 
345                                         alt="Compact disk icon for source code download." 
346                                         width="25" height="25" />
347                                 Download</a>
348                             </td>
349                         </tr>
350                         <tr>
351                             <td>
352                             <em>life.html</em>
353                             </td>
354 
355                             <td>
356                             HTML code for this page which calls gameOfLife.js
357                             </td>
358 
359                             <td>
360                                 <a href="life.html.html">
361                                    <img src="../../../Images/eye.png" 
362                                         alt="Eye icon for source code viewing." 
363                                         width="30" height="30" />
364                                 View</a>
365                             </td>
366                         </tr>
367                     </table>
368                 </section>
369 
370                 <section>
371                     <h3>Debugging</h3>
372 
373                     The browsers (Safari, Firefox, Opera) have developer tools for debugging,
374 
375                     <figure>
376                         <img src="Images/SafariDeveloperTools.jpg" alt="Safari Web Browser Developer Tools" >
377 
378                        <figcaption>
379                            Safari Web Browser Developer Tools
380                        </figcaption>
381                     </figure>
382                </section>
383             </article>
384 
385             <footer class="footnote">
386                 <hr />
387 
388                 <!-- A copyright to preserve my legal rights. -->
389                 <p class="footnote">
390                     Copyright &copy; 1986-2022 by Sean Erik O'Connor.
391                     All Rights Reserved.
392                     &nbsp;&nbsp;&nbsp;
393                     last updated 01 Jan 24.
394                 </p>
395             </footer>
396         </div> <!-- wrapper -->
397     </body>
398 </html>