{"id":4109,"date":"2020-05-08T00:01:13","date_gmt":"2020-05-08T07:01:13","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4109"},"modified":"2020-05-02T09:05:34","modified_gmt":"2020-05-02T16:05:34","slug":"tic-tac-toe-evaluation-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4109","title":{"rendered":"Tic-Tac-Toe Evaluation &#8211; Solution"},"content":{"rendered":"<p>The insidious part of <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4095\">this month&#8217;s Exercise<\/a> is writing a function that doesn&#8217;t count a stalemate as a win. It&#8217;s what happened to me for my first draft of a solution.<br \/>\n<!--more--><br \/>\nThe code you must write for the <em>is_winner()<\/em> function evaluates rows, columns, and diagonals for matching characters. Specifically, either <code>'x'<\/code> or <code>'o'<\/code>. But the space character, <code>' '<\/code>, can also match up in a row, column, or (less likely) diagonally. If you don&#8217;t code the function properly, it could return that &#8220;space&#8221; won the game. That&#8217;s just not fair!<\/p>\n<p>For my solution, I checked diagonals first, then columns and rows. Here&#8217;s the first <em>if<\/em> test, which checks for the NE-SE diagonal:<\/p>\n<p><code>if( *(g+0)==*(g+4) &amp;&amp; *(g+4)==*(g+8) )<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;r = *(g+0);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;if( r=='x' || r=='o' )<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return(r);<br \/>\n}<\/code><\/p>\n<p>The <em>if<\/em> test clusters the upper-left\/center and the center\/lower-right squares or offsets in the grid. This is because you cannot stack logical expressions in a <em>if<\/em> condition. The following expression is invalid:<\/p>\n<p><code>if( *(g+0)==*(g+4)==*(g+8) )<\/code><\/p>\n<p>Tests must be done two at a time, which is how the first diagonal is evaluated. If all the characters match, variable <code>r<\/code> is assigned to the upper right square (because all the characters match it). A second <em>if<\/em> test confirms that the character is either <code>'x'<\/code> or <code>'o'<\/code>. When true, the character is returned. Otherwise, the matching character is the space, which isn&#8217;t a winning condition.<\/p>\n<p>My solution next checks the SW-NE diagonal, using the same technique but different offsets in the array.<\/p>\n<p>Rows and columns are checked by using a <em>for<\/em> loop and various offsets and such. Here is my solution for the <em>is_winner()<\/em> function.<\/p>\n<h3>2020_05-Exercise.c<\/h3>\n<pre class=\"screen\">\r\n<span class=\"comments\">\/* determine whether the game was won *\/<\/span>\r\nchar is_winner( char *g )\r\n{\r\n    char r;\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* check diagonals first *\/<\/span>\r\n        <span class=\"comments\">\/* NW-SE *\/<\/span>\r\n    if( *(g+0)==*(g+4) &amp;&amp; *(g+4)==*(g+8) )\r\n    {\r\n        r = *(g+0);\r\n        if( r=='x' || r=='o' )\r\n            return(r);\r\n    }\r\n        <span class=\"comments\">\/* SW-NE *\/<\/span>\r\n    if( *(g+6)==*(g+4) &amp;&amp; *(g+4)==*(g+2) )\r\n    {\r\n        r = *(g+6);\r\n        if( r=='x' || r=='o' )\r\n            return(r);\r\n    }\r\n\r\n    <span class=\"comments\">\/* check columns *\/<\/span>\r\n    for( x=0; x&lt;3; x++ )\r\n    {\r\n        if( *(g+0+x)==*(g+3+x) &amp;&amp; *(g+3+x)==*(g+6+x) )    \r\n        {\r\n            r = *(g+0+x);\r\n            if( r=='x' || r=='o' )\r\n                return(r);\r\n        }\r\n    }\r\n\r\n    <span class=\"comments\">\/* check rows *\/<\/span>\r\n    for( x=0; x&lt;3; x++ )\r\n    {\r\n        if( *(g+(3*x))==*(g+(3*x)+1) &amp;&amp; *(g+(3*x)+1)==*(g+(3*x)+2) )\r\n        {\r\n            r = *(g+(3*x));\r\n            if( r=='x' || r=='o' )\r\n                return(r);\r\n        }\r\n    }\r\n\r\n    return(' ');\r\n}<\/pre>\n<p><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2020_05-Exercise.c\" rel=\"noopener noreferrer\" target=\"_blank\">Click here<\/a> to view my full solution on GitHub.<\/p>\n<p>The solution for game 5 in the array (element 4) is the true test. It&#8217;s layout can trip up the column test because three spaces appear in the first column, as you can see in the solution&#8217;s output here:<\/p>\n<pre class=\"screen\">\r\n x x o\r\n o o x\r\n x o x\r\nGame 1: No winner\r\n\r\n o   x\r\n   x o\r\n x    \r\nGame 2: X wins!\r\n\r\n x x  \r\n o x x\r\n o o o\r\nGame 3: O wins!\r\n\r\n o   x\r\n o o o\r\n x   x\r\nGame 4: O wins!\r\n\r\n   x o\r\n   o x\r\n     o\r\nGame 5: No winner\r\n\r\n x   o\r\n x o  \r\n x o x\r\nGame 6: X wins!<\/pre>\n<p>If you&#8217;re not careful with your <em>is_winner()<\/em> function, Game 5 comes back with the space character as the winner.<\/p>\n<p>I hope you enjoyed this Exercise and that your solution rendered proper answers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The insidious part of this month&#8217;s Exercise is writing a function that doesn&#8217;t count a stalemate as a win. It&#8217;s what happened to me for my first draft of a solution.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-4109","post","type-post","status-publish","format-standard","hentry","category-solution"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4109","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4109"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4109\/revisions"}],"predecessor-version":[{"id":4131,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4109\/revisions\/4131"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}