<?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>Forem: Syed Ali Mansoor</title>
    <description>The latest articles on Forem by Syed Ali Mansoor (@alimansoorcreate).</description>
    <link>https://forem.com/alimansoorcreate</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%2F615580%2Fbf9a18c3-8503-42a9-8ed1-9873847645d7.jpg</url>
      <title>Forem: Syed Ali Mansoor</title>
      <link>https://forem.com/alimansoorcreate</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/alimansoorcreate"/>
    <language>en</language>
    <item>
      <title>Component Breakdown &amp; State Management ⚙ - Building a tic-tac-toe game with React from scratch</title>
      <dc:creator>Syed Ali Mansoor</dc:creator>
      <pubDate>Mon, 04 Jul 2022 05:41:35 +0000</pubDate>
      <link>https://forem.com/alimansoorcreate/component-breakdown-state-management-building-a-tic-tac-toe-game-with-react-from-scratch-16l6</link>
      <guid>https://forem.com/alimansoorcreate/component-breakdown-state-management-building-a-tic-tac-toe-game-with-react-from-scratch-16l6</guid>
      <description>&lt;p&gt;Welcome! 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ℹ️ This post is part of a series, where I pen down my journey as I plan and build a tic-tac-toe game from ideation to release&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-wireframing-design-2nn5"&gt;previous post&lt;/a&gt;, we designed the app's UI, from displaying the start screen to displaying the result of a tic-tac-toe game:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmf012ek8yrnj50al6qqv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmf012ek8yrnj50al6qqv.png" alt="User flow diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The React mindset dictates that user interfaces be broken down into individual components, each of whom performs a single task. This will help us abstract away irrelevant logic while developing the app and reuse code whenever possible. Let's understand this with an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7qfjqcfksllf3ylr9r4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7qfjqcfksllf3ylr9r4.png" alt="Game screen with player names labelled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this screen, we can see some repetition happening in the form of a piece of UI that displays a player's name and mark (inside the dotted square). &lt;/p&gt;

&lt;p&gt;We can either write code to display both player's details separately, or we can create a single component that accepts a player's details as parameters, and then handles displaying those details itself. We can then use that component twice, telling it to display a different player each time:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0iz7sli9gxeu9ow8n588.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0iz7sli9gxeu9ow8n588.png" alt="Now using a component with different parameters each time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence we only need to write the code to display details once and can reuse it for both players!&lt;/p&gt;

&lt;p&gt;Seeing the clear benefit of this approach, let us go ahead and break our app's UI down into individual components. We will start off with the three screens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start&lt;/li&gt;
&lt;li&gt;Settings&lt;/li&gt;
&lt;li&gt;Game&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All other components would be children of these, and each of these represents a different section in the user flow. Therefore we could also call them &lt;em&gt;page/layout components&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Start
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftw6yi1rz60um1yekk10n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftw6yi1rz60um1yekk10n.png" alt="Start component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Start&lt;/code&gt; page will consist of only two components: &lt;code&gt;StartButton&lt;/code&gt;, and &lt;code&gt;Attribution&lt;/code&gt;. Displaying the X and O in the background can be handled by &lt;code&gt;Start&lt;/code&gt; itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Settings
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mjd18jc3h5mvajfnpo0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9mjd18jc3h5mvajfnpo0.png" alt="Settings component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;SettingsForm&lt;/code&gt; component will house and lay out the &lt;code&gt;SelectGameMode&lt;/code&gt;, &lt;code&gt;SelectGridSize&lt;/code&gt;, and &lt;code&gt;EnterPlayerNames&lt;/code&gt; components, each of which will enable the user to edit the game settings. &lt;code&gt;EnterPlayerNames&lt;/code&gt; will house 2 instances of &lt;code&gt;PlayerNameField&lt;/code&gt;, which will allow editing the name of a single player.&lt;/p&gt;

&lt;p&gt;When the game mode is PvP, both fields will be editable, whereas in PvC, only the player 1 field will be editable and the player 2 field will contain the uneditable text "A.I."&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Game
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpk7pay82mqu8aybu8ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpk7pay82mqu8aybu8ne.png" alt="Game component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The top section of the game screen will be contained in &lt;code&gt;GameHeader&lt;/code&gt; and the rest of the components will be direct children of &lt;code&gt;Game&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Grid&lt;/code&gt; will render a square grid of &lt;code&gt;GridCell&lt;/code&gt; components, and each &lt;code&gt;GridCell&lt;/code&gt; will update its background color and image appropriately when it is clicked or when there is a match.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadhd42cjg4hq2yvg3rbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadhd42cjg4hq2yvg3rbz.png" alt="Game component result state"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the game ends, the &lt;code&gt;Result&lt;/code&gt; component will be displayed, stating the outcome, and &lt;code&gt;RestartButton&lt;/code&gt; will become highlighted, to probe the player(s) to play another game.&lt;/p&gt;

&lt;p&gt;Let us now think about the data that our game will need to keep track of.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining data
&lt;/h2&gt;

&lt;p&gt;React applications work with data that may frequently change and the UI needs to update in respond to these changes. Such data is called state, and it can be stored either in the global scope, where it is accessible to all components, or in the component scope, where it is accessible to only a single component and optionally its children. State management libraries like &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt; allow us to store data in the global scope and write methods to access and change it.&lt;/p&gt;

&lt;p&gt;It is good practice to store data that is related to the business logic in the global scope, and that which is related to UI/component logic in the component scope.&lt;/p&gt;

&lt;p&gt;We can understand this with the example of an online shopping site. The items in your cart would be stored in the global scope, but whether the cart is currently open/visible or closed/hidden would be stored in the component representing the cart itself.&lt;/p&gt;

&lt;p&gt;Using this convention, we can extract the following data to be stored in the global scope of our application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game mode: string containing either "PvC" or "PvP"
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GameMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PvC&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PvP&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Grid size: the number 3, 4, or 5
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GridSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Players: array containing 2 player objects,
    where each player object stores the type of player ("human"/"ai"), the name of player, and their score
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Players&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Player&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;human&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Grid: array containing child arrays, each of which contains cell objects, where each cell object stores its mark (""/"X"/"O") and whether it is part of a match
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Grid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;[][]&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Current player: number, either 0 or 1, representing the index of the current player
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CurrentPlayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Game end: object representing whether a match has been made, whether there has been a draw and whether the game has ended
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;GameEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="na"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="na"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now have ourselves the following global state tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;gameMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;gridSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;players&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;currentPlayer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;gameEnd&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have a solid component hierarchy, as well as a global state tree, we can finally start the development process.&lt;/p&gt;

&lt;p&gt;⚡ Join me in the next post in this series, where we will set up our development environment and build the first two pages of the app&lt;/p&gt;

&lt;p&gt;❤️ Remember to like this post and leave your thoughts in the comments!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>gamedev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Wireframing &amp; Design 🎨 - Building a tic-tac-toe game with React from scratch</title>
      <dc:creator>Syed Ali Mansoor</dc:creator>
      <pubDate>Mon, 20 Jun 2022 07:58:57 +0000</pubDate>
      <link>https://forem.com/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-wireframing-design-2nn5</link>
      <guid>https://forem.com/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-wireframing-design-2nn5</guid>
      <description>&lt;p&gt;Hello there! 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ℹ️ This post is part of a series, where I pen down my journey as I plan and build a tic-tac-toe game from ideation to release&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-ideation-2a1e"&gt;previous post&lt;/a&gt;, we set the foundations for our tic-tac-toe game by planning the entire app ahead of time. We broke down the app's functionality into a list of specific objectives and goals. These will now help us in creating the look of the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Wireframing
&lt;/h2&gt;

&lt;p&gt;Before delving too much into the colours, animations, and fine details, we need to draw up a &lt;span title="A rough design containing less detail"&gt;&lt;strong&gt;low-fidelity wireframe&lt;/strong&gt;&lt;/span&gt; which will provide a basic layout for the different screens in our app, and help visualize user flow.&lt;/p&gt;

&lt;p&gt;My tool of choice for this job is &lt;a href="https://www.whimsical.com"&gt;Whimsical&lt;/a&gt;. It has a lot of customizable UI elements and controls built-in which allow for quick wireframing. &lt;/p&gt;

&lt;p&gt;The app can be broken down into three major views:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Displaying game settings&lt;/li&gt;
&lt;li&gt;The actual game&lt;/li&gt;
&lt;li&gt;Displaying the game's result (win/draw)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's start with the first view. In the previous post we decided to allow setting the following game settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game mode (PvP/PvC)&lt;/li&gt;
&lt;li&gt;Grid size (3 - 5)&lt;/li&gt;
&lt;li&gt;Player name(s)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oWtqGZ_y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1jv6jsnbdpfw7fz3noz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oWtqGZ_y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i1jv6jsnbdpfw7fz3noz.png" alt="Game settings screens" width="880" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The layout is centered on the screen, so that the user doesn't have to move their eyes much to the sides. It also presents a top-to-bottom hierarchy, wherein focus will first fall on the heading/logo, then on each option, and then finally on the action button, which will start the game.&lt;/p&gt;

&lt;p&gt;For the second view, we need to have the following elements be visible to the user at all times:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tic-tac-toe grid&lt;/li&gt;
&lt;li&gt;Current player indicator&lt;/li&gt;
&lt;li&gt;Players' names&lt;/li&gt;
&lt;li&gt;Players' scores&lt;/li&gt;
&lt;li&gt;An option to reset the grid&lt;/li&gt;
&lt;li&gt;An option to adjust the settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's add them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DS2uUHt1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wt8darg462xmxb9pk069.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DS2uUHt1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wt8darg462xmxb9pk069.png" alt="Game screen" width="880" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The toggle switch in the bottom will not be an actual input control, but rather an indication of the current player, whose name will be present on the switch's thumb. I made the reset and settings buttons smaller and moved them to the top right since they are a secondary part of the interface and the user's focus will lie on the grid for a larger part of their time on the app.&lt;/p&gt;

&lt;p&gt;Now for the third screen, we need to display buttons to restart the game and edit settings, and information about the result of the game, i.e. whether someone won or there was a draw, and if someone did win, who was it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AaTxawxI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6w68noo7x478gacnwc3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AaTxawxI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6w68noo7x478gacnwc3s.png" alt="Game result screen" width="880" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice and simple! 👌&lt;/p&gt;

&lt;p&gt;Creating wireframes before jumping into designing has helped us lay a foundation for the next step and make core design decisions beforehand. Notice how they don't depict &lt;em&gt;too&lt;/em&gt; much, but show only what is absolutely necessary, and that is enough for us to make a mental model of the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Designing
&lt;/h2&gt;

&lt;p&gt;Now we will really get into the finer details and design an interface that looks beautiful, and is functional. My tool of choice for this task is &lt;a href="https://icons8.com/lunacy"&gt;Lunacy&lt;/a&gt;, a free design app for Windows, macOS and Linux.&lt;/p&gt;

&lt;p&gt;Here is a list of the things we need to design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game logo&lt;/li&gt;
&lt;li&gt;Splash screen&lt;/li&gt;
&lt;li&gt;Settings screen

&lt;ul&gt;
&lt;li&gt;Hover/active states for:

&lt;ul&gt;
&lt;li&gt;Game mode selector&lt;/li&gt;
&lt;li&gt;Grid size selector&lt;/li&gt;
&lt;li&gt;Player name fields&lt;/li&gt;
&lt;li&gt;Start button&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Game screen

&lt;ul&gt;
&lt;li&gt;X/O symbols&lt;/li&gt;
&lt;li&gt;Hover/active states for:

&lt;ul&gt;
&lt;li&gt;Grid (cells)&lt;/li&gt;
&lt;li&gt;Reset and settings buttons&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Result screen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each screen has to be designed for both mobile and desktop viewers. Let's get to it! 🖌️&lt;/p&gt;

&lt;h3&gt;
  
  
  Splash screen
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2m8MQTHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/joelc21h4ozdhqbwtdam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2m8MQTHI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/joelc21h4ozdhqbwtdam.png" alt="Splash screen" width="880" height="431"&gt;&lt;/a&gt;&lt;br&gt;
This screen consists of the logo inside a button which can be pressed to start the game. Also a little attribution to the app's eventual developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Settings screen
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xg9GQagE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msb2f5oe9xfflqy6fc35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xg9GQagE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msb2f5oe9xfflqy6fc35.png" alt="Settings screen" width="880" height="431"&gt;&lt;/a&gt;&lt;br&gt;
I switched up the layout for this one a bit and for the grid size selector, I dropped the slider in favour of buttons to improve consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Game screen
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fu2q-4fZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bijmx19vk8mk9f25i0eg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fu2q-4fZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bijmx19vk8mk9f25i0eg.png" alt="Game screen" width="880" height="431"&gt;&lt;/a&gt;&lt;br&gt;
The game screen is nearly the same as in the wireframe, although while experimenting with hover states, I thought of a feature where the user could reset the score by simply clicking on it. Additionally, each cell should show the mark of the current player on hover. &lt;br&gt;
&lt;strong&gt;Hover state:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--y83tuKLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yo3px6appqs8w823mbk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--y83tuKLv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yo3px6appqs8w823mbk0.png" alt="Game screen hover" width="880" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Game result
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wZ5bsXat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kg52riir8a3507umyg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wZ5bsXat--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kg52riir8a3507umyg5.png" alt="Game result" width="880" height="431"&gt;&lt;/a&gt;&lt;br&gt;
I dropped the idea of a separate game result screen in favour of an overlay stating the result. This would prevent too many layout shifts and re-renders, would allow the user to see the end game state, and may also allow us to add some neat animations.&lt;/p&gt;

&lt;p&gt;The overlay should display either "xxx takes the game!", or "It's a draw!"&lt;/p&gt;

&lt;p&gt;View all the designs, including hover and active states on an infinitely zoomable canvas &lt;a href="https://whimsical.com/ui-design-9632Dof26eQUHx9S7zqihd"&gt;here&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Now that we know how the app is supposed to look on a screen, we have to get just a few more things done before we can start the development process.&lt;/p&gt;

&lt;p&gt;Firstly, a component breakdown, wherein we will identify small sections of the app that can be isolated and developed on their own.&lt;/p&gt;

&lt;p&gt;After that, we will decide what data our app will store, where we will store it, and how each component will access and modify it.&lt;/p&gt;

&lt;p&gt;⚡ Stay tuned for the next post in this series, where we will perform a component breakdown and define our app's data.&lt;/p&gt;

&lt;p&gt;❤️ Remember to like this post and leave your thoughts in the comments!&lt;/p&gt;

</description>
      <category>react</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Ideation 💡 - Building a tic-tac-toe game with React from scratch</title>
      <dc:creator>Syed Ali Mansoor</dc:creator>
      <pubDate>Wed, 01 Jun 2022 12:48:49 +0000</pubDate>
      <link>https://forem.com/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-ideation-2a1e</link>
      <guid>https://forem.com/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-ideation-2a1e</guid>
      <description>&lt;p&gt;Greetings, fellow human! 👋&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ℹ️ This post is part of a series, where I pen down my journey as I plan and build a tic-tac-toe game from ideation to release&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every project needs a space where you can jot down your thoughts, gather resources, and plan ahead. Some demand a robust project management system with all the latest features, some need nothing more than a todo list, and some do just fine with traditional pencil and paper.&lt;/p&gt;

&lt;p&gt;The project hub of my choice is &lt;a href="https://www.notion.so"&gt;Notion&lt;/a&gt;, a great app/website that does it all—or at least, all that &lt;em&gt;I&lt;/em&gt; need. I start off the planning process with a new project page, inside of which I have just two sections, nothing more. An inline database called Bucket will store everything I prepare to assist the process, and a Links section will be where I place articles and resources from the internet that I find useful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O8HdMCIq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gdtt4grx1sye4210g6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O8HdMCIq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gdtt4grx1sye4210g6j.png" alt="Project page" width="880" height="1106"&gt;&lt;/a&gt; &lt;/p&gt;
The links already there helped inspire my planning process



&lt;p&gt;With the project hub all set up, it is time to proceed. ⏩&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the app's functionality
&lt;/h2&gt;

&lt;p&gt;With every programming venture, it is important to first identify and break down the app's functionality. &lt;em&gt;What are the minimum necessary objectives that our app should be able to perform?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This helps plan out features extensively beforehand and assists in researching solutions to problems that we may encounter. It also provides a checklist of goals to mark off during development.&lt;/p&gt;

&lt;p&gt;To implement this practically, we start off with broad objectives and then work our way backwards until we end up with highly specific, actionable goals.&lt;/p&gt;

&lt;p&gt;Essentially, the app's objective is this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Play game(s) of tic-tac-toe&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But this doesn't help much when you're building it from scratch, and so we need to think more specifically. I would preferably want my app to have three stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define game settings&lt;/li&gt;
&lt;li&gt;Play a game or multiple games of tic-tac-toe&lt;/li&gt;
&lt;li&gt;Keep track of scores&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that the app has been broken down into three separate stages, we can identify the major objectives in each stage. Let's start by breaking down the first stage&lt;/p&gt;

&lt;h3&gt;
  
  
  Define game settings
&lt;/h3&gt;

&lt;p&gt;What settings must the game require?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Game mode (PvP or PvC?)&lt;/li&gt;
&lt;li&gt;Grid size (3 - 5)&lt;/li&gt;
&lt;li&gt;Player name(s)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are the three things I deem essential to have before the game can start. I am limiting the grid size to a maximum of 5x5 to avoid the cells from becoming too small on certain screens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Play a game or multiple games of tic-tac-toe
&lt;/h3&gt;

&lt;p&gt;What are the specific steps in each game?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Display empty grid&lt;/li&gt;
&lt;li&gt;Allow the player to make a move&lt;/li&gt;
&lt;li&gt;Switch players&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;For PvC:&lt;/em&gt; Deduce the optimal move for the computer&lt;/li&gt;
&lt;li&gt;Identify a game result (win/draw)&lt;/li&gt;
&lt;li&gt;If there is a result, display it&lt;/li&gt;
&lt;li&gt;If there is a result, repeat from 1.&lt;/li&gt;
&lt;li&gt;Otherwise, repeat from 2.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The game has now been outlined and each step is highly specific, which allows us to move towards the next and final objective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep track of score
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Initialize scores for both players to 0&lt;/li&gt;
&lt;li&gt;If there is a win, increment the score of the winning player&lt;/li&gt;
&lt;li&gt;If the settings are changed, repeat from 1.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although this objective was not as in-depth or complex as the previous one, it is still a basic feature of our app and therefore equally important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final list of objectives
&lt;/h3&gt;

&lt;p&gt;Let's see the complete list altogether&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
Define game settings
&lt;ol&gt;
&lt;li&gt;Game mode (PvP or PvC?)&lt;/li&gt;
&lt;li&gt;Grid size (3 - 5)&lt;/li&gt;
&lt;li&gt;Player name(s)&lt;/li&gt;
&lt;/ol&gt;




&lt;/li&gt;

&lt;li&gt;

Play a game or multiple games of tic-tac-toe

&lt;ol&gt;
&lt;li&gt;Display empty grid&lt;/li&gt;
&lt;li&gt;Allow the player to make a move&lt;/li&gt;
&lt;li&gt;Switch players&lt;/li&gt;
&lt;li&gt; &lt;em&gt;For PvC:&lt;/em&gt; Deduce the optimal move for the computer&lt;/li&gt;
&lt;li&gt;Identify a game result (win/draw)&lt;/li&gt;
&lt;li&gt;If there is a result, display it&lt;/li&gt;
&lt;li&gt;If there is a result, repeat from 1.&lt;/li&gt;
&lt;li&gt;Otherwise, repeat from 2.&lt;/li&gt;
&lt;/ol&gt;




&lt;/li&gt;

&lt;li&gt;

Keep track of score

&lt;ol&gt;
&lt;li&gt;Initialize scores for both players to 0&lt;/li&gt;
&lt;li&gt;If there is a win, increment the score of the winning player&lt;/li&gt;
&lt;li&gt;If the settings are changed, repeat from 1.&lt;/li&gt;
&lt;/ol&gt;




&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;We now have a set of specific, actionable steps that can be implemented separately. Great!&lt;/p&gt;

&lt;h2&gt;
  
  
  Tackling logic problems beforehand
&lt;/h2&gt;

&lt;p&gt;With the game broken down into individual pieces, let's talk about two important problems that I foresee to be especially complicated and my approach to solving them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deducing the game's result
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key question:&lt;/strong&gt; How do you identify when a player has won the game?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There have been many approaches to this, and most people initially think of using loops coupled with conditional statements to check for matches. This results in code which looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for row &amp;lt;- 1 to 3
    for col &amp;lt;- 1 to 2
        if grid[row][col] != grid[row][col + 1] then
            next row
    next col
    return true
next row
return false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are essentially looping through each row and then checking whether adjacent cells in each row contain the same value. If not, we skip to the next row. Once all cells in a particular row have been checked and there were no skips, this implies that there is a match in said row.&lt;/p&gt;

&lt;p&gt;I do not like this approach as it involves a lot of looping and nesting, and even after the previous code, we still have to check for column matches and diagonal matches, leading to more lines, more bugs, and ultimately more headaches.&lt;/p&gt;

&lt;p&gt;Instead, I prefer the use of counters, which will store the number of X's and O's in each row, column, and diagonal, and are updated after every move. This is illustrated below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DwLvPCaK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3pwza1pe7wqgp3e99e8a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DwLvPCaK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3pwza1pe7wqgp3e99e8a.png" alt="Depiction of counters" width="880" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each pair of values in this diagram is keeping a count of X's and O's in it's row/column/diagonal. As an example, there is 1 X and 1 O in the main diagonal, therefore the main diagonal counter stores the values &lt;code&gt;(1, 1)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;
  &lt;em&gt;Main diagonal??? Which one is that?&lt;/em&gt;
  &lt;br&gt;
All rectangular grids and matrices have two diagonals, joining the opposite corners of the rectangle. The diagonal from the top-left corner to the bottom-right corner is called the &lt;em&gt;main, principal, major, or leading diagonal&lt;/em&gt;. Similarly, the diagonal from the top-right corner to the bottom-left corner is called the &lt;em&gt;anti, counter, minor, or trailing diagonal&lt;/em&gt;. Look at the illustration below for a better understanding:

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HRNqoUri--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9bxr9gm57pprwmgsklw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HRNqoUri--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j9bxr9gm57pprwmgsklw.png" alt="Main and Anti diagonals" width="880" height="493"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;/p&gt;

&lt;p&gt;After every valid move, these counters need to be updated. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The row and column counters will always be updated based on the row and column of the chosen grid cell. &lt;/li&gt;
&lt;li&gt;The main diagonal counter will be updated when the chosen grid cell lies on the main diagonal. This can be tested using the condition, &lt;code&gt;row === column&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The anti diagonal counter is similarly updated by testing the condition, &lt;code&gt;row + column === size - 1&lt;/code&gt;, assuming that &lt;code&gt;row&lt;/code&gt; and &lt;code&gt;column&lt;/code&gt; are zero-indexed, and &lt;code&gt;size&lt;/code&gt; stores the number of cells in any row/column.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a tic-tac-toe grid of arbitrary size, a win is possible after exactly &lt;code&gt;(size × 2) - 1&lt;/code&gt; moves. This is because on the very next move, the starting player will have made enough moves to make a match. Let's denote this value by &lt;code&gt;minMoves&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Following every move after &lt;code&gt;minMoves&lt;/code&gt;, we will check the current state of all counters and check if any one contains a value equal to &lt;code&gt;size&lt;/code&gt;. This would mean that a match has been made!&lt;/p&gt;

&lt;p&gt;After &lt;code&gt;size × size&lt;/code&gt; moves, we will do this check for the last time, and if there is still no win, a draw is declared and the game ends.&lt;/p&gt;

&lt;p&gt;This approach has a time complexity of O(n), because the only looping required will be to go through the row/column counters to detect a match.&lt;/p&gt;

&lt;p&gt;Compare this to the previous approach, which had a time complexity of O(n²) since it would loop through each row and each column to detect a match. We have ourselves a winner! 🥳&lt;/p&gt;

&lt;h3&gt;
  
  
  Deducing the optimal move for the computer
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key question:&lt;/strong&gt; How can you identify which move promises the most favourable outcome on a given grid state?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This will be implemented through an application of the Minimax algorithm, which attempts to traverse all possible moves for the computer as well as the human player repeatedly until it reaches a &lt;strong&gt;terminal state&lt;/strong&gt;, i.e. a win, draw, or loss. It then backtracks all moves and chooses the one which results in the most favourable outcome with the least number of moves.&lt;/p&gt;

&lt;p&gt;Let's assume that it is X's turn and the current grid state is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zNkq0SYJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pb0as3oib46vv1j1b7em.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zNkq0SYJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pb0as3oib46vv1j1b7em.png" alt="Initial grid state" width="434" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;X can make either of the following 3 moves:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rlnYWuYj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9sonobhaj6khyezhrhs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rlnYWuYj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9sonobhaj6khyezhrhs.png" alt="Possible moves #1" width="880" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that move #3 is resulting in a win for X, and therefore we assign a value of +1 to that move. For the other two moves however, we have not reached a terminal state, therefore we shall keep traversing possible moves, but this time for O.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jR5Vy7i---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rlzyp5mxs8u4kzl98ri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jR5Vy7i---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3rlzyp5mxs8u4kzl98ri.png" alt="Possible moves #2" width="880" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that moves #1.1 and #2.2 are resulting in a loss for X, therefore we assign a value of -1 to those moves.&lt;/p&gt;

&lt;p&gt;Since it is obvious that the the other two moves (#1.2 and #2.1) are a win for X, we assign a value of +1 to those moves. There is no need to illustrate further moves.&lt;/p&gt;

&lt;p&gt;We now have the following tree of possible moves with their respective score values:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Gs0c9jdp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfsmnih6kg7f5ft7it0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Gs0c9jdp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfsmnih6kg7f5ft7it0f.png" alt="Tree of possible moves" width="880" height="690"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;X will now make the most optimal move from the options it has using each possible move's score value. We still however haven't assigned a score value to moves #1 and #2. This can be tackled by assessing the very next set of moves and choosing the score value of the optimal move (here -1). &lt;/p&gt;

&lt;p&gt;This brings up an important idea, that an optimal move for X is one with a higher score value, while the optimal move for O is one with a lower score value. X is therefore the &lt;strong&gt;maximizing player&lt;/strong&gt; and O is the &lt;strong&gt;minimizing player&lt;/strong&gt;. Hence the name, minimax.&lt;/p&gt;

&lt;p&gt;The possible moves for X on the next turn, along with their respective score values are now as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZTGw4VQK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zscnqwe1qjmeb4a9z4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZTGw4VQK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4zscnqwe1qjmeb4a9z4r.png" alt="Possible moves for X" width="880" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;X thus chooses &lt;em&gt;it's&lt;/em&gt; optimal move, and since it is a maximizing player, it chooses the move with the highest score, leading to a win for X.&lt;/p&gt;

&lt;p&gt;There are further edge cases to this algorithm such as resolving ties using the number of moves until we reach a terminal state, but what we want right now is a general understanding and a good grasp of how the algorithm works. Implementation details can come later.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;💭 Please comment on the job I did at explaining these algorithms. Are they understandable?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We now have a set of objectives for the game, as well as the knowledge essential to building tic-tac-toe in theory. What comes next? &lt;/p&gt;

&lt;p&gt;⚡ Stay tuned for the &lt;a href="https://dev.to/alimansoorcreate/building-a-tic-tac-toe-game-with-react-from-scratch-wireframing-design-2nn5"&gt;next&lt;/a&gt; post in this series, where we will use these objectives to wireframe and design the look of our game.&lt;/p&gt;

&lt;p&gt;❤ Remember to like this post and leave your thoughts in the comments!&lt;/p&gt;




&lt;p&gt;&lt;small&gt;Cover photo by Matthew Davis on Unsplash&lt;/small&gt;&lt;br&gt;
&lt;small&gt;&lt;a href="https://www.youtube.com/watch?v=trKjYdBASyQ"&gt;Learn more about the Minimax algorithm&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>programming</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Weather app built with Svelte on Vite</title>
      <dc:creator>Syed Ali Mansoor</dc:creator>
      <pubDate>Tue, 10 May 2022 15:30:12 +0000</pubDate>
      <link>https://forem.com/alimansoorcreate/weather-app-built-with-sveltets-2mjl</link>
      <guid>https://forem.com/alimansoorcreate/weather-app-built-with-sveltets-2mjl</guid>
      <description>&lt;p&gt;Welcome! This web app is designed to display weather data (current and forecast) based on the user's location.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://alimansoor-create.github.io/weather-app/" rel="noopener noreferrer"&gt;Live site&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/alimansoor-create/weather-app/" rel="noopener noreferrer"&gt;Github repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Display current and forecast weather data for the given location&lt;/li&gt;
&lt;li&gt;Retrieve the user's location automatically&lt;/li&gt;
&lt;li&gt;Search for a different location by city name&lt;/li&gt;
&lt;li&gt;Switch the temperature unit between Celsius and Fahrenheit&lt;/li&gt;
&lt;li&gt;Toggle forecast weather data between hourly or daily forecasts&lt;/li&gt;
&lt;li&gt;Responsive layout&lt;/li&gt;
&lt;li&gt;Loading skeleton&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl6n06zgat0vlh4he9ha.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl6n06zgat0vlh4he9ha.jpeg" alt="the app's desktop layout"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89utn4j12xay7j75urg3.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89utn4j12xay7j75urg3.jpeg" alt="the app's mobile layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Searchbox&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q0kdafh8xv41vnlkimk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3q0kdafh8xv41vnlkimk.jpeg" alt="the app's searchbox"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading state&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfq0611qtcj3jhqqjkhv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfq0611qtcj3jhqqjkhv.jpeg" alt="the app's loading state"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Svelte, bundled with Vite&lt;/li&gt;
&lt;li&gt;Typescript&lt;/li&gt;
&lt;li&gt;Sass for styling&lt;/li&gt;
&lt;li&gt;Axios to make requests&lt;/li&gt;
&lt;li&gt;Notion + &lt;a href="https://whimsical.com/" rel="noopener noreferrer"&gt;Whimsical&lt;/a&gt; for planning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please do check the app out and leave your reviews below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Acknowledgements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/dev-cafe/how-to-setup-env-variables-to-your-svelte-js-app-c1579430f032" rel="noopener noreferrer"&gt;How to set up .env variables for your Svelte project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/react-live-search-with-axios" rel="noopener noreferrer"&gt;Creating a live search feature using Axios&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/country-code-emoji" rel="noopener noreferrer"&gt;country-code-emoji - a neat package that converts an ISO country code to the corresponding flag emoji and vice versa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>svelte</category>
      <category>typescript</category>
      <category>vite</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
