<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alexander Zank</title>
    <description>The latest articles on DEV Community by Alexander Zank (@alexlike).</description>
    <link>https://dev.to/alexlike</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F391197%2F0fe36520-04d6-4d43-aeab-8fce959f62da.png</url>
      <title>DEV Community: Alexander Zank</title>
      <link>https://dev.to/alexlike</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexlike"/>
    <language>en</language>
    <item>
      <title>Mega-Tic-Tac-Toe (Connect 4)</title>
      <dc:creator>Alexander Zank</dc:creator>
      <pubDate>Wed, 20 May 2020 19:27:36 +0000</pubDate>
      <link>https://dev.to/alexlike/mega-tic-tac-toe-connect-4-4hcl</link>
      <guid>https://dev.to/alexlike/mega-tic-tac-toe-connect-4-4hcl</guid>
      <description>&lt;h4&gt;
  
  
  An educational project by Pauline Hocher, Jonas Herrmann, Marcel Karas, Simeon Schwarzkopf and Alexander Zank realized at Hohenstaufen-Gymnasium Bad Wimpfen.
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;All source code is available under the MIT License under: &lt;a href="https://github.com/AlexLike/NwT-Mega-Tic-Tac-Toe"&gt;https://github.com/AlexLike/NwT-Mega-Tic-Tac-Toe&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;The goal of project Mega-Tic-Tac-Toe is the implementation of a mechanical player for a bigger sized "Connect 4" board. Programatically this is achieved by using an Arduino Genuino Uno and the code contained in this repository.&lt;br&gt;
The human player is able to choose his desired column by typing it out using a keyboard while the COM player plays random moves and constantly checks whether one of the two has won.&lt;/p&gt;
&lt;h2&gt;
  
  
  Construction outline
&lt;/h2&gt;

&lt;p&gt;A stepper motor-powered hinge allows the tile magazine to be moved around freely on top of the "Connect-4" board while the magazine's opening and reloading mechanism is realized by using a small servo. An LED strip on the bottom has been added for aesthetical reasons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HVcbf5zJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/Construction%2520Overview.jpeg%3Ftoken%3DAdDgy6LOyk1BvnHT4aixvDwxQrZ3rKcsks5cHRMuwA%253D%253D" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HVcbf5zJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/Construction%2520Overview.jpeg%3Ftoken%3DAdDgy6LOyk1BvnHT4aixvDwxQrZ3rKcsks5cHRMuwA%253D%253D" alt="Construction Outline"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Wiring outline
&lt;/h2&gt;

&lt;p&gt;Adafruit's Motorshield V2 is stacked on the Arduino Genuino Uno and connected with an array of 4 AA-batteries that will later power the two motors when connected correctly. Every LED receives an own data pin and a shared connection to the Arduino's GND. The Arduino-to-Computer serial connection is realized via an USB Type B to A cable that connects the two to each other thereby occupying pin 0 and 1 on the board.&lt;/p&gt;
&lt;h2&gt;
  
  
  Control Flow Diagram
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IT4_8GSY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/Control%2520Flow%2520Diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IT4_8GSY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/Control%2520Flow%2520Diagram.png" alt="Control Flow Diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Coding principles
&lt;/h2&gt;

&lt;p&gt;This project's code was written in native C++ with the Arduino's base and servo libraries as well as Adafruit's motorshield library V2 stacked on top. A key design decision was emphasizing the modularity and clarity of the code and keeping it as lightweight as possible so that the Arduino's dynamic storage can be used to its fullest potential.&lt;/p&gt;

&lt;p&gt;The code is clearly structured in the following sections, allowing any contributer to more easily navigate the small project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// MARK: - Dependencies&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Global definitions&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Global properties&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Controller Lifecycle&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Gameplay Methods&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Mechanical / Physical Methods&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Gameplay Helper Methods&lt;/span&gt;
&lt;span class="c1"&gt;// MARK: - Debugging Methods&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;One measure to save dynamic storage while preserving the ease of use in the adjustment and calibration process (e.g. trying different &lt;code&gt;stepperSPC&lt;/code&gt;) was the use of the C++-Keyword &lt;code&gt;#define&lt;/code&gt; for any constant value in the code, as a declaration using said keyword isn't saved to the dynamic storage at runtime but rather filled in at compiletime. The Arduino has way more static storage for code than dynamic storage for changing variables, so using the latter allows for a better use of dynamic storage, e.g. the win-detection that uses multiple variables for scanning through rows.&lt;/p&gt;

&lt;p&gt;When declaring variables, data types are also used sparingly which means that for most single variables and array objects, the &lt;code&gt;byte&lt;/code&gt; type was used. We only have to store integer values in [0;9], so the byte's range of [0;255] is more than sufficient and there's no need to use &lt;code&gt;int&lt;/code&gt; in most cases, saving 1 byte per instantiated variable. This may at first sound silly, but looking only at &lt;code&gt;gameMap&lt;/code&gt; one reaches a saving of (6 ⨉ 7) Objects ⨉ 1 Byte saved per object = 42 bytes.&lt;/p&gt;

&lt;p&gt;A greatly sophisticated subroutine is the &lt;code&gt;didWin(byte EID)&lt;/code&gt; method. It scans each row, column and diagonal for a possible winning line by using &lt;code&gt;gameMap&lt;/code&gt;'s data in &lt;code&gt;for&lt;/code&gt;-loops and the provided entitie's ID defined at the beginning. This can either be P for Player or C for COM. The following diagram explains the scans &lt;code&gt;didWin(byte EID)&lt;/code&gt; performs while running:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t_drfeS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/didWin%2520Algorithm.png%3Ftoken%3DAdDgyx1xMUKXRfD_FFSt0q-ERdUGexQjks5cHW3TwA%253D%253D" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t_drfeS2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/AlexLike/NWT-Mega-Tic-Tac-Toe/Documentation-Assets/didWin%2520Algorithm.png%3Ftoken%3DAdDgyx1xMUKXRfD_FFSt0q-ERdUGexQjks5cHW3TwA%253D%253D" alt="didWin Algorithm diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the function uses two encapsulated &lt;code&gt;for&lt;/code&gt;-loops. The root one is marked blue in the diagram, the subloop is marked orange in the diagram. It allows the Arduino to orderly scan through &lt;code&gt;gameMap&lt;/code&gt; and keep track of a winning streak in the local scope variable &lt;code&gt;currentStreak&lt;/code&gt;. In the codesnippet given below, the first &lt;code&gt;for&lt;/code&gt;-loop compared y to 255, that's because a &lt;code&gt;&amp;gt;= 0&lt;/code&gt; comparison with byte data types is buggy and might result in infinite loops. An excluding comparison to 255 is useful because a byte value is unsigned and would jump to 255 if the zero is passed negatively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Counter for directly neighboring tiles&lt;/span&gt;
&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;currentStreak&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Check winning rows, from bottom to top&lt;/span&gt;
&lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Scanning rows, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;maxY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Reset streak for each row&lt;/span&gt;
  &lt;span class="n"&gt;currentStreak&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Read from left to right&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;maxX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Player owns the field -&amp;gt; Increment currentStreak by 1&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;EID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;currentStreak&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Player doesn't own the field -&amp;gt; Reset currentStreak to 0&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;currentStreak&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Check currentStreak status and return true if won&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentStreak&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;winningStreak&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Stop checking this row if no win is possible with the remaining columns&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;winningStreak&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;currentStreak&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;maxX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>octograd2020</category>
      <category>devgrad2020</category>
      <category>cpp</category>
      <category>arduino</category>
    </item>
  </channel>
</rss>
