<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-22937959</id><updated>2011-07-28T14:53:02.132-05:00</updated><title type='text'>Schwarze Katze Project</title><subtitle type='html'>Squaring Circles one Side at a Time.  A hobby blog on game programming and other interests.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default?start-index=101&amp;max-results=100'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>110</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-22937959.post-6424768682491991596</id><published>2009-11-07T18:45:00.000-05:00</published><updated>2009-11-07T18:45:46.529-05:00</updated><title type='text'>Apple vrs Windows - Genau!</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.crispygamer.com/comics/backward/backward-2009-10-19.aspx"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_WPaGJnpjpJQ/SvYGL2ni0qI/AAAAAAAAACw/ai6_RTX1E4E/s320/backward-2009-10-19_Publish.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;That is all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-6424768682491991596?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/6424768682491991596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=6424768682491991596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/6424768682491991596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/6424768682491991596'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2009/11/apple-vrs-windows-genau.html' title='Apple vrs Windows - Genau!'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WPaGJnpjpJQ/SvYGL2ni0qI/AAAAAAAAACw/ai6_RTX1E4E/s72-c/backward-2009-10-19_Publish.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-1254605019284732590</id><published>2009-11-01T17:10:00.001-05:00</published><updated>2009-11-01T17:11:52.536-05:00</updated><title type='text'>Wine blogging - Shotfire barosa Shiraz 2007</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_WPaGJnpjpJQ/Su4HL61v17I/AAAAAAAAACo/Ia1N7CAKtpw/s1600-h/1042451x.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_WPaGJnpjpJQ/Su4HL61v17I/AAAAAAAAACo/Ia1N7CAKtpw/s320/1042451x.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Classic style shiraz. &lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-1254605019284732590?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/1254605019284732590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=1254605019284732590' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1254605019284732590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1254605019284732590'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2009/11/shotfire-barosa-shiraz-2007.html' title='Wine blogging - Shotfire barosa Shiraz 2007'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WPaGJnpjpJQ/Su4HL61v17I/AAAAAAAAACo/Ia1N7CAKtpw/s72-c/1042451x.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-162478293649104566</id><published>2009-10-14T22:38:00.000-05:00</published><updated>2009-10-14T22:38:06.893-05:00</updated><title type='text'>Baguala Torrontes 2007</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_WPaGJnpjpJQ/StaYjn4PgLI/AAAAAAAAACg/M7DresqbqTk/s1600-h/bagualatorrontes.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_WPaGJnpjpJQ/StaYjn4PgLI/AAAAAAAAACg/M7DresqbqTk/s320/bagualatorrontes.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;A light white wine.&amp;nbsp; Floral notes on the nose.&amp;nbsp; Tastes of stone fruit,&amp;nbsp; possibly apricot.&amp;nbsp; A bit of musk on the finish.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-162478293649104566?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/162478293649104566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=162478293649104566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/162478293649104566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/162478293649104566'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2009/10/baguala-torrontes-2007.html' title='Baguala Torrontes 2007'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WPaGJnpjpJQ/StaYjn4PgLI/AAAAAAAAACg/M7DresqbqTk/s72-c/bagualatorrontes.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-4346481195845240791</id><published>2009-10-07T22:27:00.002-05:00</published><updated>2009-10-07T22:30:51.042-05:00</updated><title type='text'>Wine Blogging - Kung Fu Girl Riesling 2008 Washington</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WPaGJnpjpJQ/Ss1ckdpp94I/AAAAAAAAACY/-jjCQyAXOZw/s1600-h/01090.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 170px; height: 170px;" src="http://2.bp.blogspot.com/_WPaGJnpjpJQ/Ss1ckdpp94I/AAAAAAAAACY/-jjCQyAXOZw/s200/01090.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5390066110536742786" /&gt;&lt;/a&gt;&lt;br /&gt;A &lt;span style="font-style:italic;"&gt;halb-trocken&lt;/span&gt; white wine, very fruity.  Think somewhere between peaches and lychees.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-4346481195845240791?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/4346481195845240791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=4346481195845240791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4346481195845240791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4346481195845240791'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2009/10/wine-blogging-kung-fu-girl-riesling.html' title='Wine Blogging - Kung Fu Girl Riesling 2008 Washington'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WPaGJnpjpJQ/Ss1ckdpp94I/AAAAAAAAACY/-jjCQyAXOZw/s72-c/01090.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-1763703389232808622</id><published>2009-10-04T21:51:00.002-05:00</published><updated>2009-10-04T22:04:24.272-05:00</updated><title type='text'>Playing D&amp;D was being Goth in the '80s</title><content type='html'>Something I found while digging through mu old papers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;To speak of old gods and ancient time, of both joy and sorrow, is in itself a mystery.&lt;br /&gt;&lt;br /&gt;One hears of Poseidon and Atlantis, of Yahweh and the Twelve Tribes.  One listens to tales of Lucifer and the drowned city of Ys, of Solomon and this mines.&lt;br /&gt;&lt;br /&gt;History is half deaf and half blind.  For history is written by the winners and the voices of the losers are still.&lt;br /&gt;&lt;br /&gt;Who sings of the the Sidhe that fair Avalon had forgotten? Who can speak to me of the little people who laid gifts to lost gods, of the folk of bronze and flint?&lt;br /&gt;&lt;br /&gt;Having won so often, when have we lost so much?  Having enjoyed victory, where did we lose?&lt;br /&gt;&lt;br /&gt;Who can show me the first forests of the dryads, of beasts unseen, of spirits unknown?  Who can show me the arts of people the vanquished had conquered?&lt;br /&gt;Where can I find the temples and palaces of gods who came before the gods? the toys and games of forgotten children?&lt;br /&gt;&lt;br /&gt;Having won so often, when have we lost so much?  Having enjoyed victory, where did we lose?&lt;br /&gt;&lt;br /&gt;Where can I hear the old songs of life or paens of praise, the cries pf the buried city, or the silence of the forgotten groves?  Where can I learn the old rituals of life and darkness, the rites of spring or a dying sun?&lt;br /&gt;&lt;br /&gt;History is half deaf and half blind.  For history is written by the winners and the voices of the losers are still.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-1763703389232808622?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/1763703389232808622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=1763703389232808622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1763703389232808622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1763703389232808622'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2009/10/playing-d-was-being-goth-in-80s.html' title='Playing D&amp;D was being Goth in the &apos;80s'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-8004155327631723437</id><published>2008-11-17T21:29:00.000-05:00</published><updated>2008-11-17T21:31:10.065-05:00</updated><title type='text'>La Sauvageonne, Les Ruffes 2007</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WPaGJnpjpJQ/SSIonY5q2FI/AAAAAAAAACQ/D0rsU09uoWs/s1600-h/labe_les_ruffes.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 150px; height: 142px;" src="http://4.bp.blogspot.com/_WPaGJnpjpJQ/SSIonY5q2FI/AAAAAAAAACQ/D0rsU09uoWs/s200/labe_les_ruffes.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5269819171141245010" /&gt;&lt;/a&gt;&lt;br /&gt;The label is from a different vintage but still.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-8004155327631723437?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/8004155327631723437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=8004155327631723437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8004155327631723437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8004155327631723437'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/11/la-sauvageonne-les-ruffes-2007.html' title='La Sauvageonne, Les Ruffes 2007'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_WPaGJnpjpJQ/SSIonY5q2FI/AAAAAAAAACQ/D0rsU09uoWs/s72-c/labe_les_ruffes.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-9059019655678809729</id><published>2008-11-09T13:36:00.000-05:00</published><updated>2008-11-09T13:37:08.543-05:00</updated><title type='text'>MTV Video - A Public Service Announcement</title><content type='html'>&lt;embed src="http://media.mtvnservices.com/mgid:uma:video:mtvmusic.com:54001" width="320" height="271" type="application/x-shockwave-flash" flashVars="dist=http://www.mtvmusic.com" allowFullScreen="true" AllowScriptAccess="never"&gt;&lt;/embed&gt; &lt;div style="margin:0; text-align:center; width:320px;font-family:Arial,sans-serif;font-size:10px;"&gt;&lt;a style="color:#000000;" href="http://www.mtvmsuic.com/browne_jackson"&gt;Jackson Browne&lt;/a&gt; |&lt;a style="color:#000000;" href="http://www.mtvmusic.com/"&gt;MTV Music&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-9059019655678809729?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/9059019655678809729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=9059019655678809729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/9059019655678809729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/9059019655678809729'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/11/mtv-video-public-service-announcement.html' title='MTV Video - A Public Service Announcement'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-404958798811916080</id><published>2008-04-05T17:44:00.003-05:00</published><updated>2008-12-11T08:09:45.579-05:00</updated><title type='text'>Vina Godeval 2006</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gBtHl4sSI/AAAAAAAAABc/_xTIdbBR63s/s1600-h/godeval.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gBtHl4sSI/AAAAAAAAABc/_xTIdbBR63s/s200/godeval.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5185896845560820002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.godeval.com/"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A variatel wine rescued by a Spanish nunnery.&lt;br /&gt;&lt;br /&gt;OK, is it just me, or did that just sound like a used car dealership?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-404958798811916080?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/404958798811916080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=404958798811916080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/404958798811916080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/404958798811916080'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/04/vina-godeval-2006.html' title='Vina Godeval 2006'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gBtHl4sSI/AAAAAAAAABc/_xTIdbBR63s/s72-c/godeval.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-523455821900952622</id><published>2008-04-05T17:41:00.002-05:00</published><updated>2008-12-11T08:09:45.796-05:00</updated><title type='text'>Image test</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gAKHl4sRI/AAAAAAAAABU/aZK4B9MW-Gk/s1600-h/bbw2.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gAKHl4sRI/AAAAAAAAABU/aZK4B9MW-Gk/s200/bbw2.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5185895144753770770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This has been an image test. We now return you to your normal ration of silence.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-523455821900952622?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/523455821900952622/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=523455821900952622' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/523455821900952622'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/523455821900952622'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/04/image-test.html' title='Image test'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WPaGJnpjpJQ/R_gAKHl4sRI/AAAAAAAAABU/aZK4B9MW-Gk/s72-c/bbw2.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-4443286194881682002</id><published>2008-01-20T21:58:00.000-05:00</published><updated>2008-12-11T08:09:45.964-05:00</updated><title type='text'>Wine Blogging - Show</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WPaGJnpjpJQ/R5QKn0E8MGI/AAAAAAAAABM/1Pd4AxLmMes/s1600-h/yhst-16781478792013_1981_16674981.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WPaGJnpjpJQ/R5QKn0E8MGI/AAAAAAAAABM/1Pd4AxLmMes/s200/yhst-16781478792013_1981_16674981.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5157759152356601954" /&gt;&lt;/a&gt;&lt;br /&gt;Excellent Wine.  From &lt;a href="http://store.vintagespec.com/bgsproduction05cacs.html"&gt;VintageSpec&lt;/a&gt;;&lt;br /&gt;&lt;blockquote&gt;Unlike most inexpensive Cabernet Sauvignon on the market, this one is friendly to the palate. It is full of ripe juicy dark berry fruit layered with vanilla, clove, and allspice. It is not extremely complex, but it is good! A touch of Merlot, Cabernet Franc, Petite Verdot, and Petite Syrah are incorporated to round out the boldness of the Cabernet Sauvignon grape.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-4443286194881682002?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/4443286194881682002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=4443286194881682002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4443286194881682002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4443286194881682002'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/01/wine-blogging-show.html' title='Wine Blogging - Show'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WPaGJnpjpJQ/R5QKn0E8MGI/AAAAAAAAABM/1Pd4AxLmMes/s72-c/yhst-16781478792013_1981_16674981.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-7548881815388355931</id><published>2008-01-05T17:13:00.000-05:00</published><updated>2008-12-11T08:09:46.153-05:00</updated><title type='text'>Wine Blogging - 2006 Moschofilero Boutari</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WPaGJnpjpJQ/R4ABQkE8MFI/AAAAAAAAABE/snpm4JWHkc4/s1600-h/91926d.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WPaGJnpjpJQ/R4ABQkE8MFI/AAAAAAAAABE/snpm4JWHkc4/s200/91926d.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5152119357785780306" /&gt;&lt;/a&gt;A solid dry white wine. Lots of fruit, both for the palate and the nose.  There is a bit of minerality to  refresh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-7548881815388355931?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/7548881815388355931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=7548881815388355931' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/7548881815388355931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/7548881815388355931'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2008/01/wine-blogging-2006-moschofilero-boutari.html' title='Wine Blogging - 2006 Moschofilero Boutari'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_WPaGJnpjpJQ/R4ABQkE8MFI/AAAAAAAAABE/snpm4JWHkc4/s72-c/91926d.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-5089246665891287970</id><published>2007-11-19T21:03:00.000-05:00</published><updated>2007-11-19T21:08:36.004-05:00</updated><title type='text'>Wine Blogging - Belle Glos Meiomi</title><content type='html'>A 2006 pinot noir from Sonoma, this is nice warm red wine.  Full-bodied, but still light.  Lots of fruit for the  palate.  (Think peaches and a hint of vanilla.)  Has a bit of chocolate for the finish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-5089246665891287970?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/5089246665891287970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=5089246665891287970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/5089246665891287970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/5089246665891287970'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/11/wine-blogging-belle-glos-meiomi.html' title='Wine Blogging - Belle Glos Meiomi'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-7294642065112482609</id><published>2007-11-03T17:36:00.001-05:00</published><updated>2008-12-11T08:09:46.323-05:00</updated><title type='text'>Wine Blogging - Pirramimma petit verdot</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WPaGJnpjpJQ/Ryz4Fpf-exI/AAAAAAAAAA8/WMkr8BAO1ww/s1600-h/petit.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_WPaGJnpjpJQ/Ryz4Fpf-exI/AAAAAAAAAA8/WMkr8BAO1ww/s200/petit.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5128746851591158546" /&gt;&lt;/a&gt;&lt;br /&gt;A good fall red wine.  The nose shows grilled pineapple (smell the caramel!)&lt;br /&gt;There is plenty of summer fruits like peaches in the palate and the is full bodied enough to keep one warm on those crisp autumn evenings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-7294642065112482609?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/7294642065112482609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=7294642065112482609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/7294642065112482609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/7294642065112482609'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/11/wine-blogging-pirramimma-petit-verdot.html' title='Wine Blogging - Pirramimma petit verdot'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WPaGJnpjpJQ/Ryz4Fpf-exI/AAAAAAAAAA8/WMkr8BAO1ww/s72-c/petit.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-657929708955875596</id><published>2007-08-14T19:24:00.001-05:00</published><updated>2008-12-11T08:09:46.502-05:00</updated><title type='text'>Wine Post - Teusner Jousha 2005</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_WPaGJnpjpJQ/RsJIAgDRh3I/AAAAAAAAAA0/hqcFYKwUfDs/s1600-h/winebottle_copy1.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_WPaGJnpjpJQ/RsJIAgDRh3I/AAAAAAAAAA0/hqcFYKwUfDs/s200/winebottle_copy1.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5098716901577688946" /&gt;&lt;/a&gt;&lt;br /&gt;What can I say but rant and rave, rant and rave?&lt;br /&gt;An extraordinary red wine.  The nose is a little sharp (can I say spicy?) with a lot berry and some vanilla.  The taste of the wine fills the mouth with lots of fruit (I just cannot identify it).  And while it does have some eucalyptus, among other things) at the back of the mouth, there is a very long finish of vanilla.&lt;br /&gt;&lt;br /&gt;Since the vineyard is marketing the &lt;a href="http://www.teusner.com.au/display_wine.php?ID=15"&gt;Joshua 2006&lt;/a&gt; vintage, I'd better grab the '05 while I can&lt;br /&gt;&lt;br /&gt;Ed: Raspberries, red Raspberries!!  That was the fruit that I was tasting!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-657929708955875596?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/657929708955875596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=657929708955875596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/657929708955875596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/657929708955875596'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/08/wine-post-teusner-jousha-2005.html' title='Wine Post - Teusner Jousha 2005'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_WPaGJnpjpJQ/RsJIAgDRh3I/AAAAAAAAAA0/hqcFYKwUfDs/s72-c/winebottle_copy1.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-8924373703357001645</id><published>2007-08-05T17:05:00.000-05:00</published><updated>2008-12-11T08:09:46.648-05:00</updated><title type='text'>Wine of the Day - Ciro, Rosso Classico</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_WPaGJnpjpJQ/RrZJtQDRh2I/AAAAAAAAAAs/OvG_iF1wNfg/s1600-h/Ciro+Librandi+Rosso+Classico+02.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_WPaGJnpjpJQ/RrZJtQDRh2I/AAAAAAAAAAs/OvG_iF1wNfg/s200/Ciro+Librandi+Rosso+Classico+02.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5095341070167934818" /&gt;&lt;/a&gt;&lt;br /&gt;A dark red wine, Ciro starts off with caramel and fig overtones and has a nice warm finish.  One point of interest, the grape used in this wine also made the wine that Greece imported way, way, WAY back when Greece was establishing colonies on the Italian peninsula.&lt;br /&gt;Still a very good, solid table red.&lt;br /&gt;&lt;br /&gt;PS. Cherry.  Did I mention cherry in the finish?  There is a taste of cherries (dark cherries) in the finish that lingers a bit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-8924373703357001645?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/8924373703357001645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=8924373703357001645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8924373703357001645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8924373703357001645'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/08/wine-of-day-ciro-rosso-classico.html' title='Wine of the Day - Ciro, Rosso Classico'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_WPaGJnpjpJQ/RrZJtQDRh2I/AAAAAAAAAAs/OvG_iF1wNfg/s72-c/Ciro+Librandi+Rosso+Classico+02.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-524146189025895905</id><published>2007-08-01T19:17:00.000-05:00</published><updated>2007-08-01T19:28:37.487-05:00</updated><title type='text'>Wine of the Day - Palazzo Della Torre</title><content type='html'>A dry red wine, light enough for the heat of summer but has enough body to hold its own with grilled or braised meals.  Lots of woody aromas for the nose with floral notes, the taste is more a blend between herbs and currants with some oak coming out at the back of the tongue.&lt;br /&gt;&lt;br /&gt;This wine is unusual in that some of the grapes used are dried for three months before blended with the rest of the harvest.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-524146189025895905?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/524146189025895905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=524146189025895905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/524146189025895905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/524146189025895905'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/08/wine-of-day-palazzo-della-torre.html' title='Wine of the Day - Palazzo Della Torre'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-4446229830044461460</id><published>2007-06-23T09:53:00.000-05:00</published><updated>2007-06-23T09:56:55.457-05:00</updated><title type='text'>Wine Blogging: Spier Pinotage, 2005</title><content type='html'>Spier 2005 Pinotage&lt;br /&gt;&lt;br /&gt;A ruby red Shiraz.  Jammy, but not overly sweet.  More to the herbal / woodsy end of red wines.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-4446229830044461460?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/4446229830044461460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=4446229830044461460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4446229830044461460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/4446229830044461460'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/06/wine-blogging-spier-pinotage-2005.html' title='Wine Blogging: Spier Pinotage, 2005'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-1794941708805365435</id><published>2007-05-24T17:58:00.000-05:00</published><updated>2007-05-24T18:03:34.118-05:00</updated><title type='text'>ToDo list</title><content type='html'>What I need to do ...&lt;br /&gt;1) I had to re-create my Poggle game program, so I should do a write-up of what I changed.&lt;br /&gt;2) A study of my Concentration game program, with respect to unit and regression tests.&lt;br /&gt;3) Re-create my Kono game program.&lt;br /&gt;4) Go over game position evaluation, a la Conway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-1794941708805365435?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/1794941708805365435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=1794941708805365435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1794941708805365435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1794941708805365435'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/todo-list.html' title='ToDo list'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-8730891152197810862</id><published>2007-05-22T21:38:00.000-05:00</published><updated>2008-12-11T08:09:47.043-05:00</updated><title type='text'>Wine Blogging: The Pretty Miss, Creed of Barossa</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_WPaGJnpjpJQ/RlOpZWqPNoI/AAAAAAAAAAc/urxnh5nHLTM/s1600-h/The+Pretty+Miss+Front+Label.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_WPaGJnpjpJQ/RlOpZWqPNoI/AAAAAAAAAAc/urxnh5nHLTM/s320/The+Pretty+Miss+Front+Label.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5067580258766501506" /&gt;&lt;/a&gt;&lt;br /&gt;A very good blended red wine.  Warm with lots of fruit in the palate, somewhere between cherry and plum.  Recommended meal would be grilled porterhouse steak that was rested on a mix of chopped rosemary and thyme with a drizzle of olive oil.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-8730891152197810862?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/8730891152197810862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=8730891152197810862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8730891152197810862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8730891152197810862'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/wine-blogging.html' title='Wine Blogging: The Pretty Miss, Creed of Barossa'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_WPaGJnpjpJQ/RlOpZWqPNoI/AAAAAAAAAAc/urxnh5nHLTM/s72-c/The+Pretty+Miss+Front+Label.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-104045587577258035</id><published>2007-05-21T23:10:00.000-05:00</published><updated>2007-05-22T00:14:09.009-05:00</updated><title type='text'>Programming Mephistopheles' Computer</title><content type='html'>In terms of paranoia, there are three ways to look at computers;&lt;br /&gt;Naive - Once a program compiles and is debugged successfully, there will be no problems with the program.  Apart from the user of course.&lt;br /&gt;Murphy's Computer - Programs will fail fail at random.  Usually at the worst moment for the user.&lt;br /&gt;Mephistopheles' Computer - Programs will not just fail, they will fail in a manner to cause the most pain for the user.&lt;br /&gt;&lt;br /&gt;While it is a good idea to lock down the program's input so that a &amp;quot;clueless user&amp;quot; (translation: some one who can find an undocumented feature) cannot break a program, there are are other ways that inputs can mess up a system.  For instance between threads, between processes, or between function calls.  In many cases, the programmer must add reality checks to any input from any source, &amp;quot;trusted&amp;quot; or not, in order to keep problem at a minimum.&lt;br /&gt;&lt;br /&gt;For instance, reading and writing to the Windows registry.  The cases a program will access the registry can be summed into three;  when the program starts, when the program stops, and when the program's parameters change.&lt;br /&gt;When the program starts, either the registry entries are there or they are not, as in starting the program for the first time.  Plus, just because the root entry is there for the program, does not mean that the sub-entries are there as well.&lt;br /&gt;All a quitting program wants is to write what ever values it has into the registry.  If the entry is not there the entry can be created for the value to be stored..&lt;br /&gt;When the program changes parameters, all that it needs is to store the old value and read the new value.  While if the entry for the old value does not exist and can be created, a non-existent new value means that the program must recreated this new value with the programmed defaults.&lt;br /&gt;&lt;br /&gt;Note that with multiple choices, the program does not have to check those choices not wanted.  When done properly, this can be done on-the-fly.&lt;br /&gt;&lt;br /&gt;Just remember, &amp;quot;The devil is in the detail.&amp;quot;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-104045587577258035?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/104045587577258035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=104045587577258035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/104045587577258035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/104045587577258035'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/programming-mephistopheles-computer.html' title='Programming Mephistopheles&apos; Computer'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-1509066755676074963</id><published>2007-05-20T19:54:00.000-05:00</published><updated>2008-12-11T08:09:47.209-05:00</updated><title type='text'>Today's Wine Domaine du Loou, Espirit de Blancs</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlDuz2qPNnI/AAAAAAAAAAU/LwxhX5Xt9NA/s1600-h/VAR+loou+98.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlDuz2qPNnI/AAAAAAAAAAU/LwxhX5Xt9NA/s320/VAR+loou+98.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5066812155405219442" /&gt;&lt;/a&gt;&lt;br /&gt;Domaine du Loou, Espirit de Blancs is a nice crisp wine from Provence.  Its taste of green apple will complement curries and satay dishes.  The residual sugars will go nicely with any spicy dish, but don't serve this wine with intense tomato based chilies.&lt;br /&gt;&lt;br /&gt;Recommended meal: Fine Cooking's Best of issue, Spring/Summer 2007's Thai Marinated Roast Chicken with Lemongrass-Peanut Pan Sauce with Bon Appetit's June 2007 issue's Strawberry-Blueberry Summer Pudding for dessert.  In order to get more sauce for the chicken recipe, I would recommend that a quarter cup of chicken broth be added to the roasting pan, either for the basting for just for scrapping up the drippings.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-1509066755676074963?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/1509066755676074963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=1509066755676074963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1509066755676074963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/1509066755676074963'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/todays-wine-domaine-du-loou-espirit-de.html' title='Today&apos;s Wine Domaine du Loou, Espirit de Blancs'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlDuz2qPNnI/AAAAAAAAAAU/LwxhX5Xt9NA/s72-c/VAR+loou+98.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-8148947371170572346</id><published>2007-05-20T15:18:00.000-05:00</published><updated>2008-12-11T08:09:47.405-05:00</updated><title type='text'>Today's Wine, Joel Gott Cabernet Sauvignon 2005</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlCuT2qPNmI/AAAAAAAAAAM/mYeCdLt-u90/s1600-h/swllc_1947_125559.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlCuT2qPNmI/AAAAAAAAAAM/mYeCdLt-u90/s320/swllc_1947_125559.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5066741236905227874" /&gt;&lt;/a&gt;&lt;br /&gt;(Actually yesterday's wine.)&lt;br /&gt;Joel Gott Cabernet Sauvignon 2005, Blend 815 is a big fruity wine.  About 17.00 USD.  It goes well with grilled foods.  Think sirloin burgers topped with roasted onions and bleu cheese.&lt;br /&gt;&lt;br /&gt;I had this with skirt steak simmered in chili sauce (cooked ancho and jalapeno peppers pureed with garlic, salt, anise seed and tomatillos, then strained) and served with guacamole.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-8148947371170572346?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/8148947371170572346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=8148947371170572346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8148947371170572346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/8148947371170572346'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/todays-wine-jole-gott-cabernet.html' title='Today&apos;s Wine, Joel Gott Cabernet Sauvignon 2005'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_WPaGJnpjpJQ/RlCuT2qPNmI/AAAAAAAAAAM/mYeCdLt-u90/s72-c/swllc_1947_125559.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-6827933741244322005</id><published>2007-05-20T10:58:00.000-05:00</published><updated>2007-05-20T10:59:08.790-05:00</updated><title type='text'>Testing, Testing .. 1, 2, 3</title><content type='html'>Is this Mic still open?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-6827933741244322005?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/6827933741244322005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=6827933741244322005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/6827933741244322005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/6827933741244322005'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2007/05/testing-testing-1-2-3.html' title='Testing, Testing .. 1, 2, 3'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115154884759036132</id><published>2006-06-28T20:26:00.000-05:00</published><updated>2006-06-28T21:40:47.660-05:00</updated><title type='text'>Kono: the Board class (again)</title><content type='html'>Actually a bit more than a variable move made it necessary to refoactor every thing.&lt;br /&gt;&lt;br /&gt;O.K., the &lt;span style="font-weight:bold;"&gt;CBoard&lt;/span&gt; class is purely about the playing field.  The reason why earlier versions placed movement functionality here was confusion about the similarity between checking for possible movement paths and checking for neighbouring regions.&lt;br /&gt;&lt;br /&gt;So, the minimum required for the CBoard class is (ignoring Singleton issues) drawing the board and retrieving board and region information.  The functions about neighbourhoods can be skipped as there is no special or missing neighbouring cells to be concerned with.&lt;br /&gt;&lt;br /&gt;The named constants:&lt;br /&gt;Private;&lt;br /&gt;drawing constants for the playing field, and&lt;br /&gt;number of cells&lt;br /&gt;Public:&lt;br /&gt;OFF_BOARD.&lt;br /&gt;&lt;br /&gt;Variables:&lt;br /&gt;Private;&lt;br /&gt;array of regions for selecting pieces, and&lt;br /&gt;array of regiond for selecting playing regions.&lt;br /&gt;&lt;br /&gt;Static Functions (no need to create or release instances to call these):&lt;br /&gt;Public;&lt;br /&gt;retrieve dimensions of layout (number of cells for each direction), and&lt;br /&gt;check that location (x,y) is in bounds.&lt;br /&gt;&lt;br /&gt;Functions:&lt;br /&gt;Public;&lt;br /&gt;retrieve the region for location (x,y),&lt;br /&gt;match location (x,y) to point,&lt;br /&gt;drawing,&lt;br /&gt;retrieving the size of the playing field (in pixels), and&lt;br /&gt;Singleton functionality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115154884759036132?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115154884759036132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115154884759036132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115154884759036132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115154884759036132'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/kono-board-class-again.html' title='Kono: the Board class (again)'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115056834367401527</id><published>2006-06-17T12:27:00.000-05:00</published><updated>2006-06-17T13:22:03.363-05:00</updated><title type='text'>The Scoring System, Nimbers III</title><content type='html'>Once Nimber arithmetic is explained with 3 stacks, there is no need to go any further.  The value of four or more stacks can be determined as combinations of 1, 2 and/or 3 stacks.&lt;br /&gt;&lt;br /&gt;The starting point here is to use 3 stacks containing 1, 2 and 3 counters.  These 3 stacks (1* + 2* + 3*) have the combined value of 0.  If the first person removes one of the stacks, the second person can then equalize the remaining stacks and leave the Game with a value of 0 again.  Alternatively if the first person equalizes two of the three  stacks, then the second person can remove the un-equal third stack and leave the game with 2 equal stacks again.&lt;br /&gt;So the first set of equivalences in Nimber Addition are;&lt;br /&gt;&lt;br /&gt;1* + 2* + 3* = 0&lt;br /&gt;1* + 2* = 3*&lt;br /&gt;1* + 3* = 2*&lt;br /&gt;2* + 3* = 1*&lt;br /&gt;&lt;br /&gt;The next triplet of Nimbers in Winning Ways, Vol. 1 that equal 0 can be played out in much the same manner.  In addition to the moves mentioned before (first player: removes a stack, second player: equalizes the remaining stacks and first player: equalizes 2 stacks, second player: removes the un-equal stack), the second player also has the following strategy.  If the first player reduces one of the bigger stacks to either 2* or 3*, the second player can remove counters from the other large stack to give it a value of 3* or 2* respectively.  The game now has the value of 1* + 2* + 3* or, as previously determined, 0.&lt;br /&gt;&lt;br /&gt;Evaluating any random set of 3 stacks is not terribly difficult.  One just has to find the Nimber value of two smaller stacks.  If this value equals the third stack, the total value of the triplet is 0 and the first person to play loses.  If the combined Nimber value of the smaller stack does &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equal the third stack, all the first player needs to do to win is to reduce the third stack to the value calculated and leave the Game with the value of 0.&lt;br /&gt;&lt;br /&gt;Further examples of Nimber addition can be found in Berkamp, Conway and Guy's &amp;quot;Winning Ways, Vol. 1&amp;quot;, pages 42 and 59 - 59.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115056834367401527?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115056834367401527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115056834367401527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115056834367401527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115056834367401527'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/scoring-system-nimbers-iii.html' title='The Scoring System, Nimbers III'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115056516251934580</id><published>2006-06-17T12:11:00.000-05:00</published><updated>2006-06-17T13:19:53.316-05:00</updated><title type='text'>The Scoring System, Nimbers II</title><content type='html'>Beginning with two stacks, the properties of Nimbers start appearing.&lt;br /&gt;&lt;br /&gt;Two stacks of equal height (with equal Nimber values) turns out to have a total value of 0 (the first person to move loses).  If the first person takes an entire stack, the second person take the second stack and the first person is left without a move.  On the other hand if the first person takes only part of a stack, the second person takes the same amount from the other stack and leaves the total value 0 as before.&lt;br /&gt;Thus the first property of Nimbers is that two Nimbers of equal value total to 0 (n* + n* = 0). In other words, a Nimber is its own negative.&lt;br /&gt;&lt;br /&gt;Two stacks of unequal value mean that the first person wins, of course.  The best strategy is for the first person to equalize the stacks leaving a Game with the value of 0 for the second player.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115056516251934580?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115056516251934580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115056516251934580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115056516251934580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115056516251934580'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/scoring-system-nimbers-ii.html' title='The Scoring System, Nimbers II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115024930366474865</id><published>2006-06-13T20:32:00.000-05:00</published><updated>2006-06-13T20:41:43.666-05:00</updated><title type='text'>The Scoring System II, Nimbers</title><content type='html'>Now consider Lucy and Robert with a single stack of cookies.  They take turns eating one or more cookies from the stack.  The loser in this game is the one that cannot get any more cookies to eat from the stack.&lt;br /&gt;&lt;br /&gt;The best strategy for either player is to grab the entire stack.&lt;br /&gt;&lt;br /&gt;Here the first person to play wins.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115024930366474865?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115024930366474865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115024930366474865' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115024930366474865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115024930366474865'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/scoring-system-ii-nimbers.html' title='The Scoring System II, Nimbers'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115024867134934802</id><published>2006-06-13T20:18:00.000-05:00</published><updated>2006-06-13T20:31:11.360-05:00</updated><title type='text'>The Scoring System I</title><content type='html'>Skipping over fractional game values for the time being, let us talk whole numbers.&lt;br /&gt;&lt;br /&gt;We will start off considering games blocking games where the first person without a move loses.  By convention, the Left player (which I'll name Lucy) will win if the game's value is positive, &amp;gt;0, or, in other words, has move moves than the opposing side.  And the right player (Robert) will win if the game's value is less than 0, more moves than Lucy.&lt;br /&gt;If the game has a value of 0 (think of a game board without pieces), then the first person to move is the loser (no piece to move).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Follow along with Berlekamp, Conway, and Guy in "Winning Ways".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115024867134934802?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115024867134934802/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115024867134934802' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115024867134934802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115024867134934802'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/scoring-system-i.html' title='The Scoring System I'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-115023341372262295</id><published>2006-06-13T16:12:00.000-05:00</published><updated>2006-06-13T16:16:53.740-05:00</updated><title type='text'>scheduling</title><content type='html'>One of the problems I am having is that when I built up my collection of programs I tended to skip around, going from one program to another, to avoid burning out.  This tends to make for long development times.&lt;br /&gt;&lt;br /&gt;I will try to blog on a regular basis, once I get my scheduling together.  Until then, all I can do is random posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-115023341372262295?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/115023341372262295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=115023341372262295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115023341372262295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/115023341372262295'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/scheduling.html' title='scheduling'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114989915382572709</id><published>2006-06-09T19:17:00.000-05:00</published><updated>2006-06-09T19:25:53.826-05:00</updated><title type='text'>Kono: regarding Rules class</title><content type='html'>Applying rules of the game without specifiing who is in that location just dose not make sense.  About the only way that one can apply a movement rule and not care about ownership is with non-partisan (pieces can be moved by anyone) games or games that have both partisan and non-partisan pieces.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114989915382572709?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114989915382572709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114989915382572709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114989915382572709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114989915382572709'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/kono-regarding-rules-class.html' title='Kono: regarding Rules class'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114964255699034831</id><published>2006-06-06T20:08:00.000-05:00</published><updated>2006-06-06T20:09:17.013-05:00</updated><title type='text'>Happy 6/6/6</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3450/2341/1600/666mob.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/3450/2341/320/666mob.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114964255699034831?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114964255699034831/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114964255699034831' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114964255699034831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114964255699034831'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/happy-666.html' title='Happy 6/6/6'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114947173572416680</id><published>2006-06-04T20:38:00.000-05:00</published><updated>2006-06-04T20:42:15.736-05:00</updated><title type='text'>Kono, re-going over the go-over</title><content type='html'>It is rather embassasing to re-do teh rules class in order to get it to check that the piece moved is actually owned, much less owned by the proper side.  I.e., &lt;span style="font-weight:bold;"&gt;Pre-Condition&lt;/span&gt; from point is player&lt;span style="font-style:italic;"&gt;X&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114947173572416680?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114947173572416680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114947173572416680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114947173572416680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114947173572416680'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/06/kono-re-going-over-go-over.html' title='Kono, re-going over the go-over'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114912846045457764</id><published>2006-05-31T21:19:00.000-05:00</published><updated>2006-06-03T20:07:43.596-05:00</updated><title type='text'>More Books II</title><content type='html'>&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0521646529&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0521808324&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114912846045457764?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114912846045457764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114912846045457764' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114912846045457764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114912846045457764'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/more-books-ii.html' title='More Books II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114912834608102448</id><published>2006-05-31T21:16:00.000-05:00</published><updated>2006-05-31T21:19:06.093-05:00</updated><title type='text'>More Books</title><content type='html'>Gotta collect them all!&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1568811306&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=156881142X&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1568811438&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1568811446&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114912834608102448?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114912834608102448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114912834608102448' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114912834608102448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114912834608102448'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/more-books.html' title='More Books'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114883972392144016</id><published>2006-05-28T13:07:00.000-05:00</published><updated>2006-05-28T13:09:22.576-05:00</updated><title type='text'>An Edward Gorey Death</title><content type='html'>&lt;div style="width:380; background-color:rgb(216,233,237); text-align:center;"&gt;&lt;br /&gt; &lt;div style="background:rgb(129,172,201); height:4px;"&gt;&lt;br /&gt;  &lt;img src="http://www.quizilla.com/images/blue_drk_corner1.gif" style="float: left" height="4" hspace="0" /&gt;&lt;br /&gt;  &lt;img src="http://www.quizilla.com/images/blue_drk_corner2.gif" style="float: right" height="4" hspace="0" /&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt; &lt;div style="background:rgb(129,172,201); padding: 0pt 0pt 5px;"&gt;&lt;br /&gt;  &lt;span style="font-size:px; color:rgb(255,255,255); padding:3px; font-family:Arial;"&gt;&lt;strong&gt;What horrible Edward Gorey Death will you die?&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt; &lt;div style="padding:5px; text-align:left; font-size:px; font-family:Arial; background-color:rgb(216,233,237);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://images.quizilla.com/R/redshoecult/1044341243_turesQUIZl.jpg"&gt;&lt;br/&gt;You will swallow some tacks. You are a little weird, maybe not so much in a good way. Buy a yellow tie and wear it on your head.&lt;br/&gt;Take this &lt;a target="quizilla" style="color:rgb(0,0,0)" href="http://quizilla.com/redirect.php?statsid=17&amp;url=http://www.quizilla.com/users/redshoecult/quizzes/What+horrible+Edward+Gorey+Death+will+you+die%3F"&gt;quiz&lt;/a&gt;!&lt;br/&gt;&lt;br /&gt;&lt;br /&gt;&lt;br/&gt;&lt;a href="http://www.quizilla.com/redirect.php?statsid=18&amp;url=http://www.quizilla.com/" target="quizilla"&gt;&lt;br /&gt;&lt;img border="0" src="http://www.quizilla.com/images/codepastes/30qzlogo.gif" style="padding:2px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="color:rgb(0,0,0);" target="quizilla" href="http://www.quizilla.com/redirect.php?statsid=18&amp;url=http://www.quizilla.com"&gt;Quizilla&lt;/a&gt; | &lt;br /&gt;&lt;a style="color:rgb(0,0,0);"  target="quizilla" href="http://www.quizilla.com/redirect.php?statsid=21&amp;url=http://www.quizilla.com/register"&gt;Join&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;| &lt;a style="color:rgb(0,0,0);" target="quizilla" href="http://www.quizilla.com/redirect.php?statsid=20&amp;url=http://www.quizilla.com/makeaquiz.php"&gt;Make A Quiz&lt;/a&gt; | &lt;a target="quizilla" href="http://www.quizilla.com/redirect.php?statsid=42&amp;url=http://www.quizilla.com/users/redshoecult/quizzes/"&gt;More Quizzes&lt;/a&gt; | &lt;a style="color:rgb(0,0,0);" target="quizilla" href="http://www.quizilla.com/redirect.php?statsid=19&amp;url=http://www.quizilla.com/codepastes/?quizid=41545"&gt;Grab Code&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114883972392144016?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114883972392144016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114883972392144016' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114883972392144016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114883972392144016'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/edward-gorey-death.html' title='An Edward Gorey Death'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114869208187625313</id><published>2006-05-26T19:59:00.000-05:00</published><updated>2006-05-26T20:08:01.893-05:00</updated><title type='text'>Kono: the beginning</title><content type='html'>The two classes that are essentially remain the same (expect for the Microsoft supplied classes) are the &lt;span style="font-weight:bold;"&gt;CStone&lt;/span&gt; and the &lt;span style="font-weight:bold;"&gt;CBoard&lt;/span&gt; classes.  And about the &lt;span style="font-weight:bold;"&gt;ONLY&lt;/span&gt; thing that changes for the &lt;span style="font-weight:bold;"&gt;CBoard&lt;/span&gt; class is 1) the movement functions are moved the &lt;span style="font-weight:bold;"&gt;CRule&lt;/span&gt; class, 2) the named constant for the size of the playing area becomes private, and 3) that a new public function is added to indicate whether or not a given point is indeed on the playing area.&lt;br /&gt;&lt;br /&gt;PS.  I will start commenting on the COwner class when I finished refactoring it.  The only other bit than needs to be mentioned is that the stored piece arrays are combined within a CPoint array in order to keep the location values together.  (Saves on mental sweat.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114869208187625313?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114869208187625313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114869208187625313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114869208187625313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114869208187625313'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/kono-beginning.html' title='Kono: the beginning'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114852552088794078</id><published>2006-05-24T21:50:00.000-05:00</published><updated>2006-05-24T21:52:00.900-05:00</updated><title type='text'>Kono:  Today's post is brought to you by the letter R</title><content type='html'>R for ARRRRRGH!&lt;br /&gt;&lt;br /&gt;And here is my book recommendation;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1568811276&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114852552088794078?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114852552088794078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114852552088794078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114852552088794078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114852552088794078'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/kono-todays-post-is-brought-to-you-by.html' title='Kono:  Today&apos;s post is brought to you by the letter R'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114843152757106681</id><published>2006-05-23T19:33:00.000-05:00</published><updated>2006-05-23T19:45:27.583-05:00</updated><title type='text'>Kono: Refactoring</title><content type='html'>If I ever compile these posts, I will include my old code so programmers can have something to point to and snicker.&lt;br /&gt;&lt;br /&gt;1) The first part that gets changed is to place every function that reflects / models / or is based on a rule of the game into the &lt;span style="font-weight:bold;"&gt;Rules&lt;/span&gt; class.&lt;br /&gt;&lt;br /&gt;2) Hide as much as possible.  While the signels enumerated constants need to remain exposed, there are others that do not.  The size of the board (&lt;span style="font-style:bold;"&gt;CBoard::DX&lt;/span&gt;) is one.&lt;br /&gt;&lt;br /&gt;3) Even if copying data in two classes is faster, don't.  Better to 'waste' computer cycles in function calls that to miss synchronizing the data and causing odd results.  (The exapmle here is the &lt;span style="font-style:italic;"&gt;COwner::Player ownership&lt;/span&gt; array in the &lt;span style="font-weight:bold;"&gt;CGame&lt;/span&gt; class.)&lt;br /&gt;&lt;br /&gt;4) Right now the only other bit that I can see is to minimize the amount of data that goes into the &lt;span style="font-weight:bold;"&gt;Undo&lt;/span&gt; and the &lt;span style="font-weight:bold;"&gt;MoveGenerator&lt;/span&gt; classes.  (Note: Optimize was not mentioned.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114843152757106681?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114843152757106681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114843152757106681' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114843152757106681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114843152757106681'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/kono-refactoring.html' title='Kono: Refactoring'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114834899435857006</id><published>2006-05-22T19:57:00.000-05:00</published><updated>2006-05-22T20:49:54.450-05:00</updated><title type='text'>Poggle: more solutions</title><content type='html'>5-by-5&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="5"&gt;Black and White&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="5"&gt;3 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="5"&gt;4 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="5"&gt;5 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;6-by-6&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="6"&gt;Black and White&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="6"&gt;3 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="6"&gt;4 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="6"&gt;5 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;7-by-7&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="7"&gt;Black and White&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="7"&gt;3 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="7"&gt;4 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="7"&gt;5 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114834899435857006?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114834899435857006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114834899435857006' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114834899435857006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114834899435857006'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/poggle-more-solutions.html' title='Poggle: more solutions'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114815821979815480</id><published>2006-05-20T15:14:00.000-05:00</published><updated>2006-05-22T20:51:16.306-05:00</updated><title type='text'>Poggle, the solutions</title><content type='html'>One interesting point is that there is only &lt;span style="font-weight:bold;"&gt;ONE&lt;/span&gt; solution for each of the 3-by-3 Poggle variants.  For the 4-by-4 Poggle versions, quite a few more.&lt;br /&gt;The 4-by-4 Poggle game's linear algebra solutions required that two or more buttons be completely specified before the entire solution could be show.  I did re-discover a solution for this version that I had first found back when I was first putting this program together. (A "d'oh!" type solution you will see when it is described.)&lt;br /&gt;&lt;br /&gt;For the 3-by-3 Poggle puzzles;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="3"&gt;2 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="3"&gt;3 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="3"&gt;4 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td colspan="3"&gt;5 Colours&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;For the 4-by-4 Poggle version, consider the following.  There are location on any Poggle board that toggle EXACTLY 4 buttons.  Given that the 4-by-4 Poggle board has 16 button, only 4 buttons should be pressed to cover the entire Poggle board.  And here they are.&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;and its mirror image&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;X&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;.  See what was meant by this solution being a 'kick yourself' moment for not seeing it immediately?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114815821979815480?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114815821979815480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114815821979815480' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114815821979815480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114815821979815480'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/poggle-solutions.html' title='Poggle, the solutions'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114800465759222757</id><published>2006-05-18T19:50:00.000-05:00</published><updated>2006-05-18T21:10:57.683-05:00</updated><title type='text'>Poggle, Revisited II</title><content type='html'>You know you're in trouble when one find statements similar to "... which proves that &lt;span style="font-weight:bold;"&gt;some&lt;/span&gt; initial states are insolvable." (My emphasis.)  The question becomes, how does one find out this difference?&lt;br /&gt;&lt;br /&gt;In "Adventures in Groups Theory", David Joyner points to a &lt;a href="http://www.math.niu.edu/~rusin/papers/uses-math/games/other/lights"&gt;post&lt;/a&gt; by D. Rusin.  In it, one Carsten Haese lays out the solution to a similar game that can be applied to Poggle.  I will attempt to reproduce it in this post.&lt;br /&gt;&lt;br /&gt;Short form: convert the game to linear algebraic form and solve.  &lt;span style="font-style:italic;"&gt;Not-so&lt;/span&gt; short form: stock up on asprin.&lt;br /&gt;&lt;br /&gt;Think of Poggle as a state machine with; a internal state (here, the buttons that are light), an input alphabet (the buttons), an output alphabet (the lights), an internal trasition table (the new internal state, given a specified internal state and the input), and an output table (given an internal state and an input, the output).  As the output, input and internal state can be folded into one set and the tables can be considered as one, there are only two items that need to be looked at.&lt;br /&gt;&lt;br /&gt;The state can be represented by a one-dimensional vector that is n-squared elements long.  Think of this vector representing the Poggle board's display layed out row by row (from top to bottom).&lt;br /&gt;&lt;br /&gt;Now to build the transition table.  The size of the table will be n-squared by n-squared elements.  The building blocks cosist of;&lt;br /&gt;the Identity Matrix (size n-by-n),&lt;br /&gt;the Zero Matrix (size n-by-n), and&lt;br /&gt;&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;B&lt;/span&gt;&lt;/td&gt;&lt;td&gt;=&lt;/td&gt;&lt;td&gt;&lt;table border="1" cellpadding="5" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="6" align="center"&gt; .. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt; (size n-by-n).&lt;br /&gt;The construction of the B matrix is placing 1's in the main diagonal of the n-by-n matrix and in the diagonals above and below it.  0's are placed every where else.&lt;br /&gt;&lt;br /&gt;The transition matrix is formed&lt;br /&gt;&lt;table border="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt;&lt;/td&gt;&lt;td&gt;=&lt;/td&gt;&lt;td&gt;&lt;table border="1" cellpadding="5" cellspacing="0"&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;B&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;B&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;B&lt;/span&gt;&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="6" align="center"&gt; .. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;0&lt;/span&gt;&lt;/td&gt;&lt;td&gt; .. &lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;B&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;For instance the 3-by-3 Poggle board's transition matrix is;&lt;table&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;For Poggle the solution can be foudn with the linear equation;&lt;br /&gt;(&lt;span style="font-weight:bold;"&gt;A&lt;/span&gt; &lt;span style="font-style:italic;"&gt;x&lt;/span&gt; = &lt;span style="font-style:italic;"&gt;s0&lt;/span&gt;) mod y.&lt;br /&gt;where &lt;span style="font-style:italic;"&gt;s0&lt;/span&gt; is the starting vector (a 1 dimensional vector containing n-squared 1's for Poggle), and &lt;span style="font-style:italic;"&gt;x&lt;/span&gt; is the vector containing the buttons to input.  The modulus y is simply the total number of colours that the program cycles through.&lt;br /&gt;&lt;br /&gt;Using {a,b,c,d,e,f,g,h,i} to denote the solution vector, the 3-by-3 Pobble board can be solved with the solution of;&lt;br /&gt;a + b + d = 1 mod y,&lt;br /&gt;a + b + c + e = 1 mod y,&lt;br /&gt;b + c + f = 1 mod y,&lt;br /&gt;a + d + e + g = 1 mod y,&lt;br /&gt;b + d + e + f + h = 1 mod y,&lt;br /&gt;c + e + f + i = 1 mod y,&lt;br /&gt;d + g + h = 1 mod y,&lt;br /&gt;e + g + h + i = 1 mod y,&lt;br /&gt;f + h + i = 1 mod y.&lt;br /&gt;&lt;br /&gt;For y=2 it is easy to see that {1,0,1,0,1,0,1,0,1} is the solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114800465759222757?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114800465759222757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114800465759222757' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114800465759222757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114800465759222757'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/poggle-revisited-ii.html' title='Poggle, Revisited II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114792174266170522</id><published>2006-05-17T22:04:00.000-05:00</published><updated>2006-05-17T22:09:02.670-05:00</updated><title type='text'>Programming Query</title><content type='html'>When programming (and this is top-down, caller-to-callee programming) does one; program a function call before writting the function? program a function stub with a bogus and/or error return so that the program compiles? or, write a function stub and include an assert or otherwise alert the person running the program of the missing function?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114792174266170522?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114792174266170522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114792174266170522' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114792174266170522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114792174266170522'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/programming-query.html' title='Programming Query'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114783295477684526</id><published>2006-05-16T21:14:00.000-05:00</published><updated>2006-05-16T21:29:14.790-05:00</updated><title type='text'>Kono, some changes</title><content type='html'>OK, one added class is a Singleton class to check moves against rules of the game.  This will (not in this game but in others) reduce the CBoard class to checking if cell X and cell Y are, in fact, neighbours.&lt;br /&gt;The other class that will be added is a display class that will show either al possible moves or possible moves that were graded into best to worst.&lt;br /&gt;&lt;br /&gt;One big change in this program is that the game can be saved.  A short-cut toward this is to derive the CGame and the COwner classes from CObject to take advantage of the Serialize function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114783295477684526?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114783295477684526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114783295477684526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114783295477684526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114783295477684526'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/kono-some-changes.html' title='Kono, some changes'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114774886831695733</id><published>2006-05-15T22:02:00.000-05:00</published><updated>2006-05-15T22:07:48.316-05:00</updated><title type='text'>Kono, the rule of the game</title><content type='html'>The playing field is a 4 by 4 square.  Each player has 8 pieces starting on opposing halves of the playing field.&lt;br /&gt;&lt;br /&gt;Pieces can &lt;span style="font-weight:bold;"&gt;move&lt;/span&gt; one place either vertically or horizontally.&lt;br /&gt;&lt;br /&gt;Pieces &lt;span style="font-weight:bold;"&gt;capture&lt;/span&gt; by jumping over one friendly piece onto an opposing piece, again either vertically or horizontally.&lt;br /&gt;&lt;br /&gt;One side wins when the other side cannot move, either by blocking the other side's pieces or by capturing all of the opposing pieces.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114774886831695733?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114774886831695733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114774886831695733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114774886831695733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114774886831695733'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/kono-rule-of-game.html' title='Kono, the rule of the game'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114758360553756715</id><published>2006-05-14T00:00:00.000-05:00</published><updated>2006-05-14T00:13:25.546-05:00</updated><title type='text'>The next game</title><content type='html'>One can almost flip a coin between Alquerque and 'Four Field' Kono, remove all the opposing pieces or keep the pieces from moving.  Well, considering that the popular game to program is Alquerqeu, I will go with Kono.  The mechanism is pretty much the same if one elides past the &lt;span style="font-style:italic;"&gt;huff&lt;/span&gt; rule and the capture method.&lt;br /&gt;I could have gone with Alquerque's cousin, Fanorona.  But the capture rules are not exactly clear.&lt;br /&gt;&lt;br /&gt;I will present 'Fox and Geese' and Four Handed Shaturanga (an early form of chess) later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114758360553756715?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114758360553756715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114758360553756715' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114758360553756715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114758360553756715'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/next-game.html' title='The next game'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114758204970066754</id><published>2006-05-13T23:40:00.000-05:00</published><updated>2006-05-13T23:47:29.710-05:00</updated><title type='text'>Mu Torere, Improvements</title><content type='html'>Step 21.&lt;br /&gt;&lt;br /&gt;Well one thing that can be added is accessibility, again.  In other words, adjusting the colours and enabling keybourd-only input.&lt;br /&gt;&lt;br /&gt;Another improvement is to change the art-work.  As was said earlier another background that can be used is an eight spoked wheel, with or without the rim.  A bitmap can be used for the background too.  Use your imagination, is the playing field scratched on stone?  scribbled into sand? or in-laid in wood?  3-D sprites can also be used for the playing pieces.&lt;br /&gt;&lt;br /&gt;Other improvements range from optimizing the program to adding more moves to the 'AI's' look-ahead.&lt;br /&gt;&lt;br /&gt;Good Luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114758204970066754?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114758204970066754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114758204970066754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114758204970066754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114758204970066754'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-improvements.html' title='Mu Torere, Improvements'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114738432139138629</id><published>2006-05-11T16:50:00.000-05:00</published><updated>2006-05-11T16:52:01.406-05:00</updated><title type='text'>Mu Torere, the Final test</title><content type='html'>Step 19.&lt;br /&gt;Like last time, the program needs to be checked for syntax errors at each of the previous steps.&lt;br /&gt;&lt;br /&gt;For Q &amp; A (re-test all the steps each time corrections are needed);&lt;br /&gt;&lt;br /&gt;A - Run the 'Mu Torere' program. Examine the menu, but do not try anything.  Then exit the program.&lt;br /&gt;Did it start cleanly? Was the menu correct? Was the program displaying correctly? Did the program exit cleanly?&lt;br /&gt;&lt;br /&gt;B - Run the program.  Select and then re-select the Colour Legend menu item.  Select the 'Change User Colour' menu item and change the colour.  Do the same with the 'Change Computer Colour' menu item.  Select each of the pre-set AI level of effort menu items.  Select the Custom AI Level menu item and change the value to the neighbourhood ( + / - the &lt;span style="font-weight:bold;"&gt;EPSILON&lt;/span&gt; that you picked ) of each pre-set level, selecting 'OK' each time and re-selecting the Custom AI Level dialog to select the next value. Exit the program and then re-start it.  Examine the menu items again.&lt;br /&gt;Did the Colour Legend display toggle (appear / disappear) along with the selection? Was the Colour Legend menu item checked at the same time as the Legend was displayed and unchecked when the Legend was NOT displayed?  Did the colours of the proper pieces change as new colours were selected and were those colours the ones selected?  Did the Colour Legend change as well and show the right colours?&lt;br /&gt;Did the AI Level menu items check and uncheck as different levels were selected?  Did the check mark follow the selection?  Did the changing the AI Level with the Custom AI Level dialog do anything?  Did the checkmark show when the custom value was in the neighbourhood?&lt;br /&gt;When re-starting the program, did the colours match those selected during the last run?  Does the Custom AI value match that from the last run?&lt;br /&gt;And does the program start and exit cleanly?&lt;br /&gt;&lt;br /&gt;C - Run the program.  Set the AI level of effort to 'Off' or set the Custom AI Level to 0. Select points on; the Desktop, the program caption, the program's background, the program's empty location, all pieces owned by the Computer, each of the User owned pieces that &lt;span style="font-weight:bold;"&gt;CANNOT&lt;/span&gt; be moved legally (one of the middle ones), a User piece that &lt;span style="font-weight:bold;"&gt;CAN&lt;/span&gt; be moved legally.  After the Computer moves, select points on; the program's background, the program's new empty location, all of the Computer's pieces, all of the User pieces that &lt;span style="font-weight:bold;"&gt;CANNOT&lt;/span&gt; legally move, and then the User piece that &lt;span style="font-weight:bold;"&gt;CAN&lt;/span&gt; legally move.  Select the 'New' menu item and then exit the program.&lt;br /&gt;&lt;br /&gt;Did the program move the expected legal pieces as expected and &lt;span style="font-weight:bold;"&gt;ONLY&lt;/span&gt; when a legal &lt;span style="font-weight:bold;"&gt;USER&lt;/span&gt; piece was selected? Was this behaviour repeated with the new positions?  Did selecting 'New' reset the program to the initial positions?&lt;br /&gt;Again, did the program start and exit cleanly?&lt;br /&gt;&lt;br /&gt;D - Start the program again and play a few rounds.  If the choice was made to &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; let the AI level of effort change after starting play, test that this is so.  Continue until one side or the other wins.  Try selected various points on the program to see if the program continues to move pieces.  Select 'New' and continue playing with the AI 'Off' until the side that did not win, wins.&lt;br /&gt;&lt;br /&gt;Did selecting a new AI level work?  Did the winning side messages display correctly?  Did the program stop playing at this point?&lt;br /&gt;Again, did the program start and exit cleanly?&lt;br /&gt;&lt;br /&gt;Step 20.&lt;br /&gt;Re compile the program as '&lt;span style="font-style:italic;"&gt;Release&lt;/span&gt;'.  Make sure that all options that appear under '&lt;span style="font-style:italic;"&gt;Debug&lt;/span&gt;' compiling are no longer availible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114738432139138629?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114738432139138629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114738432139138629' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114738432139138629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114738432139138629'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-final-test.html' title='Mu Torere, the Final test'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114731110937220640</id><published>2006-05-10T20:20:00.000-05:00</published><updated>2006-05-10T20:31:49.396-05:00</updated><title type='text'>Mu Torere, the rest of the story</title><content type='html'>Step 17.&lt;br /&gt;Not much else to do at this point.&lt;br /&gt;&lt;br /&gt;Just add the event handlers for the AI menu items, and code the relevant values into them.  The only vit that I would recommend is to use some sort of variance value when coding the OnUpdate&lt;span style="font-style:italic;"&gt;XXX&lt;/span&gt;() handlers.  This way when the user pick a custom AI level-of-effort that is in the neighbourhood of the program's idea of the level, the right menu item is checked.  For example;&lt;br /&gt;&lt;br /&gt;pCmdUI-&gt;SetCheck(abs(((CMuTorereApp*)AfxGetApp())-&gt;getAI() - &lt;span style="font-weight:bold;"&gt;CAILevel::LOW&lt;/span&gt;) &lt; &lt;span style="font-weight:bold;"&gt;CAILevel::EPSILON&lt;/span&gt; ? 1 : 0);&lt;br /&gt;&lt;br /&gt;I used &lt;span style="font-weight:bold;"&gt;CAILevel::EPSILON&lt;/span&gt; with the value of 3 to determine how close user chosen values had to be.&lt;br /&gt;&lt;br /&gt;Step 18.&lt;br /&gt;The registry stuff was much the same as that for the Poggle project.  So go to &lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/poggle-working-with-registry.html"&gt;this page&lt;/a&gt; to review.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114731110937220640?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114731110937220640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114731110937220640' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114731110937220640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114731110937220640'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-rest-of-story.html' title='Mu Torere, the rest of the story'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114723127816856374</id><published>2006-05-09T21:32:00.000-05:00</published><updated>2006-05-09T22:21:18.233-05:00</updated><title type='text'>Mu Torere, setting the AI</title><content type='html'>Step 16.&lt;br /&gt;The dialog for the custom AI 'Level-of-Effort' is fairly simple.  All the special functionality works on a dialog box that contains a horizontal scrollbar, a couple of static texts to mark the high and low end of the scrollbar, an edit box and the 'OK' and 'Cancel' buttons.  The only functions that need to be explained are the InitDialog(), the OnHScroll() and the OnEnChangeEdit1() (or what ever the edit box is id'ed in your program) functions.&lt;br /&gt;Using MS's IDE one should associate a variable with the edit box.&lt;br /&gt;&lt;br /&gt;Oh yes, there are a few named constants to specify the AI levels for the program.  As long as 0 is used for the Off end of the scale and around 95 for High, it really does not matter what value is used for the Low and Middle of the scale (example, 25 and 66 respectively).  Remember that the program uses the randomMove() function whenever the random value (mod 100) is &lt;span style="font-weight:bold;"&gt;GREATER&lt;/span&gt; than the AI level choosen.&lt;br /&gt;&lt;br /&gt;On dialog initialization;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;BOOL CAILevel::OnInitDialog()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get a CEdit pointer the the dialog's Edit box.&lt;br /&gt;Get a CScrollbar pointer to the dialog's horizontal scrollbar.&lt;br /&gt;&lt;br /&gt;Get the text associated with the edit box.  (Part of the Data Exchange process.)&lt;br /&gt;Re-format the text as integer.  (Use _tstoi() for the UNICODE enabled programs.)&lt;br /&gt;&lt;br /&gt;Set the lower and upper limits of the scrollbar to 0 and 100 resp.&lt;br /&gt;Set the scrollbar position to the integer value retrieved from the edit box. (As this is an initialization, the scrollbar will not need redrawing.)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;On changes of the edit box;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CAILevel::OnEnChangeEdit1()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get a CEdit pointer the the dialog's Edit box.&lt;br /&gt;Get a CScrollbar pointer to the dialog's horizontal scrollbar.&lt;br /&gt;&lt;br /&gt;Get the text associated with the edit box.  (Part of the Data Exchange process.)&lt;br /&gt;Re-format the text as integer.  (Use _tstoi() for the UNICODE enabled programs.)&lt;br /&gt;&lt;br /&gt;Set the scrollbar position to the integer value retrieved from the edit box.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;to reflect the changes of the scrollbar in the edit bxo (and the variable that is retrievable);&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CAILevel::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get the lowest limit, the highest limit and the current position of the scrollbar.&lt;br /&gt;&lt;br /&gt;Given how the scrollbar position is changing (given by &lt;span style="font-style:italic;"&gt;nSBCode&lt;/span&gt;),change the scrollbar position as appropriate.&lt;br /&gt;&lt;br /&gt;Get the CEdit pointer the edit box.&lt;br /&gt;Set the edit box's text to the value of the scrollbar's current position.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114723127816856374?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114723127816856374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114723127816856374' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114723127816856374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114723127816856374'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-setting-ai.html' title='Mu Torere, setting the AI'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114705345373411704</id><published>2006-05-07T19:59:00.000-05:00</published><updated>2006-05-07T20:57:33.870-05:00</updated><title type='text'>Mu Torere AI II</title><content type='html'>Step 15.&lt;br /&gt;&lt;br /&gt;Two new steps and a modification for the Move Generator class and a new function and a modification for the Game class.&lt;br /&gt;&lt;br /&gt;The modification is for the CMoveGenerator's getMove function;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;int CMoveGenerator::getMove(const int&amp; aiL)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Condition:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;aiL&lt;/span&gt; is between 0% and 100%, inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If a random value (mod 100) is greater than &lt;span style="font-style:italic;"&gt;aiL&lt;/span&gt;, use the &lt;span style="font-style:italic;"&gt;randomMove&lt;/span&gt;(&lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt;) function.&lt;br /&gt;Otherwise use the &lt;span style="font-style:italic;"&gt;aiMove&lt;/span&gt;(&lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt;) function.&lt;br /&gt;&lt;br /&gt;(The move returned should &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equal &lt;span style="font-weight:bold;"&gt;CBoard::OFF_BOARD&lt;/span&gt;.)&lt;br /&gt;&lt;br /&gt;Return the move.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Instead of constructing the class instance with the value to use for the AI effort, we are just going to submit the value when getting the Computer's move.  No need to store anything that way.&lt;br /&gt;&lt;br /&gt;The 'AI';&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;int CMoveGenerator::aiMove(const COwner::Player&amp; tag)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Condition:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is either &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create two COwner::NUM_PIECES-sized integer arrays.&lt;br /&gt;&lt;br /&gt;Initialize both arrays with the MoveGenerator's &lt;span style="font-style:italic;"&gt;thisGame&lt;/span&gt;'s &lt;span style="font-style:italic;"&gt;buildMove&lt;/span&gt;() for player &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt;.&lt;br /&gt;(The returned caount should be within limits.)&lt;br /&gt;&lt;br /&gt;Use &lt;span style="font-style:italic;"&gt;evaluateMoves&lt;/span&gt;() to assign values.&lt;br /&gt;(The returned array should &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equal NULL.)&lt;br /&gt;&lt;br /&gt;Return a move given that;&lt;br /&gt;If any move was assigned a &lt;span style="font-weight:bold;"&gt;1&lt;/span&gt; (the player tag won) has the highest priority.&lt;br /&gt;Otherwise, pick a random move with the value of &lt;span style="font-weight:bold;"&gt;0&lt;/span&gt; (no-one won).&lt;br /&gt;Any moves assigned &lt;span style="font-weight:bold;"&gt;-1&lt;/span&gt; are to be ignored.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;And, yes, only one array to store the moves could be used here.  The thought in my &lt;span style="font-style:italic;"&gt;so-called&lt;/span&gt; mind was that the issue was where the next move needs to be considered as well, needing a spare array.&lt;br /&gt;&lt;br /&gt;Evaluating the move;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CMoveGenerator::evaluateMoves(const COwner::Player&amp; forTag, const CGame&amp; startG, int* moves)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Condition:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is either &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;moves&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create an integer array with COwner::NUM_PIECES with elements.&lt;br /&gt;Assign a COwner::Player variable to the opposing player.&lt;br /&gt;&lt;br /&gt;For each move in &lt;span style="font-style:italic;"&gt;moves&lt;/span&gt;;&lt;br /&gt;{&lt;br /&gt;If move equals CBoard::OFF_BOARD,&lt;br /&gt;Re-assign element to and go to next element.&lt;br /&gt;&lt;br /&gt;Create a temporary CGame variable with &lt;span style="font-style:italic;"&gt;thisGame&lt;/span&gt;'s values.&lt;br /&gt;Apply this move to the temporary CGame.&lt;br /&gt;&lt;br /&gt;Did &lt;span style="font-style:italic;"&gt;forTag&lt;/span&gt; win?&lt;br /&gt;{&lt;br /&gt;Assign &lt;span style="font-weight:bold;"&gt;+1&lt;/span&gt; to the element.&lt;br /&gt;}&lt;br /&gt;Else,&lt;br /&gt;{&lt;br /&gt;Use the created move array to store the opponent's moves given the applied move.  (The program has already tested the applied move to see if &lt;span style="font-style:italic;"&gt;forTag&lt;/span&gt; won, now check the opposing side.)&lt;br /&gt;&lt;br /&gt;If any of the opposing move is a winner,&lt;br /&gt;{&lt;br /&gt;Assign &lt;span style="font-weight:bold;"&gt;-1&lt;/span&gt; to this &lt;span style="font-style:italic;"&gt;moves&lt;/span&gt; element.&lt;br /&gt;}&lt;br /&gt;Else,&lt;br /&gt;{&lt;br /&gt;Assign &lt;span style="font-style:bold;"&gt;0&lt;/span&gt; to this &lt;span style="font-style:italic;"&gt;moves&lt;/span&gt; element.&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Creating the move array before the loop gets the possible error condition out of the way.&lt;br /&gt;&lt;br /&gt;The new function in CGame is;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CGame::applyMove(const COwner::Player&amp; tag, const int&amp; moveFrom)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Condition:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is either &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;moveFrom&lt;/span&gt; is with CBoard bounds.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;moveFrom&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equals &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;Pre-Condition:&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Apply Move(&lt;span style="font-style:italic;"&gt;tag&lt;/span&gt;,&lt;span style="font-style:italic;"&gt;moveTag&lt;/span&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The modification in CGame is in the computerMove() function, one just needs to give the CMoveGenerator's getMove() function the specified AI level.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114705345373411704?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114705345373411704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114705345373411704' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114705345373411704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114705345373411704'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-ai-ii.html' title='Mu Torere AI II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114686105489339103</id><published>2006-05-05T15:07:00.000-05:00</published><updated>2006-05-05T15:30:54.920-05:00</updated><title type='text'>Mu Torere, Undo II</title><content type='html'>Step 14.&lt;br /&gt;All of the functions in CUndoQueue are pass-through. One way looking at this is to consider the Interface - Implementation Pattern.  One class to give the using program something to handle, and the other class actually does the work but is 'hidden' from the program.  One distinct advantage is that once the Interface part is stable, any functional changes in the Implementation will not cause the rest of the program to be re-compiled.&lt;br /&gt;&lt;br /&gt;Step 15.&lt;br /&gt;There are only a few places that need changing in the Document class to add the undo interface.  Of course the menu item 'Undo' needs to have event handlers for the OnUndo and the OnUpdateUndo events.  OnUndo just calls the undo() function of the &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;, apply it to the &lt;span style="font-style:italic;"&gt;game&lt;/span&gt; and update the program's view.  The OnUpdateUndo calls the &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;'s canUndo() function and uses it to enable or disable the 'Undo' menu item.&lt;br /&gt;&lt;br /&gt;The undo &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;, a pointer, is created in the Document's constructor using the value stored in the App class to determine the number of element in the &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;.&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt; is initialized then in the Document's OnNewDocument. At the risk of being obvious, this means that each new game starts with an empty undo queue.&lt;br /&gt;&lt;br /&gt;As for the mechanism of storing the &lt;span style="font-style:italic;"&gt;game&lt;/span&gt; in the &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;, it will proceed along the following lines;&lt;br /&gt;&lt;br /&gt;The current &lt;span style="font-style:italic;"&gt;game&lt;/span&gt; is stored in a temporary CGame variable.&lt;br /&gt;The move function of CGame, &lt;span style="font-style:italic;"&gt;selectMove&lt;/span&gt;() is called.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;ONLY IF&lt;/span&gt; a valid move was done is the CGame value in the temporary variable stored in the &lt;span style="font-style:italic;"&gt;queue&lt;/span&gt;.  &lt;span style="font-weight:bold;"&gt;Note&lt;/span&gt; that valid move will include cases were the Computer or the User won.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114686105489339103?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114686105489339103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114686105489339103' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114686105489339103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114686105489339103'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-undo-ii.html' title='Mu Torere, Undo II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114668421629020884</id><published>2006-05-03T14:23:00.000-05:00</published><updated>2006-05-03T20:44:18.646-05:00</updated><title type='text'>Mu Torere, Undo</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Disclaimer&lt;/span&gt;:  Before going on to describing the Undo functionality, here is the reason for the program using a base and derived class and for storing the old information as a CGame object.&lt;br /&gt;It looked like a good idea at the time, OK?&lt;br /&gt;Seriously though, the reasoning for the Queue class from the undo calls was to allow updating the Queue class for further functionality in the future and to avoid the temptation of putting queue functionality in the undo calls.&lt;br /&gt;As for using an entire CGame object, well consider that a placeholder.  To minimize the run-time footprint one can extract the bare minimum data needed to represent the game and then apply this data later.  But that can be left for future updates.&lt;br /&gt;&lt;br /&gt;Step 13.&lt;br /&gt;The Base Queue.&lt;br /&gt;The &lt;span style="font-weight:bold;"&gt;CCircleQueue&lt;/span&gt; class uses several named constants to improve program readability.&lt;br /&gt;First off are the upper and lower limits to size of the queue.  Now it seems to make very little sense to worry about limits while talking about a static queue.  &lt;span style="font-weight:bold;"&gt;Except&lt;/span&gt;, suppose the decision on the queue size was re-considered and a change was requested.  In this program the change can be implemented in the registry and avoids the re-compiling that a hard-coded number would need.&lt;br /&gt;While the upper limit is pretty much arbitrary, the lower limit of 2 was chosen with the view to keep the special cases within reason.&lt;br /&gt;&lt;br /&gt;The data structure is relatively simple; one pointer going &lt;span style="font-style:italic;"&gt;forward&lt;/span&gt; (into the future), one pointer going &lt;span style="font-style:italic;"&gt;back&lt;/span&gt; (back to the past), and one pointer to the &lt;span style="font-style:italic;"&gt;data&lt;/span&gt;.  The class uses two pointers to this data structure for its purposes.&lt;br /&gt;&lt;br /&gt;The constructor simply sets the structure pointers, &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;stopPoint&lt;/span&gt;, to NULL and sets the bookkeeping integer, &lt;span style="font-style:italic;"&gt;qSize&lt;/span&gt;, to 0.  The queue will be created seperately.  The destructor uses a seperate function to actually de-allocate the queue.&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CCircleQueue::Release(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt;-&gt;&lt;span style="font-style:italic;"&gt;forward&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;While a temp pointer is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equal to topPoint &lt;span style="font-weight:bold;"&gt;AND&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL,&lt;br /&gt;{&lt;br /&gt;Copy the temp pointer to another pointer for deletion.&lt;br /&gt;Move the temp pointer over to temp-&gt;&lt;span style="font-style:italic;"&gt;forward&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Process the copied pointer by deleting its &lt;span style="font-style:italic;"&gt;data&lt;/span&gt; pointer if &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL and by deleting this pointer.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Delete &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt;-&gt;&lt;span style="font-style:italic;"&gt;data&lt;/span&gt;, if &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;br /&gt;Delete &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Finally, set &lt;span style="font-style:italic;"&gt;stopPoint&lt;/span&gt; to NULL&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The Queue creation begins with;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CCircleQueue::newQueue(const int&amp; levels)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That levels is between &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_LLIMIT&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_ULIMIT&lt;/span&gt; inclusively.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assign an integer variable, &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt;, to &lt;span style="font-style:italic;"&gt;levels&lt;/span&gt; (or the value of &lt;span style="font-style:italic;"&gt;levels&lt;/span&gt; that is within bounds).&lt;br /&gt;&lt;br /&gt;Create 2 elements for the initial Queue using topPoint and a temporary pointer.  If this allocation fails, return false.&lt;br /&gt;Assign the forward and back pointers.&lt;br /&gt;&lt;br /&gt;Assign &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_LLIMIT&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;qSize&lt;/span&gt;.&lt;br /&gt;While &lt;span style="font-style:italic;"&gt;qSize&lt;/span&gt; is less than &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt; &lt;span style="font-weight:bold;"&gt;AND&lt;/span&gt; less than or equal to &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_ULIMIT&lt;/span&gt;,&lt;br /&gt;Add a queue element using growOne(). If this fails at any point( &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; equal to &lt;span style="font-weight:bold;"&gt;CCircleQueue::QGROW_GOOD&lt;/span&gt;), break out of loop. (qSize is incremented within growOne().)&lt;br /&gt;&lt;br /&gt;In any case, return true.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The function used for growing the Queue builds on an already initialized queue.  At this time the only point at which the queue will grow is from topPoint (which is known) and will only use the forward structure pointer.  This means that (if the queue is already in use and has data) the historical data structure can still be reached.&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;CCircleQueue::qReport  CCircleQueue::growOne(const CCircleQueue::qPoint&amp; addTo)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt;-&gt;&lt;span style="font-style:italic;"&gt;forward&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;addTo&lt;/span&gt; equals &lt;span style="font-weight:bold;"&gt;CCircleQueue::QPOINT_FIRST&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Attempt to allocate a queue element.  Set its data pointer to NULL.&lt;br /&gt;&lt;br /&gt;Insert this element into the queue forward of &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Return &lt;span style="font-weight:bold;"&gt;CCircle::QGROW_GOOD&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;There are two distinct error returns from this function.  &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_ERROR&lt;/span&gt; is used on the event of a mal-formed queue, while &lt;span style="font-weight:bold;"&gt;CCircleQueue::QGROW_FAIL&lt;/span&gt; reports a failure (possible memory shortage) in adding additional queue elements.&lt;br /&gt;&lt;br /&gt;The queue resetting function is as follows;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CCircleQueue::resetQueue(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;topPoint&lt;/span&gt; is &lt;span style="font-style:bold;"&gt;NOT&lt;/span&gt; NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;qSize&lt;/span&gt; is between &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_LLIMIT&lt;/span&gt; and &lt;span style="font-weight:bold;"&gt;CCircleQueue::Q_ULIMIT&lt;/span&gt; inclusive.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;A while loop is used to visit each element in the queue, delete any allocated CGame pointer and set those pointers to NULL.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;NOTE&lt;/span&gt;:If the loop eve finds that the next element in the queue is missing (NULL), the program SHOULD exit.&lt;br /&gt;&lt;br /&gt;Finally, stopPoint is set to NULL.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;The program does use a 'called-out-of-order' condition statment before the preconditions, if qSize is less than CCircleQueue::Q_LLIMIT then the create Queue function is called with the specification of CCircleQueue::Q_LLIMIT.&lt;br /&gt;&lt;br /&gt;Both the push() and the pop() functions are overloaded.  But the basic push() function is;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CCircleQueue::push(const CGame&amp; data, const CCircleQueue::qPoint&amp; addTo)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That topPoint is NOT NULL.&lt;br /&gt;That qSize is between CCircleQueue::Q_LLIMIT and CCircleQueue::Q_ULIMIT inclusive.&lt;br /&gt;That addTo equals CCircleQueue::QPOINT_FIRST.&lt;br /&gt;&lt;br /&gt;Again a 'called-out-of-order' condition statment before the preconditions, if qSize is less than CCircleQueue::Q_LLIMIT then the create Queue function is called with the specification of CCircleQueue::Q_LLIMIT.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Attempt to allocate a new CGame pointer for the queue.  Set this allocation to data.&lt;br /&gt;&lt;br /&gt;If this is the very first data pointer for the queue (topPoint-&gt;data == NULL),&lt;br /&gt;{&lt;br /&gt;(stopPoint should be NULL at this time.)&lt;br /&gt;&lt;br /&gt;Set topPoint-&gt;data to the new CGame allocated pointer.&lt;br /&gt;Set stopPoint to topPoint.&lt;br /&gt;}&lt;br /&gt;Else if the queue is full up (the pointer forward of topPoint is stopPoint),&lt;br /&gt;{&lt;br /&gt;(There is a valid pointer for stopPoint-&gt;forward.)&lt;br /&gt;&lt;br /&gt;Set topPoint to stopPoint.&lt;br /&gt;Move stopPoint to stopPoint-&gt;forward.&lt;br /&gt;&lt;br /&gt;Delete the CGame allocation (if it exists) in the current topPoint-&gt;data.&lt;br /&gt;Set topPoint-&gt;data to the new CGame allocated pointer.&lt;br /&gt;}&lt;br /&gt;Otherwise,&lt;br /&gt;{&lt;br /&gt;(stopPoint should be a valid pointer.)&lt;br /&gt;(topPoint-&gt;forward should exist.)&lt;br /&gt;&lt;br /&gt;Move topPoint to topPoint-&gt;forward.&lt;br /&gt;Delete the CGame allocation (if it exists) in the current topPoint-&gt;data.&lt;br /&gt;Set topPoint-&gt;data to the new CGame allocated pointer.&lt;br /&gt;}&lt;br /&gt;After all that return true.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;And the pop() function is;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CCircleQueue::pop(CGame&amp; data, const CCircleQueue::qPoint&amp; getFrom)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;br /&gt;That topPoint is NOT NULL.&lt;br /&gt;That qSize is between CCircleQueue::Q_LLIMIT and CCircleQueue::Q_ULIMIT inclusive.&lt;br /&gt;That getFrom equals CCircleQueue::QPOINT_FIRST.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If stopPoint is NULL, there is nothing left to pop.&lt;br /&gt;&lt;br /&gt;If this is the last one in the queue (topPoint == stopPoint),&lt;br /&gt;{&lt;br /&gt;(topPoint-&gt;data should exist.)&lt;br /&gt;&lt;br /&gt;Set returned data to topPoint-&gt;data.&lt;br /&gt;Delete topPoint-&gt;data and set it to NULL.&lt;br /&gt;&lt;br /&gt;Set stopPoint to NULL.&lt;br /&gt;}&lt;br /&gt;Else,&lt;br /&gt;{&lt;br /&gt;(topPoint-&gt;data should exist.)&lt;br /&gt;(topPoint-&gt;back should exist.)&lt;br /&gt;&lt;br /&gt;Set returned data to topPoint-&gt;data.&lt;br /&gt;Delete topPoint-&gt;data and set it to NULL.&lt;br /&gt;&lt;br /&gt;Move topPoint to topPoint-&gt;back.&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;The test for popping data is check if topPoint is NOT NULL AND that stopPoint is NOT NULL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114668421629020884?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114668421629020884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114668421629020884' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114668421629020884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114668421629020884'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-undo.html' title='Mu Torere, Undo'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114644180154150953</id><published>2006-04-30T17:10:00.000-05:00</published><updated>2006-05-03T14:26:33.116-05:00</updated><title type='text'>Mu Torere, a digression</title><content type='html'>In this entry the number of possible combinations of playing pieces will be determined.  What will be done is to find the &lt;a href="http://en.wikipedia.org/wiki/Generating_function"&gt;Generating Function&lt;/a&gt; given by &lt;a href="http://en.wikipedia.org/wiki/Burnside%27s_Lemma"&gt;Burnside's Lemma&lt;/a&gt;, which is a special case of &lt;a href="http://en.wikipedia.org/wiki/Polya_theorem"&gt;Polya's enumeration theorem&lt;/a&gt;.  Before anyone asks, the only thing that I could determine about Generating Functions is that they are a way to encode sequences (and not a decent how-to in the description either.)  Examples are better.&lt;br /&gt;&lt;br /&gt;First off, &lt;a href="http://en.wikipedia.org/wiki/Permutation_group"&gt;Permutation Groups&lt;/a&gt; are collection of permutaion operations (element swapping) on the elements of a set.  They can be denoted by cycle decompositions of the swaps being made.  For instance;&lt;table border="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;A 2-element swap on a 6 element Set&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;123456&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;153426&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;=&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;(1)(3)(4)(6)(25)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;has 4 1-element cycles and 1 2-element cycle&lt;br /&gt;While&lt;table border="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Rotation on the same 6 element Set&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;123456&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;234561&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;=&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;(123456)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;ha only 1 cycle of 6 elements.&lt;br /&gt;&lt;br /&gt;Polya's enumeration theorem uses equivalent decompositions, i.e. (1)(2)(3)(4)(56) and  (1)(3)(4)(5)(26) having 4 1 elements cycles and 1 2 element cycles are equivalent, to &lt;br /&gt;create the generating function.  Each permutation operation is weighted according to the number of equivalents and then the average is taken.&lt;br /&gt;As an &lt;a href="http://en.wikipedia.org/wiki/Polya_theorem#Example_computation:_enumerating_graphs_on_three_and_four_vertices_by_the_number_of_edges"&gt;example&lt;/a&gt;  the number of distinct ways to add edges to a 3 vertice graph  can be found as follows.  The permutations on a 3 element set is (&lt;a href="http://en.wikipedia.org/wiki/Cycle_index#Sample_computations"&gt;second example&lt;/a&gt;);&lt;br /&gt;[1 2 3] = (1)(2)(3)&lt;br /&gt;[1 3 2] = (1)(2 3)&lt;br /&gt;[2 1 3] = (1 2)(3)&lt;br /&gt;[2 3 1] = (1 2 3)&lt;br /&gt;[3 1 2] = (1 3 2)&lt;br /&gt;[3 2 1] = (1 3)(2)&lt;br /&gt;Which creates the function; 1/6 ( x1^3 + 3 a1 a2 + 2 a3 ).  The translation is that there is one equivalent of 1-cycle * 1-cycle * 1-cycle plus three equivalents of 1-cycle * 2-cycle plus two of 3-cycle operations.&lt;br /&gt;The generating function is then created using (z+1), where z denotes an edge and 1 denotes no edge.  This produces ((z+1)^3 +3 (z+1)(z^2+1)+(z^3+1))/6.&lt;br /&gt;Or rather, z^3 + z^2 + z^1 + 1.  Which can be read as there is only one way to add three edges to the graph, only one way to add 2 edges, only one way to add 1 edge and only one way to add no edges.  Only considering rotations will procude the same results.&lt;br /&gt;&lt;br /&gt;For Mu Torere, only the rotation permutations will be used.  This allows us to equate, for instance, all swaps that are 2 places apart.  Ignoring teh central location, means that only 8 locations need be considered.  From this, the permutaion groups are;&lt;br /&gt;[12345678] = (1)(2)(3)(4)(5)(6)(7)(8)&lt;br /&gt;[23456781] = (12345678)&lt;br /&gt;[34567812] = (1357)(2468)&lt;br /&gt;[45678123] = (14725836)&lt;br /&gt;[56781234] = (15)(26)(37)(48)&lt;br /&gt;[67812345] = (16385274)&lt;br /&gt;[78123456] = (1753)(1864)&lt;br /&gt;[81234567] = (18765432)&lt;br /&gt;Being 4 permutations 8-element cycles, 1 permutation group of 1-element cycles, 1 permutation group of 2-element cycles, and 2 groups of 4-element cycles.  This gives the preliminary function of 1/8 (g1^8 + g2^4 + 2 g4^2 + 4 g8).&lt;br /&gt;For the generating function, we will use (&lt;span style="font-style:italic;"&gt;c&lt;/span&gt;+&lt;span style="font-style:italic;"&gt;u&lt;/span&gt;+1) where &lt;span style="font-style:italic;"&gt;c&lt;/span&gt; will denote a piece owned by the Computer, &lt;span style="font-style:italic;"&gt;u&lt;/span&gt; will denote one owned by the User, and 1 will be a empty location.  This creates the generating function ((&lt;span style="font-style:italic;"&gt;c&lt;/span&gt;+&lt;span style="font-style:italic;"&gt;u&lt;/span&gt;+1)^8 + (&lt;span style="font-style:italic;"&gt;c&lt;/span&gt;^2+&lt;span style="font-style:italic;"&gt;u&lt;/span&gt;^2+1)^4 + 2 (&lt;span style="font-style:italic;"&gt;c&lt;/span&gt;^4+&lt;span style="font-style:italic;"&gt;u&lt;/span&gt;^4+1)^2 + 4(&lt;span style="font-style:italic;"&gt;c&lt;/span&gt;^8+&lt;span style="font-style:italic;"&gt;u&lt;/span&gt;^8+1))/8.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;HomeWork&lt;/span&gt;:  What terms will we need to examine?  And what will be final number?&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;The terms to examine are C^4 U^4, C^4 U^3, and C^3 U^4.&lt;br /&gt;The numbers are 10, 35, and 35, which totals 80.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114644180154150953?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114644180154150953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114644180154150953' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114644180154150953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114644180154150953'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-digression.html' title='Mu Torere, a digression'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114634734488219561</id><published>2006-04-29T16:31:00.000-05:00</published><updated>2006-04-29T16:49:04.916-05:00</updated><title type='text'>Mu Torere AI</title><content type='html'>While I recover the Undo functionality, I will go over the background of the program's AI in the meanwhile.&lt;br /&gt;&lt;br /&gt;Essentially, the program can use one of 3 kinds of decision making routines to simulate a proper AI.  (This is in addition to the random move routine.)&lt;br /&gt;The first is the basic tree graph to layout what move lead to which moves and an evaluation of that move.  For this version I will only evaluate the NEXT Computer's move and the following User's move (one ply each) for the winning move.&lt;br /&gt;Another is to use pattern recognition.  The program can check the current positions of the playing pieces and find out if a winning move is possible.&lt;br /&gt;The related routine (the third one) is to use a state machine.  The program will not need to decipher the game to find the proper state, but the current state of the game will need to be stored to determine the next game state.  The trade-offs are pretty much obvious, program complexity (deciphering the game to a state value) versus footprint (storing the current state and the next-state table.)&lt;br /&gt;&lt;br /&gt;The pattern matching and the state machine routines are possible because of the limited distinct positions of the playing pieces.  (At least the computer can calculate them).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114634734488219561?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114634734488219561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114634734488219561' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114634734488219561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114634734488219561'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai_29.html' title='Mu Torere AI'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114634474992243543</id><published>2006-04-29T15:59:00.000-05:00</published><updated>2006-04-29T16:05:49.923-05:00</updated><title type='text'>Poggle update</title><content type='html'>OK, I found the references I wanted to prove that Poggle can be solved.  It seems that this game was marketed under the name Merlin's Machine, Lights Out and Orbix.  The obly difference it seems is that the neighbourhood of cells along the edge and corners of the game wrapp around to the other side.  (Which should suggest ideas.)&lt;br /&gt;The only issue is that this kind of problem has only been looked at using wrap-around neighbourhoods.  &lt;br /&gt;&lt;br /&gt;SoI need to apply a little mental knuckle-work.&lt;br /&gt;&lt;br /&gt;Now I just need to read the chapter.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=schwarzekatze-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0801869471&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114634474992243543?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114634474992243543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114634474992243543' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114634474992243543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114634474992243543'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/poggle-update.html' title='Poggle update'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114624399127446549</id><published>2006-04-28T12:04:00.000-05:00</published><updated>2006-04-28T12:11:03.140-05:00</updated><title type='text'>Mu Torere, the AI II</title><content type='html'>Step 12.&lt;br /&gt;Given all the de-allocation problems with CMoveGenerator as a Singleton, I decided to toss it over and just use a pointer within the Computer's move function (see update in last step.)&lt;br /&gt;&lt;br /&gt;So there are only three functions that need to be constructed at this time, in addition to the constructor (which preps the RNG.)  The public functions are the &lt;span style="font-style:italic;"&gt;getMove(void)&lt;/span&gt; returning the CBoard location the Computer moves to and &lt;span style="font-style:italic;"&gt;setGame(const CGame* data)&lt;/span&gt;.  The private function, &lt;span style="font-style:italic;"&gt;randomMove(const COwner::Player&amp; tag)&lt;/span&gt;, just grabs an availible move at random.  The decision tree part for the AI will be added later.  This is enough to start play testing the program.&lt;br /&gt;&lt;br /&gt;The only thing really unusual about the comstructor is that it requires an integer. This will be for the AI part.&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;The Constructor&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CMoveGenerator::CMoveGenerator(const int&amp; aiL)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Enforce limits on the chosen AI level.&lt;br /&gt;&lt;br /&gt;If debugging, seed Random Number Generator with specific value.&lt;br /&gt;Otherwise, use the value returned from &lt;span style="font-style:italic;"&gt;time()&lt;/span&gt; as the seed.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;In case this is new, the standard headers for doing this are &lt;span style="font-style:italic;"&gt;time.h&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;math.h&lt;/span&gt;, and &lt;span style="font-style:italic;"&gt;stdlib.h&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Updating the CMoveGenerator instance with the current game is straight forward.&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;void CMoveGenerator::setGame(const CGame* aGame)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-Condition&lt;/span&gt;:&lt;br /&gt;That aGame is valid.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Set private CGame variable to &lt;span style="font-weight:bold;"&gt;COPY&lt;/span&gt; aGame.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;This point is one that is debatable.  Just how much data is needed to determine the next move?  Here the costs on system resources from multiple copies of the CGame object were balanced against the straight-forwardness of only one operation needed to list the possible moves.&lt;br /&gt;&lt;br /&gt;The interface of getMove() allows the program to hide all the messy details of actually determing the next move.&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;int CMoveGenerator::getMove(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Call the private move generator for the Computer's move.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Post-Condition&lt;/span&gt;:&lt;br /&gt;That the returned move is valid.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The only move generator right now is purely random (as much as a ccomputer can get anyway.)&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;int CMoveGenerator::randomMove(const COwner::Player&amp; tag)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Allocate memory to store the possible moves.&lt;br /&gt;&lt;br /&gt;Get the possible moves based on the store data.&lt;br /&gt;Perform reality checks on data.  (Not much to this one.  The only biggie is the possiblity that this function is called when there are no moves left.)&lt;br /&gt;&lt;br /&gt;Get a random possible move.  I used a while loop (with an emergency limiter) to extract a non-&lt;span style="font-weight:bold;"&gt;CBoard::OFF_BOARD&lt;/span&gt; value.&lt;br /&gt;&lt;br /&gt;Clean-up and return the move.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114624399127446549?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114624399127446549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114624399127446549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114624399127446549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114624399127446549'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai-ii.html' title='Mu Torere, the AI II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114592941315793956</id><published>2006-04-24T20:36:00.000-05:00</published><updated>2006-04-24T20:43:33.156-05:00</updated><title type='text'>Complaint, MS de-allocation.</title><content type='html'>Every once in a while the Microsoft compiler will complain when de-allocating memory.  It seems that the guard space allocated along with that allocated by new has been altered.  From comments within the provided code, the only other explaination for this is that the de-allocation is being done on the 'wrong' heap.&lt;br /&gt;&lt;br /&gt;Solution?  If your program breaks when de-allocating the same bit of memory over and over again (And I am NOT talking memory leaks.), the best work-around that I have found is to allocate an extra amount of memory for that 'problem' allocation to keep everyone happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114592941315793956?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114592941315793956/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114592941315793956' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114592941315793956'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114592941315793956'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/complaint-ms-de-allocation.html' title='Complaint, MS de-allocation.'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114584512650995330</id><published>2006-04-23T20:47:00.000-05:00</published><updated>2006-04-28T12:09:44.796-05:00</updated><title type='text'>Mu Torere, moving the pieces II</title><content type='html'>Step 11.&lt;br /&gt;Now the User and the Computer needs to move.  An enumerated type lSelection needs to be created with Invalid, Valid, ComputerWon, and UserWon as values to allow for CGame to signal the Document.&lt;br /&gt;AND, might as well do this now, a boolean flag needs to be added to the CGame class to denote that there are no more moves to do.  This flag will need to be added to the various copying functions.&lt;br /&gt;&lt;br /&gt;For the User the CGame adds the function&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;CGame::lSelection CGame::selectMove(const CPoint&amp; point)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If the finished flag is true, then return a &lt;span style="font-weight:bold;"&gt;CGame::Invalid&lt;/span&gt; signal.&lt;br /&gt;&lt;br /&gt;Get a pointer to the CBoard instance.&lt;br /&gt;If this pointer is NULL, return &lt;span style="font-weight:bold;"&gt;CGame::Invalid&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If there is no valid selection from CBoard's &lt;span style="font-style:italic;"&gt;whatIndex()&lt;/span&gt;, return &lt;span style="font-weight:bold;"&gt;CGame Invalid&lt;/span&gt;.&lt;br /&gt;Otherwise,&lt;br /&gt;Test the move.  If not possible to move, return &lt;span style="font-weight:bold;"&gt;CGame::Invalid&lt;/span&gt;.&lt;br /&gt;If moving is not possible, return &lt;span style="font-weight:bold;"&gt;CGame::Invalid&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If the User won, set the finished flag to true and return &lt;span style="font-weight:bold;"&gt;CGame::UserWon&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Get the move from the computer Move function.&lt;br /&gt;ASSERT that this move is not &lt;span style="font-weight:bold;"&gt;CBoard::OFF_BOARD&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Move the Computer's piece.&lt;br /&gt;ASSERT that this Move was possible.&lt;br /&gt;&lt;br /&gt;If the Computer won, set the finished flag to true and return &lt;span style="font-weight:bold;"&gt;CGame::ComputerWon&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If nothing else, &lt;span style="font-weight:bold;"&gt;CGame::Valid&lt;/span&gt;.&lt;/td&gt;&lt;/table&gt;I should point out the issue with the move.  (As if you had not noticed.)  If the User's move work but the Computer's did not, at this poin the only reasonable action is to exit the program, preffereably with some message to the user. Even then there must be a better way to handle this situation.&lt;br /&gt;The only thing that I can think of is to use the Undo functionality to restore the game, and try again.  (Either ask the user to re-do the move, or to loop a few times and THEN ask the user.)&lt;br /&gt;&lt;br /&gt;The function for testing who won;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;COwner::Player CGame::whoWon(void) const&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If the &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt; is the center location (8), return &lt;span style="font-weight:bold;"&gt;COwner::playN&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Get the &lt;span style="font-weight:bold;"&gt;COwner::Player&lt;/span&gt; value of the side that owns the center.&lt;br /&gt;&lt;br /&gt;Switch on the value in &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;,&lt;br /&gt;{&lt;br /&gt;If either neighbouring array element (element 7 is next to element 0) is owned by the same side of the center,  return that &lt;span style="font-weight:bold;"&gt;COwner::Player&lt;/span&gt; value. &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Otherwise, just return &lt;span style="font-style:italic;"&gt;COnwer::playN&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The function for testing the move;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CGame::canMove(const COwner::Player&amp; tag, const int&amp; fromLoc)const&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get the pointer to the CBoard instance.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pre-Conditions&lt;/span&gt;:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is either &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; is greater than or equal to 0 and less than &lt;span style="font-weight:bold;"&gt;CBoard::NUM_PLACES&lt;/span&gt;.&lt;br /&gt;And that &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; is NOT equal to &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get a pointer to the CBoard instance.&lt;br /&gt;&lt;br /&gt;If the move from &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt; is NOT possible, return false.&lt;br /&gt;&lt;br /&gt;Get the &lt;span style="font-weight:bold;"&gt;COwner::Player&lt;/span&gt; value of the opposing side.&lt;br /&gt;&lt;br /&gt;If &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt; is the center location, test to see if one and / or the other neighbour of &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; is owned by the opposing side.&lt;br /&gt;If this is the case, return true.&lt;br /&gt;Otherwise, return false.&lt;br /&gt;&lt;br /&gt;And if &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt; is NOT the center, return true.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;And the function for the computer's move;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;int CGame::computerMove(void) const&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strike&gt;Get a pointer to the CMoveGenerator instance.&lt;/strike&gt;&lt;br /&gt;Allocate a CMoveGenerator instance.&lt;br /&gt;Test pointer to see if it is valid.&lt;br /&gt;&lt;br /&gt;Setup the MoveGenerator instance with the current CGame.&lt;br /&gt;&lt;br /&gt;Get the move.&lt;br /&gt;ASSERT that the move will not be &lt;span style="font-weight:bold;"&gt;CBoard::OFF_BOARD&lt;/span&gt;.  (Actually done AFTER releasing the CMoveGenerator instance.)&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;Release&lt;/strike&gt; Delete the CMoveGenerator instance.&lt;br /&gt;&lt;br /&gt;Return the move&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update&lt;/span&gt;: Changed CMoveGenerator instance from Singleton instance to straight pointer allocation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114584512650995330?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114584512650995330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114584512650995330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114584512650995330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114584512650995330'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-moving-pieces-ii.html' title='Mu Torere, moving the pieces II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114575596390816158</id><published>2006-04-22T20:01:00.000-05:00</published><updated>2006-04-22T20:32:53.863-05:00</updated><title type='text'>Mu Torere, moving the pieces</title><content type='html'>(I neglected to post this before going on about the AI.)&lt;br /&gt;&lt;br /&gt;There are two classes that have information that changes because pieces move.  I will cover the user interaction part in the next post.&lt;br /&gt;&lt;br /&gt;For the COwner class;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool COwner::Move(const int&amp; fromL, const int&amp; toL)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-Conditions:&lt;/span&gt;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;fromL&lt;/span&gt; is greater than 0 and less than &lt;span style="font-weight:bold;"&gt;CBoard::NUM_PLACES&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;toL&lt;/span&gt; is greater than 0 and less than &lt;span style="font-weight:bold;"&gt;CBoard::NUM_PLACES&lt;/span&gt;.&lt;br /&gt;And that &lt;span style="font-style:italic;"&gt;fromL&lt;/span&gt; is NOT equal to &lt;span style="font-style:italic;"&gt;toL&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get the element in Board's &lt;span style="font-style:italic;"&gt;loc&lt;/span&gt; array that has the same value as &lt;span style="font-style:italic;"&gt;fromL&lt;/span&gt;.  Return false if this fails.&lt;br /&gt;&lt;br /&gt;Then assign &lt;span style="font-style:italic;"&gt;toL&lt;/span&gt; to this element.&lt;br /&gt;Return true.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;And for the CGame class;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CGame::Move(const COwner::Player&amp; tag, const int&amp; fromLoc)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pre-Conditions:&lt;/span&gt;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is either &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; is greater than 0 and less than &lt;span style="font-weight:bold;"&gt;CBoard::NUM_PLACES&lt;/span&gt;.&lt;br /&gt;And that &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; is NOT equal to &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; was &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;If the &lt;span style="font-style:italic;"&gt;Computer&lt;/span&gt;'s Move routine succeeds&lt;br /&gt;{&lt;br /&gt;Change the &lt;span style="font-style:italic;"&gt;owned&lt;/span&gt; array as appropriate.&lt;br /&gt;Assign &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;return true.&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;If the &lt;span style="font-style:italic;"&gt;User&lt;/span&gt;'s Move routine succeeds&lt;br /&gt;{&lt;br /&gt;Change the &lt;span style="font-style:italic;"&gt;owned&lt;/span&gt; array as appropriate.&lt;br /&gt;Assign &lt;span style="font-style:italic;"&gt;fromLoc&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;emptyLoc&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;return true.&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;If the program gets this far return false.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114575596390816158?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114575596390816158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114575596390816158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114575596390816158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114575596390816158'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-moving-pieces.html' title='Mu Torere, moving the pieces'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114557963654454937</id><published>2006-04-20T19:32:00.000-05:00</published><updated>2006-04-21T13:19:05.096-05:00</updated><title type='text'>Mu Torere, the AI!</title><content type='html'>Now we are cooking with gas!  The only thing is that this will not be that elaborate, and for that matter the AI will not much more that an Random Number Generator in order to check the rest of hte system.  But here goes.&lt;br /&gt;&lt;br /&gt;First a few functions are needed to establish the ground work, specifically copy contructors and the like.&lt;br /&gt;While 'friend' classes and functions could have been used, adding a CGame object or pointer directly to the CMoveGenerator allows for the contruction of building hypothetical moves, e.g. 'What Computer moves are availible if the User moved this way?'  (And yeah, I do hear the eye-balls rolling at this point.)&lt;br /&gt;&lt;br /&gt;So, for the COwner and CGame class the copy constructor looks like;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding"5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;The Copy Constructor&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CXxxxx::CXxxxx(const CXxxxx&amp; obj)&lt;br /&gt;: Copy initialization list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;For each element in array, copy &lt;span style="font-style:italic;"&gt;obj&lt;/span&gt;.array[element]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The '=' operator function works as follows;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding"5"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;The Equal Operator&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;const CXxxxx&amp; CXxxxx::operator =(const CXxxxx &amp;obj)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;this&lt;/span&gt; is NOT equal the address of &lt;span style="font-style:italic;"&gt;obj&lt;/span&gt; (&amp;&lt;span style="font-style:italic;"&gt;obj&lt;/span&gt;)then&lt;br /&gt;{&lt;br /&gt;Copy &lt;span style="font-style:italic;"&gt;obj&lt;/span&gt;'s data members.&lt;br /&gt;&lt;br /&gt;For each element in array, copy &lt;span style="font-style:italic;"&gt;obj&lt;/span&gt;.array[element]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In anycase, return the object reffered to by &lt;span style="font-style:italic;"&gt;this&lt;/span&gt;. (*&lt;span style="font-style:italic;"&gt;this&lt;/span&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I really recommend reading a good book on C++ to find out &lt;span style="font-weight:bold;"&gt;WHY&lt;/span&gt; operator=() is declared in this manner.&lt;br /&gt;&lt;br /&gt;And finally, a kluge to copy from pointers to objects for the CGame class.  I went through a bit of hoop-jumping and pointer manipulation and massaging before settling on this to extract pointer data members to copy to temporary objects.  (But then I do not know the complete ins-and-outs of C++.)  Much like the operator=() function the only difference is that there is no need to return the object to which &lt;span style="font-style:italic;"&gt;this&lt;/span&gt; reffers;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding"5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;void setGame(CGame* aGame);&lt;br /&gt;void setGame(const CGame* aGame);   // overloaded to copy-from this&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If this is NOT equal the address of &lt;span style="font-style:italic;"&gt;aGame&lt;/span&gt; (&amp;&lt;span style="font-style:italic;"&gt;aGame&lt;/span&gt;)then&lt;br /&gt;{&lt;br /&gt;Copy &lt;span style="font-style:italic;"&gt;aGame&lt;/span&gt;'s data members.&lt;br /&gt;&lt;br /&gt;For each element in array, copy &lt;span style="font-style:italic;"&gt;aGame&lt;/span&gt;-&gt;array[element]&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Note: that there is NO data validation.  While this can be added, it might be better to do that in a separate step.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114557963654454937?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114557963654454937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114557963654454937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114557963654454937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114557963654454937'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai.html' title='Mu Torere, the AI!'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114550030064304413</id><published>2006-04-19T21:19:00.000-05:00</published><updated>2006-04-19T21:31:40.653-05:00</updated><title type='text'>Mu Torere, the Stone Singleton</title><content type='html'>Step 8.&lt;br /&gt;A basic Singleton instance, all that is required of this class is to draw the playing pieces.&lt;br /&gt;Why isn't this folded in with one of the other classes?  The basic reason is that this class can be considered a working stub class.  If need be, a different drawing routine can be substituted to draw 3-D playing pieces.  Or a Sprite class can be used instead.  Or the user can decide.&lt;br /&gt;&lt;br /&gt;For drawing;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CStone::Draw(CDC* pDC, const COLORREF&amp; res, const CRect&amp; rect)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create a 2-pixel wide pen with the colour of the menu text, usu. black.&lt;br /&gt;Create a solid bruch with the provided colour, &lt;span style="font-style:italic;"&gt;res&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Select the pen and the brush into the drawing context.&lt;br /&gt;Draw an Ellipse contained by &lt;span style="font-style:italic;"&gt;rect&lt;/span&gt;.&lt;br /&gt;Select the old pen and old brush back into the drawing context.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;Note that all the needed information for drawing the piece is provided.  Nothing is stored in the CStone instance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114550030064304413?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114550030064304413/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114550030064304413' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114550030064304413'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114550030064304413'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-stone-singleton.html' title='Mu Torere, the Stone Singleton'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114549953910641196</id><published>2006-04-19T20:54:00.000-05:00</published><updated>2006-04-19T22:23:19.500-05:00</updated><title type='text'>Mu Torere, the Owner class</title><content type='html'>Step 9.&lt;br /&gt;The COwner class has only 3 variable to track, and a couple of named constants.  One variable &lt;span style="font-style:italic;"&gt;res&lt;/span&gt; holds the colour for the pieces it manages, an integer array &lt;span style="font-style:italic;"&gt;loc&lt;/span&gt; (with named constant &lt;span style="font-weight:bold;"&gt;NUM_PIECES&lt;/span&gt;) to store the location on the board, and a variable &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt; indicating which side the object is on (using COwner's enumerated &lt;span style="font-weight:bold;"&gt;Player&lt;/span&gt; type).&lt;br /&gt;A couple of in-line functions to get the CBoard and CStone instance are useful.  The only in-line function that could be added is one setting the COwner object's colour.  Just remember to check that the object has actually been set-up by looking for a proper value in &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt;. (No need to colour an un-assigned COwner object.)&lt;br /&gt;&lt;br /&gt;Aside from the drawing function, the only thing that needs adding is the set-up function for initalization and the reset function for new games.&lt;br /&gt;&lt;br /&gt;The COwner constructor just initializes the class's variables to what are essentially don't-care / error values that will be corrected when the COwner objects are properly initialized.  In this case, &lt;span style="font-style:italic;"&gt;res&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt; are set to RGB(255,0,0) and COwner::playN, while all elements in &lt;span style="font-style:italic;"&gt;loc&lt;/span&gt; are set to &lt;span style="font-weight:bold;"&gt;CBoard::OFF_BOARD&lt;/span&gt;.&lt;br /&gt;All the destructor needs to do is to Release any CBoard and CStone instances.&lt;br /&gt;&lt;br /&gt;The bare-bones void COwner::setUp(const COwner::Player&amp; tag) just sets the COwner object's &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt; variable (only if &lt;span style="font-style:italic;"&gt;tag&lt;/span&gt; is &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;) and then calls the reSet() function.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style:italic;"&gt;void COwner::reSet(void)&lt;/span&gt; initialization function does have a Pre-condition that the only &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt; values are &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.  Aside from that, the &lt;span style="font-style:italic;"&gt;loc&lt;/span&gt; array is now initalized for each side.  As long as all pieces from the same side are adjoining, placement does not matter.  In my program I initialized the User and Computer arrays so that the User had the two places on the left and the two places on the top of the playing field. (From all the examples that I have seen.)  The center playing location remains empty.&lt;br /&gt;&lt;br /&gt;For drawing;&lt;br /&gt;&lt;table border="1" cellspacing="0" cellpadding="5"&gt;&lt;tr&gt;&lt;td&gt;void COwner::Draw(CDC* pDC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PreConditions:&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;pDC&lt;/span&gt; is not-NULL.&lt;br /&gt;That the COwner object's &lt;span style="font-style:italic;"&gt;tagP&lt;/span&gt; equals &lt;span style="font-weight:bold;"&gt;COwner::playC&lt;/span&gt; or &lt;span style="font-weight:bold;"&gt;COwner::playU&lt;/span&gt;.&lt;br /&gt;That there is a valid (not-NULL) CBoard instance.&lt;br /&gt;That there is a valid (not-NULL) CStone instance.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;For each location in &lt;span style="font-style:italic;"&gt;loc&lt;/span&gt;,&lt;br /&gt;{&lt;br /&gt;Get the board location's CRect.&lt;br /&gt;DEBUG: Is the CRect not-empty (0,0,0,0)?&lt;br /&gt;If the returned CRect is empty, skip this location.&lt;br /&gt;&lt;br /&gt;Draw the CStone instance with the returned CRect and the COwner's &lt;span style="font-style:italic;"&gt;res&lt;/span&gt; colour.&lt;br /&gt;}&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Step 10.&lt;br /&gt;All that needs to be done to display the playing pieces is to;&lt;br /&gt;&lt;br /&gt;A - Create private COwner objects in CGame for the Computer and the User.&lt;br /&gt;B - Use the setUp() function for each object with the proper &lt;span style="font-weight:bold;"&gt;COwner::Player&lt;/span&gt; value for each.&lt;br /&gt;C - Create an in-line function for CGame to set the colours for the COwner objects.  My program set the colours for both COwner objects at the same time.  You can try a different approach if you wish.&lt;br /&gt;D - The CGame setColours() is called in the Document's constructor for the initial colour.  The function is also called in each of the 'Change Colour' menu item actions.&lt;br /&gt;E - Each COwner object is drawn after the CBoard instance in the CGame's drawing function.&lt;br /&gt;F - (Optional.) A reset funtion can also be added to the CGame at this time, calling each of the COwner objects.  This reset function is used in the Document's OnNewDocument(0 function.&lt;br /&gt;&lt;br /&gt;Try running the program.  The playing pieces should be of the colour that were specified, e.g. they should match the colours displayed in the CInfoDisplay legend.  Also the pieces should be in the playing location that were programming in to the COwner reSet() function.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114549953910641196?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114549953910641196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114549953910641196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114549953910641196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114549953910641196'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-owner-class.html' title='Mu Torere, the Owner class'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114541804193969696</id><published>2006-04-18T21:27:00.000-05:00</published><updated>2006-04-18T22:44:20.856-05:00</updated><title type='text'>Mu Torere, changing colours</title><content type='html'>Step 6.&lt;br /&gt;Given that the program can display colours, might as well go ahead and show how to change those colours.  But first, the menu&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;File&lt;/td&gt;&lt;td colspan=2&gt;Settings&lt;/td&gt;&lt;td&gt;Help&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;New game&lt;/td&gt;&lt;td&gt;Undo&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;About Mu Torere...&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Exit&lt;/td&gt;&lt;td&gt;Show Colour Legend&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;Change Computer Colour...&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;Change User Colour...&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;AI Level&lt;/td&gt;&lt;td&gt;Off&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;Low&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;Medium&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;hr /&gt;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;Custom AI Level...&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Step 7.&lt;br /&gt;On changing the colour in the Document;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CMuTorereDoc::OnSettingsChangeXxxx()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create CColorDialog object.&lt;br /&gt;&lt;br /&gt;Set dialog flags.&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;dlg.m_cc.Flags |= CC_FULLOPEN | CC_RGBINIT;&lt;br /&gt;dlg.m_cc.rgbResult = ((CMuTorereApp*)AfxGetApp())-&gt;getColourXxxx();&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;If the colour dialog returns IDOK.&lt;br /&gt;{&lt;br /&gt;Set the game's colours.&lt;br /&gt;Set the application's Xxxx colour.&lt;br /&gt;&lt;br /&gt;Update View with &lt;span style="font-weight:bold;"&gt;colour hint&lt;/span&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;In the View, the Update View function is as follows;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CMuTorereView::OnUpdate(CView* /*pSender*/, LPARAM lHint, CObject* /*pHint*/)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;lHint&lt;/span&gt; equals the Document's &lt;span style="font-weight:bold;"&gt;colour hint&lt;/span&gt;.&lt;br /&gt;{&lt;br /&gt;Set the colours in the CInfoDisplay instance.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In all cases, Invalidate the window to re-draw.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;In my program I set both the User and the Computer colours at the same time.  For efficiency, a different hint from the Document should be used for each colour change.&lt;br /&gt;&lt;br /&gt;The addition to the View's Draw function is minor (done after the game is drawn);&lt;br /&gt;If the application's &lt;span style="font-style:italic;"&gt;m_Display&lt;/span&gt; is true, draw the CInfoDisplay instance.&lt;br /&gt;&lt;br /&gt;The CinfoDisplay is set up in the View constructor;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;Go to the first element in the CInfoDisplay instance.&lt;br /&gt;&lt;br /&gt;Add _T("Computer") and the application's computer colour to the first element.&lt;br /&gt;Add _T("User") and the application's user colour the next element.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114541804193969696?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114541804193969696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114541804193969696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114541804193969696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114541804193969696'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-changing-colours.html' title='Mu Torere, changing colours'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114532812025592918</id><published>2006-04-17T20:24:00.000-05:00</published><updated>2006-04-17T21:49:19.466-05:00</updated><title type='text'>Mu Torere,  the Legend</title><content type='html'>The sole reason for the InfoDisplay class is to show to the user which colour belongs to which player.  In this program, the class is draw directly on the window, over-lapping the playing field.  If I ever figure out a way to allow a program to close a child modeless window, I'll post it but for now this is it.&lt;br /&gt;&lt;br /&gt;A Singleton class, CInfoDisplay contains the following as variables;&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;variable&lt;/td&gt;&lt;td&gt;inital value&lt;/td&gt;&lt;td&gt;comment&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;static CString *labels&lt;/td&gt;&lt;td&gt;NULL&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;static COLORREF *colours&lt;/td&gt;&lt;td&gt;NULL&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;static CPoint topLeft&lt;/td&gt;&lt;td&gt;CPoint(0,0)&lt;/td&gt;&lt;td&gt;for positioning&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;static int counter&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;for the iterator&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;static int numLabel&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;There are some named constants used for spacing included as well as a limit to the number of array elements.&lt;br /&gt;&lt;br /&gt;The functions that will be used are &lt;span style="font-style:italic;"&gt;static CInfoDisplay* getInstance(const int&amp; count)&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;static void Release(void)&lt;/span&gt; for the pattern (Note that getInstance requires a parameter), &lt;span style="font-style:italic;"&gt;void Draw(CDC* pDC)&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;CSize getLabelSize(CDC* pDC) const&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;static void First(void)&lt;/span&gt; (to reset &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt; to 0), &lt;span style="font-style:italic;"&gt;bool setInfo(const CString&amp; sLabel, const COLORREF&amp; rgbColour)&lt;/span&gt;, and &lt;span style="font-style:italic;"&gt;bool setRGB(const int&amp; index, const COLORREF&amp; rgb)&lt;/span&gt;.  Also note that the setRGB() function requires a index.  I would have been better not to depend on such things for synchronization.&lt;br /&gt;&lt;br /&gt;Since the labels and the colours are in dynamic arrays, the destructor can be used for the clean-up.&lt;br /&gt;&lt;table border="1"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;destructor&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CInfoDisplay::~CInfoDisplay(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; is not-NULL, delete it.&lt;br /&gt;If &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt; is not-NULL, delete it.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The additional code in this class's getInstance involves creating the &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt; arrays;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;CInfoDisplay* CInfoDisplay::getInstance(const int&amp; count)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-condition&lt;/span&gt;;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;count&lt;/span&gt; is greater than 0.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; is NULL and &lt;span style="font-style:italic;"&gt;count&lt;/span&gt; greater than 0&lt;br /&gt;{&lt;br /&gt;Create new CInfoDisplay and assign to &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt;.&lt;br /&gt;(Strictly speaking if this fails, the  function should return NULL.)&lt;br /&gt;&lt;br /&gt;If &lt;span style="font-style:italic;"&gt;count&lt;/span&gt; is greater than CInfoDisplay::&lt;span style="font-weight:bold;"&gt;MAX_LABELS&lt;/span&gt;, use CInfoDisplay::&lt;span style="font-weight:bold;"&gt;MAX_LABELS&lt;/span&gt; instead.&lt;br /&gt;&lt;br /&gt;Try allocating CString[&lt;span style="font-style:italic;"&gt;count&lt;/span&gt;] memory and assigning it to &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Try allocating COLORREF[&lt;span style="font-style:italic;"&gt;count&lt;/span&gt;] memory and assigning it to &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;If &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; is not-NULL, assign _T(" ") to each element.&lt;br /&gt;If &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt; is not_NULL, assign RGB(255,0,0), i.e. red, to each element.&lt;br /&gt;&lt;br /&gt;Assign (0,0) to &lt;span style="font-style:italic;"&gt;topLeft&lt;/span&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Return &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Note the use of _T() for the CString elements.  This Microsoft macro handles the difference between UNICODE and ANSCII at compile-time.&lt;br /&gt;&lt;br /&gt;For the iterator function;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CInfoDisplay::setInfo(const CString&amp; sLabel, const COLORREF&amp; rgbColour)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-condition&lt;/span&gt;;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; is not-NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt; is greater or equal to 0 and less than &lt;span style="font-style:italic;"&gt;numLabel&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; is not_NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt; is not-NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;If &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt; equals &lt;span style="font-style:italic;"&gt;numLabel&lt;/span&gt;, then return false.  // no more can be entered&lt;br /&gt;&lt;br /&gt;Assign &lt;span style="font-style:italic;"&gt;sLabel&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt;[&lt;span style="font-style:italic;"&gt;counter&lt;/span&gt;].&lt;br /&gt;Assign &lt;span style="font-style:italic;"&gt;rgbColour&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt;[&lt;span style="font-style:italic;"&gt;counter&lt;/span&gt;].&lt;br /&gt;&lt;br /&gt;Increment &lt;span style="font-style:italic;"&gt;counter&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Return true.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The index-based colour-setting function works as follows;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool CInfoDisplay::setRGB(const int&amp; index, const COLORREF&amp; rgb)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-condition&lt;/span&gt;;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; is not-NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt; is not-NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;index&lt;/span&gt; is greater than or equal to 0 and less than &lt;span style="font-style:italic;"&gt;numLabel&lt;/span&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assign &lt;span style="font-style:italic;"&gt;rgb&lt;/span&gt; to &lt;span style="font-style:italic;"&gt;colours&lt;/span&gt;[&lt;span style="font-style:italic;"&gt;index&lt;/span&gt;].&lt;br /&gt;&lt;br /&gt;Return true.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;The following function helps the program determine the size of all the text that will be drawn.  For now mostly redundant, but if positioning the CInfoDisplay instance is being done it will allow the programmer to compensate for weirdness.&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;CSize CInfoDisplay::getLabelSize(CDC* pDC) const&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-condition&lt;/span&gt;;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; is not-NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;numLabel&lt;/span&gt; is greater or equal to 0 and less than &lt;span style="font-style:italic;"&gt;numLabel&lt;/span&gt;.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; is not_NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;pDC&lt;/span&gt; is not-NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Initialize the x and y values to return.&lt;br /&gt;&lt;br /&gt;For each label,&lt;br /&gt;{&lt;br /&gt;Get the size of the text of the label. (via GetTextExtent())&lt;br /&gt;&lt;br /&gt;If the label's x-extent is greater, assign the value to x.&lt;br /&gt;&lt;br /&gt;If the label's y-extent is smaller than the rectangle used to display the colour (CInfoDisplay::&lt;span style="font-weight:bold;"&gt;CELL_SIZE&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;Increment y by CInfoDisplay::&lt;span style="font-weight:bold;"&gt;CELL_SIZE&lt;/span&gt;.&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;Increment y by the label's y-extent.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;If not at the last label&lt;br /&gt;{&lt;br /&gt;Increment y by CInfoDisplay::SPACING.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Return CSize(x,y).&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Finally, for drawing the instance;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;void CInfoDisplay::Draw(CDC* pDC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-condition&lt;/span&gt;;&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; is not-NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;labels&lt;/span&gt; is not_NULL.&lt;br /&gt;That &lt;span style="font-style:italic;"&gt;pDC&lt;/span&gt; is not-NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get the size of the text from getLabelSize().&lt;br /&gt;&lt;br /&gt;Create a solid pen with the colour of the menu text.&lt;br /&gt;&lt;br /&gt;Initialize dy with the &lt;span style="font-weight:bold;"&gt;BORDER&lt;/span&gt; value + &lt;span style="font-weight:bold;"&gt;PADDING&lt;/span&gt; value + &lt;span style="font-style:italic;"&gt;topLeft&lt;/span&gt;.y.&lt;br /&gt;For each label,&lt;br /&gt;{&lt;br /&gt;Draw the label.&lt;br /&gt;&lt;br /&gt;Get the size of the label.&lt;br /&gt;Adjust like the gatLabelSize() function.&lt;br /&gt;&lt;br /&gt;Set up a square &lt;span style="font-weight:bold;"&gt;CELL_SIZE&lt;/span&gt;-by-&lt;span style="font-weight:bold;"&gt;CELL_SIZE&lt;/span&gt; separated from the label by &lt;span style="font-weight:bold;"&gt;SPACING&lt;/span&gt;.&lt;br /&gt;Create a solid brush with the appropriate colour.&lt;br /&gt;Draw the square.&lt;br /&gt;&lt;br /&gt;Increment dv by the label height and by the &lt;span style="font-weight:bold;"&gt;SPACING&lt;/span&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Now draw the enclosing box.  Remember that the box is reduced by the &lt;span style="font-weight:bold;"&gt;BORDER&lt;/span&gt; value, that &lt;span style="font-weight:bold;"&gt;topLeft&lt;/span&gt; positions the box, and that the box's width is expanded by &lt;span style="font-weight:bold;"&gt;SPACING&lt;/span&gt; and the colour display.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114532812025592918?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114532812025592918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114532812025592918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114532812025592918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114532812025592918'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-legend.html' title='Mu Torere,  the Legend'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114521662160837115</id><published>2006-04-16T14:28:00.000-05:00</published><updated>2006-04-16T15:04:41.586-05:00</updated><title type='text'>Mu Torere, the Playing Board II</title><content type='html'>Step 4.&lt;br /&gt;Once the Board class has been set-up, all that needs to be done is to pass the right values to the right functions in the View class.  For the moment, create a Game class and two pass-through function for Draw(CDC* pDC) and getSize(void).&lt;br /&gt;Note; if interested here are the in-line functions to specifically catch allocation errors wrt. Board class.&lt;br /&gt;&lt;table border="1" caption="getBoard function"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CBoard* getBoard(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Get pointer to CBoard instance.&lt;br /&gt;&lt;br /&gt;ASSERT that pointer is not-NULL.&lt;br /&gt;&lt;br /&gt;Return pointer.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;All the second version of the getBoard() function is defined using &lt;span style="font-style:italic;"&gt;const&lt;/span&gt; to allow the CGame's getSize() function to use it.&lt;br /&gt;&lt;br /&gt;Step 5.&lt;br /&gt;It is preferred to use similar pass-through functionality in the program's Document class.  (With a private CGame variable.)&lt;br /&gt;&lt;br /&gt;Step 6.&lt;br /&gt;Since the View class's onDraw(CDC *pDC) only has one statement to be added, &lt;span style="font-style:italic;"&gt;pDoc-&gt;Draw(pDC)&lt;/span&gt;, we will go onto the OnInitialUpdate() function.&lt;br /&gt;&lt;table border="1" caption="OnInitialUpdate function"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;void CMuTorereView::OnInitialUpdate(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;// from the development's' function wizard&lt;br /&gt;Call CView::OnInitialUpdate().&lt;br /&gt;&lt;br /&gt;Get the Board class's CSize from the Document.&lt;br /&gt;&lt;br /&gt;Increase the retrieved size in the X direction by twice the window's frame.&lt;br /&gt;Increase the retrieved size in the Y direction by the Window's frame + the height of the menu and the height of the titlebar.&lt;br /&gt;&lt;br /&gt;Get the width of the desktop.&lt;br /&gt;If the retrieved size is wider than the desktop, then limit the retrieved size's width.&lt;br /&gt;&lt;br /&gt;Get the height of the desktop.&lt;br /&gt;If the retrieved size is taller than the desktop, then limit the retrieved size's height.&lt;br /&gt;&lt;br /&gt;AfxGetMainWnd()-&gt;SetWindowPos(NULL, 0, 0, tSz.cx, tSz.cy, SWP_NOMOVE | &lt;br /&gt;        SWP_NOZORDER);&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114521662160837115?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114521662160837115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114521662160837115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114521662160837115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114521662160837115'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-playing-board-ii.html' title='Mu Torere, the Playing Board II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114519682129957465</id><published>2006-04-16T08:20:00.000-05:00</published><updated>2006-04-16T15:03:44.953-05:00</updated><title type='text'>Mu Torere, the Playing Board</title><content type='html'>Step 3,&lt;br /&gt;As a starting point, the Board class is a good one.  Once this class is set-up, the View can be set to right size and to draw.  There are two of the class's functions right there, &lt;span style="font-style:italic;"&gt;getSize(void) const&lt;/span&gt; const and &lt;span style="font-style:italic;"&gt;Draw(CDC *pDC)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;The Board class will use the Singleton pattern, so &lt;span style="font-style:italic;"&gt;getInstance(void)&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;Release(void)&lt;/span&gt; will need to be added.&lt;br /&gt;Other functions needed for the game are &lt;span style="font-style:italic;"&gt;getPlace(const int&amp;) const&lt;/span&gt; to return a rectangle for drawing playing pieces, &lt;span style="font-style:italic;"&gt;whatIndex(const CPoint&amp;) const&lt;/span&gt; for determining valid mouse clicks, and &lt;span style="font-style:italic;"&gt;canMove(const int&amp; from, const int&amp; to) const&lt;/span&gt; for checking for valid neighbours.&lt;br /&gt;&lt;br /&gt;In addition to the Singleton's &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt;, the Board class also needs an array for the program's playable CRect's, &lt;span style="font-style:italic;"&gt;places[CBoard::&lt;span style="font-weight:bold;"&gt;NUM_PLACES&lt;/span&gt;]&lt;/span&gt;.&lt;br /&gt;The named constants are &lt;span style="font-weight:bold;"&gt;OFF_BOARD&lt;/span&gt; = -1 (a public constant, not really needed in the Board class but a habit), &lt;span style="font-weight:bold;"&gt;NUM_PLACES&lt;/span&gt; = 9 (private, used for readability), and &lt;span style="font-weight:bold;"&gt;BORDER&lt;/span&gt; = 20 (private).&lt;br /&gt;&lt;br /&gt;Now all of the numbers used in this class were determined by hand because of the general awkwardness of calculating the positions of the 8 points of the star plus the indents.  (Actually I use a positioning kluge to come up with the right numbers, but I will not subject the readers to that mess.)&lt;br /&gt;&lt;br /&gt;&lt;table border=1&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Constructor&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CBoard::CBoard(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;places[0].SetRect(80,20,130,70);&lt;br /&gt;places[1].SetRect(160,20,210,70);&lt;br /&gt;places[2].SetRect(220,95,270,145);&lt;br /&gt;places[3].SetRect(220,180,270,230);&lt;br /&gt;places[4].SetRect(160,250,210,300);&lt;br /&gt;places[5].SetRect(80,250,130,300);&lt;br /&gt;places[6].SetRect(20,180,70,230);&lt;br /&gt;places[7].SetRect(20,95,70,145);&lt;br /&gt;places[8].SetRect(120,130,175,185);&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;For the Singleton pattern;&lt;br /&gt;&lt;br /&gt;&lt;table border=1&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CBoard* CBoard::getInstance(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Is &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; NULL?&lt;br /&gt;{&lt;br /&gt;Try allocating new CBoard instance.&lt;br /&gt;&lt;br /&gt;If allocation fails, set &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; to NULL.&lt;br /&gt;}&lt;br /&gt;Return &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt;.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border=1&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;void CBoard::Release(void)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Is &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; not-NULL?&lt;br /&gt;{&lt;br /&gt;Delete &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Set &lt;span style="font-style:italic;"&gt;instance&lt;/span&gt; to NULL.&lt;br /&gt;}&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;For the View;&lt;br /&gt;&lt;table border=1&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;CSize CBoard::getSize(void) const&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-Condition&lt;/span&gt;:&lt;br /&gt;instance is not-NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Is &lt;span style="font-style:italic;"&gt;Return CSize(right-most point+CBoard::BORDER,bottom-most point+CBoard::BORDER)&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border=1&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;void CBoard::Draw(CDC* pDC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span style="font-weight:bold;"&gt;Pre-Condition&lt;/span&gt;:&lt;br /&gt;instance is not-NULL.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create a solid brush with the colour of the window's background.&lt;br /&gt;Create a pen with the colour of the menu's text.&lt;br /&gt;(This should provide enough contrast.)&lt;br /&gt;&lt;br /&gt;Select into drawing context the pen and brush.&lt;br /&gt;&lt;br /&gt;Draw a circle in the rectangle given by place[8].&lt;br /&gt;&lt;br /&gt;Move to center of place[0].&lt;br /&gt;Draw line to (145,95).&lt;br /&gt;Draw line to center of places[1].&lt;br /&gt;Draw line to (185,120).&lt;br /&gt;Draw line to center of places[2].&lt;br /&gt;Draw line to (205,160).&lt;br /&gt;Draw line to center of places[3].&lt;br /&gt;Draw line to (185,205).&lt;br /&gt;Draw line to center of places[4]&lt;br /&gt;Draw line to (145,230).&lt;br /&gt;Draw line to center of places[5].&lt;br /&gt;Draw line to (105,205).&lt;br /&gt;Draw line to center of places[6].&lt;br /&gt;Draw line to (90,160).&lt;br /&gt;Draw line to center of places[7].&lt;br /&gt;Draw line to (105,120).&lt;br /&gt;Draw line to center of places[0].&lt;br /&gt;&lt;br /&gt;Select into drawing context the old pen and brush.&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Note: As an alternative playing field, a 8-spoked wheel can also be draw.  Just draw the center last to keep it from being over-drawn.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114519682129957465?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114519682129957465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114519682129957465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114519682129957465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114519682129957465'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-playing-board.html' title='Mu Torere, the Playing Board'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114516163093896854</id><published>2006-04-15T23:05:00.000-05:00</published><updated>2006-04-15T23:27:10.950-05:00</updated><title type='text'>Mu Torere, the Application I</title><content type='html'>Step 2.&lt;br /&gt;Again the Application class will be used for storing the session values.  The values stored, private, will be '&lt;span style="font-style:italic;"&gt;int m_AI&lt;/span&gt;' for the AI level, '&lt;span style="font-style:italic;"&gt;int m_Undo&lt;/span&gt;' for the number of Undo's, '&lt;span style="font-style:italic;"&gt;COLORREF m_Computer&lt;/span&gt;', '&lt;span style="font-style:italic;"&gt;COLORREF m_User&lt;/span&gt;', and '&lt;span style="font-style:italic;"&gt;bool m_Display&lt;/span&gt;' for showing the playing piece display.&lt;br /&gt;Since these are private variables, you will need to add get/set accessor functions (inline) to the Application classes.  The only exception would be for the m_Undo variable, only a get function is needed as the user will NOT be able to adjust this during the game.  (If the user is feeling ambitious, he/she can go into the registry to change this value.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114516163093896854?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114516163093896854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114516163093896854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114516163093896854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114516163093896854'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-application-i.html' title='Mu Torere, the Application I'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114516034364652577</id><published>2006-04-15T22:51:00.000-05:00</published><updated>2006-04-15T23:05:43.663-05:00</updated><title type='text'>Mu Torere, the Set Up</title><content type='html'>The basic set-up of this program will be Microsoft's View-Document model, as I wrote earlier.&lt;br /&gt;&lt;br /&gt;Not much in the way a frills are needed, though I would recommend using the static MFC libraries.  After all, passing on your program to friends only to find out it woun't run from the lack of the proper libraries is not a good thing.  (This will also happen as your developement libraries become outdated.)&lt;br /&gt;&lt;br /&gt;Again, in the Mainframe class's PreCreateWindow(), the '&lt;span style="font-style:italic;"&gt;FWS_ADDTOTITLE&lt;/span&gt;' style needs removal.&lt;br /&gt;&lt;br /&gt;PS.  There was an additional class I neglected to mention last time, CInfoDisplay.  This class is more an aid to memory for the user as there is no easy way to tell the playing pieces apart except for the colour.  If you prefer you can mark the playing pieces appropriately, but follow along for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114516034364652577?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114516034364652577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114516034364652577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114516034364652577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114516034364652577'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-set-up.html' title='Mu Torere, the Set Up'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114496613408380049</id><published>2006-04-13T17:07:00.000-05:00</published><updated>2006-04-13T17:08:54.096-05:00</updated><title type='text'>Allocating memory and further thoughts on the Singleton Pattern</title><content type='html'>In all earnest, allocating memory is a prime case of "Damn'd if you do, and damn'd if you do not."  On one hand, you spend time programming allocation checking for a 200 K-byte utility that will be the only thing running on a system with 2 G-bytes of RAM.  On the other hand, you find out the hard way about the lack such checks when the utility recursively takes over the system's memory during the demo before the boss and very important clients 2 and 3.&lt;br /&gt;&lt;br /&gt;The current standards for C++ require that the new operator throws a bad_alloc exception when things go wrong during memory allocation.  Compilers can be made aware of this exception by including the '&lt;span style="font-style:italic;"&gt;new&lt;/span&gt;' header file while '&lt;span style="font-style:italic;"&gt;using namespace std;&lt;/span&gt;'  (Sorry, angle brackets are still awkward under Blogger.)&lt;br /&gt;Thus;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;bool Setup(void)&lt;br /&gt;{&lt;br /&gt;int *fields;&lt;br /&gt;&lt;br /&gt;try{&lt;br /&gt;&lt;br /&gt;fields = new int[NUM_RECORDS];&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;catch(bad_alloc e){&lt;br /&gt;&lt;br /&gt;return false;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// do something&lt;br /&gt;&lt;br /&gt;return true;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;This will allow the program to fail nicely and handle the situation, without crashing the system.&lt;br /&gt;&lt;br /&gt;PS.  C++ also allows new NOT to throw an exception, but the only reason I can see for this is to allow new to be used in constructors.  But I could be wrong.&lt;br /&gt;&lt;br /&gt;With respect to Singletons, this means that the Singleton instance can be allowed to fail (return NULL) in case of memory issues.  The other side to this is that these kind of memory failures need to be handled as well.Take a look at how Microsoft handles the situation in its View-Documents architecture.&lt;br /&gt;In Release executables, the View uses an inline GetDocument() function that returns a Document pointer that is re-cast into a pointer of the program's specific Document class.  In Debug executables, this GetDocument() function first ASSERTs that the program's Document is correctly derived before returning the pointer.&lt;br /&gt;&lt;br /&gt;The only cause for concern that might spring up is that when using a Singleton instance in serveral different classes, what happens to version control?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114496613408380049?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114496613408380049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114496613408380049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114496613408380049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114496613408380049'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/allocating-memory-and-further-thoughts.html' title='Allocating memory and further thoughts on the Singleton Pattern'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114488719207432039</id><published>2006-04-12T19:07:00.000-05:00</published><updated>2006-04-12T19:13:12.096-05:00</updated><title type='text'>Smeg. Smeg. Smeg!</title><content type='html'>My Tablet PC is screwing up.  Which should not be an issue except for the fact that I have all my projects stored on it.&lt;br /&gt;&lt;br /&gt;I really hope that all that needs doing is to update a driver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114488719207432039?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114488719207432039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114488719207432039' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114488719207432039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114488719207432039'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/smeg-smeg-smeg.html' title='Smeg. Smeg. Smeg!'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114480906332996736</id><published>2006-04-11T21:29:00.000-05:00</published><updated>2006-05-13T23:56:40.543-05:00</updated><title type='text'>Mu Torere Steps</title><content type='html'>&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/next-game.html"&gt;Next Game&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-classes.html"&gt;Mu Torere Classes&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-set-up.html"&gt;Mu Torere, the Set Up&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-application-i.html"&gt;Mu Torere, the Application I&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-playing-board.html"&gt;Mu Torere, the Playing Board&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-playing-board-ii.html"&gt;Mu Torere, the Playing Board II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-legend.html"&gt;Mu Torere, the Legend&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-changing-colours.html"&gt;Mu Torere, changing colours&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-owner-class.html"&gt;Mu Torere, the Owner class&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-stone-singleton.html"&gt;Mu Torere, the Stone Singleton&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai.html"&gt;Mu Torere, the AI!&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-moving-pieces.html"&gt;Mu Torere, moving the pieces&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-moving-pieces-ii.html"&gt;Mu Torere, moving the pieces II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai-ii.html"&gt;Mu Torere, the AI II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-ai_29.html"&gt; Mu Torere AI, again.&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-digression.html"&gt; Mu Torere, a digression&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-undo.html"&gt; Mu Torere, Undo&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-undo-ii.html"&gt; Mu Torere, Undo II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-ai-ii.html"&gt; Mu Torere AI II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-setting-ai.html"&gt; Mu Torere, setting the AI&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-rest-of-story.html"&gt; Mu Torere, the rest of the story&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-final-test.html"&gt; Mu Torere, the Final test&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/05/mu-torere-improvements.html"&gt; Mu Torere, Improvements&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I see that I will need to go back and re-do the titles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114480906332996736?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114480906332996736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114480906332996736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114480906332996736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114480906332996736'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-steps.html' title='Mu Torere Steps'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114480888038576684</id><published>2006-04-11T21:05:00.000-05:00</published><updated>2006-04-11T21:31:17.380-05:00</updated><title type='text'>Mu Torere Classes</title><content type='html'>A quick run down of the classes&lt;br /&gt;&lt;br /&gt;&lt;table celllspacing="0" border="0" cellpadding="5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td colspan="3"&gt;Microsoft classes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;View class (Drawing the game)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Application class (Storing the session values in the registry)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Document class (Managing the game)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td colspan="3"&gt;Game class (Bookkeeping for the game and its sub-components)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Board class (Singleton instance of the playing field)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Owner class (Bookkeeping for the players)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Stone class (Singleton instance for the playing pieces)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Undo class (Derived from)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;Circular Queue class&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td colspan="2"&gt;Move Generator class (Singleton, Determines the next move)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;k-Tree class (Helper class for the program's best move tree)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114480888038576684?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114480888038576684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114480888038576684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114480888038576684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114480888038576684'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/mu-torere-classes.html' title='Mu Torere Classes'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114472054417861928</id><published>2006-04-10T20:21:00.000-05:00</published><updated>2006-04-10T20:55:54.336-05:00</updated><title type='text'>Simple Blocking Game</title><content type='html'>The game with a solid lock on being the simplest game in history is widespread though out Asia. A sample of the names by which it is known (from Parlett); &lt;span style="font-style: italic;"&gt;Do-guti&lt;/span&gt; (India), &lt;span style="font-style: italic;"&gt;Pong Hau K'i&lt;/span&gt; (China), &lt;span style="font-style: italic;"&gt;On-moul-ko-no&lt;/span&gt; (Korea), &lt;span style="font-style: italic;"&gt;Sua tok&lt;/span&gt; (Thailand).&lt;br /&gt;&lt;br /&gt;The playing field can be thought of as a diagonally crossed square with one side removed. Movement is along the lines as show in the figure.   (At the risk of pointing out the obvious, the playable locations are the four corners of the square and the center.)&lt;br /&gt;&lt;br /&gt;&lt;table caption="Pong Hau K'i" border="1" cellpadding="5" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3450/2341/1600/PONG.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3450/2341/320/PONG.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;tfoot&gt;&lt;tr&gt;&lt;td&gt;Pong Hau K'i&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;&lt;/table&gt;&lt;br /&gt;Players move their pieces alternately to the empty point until one player cannot move.  The player that cannot move loses.&lt;br /&gt;&lt;br /&gt;An alternate way to start that is mentioned by R.C. Bell is that the players alternate placing their pieces onto the field before starting to move.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114472054417861928?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114472054417861928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114472054417861928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114472054417861928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114472054417861928'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/simple-blocking-game.html' title='Simple Blocking Game'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114461386465964425</id><published>2006-04-09T14:10:00.000-05:00</published><updated>2006-04-09T15:17:44.756-05:00</updated><title type='text'>Next Game</title><content type='html'>The next game that will be made in to a program is Mu Torere, a straight forward blocking game played by the Maori of New Zealand.&lt;br /&gt;&lt;br /&gt;It is played on a eight pointed star with the star's center as the ninth playable location.  Each player has four pieces and the movement rules are simple enough.&lt;br /&gt;- a Piece can move from the center to an empty star point.&lt;br /&gt;- a Piece can move from a star point to a neighbouring start point.&lt;br /&gt;- a Piece can move from a star point to the empty star center ONLY IF one or both of the neighboouring points are occupied by Pieces belonging to the opposing player.&lt;br /&gt;- in the program, the User will go first.  Letting the Computer play first is an option.&lt;br /&gt;&lt;br /&gt;A Player loses if there is no possible move availible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114461386465964425?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114461386465964425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114461386465964425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114461386465964425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114461386465964425'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/next-game.html' title='Next Game'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114460966952663051</id><published>2006-04-09T13:58:00.000-05:00</published><updated>2006-04-09T14:07:49.550-05:00</updated><title type='text'>on Poggle</title><content type='html'>&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/02/first-example.html"&gt;First Example&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/02/name-of-game-is-poggle.html"&gt;The Name of the Game is Poggle&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/02/poggle-patterns.html"&gt;Poggle Patterns&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/after-adding-board-class.html"&gt;After adding the Board Class&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/what-type-data-members-for-static.html"&gt;What type data members for static instance?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/on-menu-actions.html"&gt;On Menu actions&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/view-updates.html"&gt;View Class Update I&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/view-updates-ii.html"&gt;View Class Update II&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/clicking-on-poggle.html"&gt;Clicking on Poggle&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/big-part-of-poggle.html"&gt;The Big part of Poggle&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/drawing-re-visited.html"&gt;Drawing Re-visited&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/poggle-is-this-thing-on.html"&gt;Poggle, Is this thing on?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/03/poggle-working-with-registry.html"&gt;Poggle, Working with the Registry&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/final-exam-for-poggle.html"&gt;Final Exam for Poggle&lt;/a&gt;&lt;br /&gt;&lt;a href="http://schwarzekatzeproject.blogspot.com/2006/04/some-ideas-for-upgrading-poggle.html"&gt;Some ideas for upgrading Poggle&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now all I need to do is to go back and gammar check my posts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114460966952663051?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114460966952663051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114460966952663051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114460966952663051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114460966952663051'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/on-poggle.html' title='on Poggle'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114444202111773463</id><published>2006-04-07T15:31:00.000-05:00</published><updated>2006-04-07T16:34:43.360-05:00</updated><title type='text'>Some ideas for upgrading the Poggle executable.</title><content type='html'>Idea 1:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Localization for other languages.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There are only two places where this would need to be done.  The menu is one, the other is the Message to the user annoucing that the puzzle is solved.  Most of the material that I have read on the subject recommend to use the String table in the resources to store the message and menu strings the user will read, one String table per language.&lt;br /&gt;One solution that came up is to use resource DLLs. See the following page at &lt;a href="http://www.codeguru.com/cpp/misc/misc/article.php/c411__1"&gt;CodeGuru&lt;/a&gt; for further information.&lt;br /&gt;&lt;br /&gt;Idea 2:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Accessibility.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First off, what changes would need to be made where the mouse cannot be used?  The program then needs to handle keyboard input.  Which keys will be used for pointing? for selecting the pointed to cell?  Can the User change these input keys?&lt;br /&gt;Also, how will the selection be highlighted?  One way would be to manipulate the cursor so that it will point to the proper cell as the user uses the keyboard.  Another would be to change the display to make the selected cell stand out.&lt;br /&gt;&lt;br /&gt;As this program is visual in nature, how can vision issues be addressed.  In addition to blindness, there is colour-blindness.  Should the user be allowed to adjust the colours?  make them mono-chrome?&lt;br /&gt;&lt;br /&gt;Idea 3:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solutions.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is a very good chance that users will complain about the puzzles being impossible to solve.  So the solutions need to be documented.  How about automating the process?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114444202111773463?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114444202111773463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114444202111773463' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114444202111773463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114444202111773463'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/some-ideas-for-upgrading-poggle.html' title='Some ideas for upgrading the Poggle executable.'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114427478177144815</id><published>2006-04-05T17:05:00.000-05:00</published><updated>2006-04-05T17:06:21.790-05:00</updated><title type='text'>Final Exam for Poggle</title><content type='html'>Now that the program was coded and all the syntax errors have been fixed, the time has come to do all the finishing touches for the program.&lt;br /&gt;&lt;br /&gt;A formal and complete test schedule will not be described.  This would mean listing out ALL the "if .. [else if ..] then" staments in all coded routines and creating scenerios to trigger them.  The test set that will be described should be inclusive enough.&lt;br /&gt;&lt;br /&gt;Note all of the following should be done using the Debug version of the program.  This will allow the compiler's debugger to display the proper information.&lt;br /&gt;&lt;br /&gt;Round 1.&lt;br /&gt;- Does the program start?&lt;br /&gt;- Are all expected menu item accessible?&lt;br /&gt;- Does the Help menu work?&lt;br /&gt;- Does the program exit cleanly?&lt;br /&gt;&lt;br /&gt;For the first round that is all that is needed.  The user interface and starting/stopping the program is checked at this point.&lt;br /&gt;If the Program does not start, the initialization need to be checked.  If a three finger salute is needed to halt the program, the clean-up needs to be examined.  And the program's resources need to be examined if the menu is not correct.&lt;br /&gt;&lt;br /&gt;One final point to make here is that now is the time to start looking for memory leaks.  If one is found, it needs addressing immediately.  Usually, this will also get a majority of the memory problems that would otherwise pop up later.&lt;br /&gt;&lt;br /&gt;Round 2.&lt;br /&gt;- Using the basic options, does the game detect mouse clicks? valid ones? invalid ones?&lt;br /&gt;- Using the basic options, does the game process the user's selections properly?  Click each cell twice to address the following questions.&lt;br /&gt;- - Using the basic options, do the cells switch colours (black and white here) correctly?&lt;br /&gt;- - Using the basic options, do the correct neighbouring cells change state?&lt;br /&gt;- Using the basic options, does the game detect the winning condition? What happends when the program gets mouse clicks after this point?&lt;br /&gt;- Finally, using the basic options, does the 'New Game' menu item return the game to its starting position?&lt;br /&gt;- Exit and look for memory leaks again.&lt;br /&gt;&lt;br /&gt;Round 3 through N.&lt;br /&gt;Much of the same questions are asked for each game option.  Additionally;&lt;br /&gt;- Do the game settings menu items change the game?&lt;br /&gt;- - Is the number of cells correct?  Is it drawn correctly?&lt;br /&gt;- - Do the cells cycle through the correct colours?  Every time?&lt;br /&gt;&lt;br /&gt;Now once the winning condition has been tested for the basic game, I did not test for it to happen with the other versions.  If you get a win, more power to ya.&lt;br /&gt;&lt;br /&gt;Once the program was tested, memory leaks fixed, and debugged, the program can be compiled again for Release, i.e. optimized.&lt;br /&gt;&lt;br /&gt;Cheers&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114427478177144815?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114427478177144815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114427478177144815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114427478177144815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114427478177144815'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/final-exam-for-poggle.html' title='Final Exam for Poggle'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114409517940494146</id><published>2006-04-03T15:12:00.000-05:00</published><updated>2006-04-03T15:12:59.406-05:00</updated><title type='text'>How about that.</title><content type='html'>&lt;div style="font-family:verdana;font-size:10px;width:150px;BORDER: 1px solid;PADDING: 5px;BACKGROUND-COLOR: #ffc933; TEXT-ALIGN: left"&gt;&lt;div align="center" style="margin-bottom:5px; font-size:12px;" nowrap&gt;&lt;b&gt;I am 9% Idiot.&lt;/b&gt;&lt;br&gt;&lt;a style="font-size:10px;" target="_blank" href="http://www.fuali.com/test.aspx?id=741516d0-8635-449e-8e7b-914071fd3d36"&gt;&lt;img src="http://www.fuali.com/testimage.aspx?img=d8eacd49-c9a8-4af9-9081-8cbd55541209.gif" alt="Friggin Genius" border="0" style="margin-top:5px"&gt;&lt;/a&gt;&lt;/div&gt;I am not annoying at all. In fact most people come to me for advice.  Of course they annoy the hell out of me. But what can I do?  I am smarter than most people.&lt;div align="center" style="margin-top:5px;" nowrap&gt;&lt;a style="font-size:10px;" target="_blank" href="http://www.fuali.com/test.aspx?id=741516d0-8635-449e-8e7b-914071fd3d36"&gt;Take the&lt;br&gt;Idiot Test&lt;br&gt;@ FualiDotCom&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114409517940494146?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114409517940494146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114409517940494146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114409517940494146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114409517940494146'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/how-about-that.html' title='How about that.'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114409513388988860</id><published>2006-04-03T15:10:00.000-05:00</published><updated>2006-04-03T15:12:13.906-05:00</updated><title type='text'>Officially ...</title><content type='html'>I did not want to get caught up in all the 'April Fools' posting.&lt;br /&gt;&lt;br /&gt;Unofficially, I was too bleep-ing lazy to actually log on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114409513388988860?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114409513388988860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114409513388988860' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114409513388988860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114409513388988860'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/04/officially.html' title='Officially ...'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114385672806683712</id><published>2006-03-31T20:34:00.000-05:00</published><updated>2006-03-31T20:58:48.076-05:00</updated><title type='text'>Poggle: Working with the Registry</title><content type='html'>&lt;p&gt;&lt;span style="font-family:Arial;"&gt;The program will access the registry in two places in Poggle's Application class. One is the ExitInstance() where the menu options the user has picked are stored until the next session. The other is the InitInstance() (of course). It goes without saying that the standard warnings about working in the registry are in full force even when doing entry change programmatically.&lt;br /&gt;Not only that, for more involved programs, the programmer has to keep the registry structure for the program in mind. Will the structure need updating when the program changes? (I am doing this for my Concentration program, and it is an iron-casted pain.) How will changes in the registry (from the user or otherwise) be handled?&lt;br /&gt;&lt;br /&gt;Step 15: I put the following after the program's initialization executes LoadStdProfileSettings(0), which loads the .INI file stuff.&lt;br /&gt;&lt;br /&gt;Using the RegCreateKeyEx() function is a two-fer operation. If the key does not exit, the operation creates it. Otherwise, the key is opened for further work.  The key returned from this function can be used in the following functions to point to the proper registry entry.&lt;br /&gt;For the root registry key of the program the following options were used;&lt;br /&gt;The Registry Key to be worked on was the hive, HKEY_CURRENT_USER (wait for it) to keep the user's choices personnal.&lt;br /&gt;The SubKey used is "Software\\Your Company\\Poggle". (Thought I was going to work on the hive root, didn't you.) Note the escaped slashes.&lt;br /&gt;The registry option used was REG_OPTION_NON_VOLATILE to keep the entries between sessions.&lt;br /&gt;The Security option used was KEY_ALL_ACCESS. Used appropriately, this parameter allows the programmer to tailor the program's functionality to the best (lowest) security settings needed. Done wrong, only the Administrator will be able to run the program.&lt;/span&gt;&lt;/p&gt;   &lt;p&gt;The returned value from this function is asserted to be equal to ERROR_SUCCESS.&lt;br /&gt;The results value (what went on) is asserted NOT to be NULL.&lt;/p&gt;   &lt;p&gt;If the results value is REG_CREATED_NEW_KEY then the program's session values for size and colour cycles need to be created, via RegSetValueEx().&lt;br /&gt;Otherwise the values for this sessions can be retrieved with RegQueryValueEx().  Mind the results value of NULL (error from the registry key creation/open) should be handled as well.&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Step 16:  In the ExitInstance() function all that needs to be done is to use the RegSetValueEx() function to enter the session values before the program exits.&lt;br /&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114385672806683712?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114385672806683712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114385672806683712' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114385672806683712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114385672806683712'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/poggle-working-with-registry.html' title='Poggle: Working with the Registry'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114368157714207982</id><published>2006-03-29T19:59:00.000-05:00</published><updated>2006-03-29T20:19:37.163-05:00</updated><title type='text'>Quick aside: A comment on 'Magic Numbers'.</title><content type='html'>First off, avoid 'Magic numbers' at all times in your program!  It is extremely rare for a single use of a fudge factor in any program.  Honestly, these adjustment numbers will, not might, WILL pop-up elsewhere  as the program grows.&lt;br /&gt; The only instances where such a number is used, that I can think of, would be in a mathematical equation (which really should be in its own routine anyways) or as a throw-away value only needed for debugging, e.g. the actual value does not matter just as long it is the same for each debugging session.&lt;br /&gt;&lt;br /&gt;If a number is needed, consider making it a user defined value instead of a named constant.  Many times the user will have a better idea as to the preffered value than the developer.  (And many times the user will be a gormless git that will make a complete hash of things.  But that is another rant.)&lt;br /&gt;Case in point is the colour of the playing pieces.  Now Black and White are considered traditional.  But earlier, before mono-chrome displays, red was often used as the second colour in a number of games, i.e. Black and Red for backgammon and less commonly White and Red for chess.  And what about adding an additional player?  That third colour should be used?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114368157714207982?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114368157714207982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114368157714207982' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114368157714207982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114368157714207982'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/quick-aside-comment-on-magic-numbers.html' title='Quick aside: A comment on &apos;Magic Numbers&apos;.'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114368018893667412</id><published>2006-03-29T19:49:00.000-05:00</published><updated>2006-03-29T19:58:53.140-05:00</updated><title type='text'>Poggle: Is this thing on?</title><content type='html'>Step 14: The routine, bool finishedTest(void) the Board will use to find that the user has completed the challenge is fairly straight forward.&lt;br /&gt;&lt;br /&gt;Pre-conditions:&lt;br /&gt;- Is the Board instance valid? Actually this would be unneccessary as the routine is private and will not be call via the Singleton interface.&lt;br /&gt;- Is the Board's &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array valid?&lt;br /&gt;&lt;br /&gt;Loop through the &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array&lt;br /&gt;- - (Note: I made an assumption here that I could have Assert'ed, that all &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; values are greater than or equal to 0.)&lt;br /&gt;- - Is this element less than Board's &lt;span style="font-weight: bold;"&gt;cycle&lt;/span&gt; variable -1?&lt;br /&gt;- - - If so then return false.&lt;br /&gt;&lt;br /&gt;Return true.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114368018893667412?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114368018893667412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114368018893667412' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114368018893667412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114368018893667412'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/poggle-is-this-thing-on.html' title='Poggle: Is this thing on?'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114360013336107128</id><published>2006-03-28T21:21:00.000-05:00</published><updated>2006-03-28T21:42:13.383-05:00</updated><title type='text'>Drawing, Re-visited</title><content type='html'>Step 13:  Now that the Board's &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array is being used I can describe the void Draw(CDC* pDC) function in better detail.&lt;br /&gt;&lt;br /&gt;In the constructor create and specify 5 solid CBrush objects (Yes, they are variables of the Board class).  Using black for all off and white for all one, the three other CBrush object's colours are red, green and blue.&lt;br /&gt;&lt;br /&gt;Preconditions:&lt;br /&gt;- Is the Board instance still valid?&lt;br /&gt;- Is the supplied pDC valid?&lt;br /&gt;- Is the &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array still valid?&lt;br /&gt;- Is the &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; array still valid?&lt;br /&gt;&lt;br /&gt;For each cell of the Board,&lt;br /&gt;- - if the state of that cell is the Board's &lt;span style="font-weight: bold;"&gt;cycle&lt;/span&gt; -1 (all on), select the white CBrush&lt;br /&gt; - - else if the state of that cell is 3, select a colour CBrush.&lt;br /&gt; - - else  if the state of that cell is 2, select a colour  CBrush.&lt;br /&gt; - - else if the state of that cell is 1, select a colour  CBrush.&lt;br /&gt; - - else  the state of that cell is 0 (all off), select the black CBrush.&lt;br /&gt;&lt;br /&gt;- - Draw the cell.  Note, not specifying the CPen of the current drawing area (the pDC) will cause an 1 pixel black outline to be drawn.  It would have been better to assume that the user would have chosen the window background and a contrasting text colour and gone with that text colour to outline the cells.&lt;br /&gt;&lt;br /&gt;Post conditions:&lt;br /&gt;- The Board instance is still valid.&lt;br /&gt;- The same can be assumed about the &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; arrays.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114360013336107128?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114360013336107128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114360013336107128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114360013336107128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114360013336107128'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/drawing-re-visited.html' title='Drawing, Re-visited'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114352452330707425</id><published>2006-03-28T00:12:00.000-05:00</published><updated>2006-03-28T00:42:03.356-05:00</updated><title type='text'>The big part of Poggle</title><content type='html'>At least the part that I consider the MAIN part, everything else is secondary.&lt;br /&gt;&lt;br /&gt;Step 13: Firat of, the mod portion of the program, int changeState(const int&amp; state), the only thing that this routine does is to return the next integet in the current cycle.&lt;br /&gt;&lt;br /&gt;The pre-condition is that the current Board instance is valid.&lt;br /&gt;&lt;br /&gt;If the state parameter of the function is equal to the Board class's &lt;span style="font-weight: bold;"&gt;cycle&lt;/span&gt; variable -1, then return 0 (the starting point).&lt;br /&gt;&lt;br /&gt;Otherwise, return the state +1.&lt;br /&gt;&lt;br /&gt;Step 14: For void toggleCells(const int&amp; index);&lt;br /&gt;The pre-conditions are tha the Board instance is valid (again).&lt;br /&gt;That the the &lt;span style="font-weight: bold;"&gt;place&lt;/span&gt; index is within bounds.  (Release, otherwise just return.)&lt;br /&gt;And that the &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array is not NULL&lt;br /&gt;&lt;br /&gt;First off, the clicked CRect element.  Use the changeState() function on the &lt;span style="font-weight: bold;"&gt;state&lt;/span&gt; for the clicked CRect.&lt;br /&gt;&lt;br /&gt;If the index is greater than the Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt;-1 (top row), then apply changeState() to the CRect above the current cell.  (index - Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt;)&lt;br /&gt;If the index is less than or equal to Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt; * (Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt;) (bottom row), than apply changeState() to the CRect below the current cell. (index +Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt;).&lt;br /&gt;If the index mod() with the Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt; is NOT equal to 0 ( left side), apply changeState() to index -1.&lt;br /&gt;If the index mod() the Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt; is NOT equal to the Board's &lt;span style="font-weight: bold;"&gt;size&lt;/span&gt; -1 (right side), then apply changeState() to index +1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114352452330707425?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114352452330707425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114352452330707425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114352452330707425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114352452330707425'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/big-part-of-poggle.html' title='The big part of Poggle'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114339738343277004</id><published>2006-03-26T12:49:00.000-05:00</published><updated>2006-03-26T13:23:03.480-05:00</updated><title type='text'>Clicking on Poggle</title><content type='html'>In the View-Document model, only the View class processes mouse clicks. Which means that the program needs to jump through a couple of routines to detect and react to the user's mouse.&lt;br /&gt;&lt;br /&gt;After adding the OnLButtonDown(UINT flags, CPoint point) handler to the View class, similar functions need to be added to the Document and the Board. The View calls the Document and the Document calls the Board.&lt;br /&gt;&lt;br /&gt;Step 11: In the Document's mouse handler, void onClick(const CPoint&amp; point), there are only three statements that need to be taken.&lt;br /&gt;&lt;br /&gt;Assert that there is an instance of the Board class.  (CBoard::getInstance() != NULL)&lt;br /&gt;&lt;br /&gt;Call the Board's mouse handler.&lt;br /&gt;&lt;br /&gt;Update view. Here the programmer will use UpdateAllViews(NULL). As only one View is associated with the Document, it does not matter if one goes through the effort to find the pointer this single View or just uses NULL for all (meaning one) Views. The other bit is that with only one parameter used, no hint value is passed and the OnUpdate routine will just Invalidate() the drawing area.&lt;br /&gt;&lt;br /&gt;Note:  I used a const reference for the click point as I did not see any need to manipulate the mouse.&lt;br /&gt;&lt;br /&gt;Step 12:  There are more things to process in the Board class's mouse handler, void onClick(const CPoint&amp;amp; point).&lt;br /&gt;&lt;br /&gt;Check pre-conditions.  (Is there a valid instance?  Is &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; valid?)&lt;br /&gt;&lt;br /&gt;Is the game over? (I tested a boolean variable to avoid calling a routine.) If finished, congratulate the user again and return.&lt;br /&gt;&lt;br /&gt;Find the CRect object in &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; that contains the CPoint object &lt;span style="font-style: italic;"&gt;point&lt;/span&gt;. It is highly recommended not to use the loop variable as the record holder for this. Currently C++ standards mean that this variable is likely to be out-of-scope outside of the loop. Most compilers will enforce this, although there are reportedly some that will keep the loop variable visible outside of the loop.&lt;br /&gt;&lt;br /&gt;Ignoring out-of-bounds index values (less than 0 and greater than or equal to the Board's size variable squared), process the relevant state value and test for completion. If complete, congratulate the user and set the boolean finished variable for future reference.&lt;br /&gt;&lt;br /&gt;Process post-conditions. (Is the Board instance still valid?)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114339738343277004?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114339738343277004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114339738343277004' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114339738343277004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114339738343277004'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/clicking-on-poggle.html' title='Clicking on Poggle'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114335091184016186</id><published>2006-03-26T00:14:00.000-05:00</published><updated>2006-03-26T00:28:31.866-05:00</updated><title type='text'>Concentration: Reinventing the wheel</title><content type='html'>Specifically Object Oriented Programming.&lt;br /&gt;&lt;br /&gt;Originally, I was accessing the specific advanced/medium/beginner variables directly. Actually there was every reason to leave the decision tree at the Application (with the Application) and just ask for the output variables.&lt;br /&gt;&lt;br /&gt;Now that I have changed the options, not only do I have the normal beginner/medium/ advanced playing fields, I have the same variables for the 'Blink' (show cards before play), the 'Challenge' (change timer as player progresses), and 'Master' (hide matched cards) variants. I have to add specific registry keys for each combination of variant and still deliver them to the User with the same function call.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114335091184016186?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114335091184016186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114335091184016186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114335091184016186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114335091184016186'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/concentration-reinventing-wheel.html' title='Concentration: Reinventing the wheel'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114317591179767462</id><published>2006-03-23T22:53:00.000-05:00</published><updated>2006-03-23T23:51:51.890-05:00</updated><title type='text'>View Updates II</title><content type='html'>Most of the Desktop checks would really not be an issue with regards to Poggle, but it is best to get into the habit of checking anyways.&lt;br /&gt;&lt;br /&gt;The  maximum width bounded by the desktop is found by using GetSystemMetrics(SM_CXMAXTRACK).&lt;br /&gt;&lt;br /&gt;On the other hand, the height of the desktop is found using a different systems function. This is found using the function SystemParametersInfo() with the action SPI_GETWORKAREA. This will get the Rect denoting all the desktop that is NOT covered by the taskbar or by any application desktop toolbar. The function will need a temporary CRect object to store the retrieved value.&lt;br /&gt;&lt;br /&gt;Finally, the function SetWindowPos() needs to be called to set the program's dimensions. This function can be used via the Windows pointer from AfxGetMainWnd(). There are some differences using SetWindowPos() between the initial update and the user demanded updates that will be explained below.&lt;br /&gt;&lt;br /&gt;Step 9:  The Initial Update.&lt;br /&gt;&lt;br /&gt;Call the View class's CView::OnInitialUpdate() function.&lt;br /&gt;&lt;br /&gt;Get and adjust the size of the Board object as mentioned earlier.&lt;br /&gt;&lt;br /&gt;Set the Window size with AfxGetMainWnd()-&gt;SetWindowPos(NULL, 0, 0, adjustedSize.cx, adjustedSize.cy, SWP_NOMOVE | SWP_NOZORDER).&lt;br /&gt;&lt;br /&gt;Step 10: The On-Demand Updates.&lt;br /&gt;&lt;br /&gt;void CPoggleView::OnUpdate(CView* , LPARAM lHint, CObject*)&lt;br /&gt;{&lt;br /&gt;The only function parameter we are interested in the  lParam &lt;span style="font-style: italic;"&gt;lHint &lt;/span&gt;for communication between the Document and View.&lt;br /&gt;&lt;br /&gt;Test &lt;span style="font-weight: bold;"&gt;lHint&lt;/span&gt; for the value specifying that the View needs resizing.  (I used an &lt;span style="font-weight: bold;"&gt;enum&lt;/span&gt; to create a named constant in Poggle's Document class for this.)  If so, then&lt;br /&gt;{&lt;br /&gt;Get and adjust the size of the Board object as mentioned earlier.&lt;br /&gt;&lt;br /&gt;Set the Window size with AfxGetMainWnd()-&gt;SetWindowPos(NULL, 0, 0, adjustedSize.cx, adjustedSize.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOCOPYBITS).&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;In any case Invalidate() and redraw everything.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Note:  The flags in SetWindowPos (last parameter) specify the following:&lt;br /&gt;SWP_NOZORDER - Leaves the program in the z-order it currently is placed, If top-most it stays top-most. This flag causes the function to ignore the first parameter (pointer to reference Window pointer, here NULL.&lt;br /&gt;SWP_NOMOVE - Keep position. (Actually leave top-left corner of window in same position.) This flag causes function to ignore the second and third parameters (here 0 and 0).&lt;br /&gt;SWP_NOCOPYBITS - Discards everything within the GUI.  The program MUST redraw itself to show any changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114317591179767462?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114317591179767462/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114317591179767462' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114317591179767462'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114317591179767462'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/view-updates-ii.html' title='View Updates II'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114306904553889824</id><published>2006-03-22T17:48:00.000-05:00</published><updated>2006-03-22T21:22:02.406-05:00</updated><title type='text'>View Updates</title><content type='html'>Under Microsoft's View-Document model there are a few places that the programmer can change the size of the program's interface.&lt;br /&gt;&lt;br /&gt;The common one given as an example is to use the Mainframe class's PreCreateWindow function and alter the CREATESTRUCT variable's &lt;span style="font-weight: bold;"&gt;cx&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;cy&lt;/span&gt; parameters.  The problem is that this is only good for program where the height and width are already known.&lt;br /&gt;&lt;br /&gt;While I am talking about the CMainFrame::PreCreateWindow function;&lt;br /&gt;Step 8:  Remove the style &lt;span style="font-style: italic;"&gt;FWS_ADDTOTITLE&lt;/span&gt; from the cs.style parameter. This style adds the filename of the saved file the program is displaying or 'Untitled' when starting afresh.&lt;br /&gt;&lt;br /&gt;The other place to re-size a program is in the View class's OnInitialUpdate and OnUpdate functions using Window's SetWindowPos(). OnInitialUpdate() is called between the time the Document first connects with the View but before the View is first displayed. OnUpdate() is called by the Document's UpdateAllView() function, which allows the programmer an opportunity to refresh the View on demand.&lt;br /&gt;&lt;br /&gt;While there are some differences between the initial and on-demand updates, the bare bones is as follows;&lt;br /&gt;&lt;br /&gt;Get the size of the Board. A pass-through function in the Document class should do this as there could be additional information in the Document to be added (not in this case). Reminder, this will be the right-most and bottom-most values, plus the BORDER value in each direction.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;table border="1" cellpadding="5" cellspacing="0"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;Example: The getSize() function from CBoard&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;CSize CBoard::getSize(void) const&lt;br /&gt;{&lt;br /&gt;Assert that this instance is not NULL.&lt;br /&gt;     &lt;br /&gt;Assert that Board's &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; is not NULL.&lt;br /&gt;If Board's &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; is NULL, then return an empty CSize value, i.e. CSize(0,0).&lt;br /&gt;     &lt;br /&gt;Return Size with the right-most value of &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt;[BoardSize-1]+&lt;span style="font-weight: bold;"&gt;BORDER&lt;/span&gt; and the bottom-most value of &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt;[BoardSize * (BoardSize-1)]+&lt;span style="font-weight: bold;"&gt;BORDER&lt;/span&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;The returned size is then adjusted for the GUI.&lt;br /&gt;(For Microsoft) In the X direction this is given by GetSystemMetrics(SM_CXFIXEDFRAME) which is the width of the GUI frame for the thin frame style. (I did say to create the program with the thin frame didn't I?)&lt;br /&gt;The Y direction adjustment is given by the GetSystemMetrics(SM_CYFIXEDFRAME) PLUS GetSystemMetrics(SM_CYCAPTION) (for the caption) PLUS GetSystemMetrics(SM_CYMENU) (for the menu bar). Please Note that this last metric is for single line menus only. (I am still working on multiple line menus.)&lt;br /&gt;&lt;br /&gt;Next up, Desktop checks.&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114306904553889824?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114306904553889824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114306904553889824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114306904553889824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114306904553889824'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/view-updates.html' title='View Updates'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114296400778138975</id><published>2006-03-21T11:48:00.000-05:00</published><updated>2006-03-21T13:00:07.853-05:00</updated><title type='text'>Marks, and Revisions, and Versions, oh my!</title><content type='html'>I have not seen any sort of 'rules of thumb' for coming up with version numbers.  So here is mine.&lt;br /&gt;&lt;br /&gt;The Version (or Major Version) Number;  This increments only when the User experience with the program will change in a new and major way or when the program design changes in a manner that the entire program has to be re-engineered from soup to nuts.&lt;br /&gt;Simply extending the program's functionality, e.g. additional file types, would not make the cut.  The extention would have to involve new capabilities for the user, not just additional capabilities much like ones that user had before.&lt;br /&gt;For instance, adding a move hint capability would justify a change in version as this would involve multiple changes in multiple areas in the program to implement.&lt;br /&gt;N.B.  Zero in this position, by convention, is reserved for works in progress, alpha and beta programs.&lt;br /&gt;&lt;br /&gt;The Mark (or Minor Version) Number; This increments when the user's experience is modified or when a major portion of the program needs changing, like when a class withing the program needs refactoring.&lt;br /&gt;For instance, instead of just showing the best move, the program could indicate which moves are better than others.  The only major changes are done in a very small set of classes, usually one, and minimal changes (if any) are needed elsewhere.&lt;br /&gt;&lt;br /&gt;The Revision Number;  Capabilities and user experience remains the same but how they are implemented changes.  Usually the changes involve one, maybe two, functions.&lt;br /&gt;&lt;br /&gt;The Build Number;  Increments per build cycle.  Setting this to zero would basically depend on the developer.&lt;br /&gt;&lt;br /&gt;Sometimes Build number and Revision numbers are swapped.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114296400778138975?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114296400778138975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114296400778138975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114296400778138975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114296400778138975'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/marks-and-revisions-and-versions-oh-my.html' title='Marks, and Revisions, and Versions, oh my!'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114295683048266776</id><published>2006-03-21T10:30:00.000-05:00</published><updated>2006-03-21T11:03:33.040-05:00</updated><title type='text'>On Menu actions</title><content type='html'>Step 7: All of the menu items concerned with changing the game (its size or colour cycle) can be written the same way.&lt;br /&gt;&lt;br /&gt;Example;&lt;br /&gt;on selecting size X by X&lt;br /&gt;{&lt;br /&gt;Set Document's changed size flag to true.&lt;br /&gt;&lt;br /&gt;Set Application's size variable to X.&lt;br /&gt;&lt;br /&gt;Call OnNewDocument() to recreate Board.&lt;br /&gt;&lt;br /&gt;Update View.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;on updating size X by X menu item&lt;br /&gt;{&lt;br /&gt;Set check if Application's size variable == X.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note 1:  Accessing the Application class's members is not hard but there is one trick to remember.  AfxGetApp() returns a pointer to the CWinApp &lt;span style="font-style: italic;"&gt;base&lt;/span&gt; class, not a pointer to the Application class.  You will need to cast the pointer in order to get to the Application's class members, i.e. (CPoggle*)AfxGetApp().&lt;br /&gt;And yes it would be better to use dynamic_cast to recast the pointer.  Just remember use a try and catch structure for possible mis-casting.&lt;br /&gt;[UPDATE] Standard OO mistake here.  Directly accessing the Application's variables is not good form.  It would be much better to use Set / Get functions.&lt;br /&gt;&lt;br /&gt;Note 2:  Changing the Board's size and the Board's colour cycle really do not need to be handled in the same manner as only changing the size means re-allocating memory.  So this is another item that can be improved later on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114295683048266776?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114295683048266776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114295683048266776' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114295683048266776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114295683048266776'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/on-menu-actions.html' title='On Menu actions'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114282307854617264</id><published>2006-03-19T21:04:00.000-05:00</published><updated>2006-03-19T21:51:18.603-05:00</updated><title type='text'>State-ful variables</title><content type='html'>Step 6:  The Document-View model that Mircosoft uses has a central application class that manages the WinMain portion of the program.  Later on the registry founctions will ba added, but for now just the size of the playing field and the number of colours vaeiables need be created.  Note: It would be a good idea that the limits of the Board class be enforced at this point but this can be compensated for at the game set up.  (It is still a possible problem but only if the limits are not enforced constantly.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114282307854617264?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114282307854617264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114282307854617264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114282307854617264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114282307854617264'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/state-ful-variables.html' title='State-ful variables'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114256429077012672</id><published>2006-03-16T21:19:00.000-05:00</published><updated>2006-03-16T21:59:42.723-05:00</updated><title type='text'>The Set-up functions</title><content type='html'>Step 3:  The first set-up function is used to allocate the Rectangle array &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; and the int array &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt;. It is only called when the size of the playing area or of the color cycle needs changing. of course the program start up calls this function as well.&lt;br /&gt;&lt;br /&gt;boolean setUp(void)&lt;br /&gt;&lt;br /&gt;// preconditions&lt;br /&gt;Assert that the Board instance pointer is not NULL.  ( redundant, but just in case )&lt;br /&gt;Assert that the Board size value is within specified limits&lt;br /&gt;&lt;br /&gt;If the &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; array exists, delete it.&lt;br /&gt;If the &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array exists, delete it.&lt;br /&gt;&lt;br /&gt;Create the new Rectangle array using the Board's size value (squared) and asign it to &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt;&lt;br /&gt;Create the new Rectangle array using the Board's size value (squared) and asign it to &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Assert that &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; is not NULL. (Debug)&lt;br /&gt;If &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; is NULL, return failed. (Release)&lt;br /&gt;&lt;br /&gt;Using the constant values for the border, cell spacing and cell size, create in &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; an x-by-x square of Rectangles.&lt;br /&gt;&lt;br /&gt;// post conditions&lt;br /&gt;Assert that the Board instance is still not NULL.&lt;br /&gt;&lt;br /&gt;Return success.&lt;br /&gt;&lt;br /&gt;Step 4: The other set-up function is a reset or initialization function for new games. As everything else is set up all this function needs to do is to set the values in the &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; array to 0 (Black) and initialize any other game values in the Board instance.&lt;br /&gt;The pre-conditions are that the Board instance exists, and that there is a  valide &lt;span style="font-weight: bold;"&gt;states&lt;/span&gt; pointer.&lt;br /&gt;The post-condition is that the Board instance still exists.&lt;br /&gt;&lt;br /&gt;Step 5: Of course a function is needed to set the Board instance's field size and number of colours variables.&lt;br /&gt;&lt;br /&gt;Step 6: As I am using the Microsoft View-Document model, I put the set-up calls in the Document class's OnNewDocument function.&lt;br /&gt;&lt;br /&gt;// the variables denoting a change in the Board instance were set to true in the Document's constructor&lt;br /&gt;If there was a change in the size or number of colours do{&lt;br /&gt;&lt;br /&gt;Set the Board instance's size and number of colours.&lt;br /&gt;&lt;br /&gt;CBoard::getInstance()-&gt;setUp();&lt;br /&gt;&lt;br /&gt;Set the Documents variables for a changed Board to false.&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Reset the Board instance to game starting values.&lt;br /&gt;&lt;br /&gt;Of course, if the Board instance's setUp() failed, this will have to be passed on to the Document's base class for handling as an error.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114256429077012672?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114256429077012672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114256429077012672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114256429077012672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114256429077012672'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/set-up-functions.html' title='The Set-up functions'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114248264079735488</id><published>2006-03-15T22:54:00.000-05:00</published><updated>2006-03-15T23:17:20.806-05:00</updated><title type='text'>Changing the game: I</title><content type='html'>Step 1:  First I enumerated the various constants (&lt;span style="font-weight: bold;"&gt;enum&lt;/span&gt;), the upper and lower limits to the size of the board and some delimiters for drawing the board  (border, rectangle size, and space between).  The lowest limit I chose for the board size was 3 (for a 3-by-3 cell board) and the upper was 7.  At this time the constants for the upper and lower limits for the colours the game uses can also be added.&lt;br /&gt;I would recommend using the lower limit to initialize the board size's static variable.&lt;br /&gt;&lt;br /&gt;Step 2: Add the appropriate menu items.   I went for 'Preferences'-&gt;'Size' -&gt;[ 3x3,4x4,5x5,6x6,7x7].  Then the event handlers and update handlers can be added to the Document class for these menu items.  The update handlers will allow the program to checkmark the right menu item.  (I will go into this later.)  The menu items for the number of colours can also be dealt with at this point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114248264079735488?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114248264079735488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114248264079735488' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114248264079735488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114248264079735488'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/changing-game-i.html' title='Changing the game: I'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114239625537607475</id><published>2006-03-14T23:02:00.000-05:00</published><updated>2006-03-14T23:17:35.386-05:00</updated><title type='text'>Constant for large values of X</title><content type='html'>No doubt you have started out creating constant values using the statement '&lt;span style="font-style: italic;"&gt;#define VALUE=5&lt;/span&gt;'. The problem with this is that most debuggers will not be able to report this constant value. The fact that the preprocessor has processed this statement before the debug symbols are gathered is one reason for this.&lt;br /&gt;&lt;br /&gt;A better way to represent constant values is to use the &lt;span style="font-style: italic;"&gt;const&lt;/span&gt; keyword.  (&lt;span style="font-style: italic;"&gt;Final&lt;/span&gt; in Java.)  One advantage is that any type of variable can be called constant, and this includes user defined structures.&lt;br /&gt;&lt;br /&gt;If you would rather have the constant value have class scope, using the &lt;span style="font-style: italic;"&gt;enum&lt;/span&gt; keyword is the way to go. You cannot use a variable type other than integer, but you can reference the value through the containing class, e.g. &lt;span style="font-weight: bold;"&gt;myClass&lt;/span&gt;::&lt;span style="font-style: italic;"&gt;constVal.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114239625537607475?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114239625537607475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114239625537607475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114239625537607475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114239625537607475'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/constant-for-large-values-of-x.html' title='Constant for large values of X'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114227955520194144</id><published>2006-03-13T14:28:00.000-05:00</published><updated>2006-03-13T14:52:35.270-05:00</updated><title type='text'>A Variation on Concentration</title><content type='html'>After reading about memory tests, I thought up a variant for my Concentration game.   The user first sees the card layout.  When ready, the user clicks on the 'Blink' menu item or button.  The program then displays the card pairs for X seconds and then only shows the card backs.  In order to rely on memory only, the program only indicates match success or failure by changing the colors of the card backs.&lt;br /&gt;&lt;br /&gt;A couple of options to make the game even more sadistic.  One, if the user can match cards in under an arbitrary number of attempts, the program automatically shortens the time that the cards are displayed when the user clicks 'Blink'.&lt;br /&gt;The second, and worse, is to have the computer revert the display of the successful matches to 'un-played' after a short time.  Not only would the user have to memorize the card positions, but the successful matches as well.  Of course matching a pair of cards the second or more time would not go to the score.&lt;br /&gt;&lt;br /&gt;This observation / memory training game is not a new idea.  I have come accross it elsewhere, but the only place that I definitly remember it is in Heinlein's "Citizen of the Galaxy".  Here a bunch of odds-and-ends are thrown on the ground / a tray / the table and then covered after a short time.  Not only must the player remember what objects were thrown, the position and orientation (if possible) has to be remembered as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114227955520194144?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114227955520194144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114227955520194144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114227955520194144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114227955520194144'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/variation-on-concentration.html' title='A Variation on Concentration'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114227785445004142</id><published>2006-03-13T13:54:00.000-05:00</published><updated>2006-03-13T14:24:17.263-05:00</updated><title type='text'>What type data members for a static instance?</title><content type='html'>In &lt;span style="font-weight: bold;"&gt;Poggle&lt;/span&gt;, I am using &lt;span style="font-style: italic;"&gt;static&lt;/span&gt; for all data members in the Singleton opbject.  In other program, the only &lt;span style="font-style: italic;"&gt;static&lt;/span&gt; data member is the instance variable.&lt;br /&gt;&lt;br /&gt;About the only advantage I can think of for all data variable to be declared static is to allow the calling classes to access them, directly or throught accessor functions, without going through the Singleton instance.  The disadvantage is this will break the expected behavior of the Singleton as well as having potential syncronization issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114227785445004142?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114227785445004142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114227785445004142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114227785445004142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114227785445004142'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/what-type-data-members-for-static.html' title='What type data members for a static instance?'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114204126838680231</id><published>2006-03-10T20:32:00.000-05:00</published><updated>2006-03-11T09:12:17.096-05:00</updated><title type='text'>After adding the Board class</title><content type='html'>As the starting point one should start with four functions; one to draw, one to get the size of the field, and two to initialize the data. The first initialization function is for new games. The second is for those times the playing field changes. (Actually for non-solitare games, the Board class only needs to initialized once in its lifetime.)&lt;br /&gt;&lt;br /&gt;The data variable that the Board class will start with is a pointer to a Rectangle class, &lt;span style="font-weight: bold;"&gt;*places&lt;/span&gt;.  (CRect in Microsoft IDE.)  Since the Board will be re-sized when different game playing options are selected, pointers will allow the board information to be destroyed and recreated on the fly.  Clean-up is nothing out of the ordinary, so the Board class's destructor can be in charge of that.&lt;br /&gt;The other starting variable is a integer to hold the size information.  This is to avoid all the sizeof()/sizeof(Rectangle) hoops to jump through to get pointer array information.  I recommend just storing the length of the side.&lt;br /&gt;&lt;br /&gt;For right now, the drawing function for the class just can draw the rectangles that &lt;span style="font-weight: bold;"&gt;places&lt;/span&gt; point to.  This will suffice as a place-holder until the rest of the game's variables are added.  A single loop will be all that is required.  Just assert() that there is a valid pointer before drawing random pointers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114204126838680231?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114204126838680231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114204126838680231' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114204126838680231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114204126838680231'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/after-adding-board-class.html' title='After adding the Board class'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114187504415657421</id><published>2006-03-08T21:17:00.000-05:00</published><updated>2006-03-08T22:37:27.876-05:00</updated><title type='text'>The Singleton: One More Time</title><content type='html'>What was the bit from the &lt;span style="font-style: italic;"&gt;Highlander&lt;/span&gt; series?  "There can be only one!"&lt;br /&gt;&lt;br /&gt;The Singleton pattern enforces this idea. Hiding the details of creating the object from the calling class, a Singleton object forces the caller to access its functionality through a specialized interface. One advantage of this approach is that the caller will not need to track multiple objects over different calling objects.&lt;br /&gt;&lt;br /&gt;While, supposedly, a Singleton object in C++ can be constructed in the manner as those in Java, I will be using a point to implement Singleton objects. The only disadvantage is that the user must manage the destruction of the object, and not depend on the scope of the Singleton.&lt;br /&gt;&lt;br /&gt;Header File:&lt;br /&gt;&lt;br /&gt;class Singleton&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Singleton(void);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;~Singleton(void);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static Singleton *instance;&lt;br /&gt;&lt;br /&gt;public:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static Singleton* getInstance(void);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static void Release(void);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Source:&lt;br /&gt;&lt;br /&gt;#include "Singleton.h"&lt;br /&gt;&lt;br /&gt;Singleton* Singleton::instance=NULL;&lt;br /&gt;&lt;br /&gt;Singleton::Singleton(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//do stuff here&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;~Singleton::Singleton(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// clean up&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Singleton* Singleton::getInstance(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(instance == NULL){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;instance = new Singleton();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return instance;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Singleton::Release(void)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if(instance != NULL){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;delete instance;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;instance = NULL;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114187504415657421?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114187504415657421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114187504415657421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114187504415657421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114187504415657421'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/singleton-one-more-time.html' title='The Singleton: One More Time'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114178991896345375</id><published>2006-03-07T22:40:00.000-05:00</published><updated>2006-03-07T22:51:58.976-05:00</updated><title type='text'>Apologies</title><content type='html'>Given the lame fashion blogger renders HTML I will have to use &lt;span style="font-style: italic;"&gt;psuedo-code&lt;/span&gt; to describe my code and not write about specific dependencies.&lt;br /&gt;&lt;br /&gt;PS.  Boolean tests for less than X and greater than Y are going to really be a pain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114178991896345375?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114178991896345375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114178991896345375' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114178991896345375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114178991896345375'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/apologies.html' title='Apologies'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-22937959.post-114135339661157610</id><published>2006-03-02T21:35:00.000-05:00</published><updated>2006-03-02T21:36:36.620-05:00</updated><title type='text'>Excuse the delay</title><content type='html'>I need to find out post angle brackets.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/22937959-114135339661157610?l=schwarzekatzeproject.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://schwarzekatzeproject.blogspot.com/feeds/114135339661157610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=22937959&amp;postID=114135339661157610' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114135339661157610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/22937959/posts/default/114135339661157610'/><link rel='alternate' type='text/html' href='http://schwarzekatzeproject.blogspot.com/2006/03/excuse-delay.html' title='Excuse the delay'/><author><name>Patrick Linnen</name><uri>http://www.blogger.com/profile/07344210102976727368</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
