<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Games - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Games - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 15 May 2026 22:30:08 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/games/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ From Pixels to Predictions: How GPUs Started Powering Modern AI ]]>
                </title>
                <description>
                    <![CDATA[ When people think of artificial intelligence, they imagine complex models, data centers, and cloud servers. What most don’t realize is that the real engine behind this AI revolution started in a place few expected: inside the humble gaming PC. The sa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/from-pixels-to-predictions-how-gpus-started-powering-modern-ai/</link>
                <guid isPermaLink="false">69164b0a612455db63b30bdc</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GPU ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ hardware ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Manish Shivanandhan ]]>
                </dc:creator>
                <pubDate>Thu, 13 Nov 2025 21:18:02 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763068628238/531621b6-1931-422f-b8ff-455c1ef58dab.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When people think of artificial intelligence, they imagine complex models, data centers, and cloud servers.</p>
<p>What most don’t realize is that the real engine behind this AI revolution started in a place few expected: inside the humble gaming PC.</p>
<p>The same graphics cards once built to render smooth 3D visuals are now powering chatbots, image generators, and self-driving systems. The journey from pixels to predictions is one of the most fascinating stories in modern computing.</p>
<h2 id="heading-the-cpu-era-and-its-limits"><strong>The CPU Era and Its Limits</strong></h2>
<p>In the early days of machine learning, researchers depended on CPUs to crunch data.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762950299566/a8c9ea6a-f420-4f9e-b87c-5b584be5166a.png" alt="CPU architecture" class="image--center mx-auto" width="1000" height="500" loading="lazy"></p>
<p>CPUs were versatile and great for handling a wide range of tasks, but they had one big limitation: they worked on problems in sequence.</p>
<p>That means they could process only a few operations at a time. For small models, this was fine. But as neural networks grew in complexity, training them on CPUs became painfully slow.</p>
<p>Imagine trying to teach a computer to recognize images. A neural network might have millions of parameters, and every single one needs to be adjusted again and again during training.</p>
<p>On CPUs, that could take days or even weeks. Researchers quickly realized that if AI was going to advance, it needed a completely different kind of hardware.</p>
<h2 id="heading-how-gpus-entered-the-picture"><strong>How GPUs Entered the Picture</strong></h2>
<p><a target="_blank" href="https://aws.amazon.com/what-is/gpu/">Graphics processing units</a>, or GPUs, were originally built to render the fast-moving images in video games. They were designed for parallelism, performing thousands of small calculations at the same time.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/Axd50ew4pco" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>While a CPU might have a handful of cores, a GPU has thousands. This architecture made GPUs ideal for the kind of math used in machine learning, where the same operation needs to be applied to huge amounts of data simultaneously.</p>
<p>In a way, the GPU was built for games but destined for AI. What started as a chip to make lighting effects smoother and explosions look more realistic soon found a second life powering neural networks.</p>
<p>Around the early 2010s, researchers began experimenting with running <a target="_blank" href="https://www.freecodecamp.org/news/deep-learning-fundamentals-handbook-start-a-career-in-ai/">deep learning algorithms</a> on GPUs, and the results were stunning. Training times dropped from weeks to days, and accuracy improved.</p>
<p>It was a quiet revolution happening in research labs around the world.</p>
<h2 id="heading-the-role-of-gaming-pcs-in-early-ai-research"><strong>The Role of Gaming PCs in Early AI Research</strong></h2>
<p>Here’s where the story gets even more interesting: many of the early breakthroughs in AI didn’t come from massive data centres or expensive supercomputers. They came from researchers using consumer-grade GPUs, often sitting inside regular gaming PCs.</p>
<p>These machines, built for entertainment, turned out to be powerful enough for deep learning experiments.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/CUDA">NVIDIA’s CUDA</a> platform made this possible by allowing developers to program GPUs for tasks beyond graphics. Suddenly, a gaming GPU could handle complex scientific computations.</p>
<p>Researchers used their own rigs, sometimes the same computers they played games on at night, to train neural networks that recognized speech, images, and text. The gaming PC became a testbed for the future of artificial intelligence.</p>
<h2 id="heading-the-turning-point-alexnet-and-the-deep-learning-boom"><strong>The Turning Point: AlexNet and the Deep Learning Boom</strong></h2>
<p>In 2012, a neural network called <a target="_blank" href="https://www.pinecone.io/learn/series/image-search/imagenet/">AlexNet</a> stunned the world by winning the ImageNet competition, a major benchmark in computer vision.</p>
<p>What made AlexNet special wasn’t just its architecture but the hardware behind it. It ran on two NVIDIA GTX 580 GPUs, hardware you could buy for your <a target="_blank" href="https://www.eneba.com/hub/gaming-gear/best-gaming-pc-under-1000/">low-cost gaming PC</a>. That win marked a turning point. It proved that GPUs weren’t just for rendering graphics – they were the key to advancing AI.</p>
<p>After that, the AI world changed fast. Every major research lab and tech company started building GPU clusters. NVIDIA, sensing the opportunity, leaned into AI hardware development.</p>
<p>The same company that once catered mainly to gamers now powered Google, OpenAI, and Tesla. What started as a tool for better visuals had become the backbone of machine intelligence.</p>
<h2 id="heading-why-gpus-are-so-good-at-ai"><strong>Why GPUs Are So Good at AI</strong></h2>
<p>GPUs excel at matrix math, the kind of computation that neural networks rely on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763135976807/adcb3ce6-40e0-4bb2-b138-7f9208b4a6b4.jpeg" alt="matrix math" class="image--center mx-auto" width="1000" height="271" loading="lazy"></p>
<p>When you train a model, you’re constantly multiplying and adding matrices of numbers. GPUs do this faster because they handle thousands of operations in parallel. They’re also designed with high memory bandwidth, meaning they can move large amounts of data in and out quickly.</p>
<p>This architecture fits perfectly with deep learning workloads. Whether it’s image recognition or language translation, GPUs can process huge batches of data at once.</p>
<p>CPUs, by contrast, get bottlenecked by sequential processing. The difference in performance is like comparing a single craftsman building a house to a team of thousands working at once.</p>
<h2 id="heading-the-ai-hardware-race"><strong>The AI Hardware Race</strong></h2>
<p>As AI took off, the demand for GPUs exploded. What began in gaming PCs scaled up into massive data centers filled with thousands of cards.</p>
<p>Companies like NVIDIA developed new lines of GPUs specifically for AI, such as the Tesla and A100 series. Other players joined the race too, like AMD with its <a target="_blank" href="https://www.amd.com/en/products/software/rocm.html">ROCm platform</a>, and Google with its custom TPUs (Tensor Processing Units).</p>
<p>Yet, even today, the line between gaming and AI hardware remains blurred. The same RTX GPUs designed for gamers are still used by many AI researchers and small startups.</p>
<p>A powerful gaming PC equipped with a modern GPU can run local AI models, generate images, or even fine-tune small language models. The hardware that made virtual worlds come alive now brings intelligence to our real one.</p>
<h2 id="heading-the-future-of-gpus-and-ai"><strong>The Future of GPUs and AI</strong></h2>
<p>As AI models grow larger, new challenges are emerging. GPUs are evolving to handle trillion-parameter models, but they’re also getting smarter about energy use and efficiency.</p>
<p>Technologies like chiplet design, optical interconnects, and AI-specific cores are pushing performance further while keeping costs down.</p>
<p>Meanwhile, local AI is making a comeback. With advancements in GPU efficiency, many users are experimenting with running models on their own machines.</p>
<p>A well-equipped gaming PC can now do what once required access to a cloud GPU cluster. This shift could democratize AI development, letting anyone with the right hardware explore the field from home.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>The GPU’s journey from gaming to AI is one of the most unexpected transformations in tech history. What started as a chip to render virtual landscapes evolved into the heart of artificial intelligence. From early experiments on gaming PCs to the data centers powering today’s largest models, GPUs have bridged the worlds of creativity, computation, and cognition.</p>
<p>As we look ahead, it’s clear that the same technology that once made games more realistic is now making machines more intelligent. The story of the GPU reminds us that innovation often comes from unexpected places, and sometimes, the future of AI begins in the glow of a gaming screen.</p>
<p><em>Hope you enjoyed this article. Find me on</em> <a target="_blank" href="https://linkedin.com/in/manishmshiva"><em>Linkedin</em></a> <em>or</em> <a target="_blank" href="https://manishshivanandhan.com/"><em>visit my website</em></a><em>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build an AI for Two-Player Turn-based Games ]]>
                </title>
                <description>
                    <![CDATA[ Two-player turn-based games are games where two players play against each other, turn after turn, until one of them wins. Examples of these types of games are Tic-Tac-Toe, Backgammon, Mancala, Chess, and Connect 4. In this tutorial we will learn abou... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-an-ai-for-two-player-turn-based-games/</link>
                <guid isPermaLink="false">66c5a2608232868a133f4328</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Artificial Intelligence ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Houssein Badra ]]>
                </dc:creator>
                <pubDate>Thu, 15 Dec 2022 18:24:15 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/12/2825132-637490944552534550-16x9-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Two-player turn-based games are games where two players play against each other, turn after turn, until one of them wins. Examples of these types of games are Tic-Tac-Toe, Backgammon, Mancala, Chess, and Connect 4.</p>
<p>In this tutorial we will learn about the <strong>Minimax</strong> algorithm. It is a backtracking algorithm that is used in decision making and game theory. It finds the optimal move for a player, assuming their opponent also plays optimally. It is widely used in two-player turn-based games.</p>
<p>You will learn how to create your own AI that plays any of the games mentioned above or any other similar games. Also, to make this as comprehensible as possible, I will be applying the algorithm to a <strong>Tic-Tac-Toe</strong> game.</p>
<p>We will not cover the whole process of creating the game, but only the part related to AI since this is our topic. If you're interested in the game-creating process, you can check out this <a target="_blank" href="https://housseinbadra.github.io/BadraAI.github.io/"><strong>Tic-Tac-Toe game that uses AI</strong></a> and its source code on <a target="_blank" href="https://github.com/HousseinBadra/BadraAI.github.io.git"><strong>GitHub</strong></a>. It's a project that I built long ago but it's still one of my favorites.</p>
<h3 id="heading-table-of-contents">Table of contents</h3>
<ul>
<li>How the minimax algorithm works</li>
<li>Limitations of the minimax algorithm</li>
<li>How to improve the time complexity of the algorithm</li>
<li>Tic-Tac-Toe AI Code</li>
<li>Conclusion</li>
</ul>
<h2 id="heading-how-the-minimax-algorithm-works">How the Minimax Algorithm Works</h2>
<p>The minimax algorithm's methodology is quite simple. First, it checks all the possible combinations from a given position. Then it chooses the best possible move that maximizes the chances of winning, assuming that both players play perfectly.</p>
<p>To illustrate this, let’s consider a Tic-Tac-Toe game to make this more convincing. As you might know, in this game there are 2 players and 9 available slots. So we can represent a game by using an array of length 9. </p>
<p>Now let's take this board as an example: as you can see, a game board is an array of length 9 whose values can be either <strong>X</strong>, <strong>O</strong>, or an empty string. An empty string means this position is still available.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/new1.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Board array to game board</em></p>
<p>Now it's <strong>X</strong>'s turn. The minimax algorithm will try all the game combinations from this position. Then it'll try all the game combinations from the resulting child positions until reaching a position where the game ends by either X winning, O winning, or a draw (which occurs when the board is full and no one is winning).</p>
<p>This picture illustrates how this works:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/new2.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>All game combinations demo</em></p>
<p>We can achieve this using recursion. I will show the code at the end, but for now, let's focus on understanding how we can process the game combinations to get the optimal move. We will consider these cases:</p>
<ul>
<li>The board which has a winning position for X is valued by <strong>1 point</strong></li>
<li>The board which has a winning position for O is valued by -<strong>1 point</strong></li>
<li>The board where the position is a draw has <strong>0 points</strong></li>
</ul>
<p>If we're finding the optimal move for X, we should find the board with the most points. But what if a board isn't finished yet? Then we should choose a board depending on its child boards – but which do we choose?</p>
<p>I need you to focus on this part, as it's the most important part. When I introduced the algorithm I said that it finds all the game combinations assuming both players are playing optimally.</p>
<p>After the first generation of child boards, it will be O's turn. With the assumption that O is playing optimally, we should choose a board where O is doing his best that is one of the boards with the fewest points (since when O wins, the board returns -1). </p>
<p>Why are we choosing like this? Imagine if we pick the maximum value when it's O's turn, then we're letting X win. This makes the algorithm useless, since we need to assume O plays optimally.</p>
<p>For the 3rd generation, the player is X again and we will choose the board with the most points once more.</p>
<p>This alternating method of choosing the maximum and the minimum values is the reason why this algorithm is called the Minimax algorithm. Check out this visualization for further clarification:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/new3.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Minimax mechanism</em></p>
<p>This is the same example given above. The 2 boards at the bottom are winning for X, so each will return a value of 1. Here, it’s X’s turn so we will pick the optimal value - it happens that both boards have a value of 1 here. </p>
<p>As I said earlier, if a board doesn't satisfy winning or drawing conditions, we will look at its child boards. That's why the parents of the boards with value 1 will have a value of 1.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/new4.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Minimax algorithm mechanism</em></p>
<p>Here it's O's turn so we will pick the lowest possible value which happens to be 1. I've chosen this specific example to make things simple, but this works on all boards.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/12/new5.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Minimax mechanism</em></p>
<p>Finally it's X's turn again and we will maximize the value of the chosen board. That’s why we can choose the child board on the left or the one on the right or the one in the middle – it doesn’t matter since their values are the same. </p>
<p>In the end, the optimal move for X to maximize its winning chances is in positions 7, 8 or 9. If you're still not convinced, take any board combination and draw the combination tree and you'll get a satisfying result - I strongly recommend drawing this on paper.</p>
<h2 id="heading-limitations-of-the-minimax-algorithm">Limitations of the Minimax Algorithm</h2>
<p>As you've seen, the algorithm is recursive and the number of executions may become huge. </p>
<p>For example, for a Tic-Tac-Toe game the number of executions is approximately <strong>“9!”(9 factorial)</strong>. The reason why is for the first move there are 9 possibilities and then for each subsequent move there are 8 and so on. </p>
<p>That's not a problem for tic-tac-toe, but consider a chess game. If we were to write the number of combinations, the entire universe would not be enough. So the minimax is often used as part of an engine but it’s not enough to fulfill our needs.</p>
<h2 id="heading-how-to-improve-the-time-complexity-of-the-algorithm">How to Improve the Time Complexity of the Algorithm</h2>
<p>You may have noticed that using this approach may result in some repetitive boards and that we need to compute their value multiple times. So why not store the value of every board when calculated? </p>
<p>So now, for every iteration, we will check if a position has already occurred. If so, we will use its stored value. Else, we can compute the value of the position and then store it. </p>
<p>For storing values, we will use a dictionary which allows searching in O(1). Using this approach we can reduce the time complexity – but still, it wouldn't be efficient in some cases.</p>
<p>I’ve built a Connect 4 game with this algorithm and it was horrible in terms of runtime. So, instead of looking for all the combinations, I stopped at a certain depth which led to an AI that can see n moves ahead. </p>
<p>If you're interested, check out this <a target="_blank" href="https://github.com/HousseinBadra/badraconnect4AI.github.io.git">GitHub repository</a> for the Connect 4 game code. I wrote it a long time ago but it's cool to see.</p>
<h2 id="heading-tic-tac-toe-ai-code">Tic-Tac-Toe AI Code</h2>
<p>Now let's implement some helper functions first. We will first check if there are 3 horizontal, vertical, or diagonal non-empty string values in the board array.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Board array</span>
<span class="hljs-keyword">let</span> xo=[<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,
        <span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>,
        <span class="hljs-string">''</span>,<span class="hljs-string">''</span>,<span class="hljs-string">''</span>]

<span class="hljs-comment">// Writing this function we need to make sure the equal values are not empty strings</span>

<span class="hljs-comment">// Before this I will write a helper function to make sure 3 indexes have no empty strings</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">helper</span>(<span class="hljs-params">index1,index2,index3</span>)</span>{
  <span class="hljs-keyword">return</span> xo[index1] !=<span class="hljs-string">''</span> &amp;&amp; xo[index2] !=<span class="hljs-string">''</span> &amp;&amp; xo[index3]!=<span class="hljs-string">''</span>
}



<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkwin</span>(<span class="hljs-params"></span>)</span>{

   <span class="hljs-keyword">return</span> (xo[<span class="hljs-number">0</span>]==xo[<span class="hljs-number">1</span>] &amp;&amp; xo[<span class="hljs-number">1</span>] ==xo[<span class="hljs-number">2</span>] &amp;&amp; helper(<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">2</span>)) ||
          (xo[<span class="hljs-number">3</span>]==xo[<span class="hljs-number">4</span>] &amp;&amp; xo[<span class="hljs-number">4</span>] ==xo[<span class="hljs-number">5</span>] &amp;&amp; helper(<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>)) ||
          (xo[<span class="hljs-number">6</span>]==xo[<span class="hljs-number">7</span>] &amp;&amp; xo[<span class="hljs-number">7</span>] ==xo[<span class="hljs-number">8</span>] &amp;&amp; helper(<span class="hljs-number">6</span>,<span class="hljs-number">7</span>,<span class="hljs-number">8</span>)) ||
          (xo[<span class="hljs-number">0</span>]==xo[<span class="hljs-number">3</span>] &amp;&amp; xo[<span class="hljs-number">3</span>] ==xo[<span class="hljs-number">6</span>] &amp;&amp; helper(<span class="hljs-number">0</span>,<span class="hljs-number">3</span>,<span class="hljs-number">6</span>)) ||
          (xo[<span class="hljs-number">1</span>]==xo[<span class="hljs-number">4</span>] &amp;&amp; xo[<span class="hljs-number">4</span>] ==xo[<span class="hljs-number">7</span>] &amp;&amp; helper(<span class="hljs-number">1</span>,<span class="hljs-number">4</span>,<span class="hljs-number">7</span>)) || 
          (xo[<span class="hljs-number">2</span>]==xo[<span class="hljs-number">5</span>] &amp;&amp; xo[<span class="hljs-number">5</span>] ==xo[<span class="hljs-number">8</span>] &amp;&amp; helper(<span class="hljs-number">2</span>,<span class="hljs-number">5</span>,<span class="hljs-number">8</span>)) ||
          (xo[<span class="hljs-number">0</span>]==xo[<span class="hljs-number">4</span>] &amp;&amp; xo[<span class="hljs-number">4</span>] ==xo[<span class="hljs-number">8</span>] &amp;&amp; helper(<span class="hljs-number">0</span>,<span class="hljs-number">4</span>,<span class="hljs-number">8</span>)) ||
          (xo[<span class="hljs-number">2</span>]==xo[<span class="hljs-number">4</span>] &amp;&amp; xo[<span class="hljs-number">4</span>] ==xo[<span class="hljs-number">6</span>] &amp;&amp; helper(<span class="hljs-number">2</span>,<span class="hljs-number">4</span>,<span class="hljs-number">6</span>))

}

<span class="hljs-comment">//And finally a function to check if there is a draw which will check if all board values are not empty strings. This only works after checking that there is no winning conditions first</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">boardfull</span>(<span class="hljs-params"></span>)</span>{
  <span class="hljs-keyword">return</span> xo.every(<span class="hljs-function">(<span class="hljs-params">elem</span>)=&gt;</span>{
   <span class="hljs-keyword">return</span> elem !=<span class="hljs-string">''</span>
  })
}
</code></pre>
<p>Now we have the function to check if a winning state is there and we can finally write the Minimax like this (I've added comments in the code to help explain it):</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// As I said erlier, the algorithm will take the board, the ismax parameter to check if we want to maximize or minimize for a certain turn</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">minimax</span>(<span class="hljs-params">board,depth,ismax</span>)</span>{

    <span class="hljs-comment">// This is a recursive function, so we should set the bases cases first which will be getting a draw a win or reaching the depth</span>

    <span class="hljs-comment">// As you've seen in the visualizations, when there is a draw or winning conditions no more child boards are generated. So if a winning condition occured when it's X's turn. It got to be X who won that's why I returned 1, and the same logic applies for when Y won and I returned -1 when we were minimizing.</span>

    <span class="hljs-keyword">if</span> (checkwin()) <span class="hljs-keyword">return</span> ismax ? <span class="hljs-number">1</span> : <span class="hljs-number">-1</span>
    <span class="hljs-keyword">if</span> (boardfull()) <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>

    <span class="hljs-keyword">if</span>(ismax){

        <span class="hljs-comment">// When we're maximizing we will set a counter to -Infinity and whenever we encounter a board value higher than the counter, we will consider it as the best move</span>

     <span class="hljs-keyword">let</span> best=-<span class="hljs-literal">Infinity</span>
     board.forEach(<span class="hljs-function">(<span class="hljs-params">elem,index</span>)=&gt;</span>{

         <span class="hljs-comment">//Now to check all resulting positions we will iterate over the board and whenever there is an avaible slot we will set it to X and run minimax on this position. Look how I incrimented the depth</span>

     <span class="hljs-keyword">if</span>(elem ==<span class="hljs-string">''</span>){
       board[index]=<span class="hljs-string">'X'</span>
       <span class="hljs-keyword">let</span>  localscores=minimax(test,depth+<span class="hljs-number">1</span>,<span class="hljs-literal">false</span>)

       <span class="hljs-comment">// Here I am reetting the board to the same position </span>

       board[index]=<span class="hljs-string">''</span>
       best=max(best,localscores)
     }})
     <span class="hljs-keyword">return</span> best
     }

 <span class="hljs-comment">// This else here means we're minimizing</span>

 <span class="hljs-keyword">else</span>{

     <span class="hljs-comment">// Here we will set our counter to + Infinity because we want to find the lowest possible value</span>

    <span class="hljs-keyword">let</span> best=<span class="hljs-literal">Infinity</span>
    board.forEach(<span class="hljs-function">(<span class="hljs-params">elem,index</span>)=&gt;</span>{
    <span class="hljs-keyword">if</span>(elem ==<span class="hljs-string">''</span>){
     board[index]=humanicon
     <span class="hljs-keyword">let</span> localscores=minimax(test,depth+<span class="hljs-number">1</span>,<span class="hljs-literal">true</span>)
     board[index]=<span class="hljs-string">''</span>
     best=min(best,localscores)
    }})
    <span class="hljs-keyword">return</span> best
  }
}
</code></pre>
<p>And now we're done!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we’ve learned about the minimax algorithm, its mechanism, limitations, and how to improve it. Now you can go and customize this to work on various games to create some cool game bots.</p>
<p>In the end, I hope you learned something new from this article. </p>
<p>If you found this useful and want to get more awesome content, <a target="_blank" href="https://www.linkedin.com/in/houssein-badra-943879214">follow me on LinkedIn</a>. It will help a lot.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Implement a GameKit Leaderboard in SwiftUI ]]>
                </title>
                <description>
                    <![CDATA[ By Saamer Mansoor In this article we will talk about why and how to implement the GameCenter's Leaderboard within your app.  Why GameCenter is Making a Huge Revival You can make iPhone games without a scoreboard, but leaderboards can help make the ga... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-a-leaderboard-in-swiftui/</link>
                <guid isPermaLink="false">66d460c537bd2215d1e245bb</guid>
                
                    <category>
                        <![CDATA[ Apple ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ iOS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Swift ]]>
                    </category>
                
                    <category>
                        <![CDATA[ SwiftUI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 19 Aug 2022 21:00:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/IMG_45B142A26F90-1-copy.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Saamer Mansoor</p>
<p>In this article we will talk about why and how to implement the <a target="_blank" href="https://developer.apple.com/design/human-interface-guidelines/technologies/game-center/leaderboards/">GameCenter's Leaderboard</a> within your app. </p>
<h2 id="heading-why-gamecenter-is-making-a-huge-revival">Why GameCenter is Making a Huge Revival</h2>
<p>You can make iPhone games without a scoreboard, but leaderboards can help make the game feel more competitive, like people are competing against one another around the World. </p>
<p>Instead of creating and managing your own backend, the GameCenter Leaderboard allows you to scale with traffic infinitely, skip an entire login page for authorization, get the Image, Name, and friends playing the same game – all without your users having to enter anything. </p>
<p>Especially with iOS 16, <a target="_blank" href="https://developer.apple.com/game-center/">Apple is investing more in improving it</a>, and driving more app usage, like through Push Notifications when your friend beats your score in the game.</p>
<p>In my journey of learning SwiftUI, I have been creating and publishing apps, because IMO that's the best way to learn. </p>
<p>There wasn't much updated documentation on how to do a lot of this, especially none with SwiftUI nor with the <a target="_blank" href="https://www.freecodecamp.org/news/make-rest-api-call-in-swiftui-in-2-minutes/">advent of async and await in Swift</a>. So I consolidated and simplified it for everyone to build amazing apps. So feel free to invite me to test your apps too!</p>
<h3 id="heading-pre-requisites">Pre-Requisites:</h3>
<ul>
<li>You'll need to have an <a target="_blank" href="https://developer.apple.com/programs/">Apple Developer</a> paid account</li>
<li>You have to create the <a target="_blank" href="https://support.magplus.com/hc/en-us/articles/203808708-iOS-Creating-App-IDs">App Id for your app</a> in the provisioning profiles section of the Apple Developer Portal</li>
<li>You have to <a target="_blank" href="https://support.staffbase.com/hc/en-us/articles/115003481992-Creating-an-App-Profile-in-App-Store-Connect">create the App in the iTunes Connect Connect</a> portal</li>
</ul>
<h2 id="heading-how-to-implement-your-ios-leaderboard-in-6-steps">How to Implement Your iOS Leaderboard in 6 Steps</h2>
<p>Most of the code logic for the leaderboard is in <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/main/StairStepperMaster/StairStepperMaster/Views/LeadersTileView.swift">this file if you want to skip ahead</a>. Here's the steps as follows:</p>
<h3 id="heading-1-how-to-create-the-app-store-connect-leaderboard">1. How to Create the App Store Connect Leaderboard</h3>
<p><img src="https://user-images.githubusercontent.com/8262287/180824532-2e27ca8a-c1c0-4676-b439-f3ab09887271.png" alt="image" width="600" height="400" loading="lazy">
<em>Screenshot from the Apple iTunes Connect Portal</em></p>
<p>Once you have created the app in the App Store Connect portal successfully, go to the Services tab for the app -&gt; and make sure you're in the GameCenter page.</p>
<p>Then add a new leaderboard using the "+" sign, which can either be "Classic" (scores never reset) or "Recurring" (scores reset based on your frequency settings).</p>
<p>Most games prefer a recurring leaderboard so that the leaderboard isn't cluttered with older impossible to reach high scores.</p>
<p>The LeaderboardID you input there is the one that you need to use in all the places in the code that ask for it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/image-122.png" alt="Image" width="600" height="400" loading="lazy">
<em>Details required to create a new Leaderboard</em></p>
<h3 id="heading-2-how-to-set-up-gamecenter-authentication">2. How to Set Up GameCenter Authentication</h3>
<p>First, you'll need to authenticate users to GameCenter in order for any of this functionality to work.</p>
<p>So we'll use this code to do that, which basically makes sure that you (GKLocalPlayer.local) are authenticated, or prints an error if there is one:</p>
<pre><code>func authenticateUser() {
    GKLocalPlayer.local.authenticateHandler = { vc, error <span class="hljs-keyword">in</span>
        guard error == nil <span class="hljs-keyword">else</span> {
            print(error?.localizedDescription ?? <span class="hljs-string">""</span>)
            <span class="hljs-keyword">return</span>
        }
    }
}
</code></pre><p>If the user is authenticated, you will see a little popup in the UI. If not, the user will be taken to a page to login to their GameCenter account.</p>
<p><img src="https://user-images.githubusercontent.com/8262287/180823235-cafefcfa-3d25-46e5-8524-d7f475b9a000.png" alt="image" width="600" height="400" loading="lazy">
<em>A sign that displays when a user is logged in</em></p>
<h3 id="heading-3-how-to-display-leaderboard-items-in-the-ui">3. How to Display Leaderboard Items in the UI</h3>
<p>In order to get the data away from the GameCenter ViewController leaderboards (GKLeaderboard), you need to use the <code>loadLeaderboards</code> . </p>
<p>You can switch up the <code>loadEntries</code> function from <code>.global</code> to <code>.friends</code> in order to only pull your friends. </p>
<p>You can also retrieve the image for each player by iterating over each player and performing a <code>loadPhoto</code>. </p>
<p>Using <code>NSRang(1...5)</code>, you can choose how many players to display. This pulls the users with the highest 5 scores from the leaderboard and returns none if there's no users, such as in the case when the cycle refreshes for a recurring Leaderboard.</p>
<p>This is what pulling data from a leaderboard could look like if you take advantage of async-await:</p>
<pre><code>func loadLeaderboard() <span class="hljs-keyword">async</span> {
    playersList.removeAll()
    Task{
        <span class="hljs-keyword">var</span> playersListTemp : [Player] = []
        <span class="hljs-keyword">let</span> leaderboards = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> GKLeaderboard.loadLeaderboards(IDs: [leaderboardIdentifier])
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">let</span> leaderboard = leaderboards.filter ({ $<span class="hljs-number">0.</span>baseLeaderboardID == self.leaderboardIdentifier }).first {
            <span class="hljs-keyword">let</span> allPlayers = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> leaderboard.loadEntries(<span class="hljs-keyword">for</span>: .global, <span class="hljs-attr">timeScope</span>: .allTime, <span class="hljs-attr">range</span>: NSRange(<span class="hljs-number">1.</span>.<span class="hljs-number">.5</span>))
            <span class="hljs-keyword">if</span> allPlayers<span class="hljs-number">.1</span>.count &gt; <span class="hljs-number">0</span> {
                <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> allPlayers<span class="hljs-number">.1</span>.asyncForEach { leaderboardEntry <span class="hljs-keyword">in</span>
                    <span class="hljs-keyword">var</span> image = <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> leaderboardEntry.player.loadPhoto(<span class="hljs-keyword">for</span>: .small)
                    playersListTemp.append(Player(name: leaderboardEntry.player.displayName, <span class="hljs-attr">score</span>:leaderboardEntry.formattedScore, <span class="hljs-attr">image</span>: image))
                                print(playersListTemp)
                    playersListTemp.sort{
                        $<span class="hljs-number">0.</span>score &lt; $<span class="hljs-number">1.</span>score
                    }
                }
            }
        }
        playersList = playersListTemp            
    }
}
</code></pre><p><img src="https://user-images.githubusercontent.com/8262287/180823292-2dee4f9a-4894-4442-9241-2ad1c84b1cf7.png" alt="image" width="600" height="400" loading="lazy">
<em>You can get leaderboard data into your app</em></p>
<h3 id="heading-4-how-to-call-functionality-in-swiftui-as-the-viewpage-appears">4. How to Call Functionality in SwiftUI as the View/Page Appears</h3>
<p>You can take advantage of the <code>onAppear</code> <a target="_blank" href="https://www.hackingwithswift.com/quick-start/swiftui/how-to-respond-to-view-lifecycle-events-onappear-and-ondisappear">lifecycle function of the view</a> to actually make the calls to authenticate and load, but you can also do it on the tap of a button if you prefer that:</p>
<pre><code>.onAppear(){
    <span class="hljs-keyword">if</span> !GKLocalPlayer.local.isAuthenticated {
        authenticateUser()
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> playersList.count == <span class="hljs-number">0</span> {
        Task{
            <span class="hljs-keyword">await</span> loadLeaderboard()
        }
    }
}
</code></pre><h3 id="heading-5-how-to-load-the-submitted-scores">5. How to Load the Submitted Scores</h3>
<p>In order to load the scores, you need to submit them as well. The <code>submitScore</code> function can help you with that.</p>
<ul>
<li>The <code>flightsClimbed</code> variable should contain the score that you would like to submit.</li>
<li>GameKit makes sure to only display your best score for the life of the leaderboard.</li>
<li>The <code>leaderboardId</code> contains the value that you manually enter in your App Store Connect account:</li>
</ul>
<pre><code>func leaderboard() <span class="hljs-keyword">async</span>{
    Task{
        <span class="hljs-keyword">try</span> <span class="hljs-keyword">await</span> GKLeaderboard.submitScore(
            flightsClimbed,
            <span class="hljs-attr">context</span>: <span class="hljs-number">0</span>,
            <span class="hljs-attr">player</span>: GKLocalPlayer.local,
            <span class="hljs-attr">leaderboardIDs</span>: [<span class="hljs-string">"com.tfp.stairsteppermaster.flights"</span>]
        )
    }
    calculateAchievements()
}
</code></pre><h3 id="heading-6-how-to-display-the-gamecenter-viewcontroller-portal">6. How to display the GameCenter ViewController Portal</h3>
<p>When you're logged into GameCenter, a little annoying icon appears in the top right of your screen. When you tap on it, you are taken to the GameCenter ViewController. Luckily you can hide it if it's not part of your design, using <code>GKAccessPoint.shared.isActive = false</code>. </p>
<p>Since the GameCenter UI is a UIKit <code>ViewController</code> and not a simple SwiftUI <code>View</code>, you need to create this <a target="_blank" href="https://www.hackingwithswift.com/books/ios-swiftui/wrapping-a-uiviewcontroller-in-a-swiftui-view">UIViewControllerRepresentable</a> first (as you can <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/main/StairStepperMaster/StairStepperMaster/Views/GameCenterView.swift">see here</a>), to launch GameCenter using a different button, </p>
<p>Once you add that file to your project, you can display the GameCenter portal simply using this: <code>GameCenterView(format: gameCenterViewControllerState)</code> where gameCenterViewControllerState can be help you go to a detail page in GameCenter.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Frame-3-3.png" alt="Image" width="600" height="400" loading="lazy">
<em>GameCenter's Leaderboard View</em></p>
<h2 id="heading-things-to-keep-in-mind-while-using-gamecenters-leaderboards">Things to Keep in Mind While using GameCenter's Leaderboards:</h2>
<ul>
<li>Simulator Debugging – For some reason the authenticate to GameCenter is extremely slow on a simulator, so it might make sense to even create a mock of data when using the simulator.</li>
<li>Challenges – You can't programmatically issue GameKit Challenges to your friends anymore <a target="_blank" href="https://developer.apple.com/documentation/gamekit/gkscore/1520610-issuechallenge">due to deprecation</a>. Instead, you have to do those manually within the user's GameCenter dashboard against GameKit Achievements. Also, there's no way to view challenges you have sent. </li>
<li>Achievements – Leaderboards are different from the GameKit Achievements, which is calculated and displayed differently, but a <a target="_blank" href="https://github.com/StairMasterClimber/mobile/blob/18283a68e1c5cac4e270a85b03853887b3950156/StairStepperMaster/StairStepperMaster/Views/AchievementTileView.swift#L113">lot easier</a>. Those can also be pulled into the app as well, as you can see below:</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/Frame-2-2.png" alt="Image" width="600" height="400" loading="lazy">
<em>GameKit Challenges and Achievements</em></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>You can try out the free open-source <a target="_blank" href="https://stairmasterclimber.com/app">Stair Master Climber iPhone Health &amp; Fitness app</a> that I shared above. I would love to know what you think so that we can learn together. </p>
<p>Feel free to reach out to me on <a target="_blank" href="https://twitter.com/StairMasterApp">social media</a> or by <a target="_blank" href="mailto:hi@stairmasterclimber.com">email</a> if you have any questions.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Run Android Games on Linux with Android-x86 ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you'll learn how you can use virtual machines on Linux while having fun with vintage games. If you have an Android phone, one of your guilty pleasures might be playing some very entertaining games. Or it could be that there is an app... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/run-android-games-on-linux/</link>
                <guid isPermaLink="false">66d851497211ea6be29e1b7f</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ virtual machine ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jose Vicente Nunez ]]>
                </dc:creator>
                <pubDate>Wed, 17 Aug 2022 16:09:12 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/08/jose-article-photo.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you'll learn how you can use virtual machines on Linux while having fun with vintage games.</p>
<p>If you have an Android phone, one of your guilty pleasures might be playing some very entertaining games. Or it could be that there is an application that only runs on your phone.</p>
<p>And then you think – what if you could run the same games on your desktop PC?</p>
<p>To simplify the scenario, let's assume the applications run on Android.</p>
<p>One approach to solve your problem is to run an Android emulator on your PC. But some of them, like <a target="_blank" href="https://www.android-x86.org/download.html">Android-x86</a>, require rebooting your machine so they can take control of the hardware.</p>
<p>If you don't mind a small performance hit you can run a virtual machine at the same time as your native operating system. Specifically on Linux, there are several choices, like <a target="_blank" href="https://www.qemu.org/">QEMU</a> and <a target="_blank" href="https://www.virtualbox.org/">VirtualBox</a>, to name a few.</p>
<p>By the end of this article you will be able to do the following:</p>
<ul>
<li><p>Install VirtualBox on Fedora Linux</p>
</li>
<li><p>Run android-x86 and finish the basic setup</p>
</li>
<li><p>Install an application from the Google Play Store, just like on your phone.</p>
</li>
</ul>
<h2 id="heading-basic-requirements"><strong>Basic Requirements</strong></h2>
<p>Before you start, I assume that you have the following:</p>
<ul>
<li><p>Ability to run commands as the superuser (like <a target="_blank" href="https://www.sudo.ws/">SUDO</a>)</p>
</li>
<li><p>An account on Google.com, so you can use the Play store from within the virtual machine.</p>
</li>
</ul>
<h1 id="heading-how-to-install-virtualbox"><strong>How to Install VirtualBox</strong></h1>
<p>The first step is to install VirtualBox. For practical purposes, our installation will be basic, just enough to run our games:</p>
<pre><code class="lang-python">sudo dnf install -y kernel-devel kernel-devel<span class="hljs-number">-5.14</span><span class="hljs-number">.18</span><span class="hljs-number">-100.</span>fc33.x86_64
curl --remote-name --location https://www.virtualbox.org/download/oracle_vbox.asc
sudo rpm --<span class="hljs-keyword">import</span> ./oracle_vbox.asc
sudo dnf install -y https://download.virtualbox.org/virtualbox/<span class="hljs-number">6.1</span><span class="hljs-number">.36</span>/VirtualBox<span class="hljs-number">-6.1</span><span class="hljs-number">-6.1</span><span class="hljs-number">.36</span>_152435_fedora33<span class="hljs-number">-1.</span>x86_64.rpm
sudo dnf install -y virtualbox-guest-additions.x86_64
sudo /sbin/vboxconfig
</code></pre>
<h2 id="heading-how-to-install-the-android-x86-iso"><strong>How to Install the Android-x86 ISO</strong></h2>
<p>The first step is to download the ISO image from <a target="_blank" href="https://sourceforge.net/projects/android-x86/">Android-x86</a>. This ISO contains the Android operating system that will be installed on our virtual hard drive.</p>
<p>After that we can set up our virtual machine like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/virtualbox-androidx86.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>How a finished virtual machine looks like on VirtualBox</em></p>
<p><img src="http://localhost:63342/4f800f8a-bbed-4dd8-b03c-00449c9f6698/1437651526/fileSchemeResource/59ea74abf47f101ded05f883e4d4c256-virtualbox-androidx86.png?_ijt=r1jlidvb50q7p9rgbjri12egof" alt="Image" width="600" height="400" loading="lazy"></p>
<p>A few things to note:</p>
<ul>
<li><p>After booting the first time, I found that 1GB for the Android image was not enough. Performance improved a lot after I bumped the ram to 3GB.</p>
</li>
<li><p>Another change was the 'Graphics Controller'. Originally it was VMSVGA but then Android refused to start in graphic mode, so I switched to VboxVGA and it worked.</p>
</li>
<li><p>2 CPUS and 8GB of disk space were enough for my game.</p>
</li>
<li><p>Finally, I specified that the IDE controller was the android-x86 ISO.</p>
</li>
</ul>
<p>To start the virtual machine, you click the 'Start' button on the GUI, and then you will have to make a few decisions like bootable partition:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/androidx86-partition.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Partitioning your virtual disk. We assign 8 GB and make sure the partition can boot</em></p>
<p>Once this is done you can choose your new partition to perform the installation:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/androidx86-newpartition.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>After the new partition is created, you can choose it and you can install the Android OS there</em></p>
<p>Then the installation will proceed:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/androidx86-install.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The installer copies the files from the Android ISO image into the virtual hard drive</em></p>
<p>After the installation is complete, you can shut down the virtual machine.</p>
<h2 id="heading-first-boot"><strong>First Boot</strong></h2>
<p>Now you'll need to go to the advanced options and select the virtual disk (instead of the ISO image) to boot:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/android-x86-boot-from-disk.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>You can either boot from disk on this menu or change the boot order on the virtual machine</em></p>
<p>After that, Android will ask you some basic setup information, just like it does on your phone. The final result may look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/androidx86-running.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The virtual machine looks exactly like your Android phone.</em></p>
<h2 id="heading-how-to-install-games-from-the-google-play-store"><strong>How to Install Games from the Google Play Store</strong></h2>
<p>In my case I decided to install a game where I can fight forces of evil as 1970 <a target="_blank" href="https://en.wikipedia.org/wiki/Mazinger_Z">Mazinger Z/ Tranzor Z</a> (Yes, I love <a target="_blank" href="https://en.wikipedia.org/wiki/Go_Nagai">Go Nagai</a> Mazinger Z). To do that, search on the play store and install the game:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/android-x86-play-store.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>After Android is running and your credentials are set you can download and install any Android program you want.</em></p>
<p>And now, success! We got the game up and running.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/08/androidx86-mazingerz.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>Sorry, but now it is time to play as Mazinger Z!</em></p>
<h1 id="heading-what-did-we-learn-here"><strong>What Did We Learn Here?</strong></h1>
<ul>
<li><p>We managed to install a virtual machine engine and successfully run the Android operating system along with our regular Fedora OS</p>
</li>
<li><p>You saw how you can try and discard whole operating systems' setup, without going through the hassle of setting up a dual boot system with Grub on Linux</p>
</li>
</ul>
<p>Another nice feature of running the game inside a virtual machine is that you can fully freeze the game, then come back and restore it at exactly the same point where you left it.</p>
<p>Finally, you can do many more things with a virtual machine than just running games, for example:</p>
<ul>
<li><p>You can <a target="_blank" href="https://www.varonis.com/blog/malware-analysis-tools">analyze malware safely</a>, run un-trusted applications, and contain any damage they can cause.</p>
</li>
<li><p>Try a new operating system version before deciding to commit a proper installation (not a big issue these days as most of them provide a lice CD you can boot to try), but this is still very convenient.</p>
</li>
<li><p>Be able to run multiple operating systems simultaneously, without rebooting your machine. You most likely will start trying more advanced options of your virtual machine of choice, like <a target="_blank" href="https://www.virtualbox.org/manual/ch09.html">VirtualBox</a>.</p>
</li>
</ul>
<p>Playing games on your PC is a gateway for learning more complex stuff later. Also the fun factor is undeniable. Enjoy!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Snake Game with React, Redux, and Redux Saga ]]>
                </title>
                <description>
                    <![CDATA[ In this article, I am going to walk you through creating a snake game using a React application. It is a simple 2d game built using TypeScript, and we won't need to use any third-party graphics libraries to build it.  This is what we'll make in this ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-snake-game-with-react-redux-and-redux-sagas/</link>
                <guid isPermaLink="false">66bb553d343f42327e719662</guid>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Redux ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Keyur Paralkar ]]>
                </dc:creator>
                <pubDate>Wed, 09 Feb 2022 18:03:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/02/pexels-pixabay-80474.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, I am going to walk you through creating a snake game using a React application. It is a simple 2d game built using TypeScript, and we won't need to use any third-party graphics libraries to build it. </p>
<p>This is what we'll make in this tutorial:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--2-.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Snake is a fun game which you might have played on older feature phones like on Nokia 3310 models. </p>
<p>The concept behind it is simple: the snake roams around inside a box, and once it captures the fruit/object your points increase and the snake grows. If the snake hits the boundaries of the box or collides with itself then the game is over. </p>
<p>This article will provide you with all the necessary skills/steps to create your own Snake game from scratch. We'll first look at the code structures and their logic. Then I'll explain how they work when all of them are connected.</p>
<p>Without further ado, let’s get started.</p>
<h2 id="heading-table-of-contents">Table of contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-what-is-a-snake-game-what-are-we-going-to-use-in-it">What is a snake game? What are we going to use in it?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-redux-why-are-we-using-it">What is redux? Why are we using this?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-redux-saga-why-are-we-using-it">What is redux-saga? Why are we using this?</a></li>
<li><a class="post-section-overview" href="#heading-use-case-description">Use case description</a></li>
<li><a class="post-section-overview" href="#heading-the-application-and-data-layer-set-up">The application and data layer set up</a></li>
<li><a class="post-section-overview" href="#heading-understanding-ui-layer">Understanding UI Layer</a></li>
<li><a class="post-section-overview" href="#heading-canvas-board">Canvas Board</a></li>
<li><a class="post-section-overview" href="#heading-drawing-the-objects">Drawing the objects</a></li>
<li><a class="post-section-overview" href="#heading-moving-the-snake-across-the-board">Moving the snake across the board</a></li>
<li><a class="post-section-overview" href="#heading-drawing-the-fruit-at-a-random-position">Drawing the fruit at a random position</a></li>
<li><a class="post-section-overview" href="#heading-score-calculator">Score calculator</a></li>
<li><a class="post-section-overview" href="#heading-instruction-component">Instruction component</a></li>
<li><a class="post-section-overview" href="#heading-final-game">Final Game</a></li>
<li><a class="post-section-overview" href="#heading-summary">Summary</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you start reading this article, you should have a basic understanding of the following topics:</p>
<ul>
<li>Class Diagrams: We are going to use them to showcase our example. Here are a couple of resources you can use to learn more about them:<ul>
<li><a target="_blank" href="https://drawio-app.com/uml-class-diagrams-in-draw-io/">Class diagrams</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/uml-diagrams-full-course/">UML Diagram course</a></li>
</ul>
</li>
<li><a target="_blank" href="https://www.notion.so/JS-Classes-a-boon-to-the-society-6360d1a702fe49da9b7ba98b0e03fe37">Context Diagram and Container Diagrams</a></li>
<li><a target="_blank" href="https://reactjs.org/">React</a></li>
<li>Generators:<ul>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator">Generators</a></li>
<li><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*">Function generators</a></li>
</ul>
</li>
</ul>
<h2 id="heading-what-is-a-snake-game-what-are-we-going-to-use-in-it">What is a snake game? What are we going to use in it?</h2>
<p>A snake game is an arcade game that involves a snake moving inside a box. Your score increases based on how many objects/fruit the snake eats. This will also increase the size of the snake. If it collides with itself or to the boundary of the box then the game is over. </p>
<p>You can read more about the history or the origins of the game in the Wiki <a target="_blank" href="https://en.wikipedia.org/wiki/Snake_(video_game_genre)">link</a>.</p>
<p>We are going to use the following tools to build our game:</p>
<ul>
<li>Redux: To create and manage the global state for the application.</li>
<li>Redux-saga: A redux middleware we'll use to manage async tasks.</li>
<li>Canvas HTML tag: We'll use this to draw an object like a snake and the fruit.</li>
<li>React: UI library.</li>
<li>Chakra-UI: Component library.</li>
</ul>
<h2 id="heading-what-is-redux-why-are-we-using-it">What is redux? Why are we using it?</h2>
<p>Redux is a state container that helps you create and manage global state for your application. Redux consists of some basic parts like:</p>
<ol>
<li>Global State</li>
<li>Redux store</li>
<li>Actions and action creators</li>
<li>Reducers</li>
</ol>
<p>You can learn all about the above topics and how Redux works internally from the Redux doc’s getting started <a target="_blank" href="https://redux.js.org/introduction/getting-started">section</a>.</p>
<p>We are using the state management library Redux because it will help us manage our global state in a simpler way. It will allow us to avoid prop drilling. It will also allow us to perform complex async actions via middleware. </p>
<p>You can learn more about middleware <a target="_blank" href="https://redux.js.org/understanding/history-and-design/middleware">here</a>.</p>
<h2 id="heading-what-is-redux-saga-why-are-we-using-it">What is redux-saga? Why are we using it?</h2>
<p>Redux-saga is a middleware that helps us tap in between the dispatched action and the reducer of the redux store. This allows us to perform certain side-effects between the dispatched action and the reducer such as data fetching, listening to particular actions or setting up subscriptions, spawning actions, and more.</p>
<p>Redux saga uses generators and generator functions. A typical saga would look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">performAction</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> put({
        <span class="hljs-attr">type</span>: COPY_DATA,
        <span class="hljs-attr">payload</span>: <span class="hljs-string">"Hello"</span>
    });
}
</code></pre>
<p><code>performAction</code> is a generator function. This generator function will execute the <code>put</code> function. It creates an object and returns it to the saga, telling what type of action needs to be executed with what payload. Then the <code>put</code> call returns an object descriptor saying which saga can take it up later and execute the particular action.</p>
<p><strong>NOTE:</strong> You can read more about generators and generator functions by referring to the prerequisite section.</p>
<p>Now the question arises <em>Why are we using redux-saga middleware?</em> The answer is simple:</p>
<ol>
<li>It provides a better way to write unit test cases, which will help us test the generator functions in a simpler way.</li>
<li>It can help you perform a lot of side effects and provide better control over the changes. One example is whenever you want to watch if a particular action X is executed then perform the action Y. Functions like <code>takeEvery</code>, <code>all</code>, and so on make it simple to perform these operations. We will discuss more of this in a later section.</li>
</ol>
<p>If you are not familiar with redux-saga, then I highly recommend going through the documentation <a target="_blank" href="https://redux-saga.js.org/docs/introduction/GettingStarted/">here</a>.</p>
<h2 id="heading-use-case-description">Use case description</h2>
<p><strong>NOTE:</strong> Context, Container, and Class diagrams drawn in this blog post don't accurately follow the exact conventions of these diagrams. I've approximated them here so you can understand the basic concepts.</p>
<p>Before we start, I would suggest reading up on c4models, container diagrams, and context diagrams. You can find resources about them in the prerequisites section.</p>
<p>In this article we are going to consider the following use case: <em>Create a snake game</em>.</p>
<p>The use case is pretty self-explanatory, and we have discussed what the snake game entails above. Below is the context diagram for our use case:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/contextDiagram.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake game context diagram</em></p>
<p>Our context diagram is pretty straightforward. The player interacts with the UI. Let's dive deeper into the container game board UI and explore what other systems are present inside it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Untitled--2-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Container diagram for the snake game</em></p>
<p>As you can see from the above diagram, our Game Board UI is divided into two Layers:</p>
<ol>
<li>UI Layer</li>
<li>Data Layer</li>
</ol>
<p>The UI Layer consists of the following components:</p>
<ol>
<li><strong>Score Calculator:</strong> This is a component that will display the score whenever the snake eats the fruit.</li>
<li><strong>Canvas Board:</strong> This is a component that handles the major UI part of our game. Its basic functionality is to draw the snake on the canvas and clear the canvas. It also handles the following responsibilities:<ol>
<li>It detects if the snake has collided with itself or with the boundary walls (Collision detection).</li>
<li>Helps in moving the snake along the board with keyboard events.</li>
<li>Resets the game when the game is over.</li>
</ol>
</li>
<li><strong>Instructions:</strong> It provides the instructions for playing the game, along with the reset button.</li>
<li><strong>Utilities:</strong> These are the utility functions that we'll use throughout the application wherever needed.</li>
</ol>
<p>Let's now talk about the Data Layer. It consists of the following components:</p>
<ol>
<li><strong>Redux-saga:</strong> Set of generator functions that will perform certain actions.</li>
<li><strong>Actions and Action Creators:</strong> These are the set of constants and functions which will help in dispatching appropriate actions.</li>
<li><strong>Reducers:</strong> This will help us respond to the various actions dispatched by action creators and the sagas.</li>
</ol>
<p>We will deep dive into all of these components and see how they work collectively in the later sections. First, let's initialize our project and set up our Data layer – that is, the Redux store.</p>
<h2 id="heading-the-application-and-data-layer-set-up">The application and data layer set up</h2>
<p>Before we start understanding our game components, let's first set up our React application and the data layer. </p>
<p>The game is built with React. I highly recommend using the <a target="_blank" href="https://create-react-app.dev/">create-react-app</a> template to install all the necessary things to start your React application. </p>
<p>To create a CRA (create-react-app) project, first we need to install it. Type the below command into your terminal:</p>
<pre><code class="lang-shell">npm install -g create-react-app
</code></pre>
<p><strong>Note:</strong> Before running this command make sure you have installed Node.js in your system. Follow this <a target="_blank" href="https://nodejs.org/en/download/package-manager/">link</a> to install it.</p>
<p>Next, we will start by creating our project. Let's call it snake-game. Type the below command into your terminal to create the project:</p>
<pre><code class="lang-shell">npx create-react-app snake-game
</code></pre>
<p>This may take few minutes to complete. Once this is completed, traverse to your newly created project using the below command:</p>
<pre><code class="lang-shell">cd snake-game
</code></pre>
<p>Once inside the project, type the below command to start the project:</p>
<pre><code class="lang-shell">npm run start
</code></pre>
<p>This command will open a new tab in your browser with the React logo spinning on the page like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/image-16.png" alt="Image" width="600" height="400" loading="lazy">
<em>create-react-app initial page</em></p>
<p>Now our initial project setup is complete. Let's configure our data layer (the Redux store). Our data layer requires that we install the following packages:</p>
<ul>
<li>Redux</li>
<li>Redux-saga</li>
</ul>
<p>First, let's start off by installing these packages. Before we start, make sure you are in the project directory. Type the below command in the terminal:</p>
<pre><code class="lang-shell">npm install redux react-redux redux-saga
</code></pre>
<p>Once these packages are installed then we will first configure our Redux store. To start off, let's first create a folder named <code>store</code>:</p>
<pre><code class="lang-shell">mkdir store
</code></pre>
<p>This <code>store</code> folder will consist of all the files related to Redux. We will organize our store folder in the following manner:</p>
<pre><code class="lang-shell">store/
├── actions
│   └── index.ts
├── reducers
│   └── index.ts
└── sagas
    └── index.ts
├── index.ts
</code></pre>
<p>Let's discuss what each of the files does:</p>
<ul>
<li><code>action/index.tsx</code>: This file consists of constants that represents actions that our application can perform and dispatch to the Redux store. An example of such an action constant looks like this:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_RIGHT = <span class="hljs-string">"MOVE_RIGHT"</span>
</code></pre>
<p>We will use the same action constant to create a function which will return an object with the following properties:</p>
<ul>
<li><code>type</code>: Action type, that is action constant</li>
<li><code>payload</code>: additional data that acts as a payload.</li>
</ul>
<p>These functions which return an object with the <code>type</code> property are called action creators. We use these functions to dispatch actions to our Redux store. </p>
<p>The <code>payload</code> attribute signifies that along with the action we can also pass additional data which can be used to store or update the value inside the global state.</p>
<p><strong>NOTE</strong>: It is mandatory to have <code>type</code> property returned from the action creator. The <code>payload</code> property is optional. Also, the name of the <code>payload</code> property can be anything.</p>
<p>Let's see an example of an action creator:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//Without payload</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> moveRight = <span class="hljs-function">() =&gt;</span> ({
    <span class="hljs-attr">type</span>: MOVE_RIGHT
});

<span class="hljs-comment">//With payload</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> moveRight = <span class="hljs-function">(<span class="hljs-params">data: string</span>) =&gt;</span> ({
    <span class="hljs-attr">type</span>: MOVE_RIGHT,
    <span class="hljs-attr">payload</span>: data
});
</code></pre>
<p>Now that we know what actions and action creators are, we can move on to configuring our next artifact which is a reducer.</p>
<p>Reducers are functions that return a new global state every time an action is dispatched. They take in the current global state and return the new state based on the action that is dispatched/called.  This new state is calculated based on the previous state. </p>
<p>We should be careful here that we do not perform any side-effects inside this function. We should not alter the global state – rather we should return the updated state as a new object itself. Therefore, the reducer function should be a pure function.</p>
<p>Now enough talking about reducers. Let's have a look at our sample reducers:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> GlobalState = {
    <span class="hljs-attr">data</span>: <span class="hljs-string">""</span>
};

<span class="hljs-keyword">const</span> gameReducer = <span class="hljs-function">(<span class="hljs-params">state = GlobalState, action</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (action.type) {
        <span class="hljs-keyword">case</span> <span class="hljs-string">"MOVE_RIGHT"</span>:
            <span class="hljs-comment">/**
             * Perform a certain set of operations
             */</span>
            <span class="hljs-keyword">return</span> {
                ...state, <span class="hljs-attr">data</span>: action.payload
            };

        <span class="hljs-keyword">default</span>:
            <span class="hljs-keyword">return</span> state;
    }
}
</code></pre>
<p>In this example, we have created a reducer function which is called a <code>gameReducer</code>. It takes in the state (default parameter as a global state) and an action. Whenever we have <code>action.type</code> that matches the switch case, then it performs a particular action, like returning a new state based on the action. </p>
<p>The <code>sagas/index.ts</code> file will consist of all the sagas that we will use in our application. We do have some basic understanding of the sagas which we briefly explained in the above sections. We will dive deeper into this section when we actually start our implementation of the snake game. </p>
<p>Now we have a basic understanding of the artifacts involved in making our Redux store. Let's go ahead and create <code>store/index.ts</code> like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    createStore,
    applyMiddleware
} <span class="hljs-keyword">from</span> <span class="hljs-string">"redux"</span>;
<span class="hljs-keyword">import</span> createSagaMiddleware <span class="hljs-keyword">from</span> <span class="hljs-string">"redux-saga"</span>;
<span class="hljs-keyword">import</span> gameReducer <span class="hljs-keyword">from</span> <span class="hljs-string">"./reducers"</span>;
<span class="hljs-keyword">import</span> watcherSagas <span class="hljs-keyword">from</span> <span class="hljs-string">"./sagas"</span>;
<span class="hljs-keyword">const</span> sagaMiddleware = createSagaMiddleware();

<span class="hljs-keyword">const</span> store = createStore(gameReducer, applyMiddleware(sagaMiddleware));

sagaMiddleware.run(watcherSagas);
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> store;
</code></pre>
<p>We will first import our reducer and the saga. Next we will use the <code>createSagaMiddleware()</code> function to create a saga middleware. </p>
<p>Next, we will connect it to our store by passing it as an argument to the <code>applyMiddleware</code> function inside <code>createStore</code> which you use to create a store. We will also pass <code>gameReducer</code> to this function so that a reducer is mapped to our store.</p>
<p>Finally, we will run our sagaMiddleware using this code:</p>
<pre><code class="lang-javascript">sagaMiddleware.run(watcherSagas);
</code></pre>
<p>Our final step is to inject this <code>store</code> at the top level of our React app using the <code>Provider</code> component provided by <code>react-redux</code>. You can do this as follows:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
    //   Child components...
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>I have also installed chakra-UI as a UI component library for our project. To install chakra-UI, type the below command:</p>
<pre><code class="lang-shell">npm install @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^5
</code></pre>
<p>We also need to setup the <code>ChakraProvider</code> that will go in our <code>App.tsx</code> file. Our updated <code>App.tsx</code> file will look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    //Children components
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h2 id="heading-understanding-ui-layer">Understanding UI layer</h2>
<p>Let's first understand the dynamics of our Snake game from the UI perspective. Before we get started, our final Snake game will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake-game.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The UI Layer consists of 3 layers: <strong>Score Calculator</strong>, <strong>Canvas Board</strong>, and <strong>Instructions</strong>. The below diagram showcases these sections:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/Untitled--3-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Let's dive deeper into each of these sections to understand how our Snake game works.</p>
<h2 id="heading-canvas-board">Canvas Board</h2>
<p>We'll start off by understanding the Canvas Board:</p>
<ul>
<li>Our canvas board is going to be of dimensions <code>height: 600, width: 1000</code></li>
<li>This entire board is divided into blocks of <code>20x20</code> size. That is, every object that is drawn on this board has <code>height 20</code> and <code>width 20</code>.</li>
<li>We are using the <code>&lt;canvas&gt;</code> HTML element to draw the shapes in the canvas board component.</li>
</ul>
<p>In our project, we are writing the canvas board component inside the file <code>components/CanvasBoard.tsx</code>. Now that our basic understanding is clear about the CanvasBoard component, let's start building this component.</p>
<p>Create a simple component that returns a canvas element as below:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<p>Call this component in our <code>App.tsx</code> file with width and height of 1000 and 600 as a prop like below:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> CanvasBoard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/CanvasBoard"</span>;
<span class="hljs-keyword">import</span> ScoreCard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/ScoreCard"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">CanvasBoard</span> <span class="hljs-attr">height</span>=<span class="hljs-string">{600}</span> <span class="hljs-attr">width</span>=<span class="hljs-string">{1000}</span> /&gt;</span> //Canvasboard component added 
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>This will create a simple box of height=600 and width=1000 with a black border like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snakeCanvas1.png" alt="Image" width="600" height="400" loading="lazy">
<em>A blank canvas element with width=1000 and height=600</em></p>
<p>Now let's draw a snake at the center of this canvas. But before we can start drawing, we need to get the context of this <code>canvas</code> element. </p>
<p>The context of a canvas element provides you with all the information you need related to the canvas element. It gives you the dimensions of the canvas and also helps you draw on the canvas. </p>
<p>To get the context of our canvas element we need to call the <code>getCanvas('2d')</code> function which returns the 2d context of the canvas. The return type of this function is <code>CanvasRenderingContext2D</code> interface. </p>
<p>To do this in pure JS we would do something like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> canvas = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">'canvas'</span>);
<span class="hljs-keyword">const</span> canvasCtx = canvas.getContext(<span class="hljs-string">'2d'</span>);
</code></pre>
<p>But to do so in React we need to create a <code>ref</code> and pass it to the canvas element so that we can address it later in different hooks. To do so in our application, create one <code>ref</code> using the <code>useRef</code> hook:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> canvasRef = useRef&lt;HTMLCanvasElement | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
</code></pre>
<p>Pass the ref into our <code>canvas</code> element:</p>
<pre><code class="lang-jsx">&lt;canvas
  ref={canvasRef}
  style={{
    <span class="hljs-attr">border</span>: <span class="hljs-string">"3px solid black"</span>,
  }}
  height={height}
  width={width}
/&gt;;
</code></pre>
<p>Once the <code>canvasRef</code> is passed into the <code>canvas</code> element, we can use it inside a <code>useEffect</code> hook and store the context in a state variable. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> canvasRef = (useRef &lt; HTMLCanvasElement) | (<span class="hljs-literal">null</span> &gt; <span class="hljs-literal">null</span>);
  <span class="hljs-keyword">const</span> [context, setContext] =
    (useState &lt; CanvasRenderingContext2D) | (<span class="hljs-literal">null</span> &gt; <span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Draw on canvas each time</span>
    setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
  }, [context]);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">ref</span>=<span class="hljs-string">{canvasRef}</span>    
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<h2 id="heading-drawing-the-objects">Drawing the objects</h2>
<p>After getting the context we need to do the following tasks each time a component updates:</p>
<ol>
<li>Clear the canvas</li>
<li>Draw the snake with the current position</li>
<li>Draw a fruit at a random position inside the box</li>
</ol>
<p>We are going to clear the canvas multiple times, so we will make this a utility function. So for that, let's create a folder called <code>utilities</code>:</p>
<pre><code class="lang-shell">mkdir utilities
cd utilities
touch index.tsx
</code></pre>
<p>The above command will also create an <code>index.tsx</code> file inside the utilities folder. Add the below code in the <code>utilities/index.tsx</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> clearBoard = <span class="hljs-function">(<span class="hljs-params">context: CanvasRenderingContext2D | <span class="hljs-literal">null</span></span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (context) {
    context.clearRect(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1000</span>, <span class="hljs-number">600</span>);
  }
};
</code></pre>
<p>The <code>clearBoard</code> function is pretty straightforward. It does the following actions:</p>
<ol>
<li>It accepts the 2d canvas context objects as an argument.</li>
<li>It checks that the context is not null or undefined.</li>
<li>The <code>clearRect</code> function will clear all the pixels or objects present inside the rectangle. This function will take width and height as an argument for the rectangle to be cleared.</li>
</ol>
<p>We will use this <code>clearBoard</code> function inside our <code>CanvasBoard</code> useEffect to clear the canvas every time the component is updated. For differentiating between different <code>useEffects</code>, we will name the above useEffect as useEffect1.</p>
<p>Now let's start by drawing the snake and the fruit at a random position. Since we are going to draw the objects multiple times, we'll create a utility function called <code>drawObject</code> for it. Add the below code in the <code>utilities/index.tsx</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> interface IObjectBody {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> drawObject = <span class="hljs-function">(<span class="hljs-params">
  context: CanvasRenderingContext2D | <span class="hljs-literal">null</span>,
  objectBody: IObjectBody[],
  fillColor: string,
  strokeStyle = <span class="hljs-string">"#146356"</span>
</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (context) {
    objectBody.forEach(<span class="hljs-function">(<span class="hljs-params">object: IObjectBody</span>) =&gt;</span> {
      context.fillStyle = fillColor;
      context.strokeStyle = strokeStyle;
      context?.fillRect(object.x, object.y, <span class="hljs-number">20</span>, <span class="hljs-number">20</span>);
      context?.strokeRect(object.x, object.y, <span class="hljs-number">20</span>, <span class="hljs-number">20</span>);
    });
  }
};
</code></pre>
<p>The <code>drawObject</code> function accepts the following arguments:</p>
<ol>
<li><code>context</code> – A 2D canvas context object for drawing the object on the canvas.</li>
<li><code>objectBody</code> – This is an array of objects with each object having <code>x</code> and <code>y</code> properties, like the <code>IObjectBody</code> interface.</li>
<li><code>fillColor</code> – Color to be filled inside the object.</li>
<li><code>strokeStyle</code> – Color to be filled in the outline of the object. Defaults to <code>#146356</code>.</li>
</ol>
<p>This function will check if the context is undefined or null. Then it iterates over the <code>objectBody</code> via forEach. For each object it performs the following operations:</p>
<ol>
<li>It will assign the <code>fillStyle</code> and <code>strokeStyle</code> inside the context.</li>
<li>It will use <code>fillReact</code> to create a filled rectangle with coordinates <code>object.x</code> and <code>object.y</code> with size <code>20x20</code></li>
<li>Finally, it will use <code>strokeRect</code> to create an outlined rectangle with coordinates <code>object.x</code> and <code>object.y</code> with size <code>20x20</code> </li>
</ol>
<p>For drawing the snake we need to maintain the position of the snake. For that, we can use our global state management tool <code>redux</code>.</p>
<p>We need to update our <code>reducers/index.ts</code> file. Since we want to track the position of the snake, we will add it into our global state as follows:</p>
<pre><code class="lang-javascript">interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
  <span class="hljs-comment">//Postion of the entire snake</span>
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
};
</code></pre>
<p>Let's call this state in our <code>CanvasBoard</code> component. We will use the <code>useSelector</code> hook of react-redux to get the required state from the store. The following will give us the <code>snake</code>'s global state:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
</code></pre>
<p>Let's embed this in our <code>CanvasBoard</code> component and pass it to our <code>drawObject</code> function and see the output:</p>
<pre><code class="lang-jsx"><span class="hljs-comment">//Importing necessary modules</span>
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { clearBoard, drawObject, generateRandomPosition } <span class="hljs-keyword">from</span> <span class="hljs-string">"../utils"</span>;

<span class="hljs-keyword">export</span> interface ICanvasBoard {
  <span class="hljs-attr">height</span>: number;
  width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> canvasRef = useRef&lt;HTMLCanvasElement | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [context, setContext] = useState&lt;CanvasRenderingContext2D | <span class="hljs-literal">null</span>&gt;(<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
    <span class="hljs-keyword">const</span> [pos, setPos] = useState&lt;IObjectBody&gt;(
        generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)
      );

    useEffect(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">//Draw on canvas each time</span>
     setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>
        drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws fruit randomly</span>
    }, [context])

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
      <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
        <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
      }}
      <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
    /&gt;</span></span>
  );
};
</code></pre>
<p>Let's see what the output will look like when the snake is drawn: </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake_only.png" alt="Image" width="600" height="400" loading="lazy">
<em>Drawing snake</em></p>
<h2 id="heading-moving-the-snake-across-the-board">Moving the snake across the board</h2>
<p>Now that we have our snake drawn onto the canvas, let's learn how to move the snake across the board. </p>
<p>The movement of the snake is simple. It should always follow the below points:</p>
<ol>
<li>If the snake is moving horizontally, then it can only move up, down, and in the direction it is currently moving. For example, if the snake is moving to the right then it can move up or down or continue moving to the right.</li>
<li>If the snake is moving vertically, then it can only move to the right, left or continue in the direction it's currently moving. For example, if the snake is moving up then it can move right or left (or continue up).</li>
<li>The snake cannot move in the direction opposite to that of the current direction. That is, if the snake is moving to the left then it cannot move to the right straight away. Likewise, if it's going up it cannot move down.</li>
</ol>
<p>For the smooth movement of our snake, the snake should always move in a rectangular fashion. And it needs to meet the above points to have that movement. </p>
<p>The below diagram helps summarise how the movement of the snake works in the entire application:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/temp.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake movement explanation</em></p>
<p><strong>NOTE:</strong> In the above diagram, the entire movement of the snake starts with the <code>CanvasBoard</code> component. </p>
<p><strong>HINT:</strong> Don't worry if you cannot follow the above diagram. Just read the later sections to get more clarity.</p>
<p>To maintain the movement of the snake, we will introduce another state variable to our global state called <code>disallowedDirection</code>. The purpose of this variable is to keep track of the opposite direction of the snake's movement. </p>
<p>For example if the snake is moving left then the <code>disallowedDirection</code> will be set to right. So to summarise, we are tracking this direction so that we can avoid the snake moving in its opposite direction.</p>
<p>Let's create this variable in our global state:</p>
<pre><code class="lang-javascript">interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}

<span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
  disallowedDirection: string;
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
    <span class="hljs-comment">//Postion of the entire snake</span>
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
    <span class="hljs-attr">disallowedDirection</span>: <span class="hljs-string">""</span>
};
</code></pre>
<p>Now let's create some actions and action creators that will help us move the snake. </p>
<p>We will have two types of actions for this case:</p>
<ul>
<li>Actions for sagas<ul>
<li>These are the actions that will be dispatched from the <code>CanvasBoard</code> component. These actions will be:<ul>
<li>MOVE_RIGHT</li>
<li>MOVE_LEFT</li>
<li>MOVE_UP</li>
<li>MOVE_DOWN</li>
</ul>
</li>
</ul>
</li>
<li>Actions for reducers<ul>
<li>These are the actions that will be yielded by the saga to propagate the calls to the reducers. These actions will be:<ul>
<li>RIGHT</li>
<li>LEFT</li>
<li>UP</li>
<li>DOWN</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>We will take a closer look at these actions in the coming sections.</p>
<p>We will be creating one more action called <code>SET_DIS_DIRECTION</code> to set the <code>disallowedDirection</code> state.</p>
<p>Let's create some action creators for the movement of the snake:</p>
<ul>
<li><code>setDisDirection</code> – This action creator will be used to set the <code>disallowedDirection</code> via the <code>SET_DIS_DIRECTION</code> action. Below is the code for this action creator:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setDisDirection = <span class="hljs-function">(<span class="hljs-params">direction: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: SET_DIS_DIRECTION,
  <span class="hljs-attr">payload</span>: direction
});
</code></pre>
<ul>
<li><code>makeMove</code> – This will be used to set/update the new coordinates of the snake by updating the <code>snake</code> state variable. Below is the code for this action creator:</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> makeMove = <span class="hljs-function">(<span class="hljs-params">dx: number, dy: number, move: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: move,
  <span class="hljs-attr">payload</span>: [dx, dy]
});
</code></pre>
<p>The parameters <code>dx</code> and <code>dy</code> are the deltas. They tell the Redux store by how much we should increase/decrease the coordinates of each snake block to move the snake in the given direction. </p>
<p>The <code>move</code> parameter is used to specify in which direction will the snake be moving. We will have a look at these actions creators soon in the coming sections.</p>
<p>Finally, our updated <code>actions/index.ts</code> file will look something like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_RIGHT = <span class="hljs-string">"MOVE_RIGHT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_LEFT = <span class="hljs-string">"MOVE_LEFT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_UP = <span class="hljs-string">"MOVE_UP"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> MOVE_DOWN = <span class="hljs-string">"MOVE_DOWN"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RIGHT = <span class="hljs-string">"RIGHT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> LEFT = <span class="hljs-string">"LEFT"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> UP = <span class="hljs-string">"UP"</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> DOWN = <span class="hljs-string">"DOWN"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> SET_DIS_DIRECTION = <span class="hljs-string">"SET_DIS_DIRECTION"</span>;

<span class="hljs-keyword">export</span> interface ISnakeCoord {
  <span class="hljs-attr">x</span>: number;
  y: number;
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> makeMove = <span class="hljs-function">(<span class="hljs-params">dx: number, dy: number, move: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: move,
  <span class="hljs-attr">payload</span>: [dx, dy]
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> setDisDirection = <span class="hljs-function">(<span class="hljs-params">direction: string</span>) =&gt;</span> ({
  <span class="hljs-attr">type</span>: SET_DIS_DIRECTION,
  <span class="hljs-attr">payload</span>: direction
});
</code></pre>
<p>Now, let's have a look at the logic we are using to move the snake based on the above actions. All the snake movement will be tracked by the following actions:</p>
<ul>
<li>RIGHT</li>
<li>LEFT</li>
<li>UP</li>
<li>DOWN</li>
</ul>
<p>All these actions are the building blocks of the snake's movement. These actions, when dispatched, will always update the <code>snake</code>'s global state based on the logic we are describing below. And they will calculate new coordinates of the snake on each movement.</p>
<p>To calculate the new coordinates of the snake after each movement, we will use the following logic:</p>
<ol>
<li>Copy the coordinates into a new variable called <code>newSnake</code></li>
<li>Add at the start of the <code>newSnake</code> the new x and y coordinates. These x and y attributes of these coordinates are updated by adding the x and y values from the action's payload.</li>
<li>Finally, remove the last entry from the <code>newSnake</code> array.</li>
</ol>
<p>Now that we have some understanding of how the snake is moving, let's add the following cases in our <code>gameReducer</code>:</p>
<pre><code class="lang-javascript">    <span class="hljs-keyword">case</span> RIGHT:
    <span class="hljs-keyword">case</span> LEFT:
    <span class="hljs-keyword">case</span> UP:
    <span class="hljs-keyword">case</span> DOWN: {
      <span class="hljs-keyword">let</span> newSnake = [...state.snake];
      newSnake = [{
        <span class="hljs-comment">//New x and y coordinates</span>
        <span class="hljs-attr">x</span>: state.snake[<span class="hljs-number">0</span>].x + action.payload[<span class="hljs-number">0</span>],
        <span class="hljs-attr">y</span>: state.snake[<span class="hljs-number">0</span>].y + action.payload[<span class="hljs-number">1</span>],
      }, ...newSnake];
      newSnake.pop();

      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">snake</span>: newSnake,
      };
    }
</code></pre>
<p>For every movement of the snake, we update the new x and y coordinates which are increased by payloads <code>action.payload[0]</code> and <code>action.payload[1]</code>. We successfully completed setting up the actions, actions creators, and the reducer logic. </p>
<p>We are good to go and can now use all of this in our <code>CanvasBoard</code> component.</p>
<p>First, let's add a useEffect hook in our <code>CanvasBoard</code> component. We will use this hook to attach/add an event handler. This event handler will be attached to the event <code>keypress</code>. We are using this event because whenever we press the <code>w</code> <code>a</code> <code>s</code> <code>d</code> keys we should be able to control the movement of the snake. </p>
<p>Our useEffect will look something like below:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    };
  }, [disallowedDirection, handleKeyEvents]);
</code></pre>
<p>It works in the following manner:</p>
<ol>
<li>On the mounting of the component, the event listener with callback function <code>handleKeyEvents</code> is attached to the window object.</li>
<li>On the unmounting of the component, the event listener is removed from the window object.</li>
<li>If there is any change in the direction or <code>handleKeyEvents</code> function, we will re-run this useEffect. Therefore, we have added <code>disallowedDirection</code> and <code>handleKeyEvents</code> into the dependency array.</li>
</ol>
<p>Let's have a look at how the <code>handleKeyEvents</code> callback is created. Below is the code for the same:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> handleKeyEvents = useCallback(
    <span class="hljs-function">(<span class="hljs-params">event: KeyboardEvent</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (disallowedDirection) {
        <span class="hljs-keyword">switch</span> (event.key) {
          <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>:
            moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">-20</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>:
            moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>:
            moveSnake(<span class="hljs-number">-20</span>, <span class="hljs-number">0</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
          <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>:
            event.preventDefault();
            moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection);
            <span class="hljs-keyword">break</span>;
        }
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">if</span> (
          disallowedDirection !== <span class="hljs-string">"LEFT"</span> &amp;&amp;
          disallowedDirection !== <span class="hljs-string">"UP"</span> &amp;&amp;
          disallowedDirection !== <span class="hljs-string">"DOWN"</span> &amp;&amp;
          event.key === <span class="hljs-string">"d"</span>
        )
          moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection); <span class="hljs-comment">//Move RIGHT at start</span>
      }
    },
    [disallowedDirection, moveSnake]
  );
</code></pre>
<p>We have wrapped this function with a <code>useCallback</code> hook. This is because we want the memoized version of this function which is called on every state change (that is, on the change of <code>disallowedDirection</code> and <code>moveSnake</code>).  This function is called on every key pressed on the keyboard. </p>
<p>This event handler callback function serves the following purpose:</p>
<ul>
<li>If the <code>disallowedDirection</code> is empty then we make sure that the game will start only when the user presses the <code>d</code> key. This means that the game starts only when the snake moves to the right. </li>
</ul>
<p><strong>NOTE</strong>: Initially the global state variable <code>disallowedDirection</code> value is an empty string. In this way, we know that if its value is empty then it's the start of the game.</p>
<p>Once the game starts, the <code>disallowedDirection</code> won’t be empty and then it listens to all the keyboard presses such as <code>w</code> <code>s</code> and <code>a</code>.</p>
<p>Finally, on every keypress, we are calling the function called <code>moveSnake</code>. We will take a closer look into it in the next section.</p>
<p>The <code>moveSnake</code> function is a function that dispatches an action passed to the <code>makeMove</code> action creator. This function accepts three arguments:</p>
<ol>
<li><strong>dx</strong> - <strong>Delta for x-axis</strong>. This tells by how much the snake should move along the x-axis. If <code>dx</code> is positive then it moves to the right, if it's negative it moves to the left.</li>
<li><strong>dy - Delta for the y-axis</strong>. This tells by how much the snake should move along the y-axis. If <code>dy</code> is positive then it moves down, if it's negative it moves up.</li>
<li><strong>disallowedDirection -</strong> This value tells that the snake should not move in the opposite direction. This is an action that is captured by our middleware saga.</li>
</ol>
<p>The code for the <code>moveSnake</code> function will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> moveSnake = useCallback(
    <span class="hljs-function">(<span class="hljs-params">dx = <span class="hljs-number">0</span>, dy = <span class="hljs-number">0</span>, ds: string</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (dx &gt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"RIGHT"</span>) {
        dispatch(makeMove(dx, dy, MOVE_RIGHT));
      }

      <span class="hljs-keyword">if</span> (dx &lt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"LEFT"</span>) {
        dispatch(makeMove(dx, dy, MOVE_LEFT));
      }

      <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &lt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"UP"</span>) {
        dispatch(makeMove(dx, dy, MOVE_UP));
      }

      <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &gt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"DOWN"</span>) {
        dispatch(makeMove(dx, dy, MOVE_DOWN));
      }
    },
    [dispatch]
  );
</code></pre>
<p>The <code>moveSnake</code> is a simple function that checks for the conditions:</p>
<ol>
<li>If dx &gt; 0, and the <code>disallowedDirection</code> is not <code>RIGHT</code>, then it can move in the RIGHT direction.</li>
<li>If dx &lt; 0, and the <code>disallowedDirection</code> is not <code>LEFT</code>, then it can move in the LEFT direction.</li>
<li>If dy &gt; 0, and the <code>disallowedDirection</code> is not <code>DOWN</code>, then it can move in the DOWN direction.</li>
<li>If dy &lt; 0, and the <code>disallowedDirection</code> is not <code>UP</code>, then it can move in the UP direction.</li>
</ol>
<p>This <code>disallowedDirection</code> value is set in our sagas which we'll talk about more in the later sections of this article. If we revisit the <code>handleKeyEvents</code> function now it makes much more sense. Let's walk through an example over here:</p>
<ul>
<li>Suppose you want to move the snake to the RIGHT. Then this function will detect that the <code>d</code> key is pressed.</li>
<li>Once this key is pressed it calls the <code>makeMove</code> function (Game start condition) with <code>dx</code> as 20 (+ve), <code>dy</code> as 0, and the previously set <code>disallowedDirection</code> previously is called over here.</li>
</ul>
<p>In this way, we make the movement of the snake in a particular direction. Now let's have a look at the <code>sagas</code> that we have used, and how they handle the movement of the snake.  </p>
<p>Let's create a file called <code>saga/index.ts</code>. This file will consist of all our sagas. This is not a rule, but in general, we create two sagas. </p>
<p>The first one is the saga which dispatches the actual actions to the store – let's call this <em>worker saga</em>. The second is the watcher saga which watches for any action that is being dispatched – let's call this <em>watcher saga</em>.</p>
<p>Now we need to create a watcher saga that will look out for the following actions: <code>MOVE_RIGHT</code>, <code>MOVE_LEFT</code>, <code>MOVE_UP</code>, <code>MOVE_DOWN</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSaga</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeLatest(
      [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN],
      moveSaga
    ); 
}
</code></pre>
<p>This watcher saga will watch for the actions above and execute the <code>moveSaga</code> function which is a worker saga. </p>
<p>You will notice that we have used a new function named <code>takeLatest</code>. This function will call the worker saga and cancel any previous saga calls if any of the actions mentioned in the first argument are dispatched.</p>
<p>From the words of the redux-saga <a target="_blank" href="https://redux-saga.js.org/docs/api/#takelatestpattern-saga-args">docs</a>:</p>
<blockquote>
<p><code>takeLatest(pattern, saga, ...args)</code><a target="_blank" href="https://redux-saga.js.org/docs/api/#takelatestpattern-saga-args"></a></p>
<p>Forks a <code>saga</code> on each action dispatched to the Store that matches <code>pattern</code>. And automatically cancels any previous <code>saga</code> task started previously if it's still running.</p>
<ul>
<li>Each time an action is dispatched to the store. And if this action matches <code>pattern</code>, <code>takeLatest</code> starts a new <code>saga</code> task in the background. If a <code>saga</code> task was started previously (on the last action dispatched before the actual action), and if this task is still running, the task will be cancelled.</li>
<li><code>pattern: String | Array | Function</code> - for more information see docs for <code>[take(pattern)](https://redux-saga.js.org/docs/api/#takepattern)</code></li>
<li><code>saga: Function</code> - a Generator function</li>
<li><code>args: Array&lt;any&gt;</code> - arguments to be passed to the started task. <code>takeLatest</code> will add the incoming action to the argument list (i.e. the action will be the last argument provided to <code>saga</code>)</li>
</ul>
</blockquote>
<p>Now let's create a worker saga called <code>moveSaga</code> which will actually dispatch the actions to the Redux store:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
    type: string;
    payload: ISnakeCoord;
  }</span>): <span class="hljs-title">Generator</span>&lt;
    | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
    | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
    | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
  &gt; {
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
    <span class="hljs-comment">//dispatches movement actions</span>
     <span class="hljs-keyword">yield</span> put({
           <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
           <span class="hljs-attr">payload</span>: params.payload,
      }); 

      <span class="hljs-comment">//Dispatches SET_DIS_DIRECTION action</span>
      <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
        <span class="hljs-keyword">case</span> RIGHT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> LEFT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> UP:
          <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> DOWN:
          <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
          <span class="hljs-keyword">break</span>;
      }
      <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
    }
  }
</code></pre>
<p>The <code>moveSaga</code> worker saga performs the following functions:</p>
<ol>
<li>It executes inside an infinite loop. </li>
<li>So once a direction is given – that is if the <code>d</code> key is pressed and <code>MOVE_RIGHT</code> action is dispatched – then it starts dispatching the same action until a new action (that is, direction) is given. This is handled by the below snippet:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">yield</span> put({
    <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
    <span class="hljs-attr">payload</span>: params.payload,
});
</code></pre>
<ol start="3">
<li>Once the above action is dispatched we set the disallowed direction to the opposite direction which is taken care of by the action creator <code>setDisDirection</code>.</li>
</ol>
<p>Now let's stitch these sagas into our <code>sagas/index.ts</code> file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> {
    CallEffect,
    delay,
    put,
    PutEffect,
    takeLatest
} <span class="hljs-keyword">from</span> <span class="hljs-string">"redux-saga/effects"</span>;
<span class="hljs-keyword">import</span> {
    DOWN,
    ISnakeCoord,
    LEFT,
    MOVE_DOWN,
    MOVE_LEFT,
    MOVE_RIGHT,
    MOVE_UP, RIGHT,
    setDisDirection, UP
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../actions"</span>;

  <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
    type: string;
    payload: ISnakeCoord;
  }</span>): <span class="hljs-title">Generator</span>&lt;
    | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
    | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
    | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
  &gt; {
    <span class="hljs-keyword">while</span> (<span class="hljs-literal">true</span>) {
      <span class="hljs-keyword">yield</span> put({
        <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
        <span class="hljs-attr">payload</span>: params.payload,
      });
      <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
        <span class="hljs-keyword">case</span> RIGHT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> LEFT:
          <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> UP:
          <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
          <span class="hljs-keyword">break</span>;

        <span class="hljs-keyword">case</span> DOWN:
          <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
          <span class="hljs-keyword">break</span>;
      }
      <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
    }
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">yield</span> takeLatest(
      [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN],
      moveSaga
    );
  }

  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> watcherSagas;
</code></pre>
<p>Now let's update our <code>CanvasBoard</code> component to incorporate these changes.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">//Importing necessary modules</span>
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { drawObject, generateRandomPosition } <span class="hljs-keyword">from</span> <span class="hljs-string">"../utils"</span>;

<span class="hljs-keyword">export</span> interface ICanvasBoard {
    <span class="hljs-attr">height</span>: number;
    width: number;
}

<span class="hljs-keyword">const</span> CanvasBoard = <span class="hljs-function">(<span class="hljs-params">{ height, width }: ICanvasBoard</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> canvasRef = useRef &lt; HTMLCanvasElement | <span class="hljs-literal">null</span> &gt; (<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> [context, setContext] = useState &lt; CanvasRenderingContext2D | <span class="hljs-literal">null</span> &gt; (<span class="hljs-literal">null</span>);
    <span class="hljs-keyword">const</span> snake1 = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.snake);
    <span class="hljs-keyword">const</span> [pos, setPos] = useState &lt; IObjectBody &gt; (
        generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)
    );

    <span class="hljs-keyword">const</span> moveSnake = useCallback(
        <span class="hljs-function">(<span class="hljs-params">dx = <span class="hljs-number">0</span>, dy = <span class="hljs-number">0</span>, ds: string</span>) =&gt;</span> {
            <span class="hljs-keyword">if</span> (dx &gt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"RIGHT"</span>) {
                dispatch(makeMove(dx, dy, MOVE_RIGHT));
            }

            <span class="hljs-keyword">if</span> (dx &lt; <span class="hljs-number">0</span> &amp;&amp; dy === <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"LEFT"</span>) {
                dispatch(makeMove(dx, dy, MOVE_LEFT));
            }

            <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &lt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"UP"</span>) {
                dispatch(makeMove(dx, dy, MOVE_UP));
            }

            <span class="hljs-keyword">if</span> (dx === <span class="hljs-number">0</span> &amp;&amp; dy &gt; <span class="hljs-number">0</span> &amp;&amp; ds !== <span class="hljs-string">"DOWN"</span>) {
                dispatch(makeMove(dx, dy, MOVE_DOWN));
            }
        },
        [dispatch]
    );

    <span class="hljs-keyword">const</span> handleKeyEvents = useCallback(
        <span class="hljs-function">(<span class="hljs-params">event: KeyboardEvent</span>) =&gt;</span> {
            <span class="hljs-keyword">if</span> (disallowedDirection) {
                <span class="hljs-keyword">switch</span> (event.key) {
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"w"</span>:
                        moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">-20</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"s"</span>:
                        moveSnake(<span class="hljs-number">0</span>, <span class="hljs-number">20</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"a"</span>:
                        moveSnake(<span class="hljs-number">-20</span>, <span class="hljs-number">0</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                    <span class="hljs-keyword">case</span> <span class="hljs-string">"d"</span>:
                        event.preventDefault();
                        moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection);
                        <span class="hljs-keyword">break</span>;
                }
            } <span class="hljs-keyword">else</span> {
                <span class="hljs-keyword">if</span> (
                    disallowedDirection !== <span class="hljs-string">"LEFT"</span> &amp;&amp;
                    disallowedDirection !== <span class="hljs-string">"UP"</span> &amp;&amp;
                    disallowedDirection !== <span class="hljs-string">"DOWN"</span> &amp;&amp;
                    event.key === <span class="hljs-string">"d"</span>
                )
                    moveSnake(<span class="hljs-number">20</span>, <span class="hljs-number">0</span>, disallowedDirection); <span class="hljs-comment">//Move RIGHT at start</span>
            }
        },
        [disallowedDirection, moveSnake]
    );
    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">//Draw on canvas each time</span>
        setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>
                    clearBoard(context);
        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>
    }, [context]);

    useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);

        <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> {
            <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
        };
    }, [disallowedDirection, handleKeyEvents]);

    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
            <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
                <span class="hljs-attr">border:</span> "<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> <span class="hljs-attr">black</span>",
            }}
            <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
            <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
        /&gt;</span></span>
    );
};
</code></pre>
<p>Once you've made these changes you can try moving the snake. And voilà! You will see the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--3-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Moving snake across the board</em></p>
<h2 id="heading-drawing-the-fruit-at-a-random-position">Drawing the fruit at a random position</h2>
<p>To draw a fruit at a random position on the board we will use the <code>generateRandomPosition</code> utility function. Let's have a look at this function:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">randomNumber</span>(<span class="hljs-params">min: number, max: number</span>) </span>{
  <span class="hljs-keyword">let</span> random = <span class="hljs-built_in">Math</span>.random() * max;
  <span class="hljs-keyword">return</span> random - (random % <span class="hljs-number">20</span>);
}
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> generateRandomPosition = <span class="hljs-function">(<span class="hljs-params">width: number, height: number</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">x</span>: randomNumber(<span class="hljs-number">0</span>, width),
    <span class="hljs-attr">y</span>: randomNumber(<span class="hljs-number">0</span>, height),
  };
};
</code></pre>
<p>This is a function that will generate random x and y coordinates in multiples of 20. These coordinates will always be less than the width and height of the board. It accepts <code>width</code> and <code>height</code> as arguments. </p>
<p>Once we have this function we can use it to draw the fruit at a random position inside the board. </p>
<p>First, let's create a state variable <code>pos</code> that will initially consist of some random position.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [pos, setPos] = useState&lt;IObjectBody&gt;(generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>));
</code></pre>
<p>Then, we will draw the fruit via our <code>drawObject</code> function. After this we will slightly update our <code>useEffect</code> hook:</p>
<pre><code class="lang-javascript"> useEffect(<span class="hljs-function">() =&gt;</span> {
        <span class="hljs-comment">//Draw on canvas each time</span>
        setContext(canvasRef.current &amp;&amp;   canvasRef.current.getContext(<span class="hljs-string">"2d"</span>)); <span class="hljs-comment">//store in state variable</span>

        clearBoard(context);

        drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>); <span class="hljs-comment">//Draws snake at the required position</span>

        drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws object randomly</span>
    }, [context]);
</code></pre>
<p>Once we have made the changes our board will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/snake_fruit.png" alt="Image" width="600" height="400" loading="lazy">
<em>Snake and fruit drawn on the board</em></p>
<h2 id="heading-score-calculator">Score calculator</h2>
<p>The game score is calculated based on how many fruits the snake has consumed without colliding with itself or with the boundary of the box. If the snake consumes the fruit then the size of the snake increases. If it collides with the edge of the box, then the game is over.  </p>
<p>Now that we know what our criteria are for calculating the score, let's have a look on how we calculate the reward.</p>
<h3 id="heading-calculating-the-reward">Calculating the reward</h3>
<p>The reward after the snake consumes the fruit is as follows:</p>
<ol>
<li>Increase the size of the snake.</li>
<li>Increase the score.</li>
<li>Place the new fruit at a different random location.</li>
</ol>
<p>If the snake consumes the fruit, then we must increase the size of the snake. This is a really simple task, we can just append the new x and y coordinates which are less than 20 from the last element of the <code>snake</code> global state array. For example, if the snake has the following coordinates:</p>
<pre><code class="lang-javascript">{
<span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
}
</code></pre>
<p>We should simply append the following object into the snake array: <code>{ x: 480, y: 280 }</code></p>
<p>In this way, we increase the size of the snake as well as add the new part/block at the end of it. For this to be implemented via Redux and redux-saga, we will need the following action and action creator:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT_SCORE = <span class="hljs-string">"INCREMENT_SCORE"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> increaseSnake = <span class="hljs-function">() =&gt;</span> ({  <span class="hljs-comment">//action creator</span>
    <span class="hljs-attr">type</span>: INCREASE_SNAKE
  });
</code></pre>
<p>We will also update our <code>gameReducer</code> to accommodate these changes. We will add the following case:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> INCREASE_SNAKE:
      <span class="hljs-keyword">const</span> snakeLen = state.snake.length;
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">snake</span>: [
          ...state.snake,
          {
            <span class="hljs-attr">x</span>: state.snake[snakeLen - <span class="hljs-number">1</span>].x - <span class="hljs-number">20</span>,
            <span class="hljs-attr">y</span>: state.snake[snakeLen - <span class="hljs-number">1</span>].y - <span class="hljs-number">20</span>,
          },
        ],
      };
</code></pre>
<p>In our <code>CanvasBoard</code> component, we will first introduce a state variable called <code>isConsumed</code>. This variable will check if the fruit is consumed or not.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> [isConsumed, setIsConsumed] = useState&lt;boolean&gt;(<span class="hljs-literal">false</span>);
</code></pre>
<p>In our <code>useEffect</code> hook where we are drawing our <code>snake</code> and the <code>fruit</code> just below that, we will add the following condition:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//When the object is consumed</span>
    <span class="hljs-keyword">if</span> (snake1[<span class="hljs-number">0</span>].x === pos?.x &amp;&amp; snake1[<span class="hljs-number">0</span>].y === pos?.y) {
      setIsConsumed(<span class="hljs-literal">true</span>);
    }
</code></pre>
<p>The above condition will check if the head of the snake <code>snake[0]</code> is equal to the <code>pos</code>, or the position of the fruit. If it is true, then it will set the <code>isConsumed</code> state variable to true.</p>
<p>Once the fruit is consumed, we need to increase the size of the snake. We can do this easily via another <code>useEffect</code>. Let's create another <code>useEffect</code> and call the action creator <code>increaseSnake</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//useEffect2</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());
    }
  }, [isConsumed]);
</code></pre>
<p>Now that we have increased the size of the snake, let's take a look at how we can update the score and generate a new fruit at another random position.</p>
<p>To generate a new fruit at another random position, we update the <code>pos</code> state variable which will re-run the useEffect1 and draw the object at <code>pos</code>. We should update our useEffect1 with a new dependency of <code>pos</code> and update useEffect2 as follows:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Generate new object</span>
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-keyword">const</span> posi = generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>);
      setPos(posi);
      setIsConsumed(<span class="hljs-literal">false</span>);

      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());
    }
  }, [isConsumed, pos, height, width, dispatch]);
</code></pre>
<p>One last thing left to do in this reward system is to update the score each time the snake eats the fruit. To do this follow the below steps:</p>
<ol>
<li>Introduce a new global state variable called <code>score</code>. Update our global state as below in the <code>reducers/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> interface IGlobalState {
  <span class="hljs-attr">snake</span>: ISnakeCoord[] | [];
  disallowedDirection: string;
  score: number;
}

<span class="hljs-keyword">const</span> globalState: IGlobalState = {
  <span class="hljs-attr">snake</span>: [
    { <span class="hljs-attr">x</span>: <span class="hljs-number">580</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">560</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">540</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">520</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
    { <span class="hljs-attr">x</span>: <span class="hljs-number">500</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">300</span> },
  ],
  <span class="hljs-attr">disallowedDirection</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">score</span>: <span class="hljs-number">0</span>,
};
</code></pre>
<ol start="2">
<li>Create the following action and action creator in our <code>actions/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> INCREMENT_SCORE = <span class="hljs-string">"INCREMENT_SCORE"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//action creator:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> scoreUpdates = <span class="hljs-function">(<span class="hljs-params">type: string</span>) =&gt;</span> ({
  type
});
</code></pre>
<ol start="3">
<li>Next, update our reducer to handle the <code>INCREMENT_SCORE</code> action. This will simply increment the global state <code>score</code> by one.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> INCREMENT_SCORE:
      <span class="hljs-keyword">return</span> {
        ...state,
        <span class="hljs-attr">score</span>: state.score + <span class="hljs-number">1</span>,
      };
</code></pre>
<ol start="4">
<li>Then we update our score state, dispatching the <code>INCREMENT_SCORE</code> action each time snake catches the fruit. For this we can update our useEffect2 as follows:</li>
</ol>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Generate new object</span>
    <span class="hljs-keyword">if</span> (isConsumed) {
      <span class="hljs-keyword">const</span> posi = generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>);
      setPos(posi);
      setIsConsumed(<span class="hljs-literal">false</span>);

      <span class="hljs-comment">//Increase snake size when object is consumed successfully</span>
      dispatch(increaseSnake());

      <span class="hljs-comment">//Increment the score</span>
      dispatch(scoreUpdates(INCREMENT_SCORE));
    }
  }, [isConsumed, pos, height, width, dispatch]);
</code></pre>
<ol start="5">
<li>Finally, we create a component called <code>ScoreCard</code>. This will display the player’s current score. We will store this in the file <code>components/ScoreCard.tsx</code>.</li>
</ol>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { useSelector } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> { IGlobalState } <span class="hljs-keyword">from</span> <span class="hljs-string">"../store/reducers"</span>;

<span class="hljs-keyword">const</span> ScoreCard = <span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> score = useSelector(<span class="hljs-function">(<span class="hljs-params">state: IGlobalState</span>) =&gt;</span> state.score);
    <span class="hljs-keyword">return</span> (
        <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h2"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"md"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{5}</span> <span class="hljs-attr">mb</span>=<span class="hljs-string">{5}</span>&gt;</span>Current Score: {score}<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span></span>
    );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> ScoreCard;
</code></pre>
<p>After this we should also add the <code>ScoreCard</code> component into the <code>App.tsx</code> file to display it on our page. </p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { ChakraProvider, Container, Heading } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;
<span class="hljs-keyword">import</span> { Provider } <span class="hljs-keyword">from</span> <span class="hljs-string">"react-redux"</span>;
<span class="hljs-keyword">import</span> CanvasBoard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/CanvasBoard"</span>;
<span class="hljs-keyword">import</span> ScoreCard <span class="hljs-keyword">from</span> <span class="hljs-string">"./components/ScoreCard"</span>;
<span class="hljs-keyword">import</span> store <span class="hljs-keyword">from</span> <span class="hljs-string">"./store"</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Provider</span> <span class="hljs-attr">store</span>=<span class="hljs-string">{store}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ChakraProvider</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Container</span> <span class="hljs-attr">maxW</span>=<span class="hljs-string">"container.lg"</span> <span class="hljs-attr">centerContent</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h1"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"xl"</span>&gt;</span>SNAKE GAME<span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">ScoreCard</span> /&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">CanvasBoard</span> <span class="hljs-attr">height</span>=<span class="hljs-string">{600}</span> <span class="hljs-attr">width</span>=<span class="hljs-string">{1000}</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Container</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ChakraProvider</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Provider</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>Once everything is in place, our snake will have a complete reward system that increases the size of the snake to update the score.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--4-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Player playing snake with updating score and snake length.</em></p>
<h3 id="heading-collision-detection">Collision detection</h3>
<p>In this section, we are going to take a look at how we implement collision detection for our Snake game.</p>
<p>In our Snake game, if a collision is detected, then the game is over – that is, the game stops. There are two conditions for collisions to happen:</p>
<ol>
<li>Snake collides with the boundaries of the box, or</li>
<li>Snake collides with itself.</li>
</ol>
<p>Let's take a look at the first condition. Suppose the head of the snake touches the boundaries of the box. In that case we will immediately stop the game. </p>
<p>For this to be incorporated into our game we will need to do as follows:</p>
<ol>
<li>Create an action and an action creator as below:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> STOP_GAME = <span class="hljs-string">"STOP_GAME"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//action creator</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> stopGame = <span class="hljs-function">() =&gt;</span> ({
  <span class="hljs-attr">type</span>: STOP_GAME
});
</code></pre>
<ol start="2">
<li>We need to update our <code>sagas/index.ts</code> file as well. We are going to make sure that saga stops dispatching actions once the <code>STOP_GAME</code> action is encountered.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
  type: string;
  payload: ISnakeCoord;
}</span>): <span class="hljs-title">Generator</span>&lt;
  | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
  | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
  | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
&gt; {
  <span class="hljs-keyword">while</span> (params.type !== STOP_GAME) {
    <span class="hljs-keyword">yield</span> put({
      <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
      <span class="hljs-attr">payload</span>: params.payload,
    });
    <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
      <span class="hljs-keyword">case</span> RIGHT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> LEFT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> UP:
        <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> DOWN:
        <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">yield</span> takeLatest(
    [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN, STOP_GAME],
    moveSaga
  );
}
</code></pre>
<ol start="3">
<li>Finally we need to update our useEffect1 by adding the following condition:</li>
</ol>
<pre><code class="lang-jsx"><span class="hljs-keyword">if</span> ( <span class="hljs-comment">//Checks if the snake head is out of the boundries of the obox</span>
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    }
</code></pre>
<p>We are also removing the event listener <code>handleKeyEvents</code>. This will make sure that once the game is over the player cannot move the snake.</p>
<p>Finally, let's have a look at how we can detect the self-collision of the snake. We are going to use a utility function called <code>hasSnakeCollided</code>. It accepts two parameters: the first is the snake array, and the second is the head of the snake. If the head of the snake touches any parts of itself then it returns true or else it returns false.</p>
<p>The <code>hasSnakeCollided</code> function will look like below:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> hasSnakeCollided = <span class="hljs-function">(<span class="hljs-params">
  snake: IObjectBody[],
  currentHeadPos: IObjectBody
</span>) =&gt;</span> {
  <span class="hljs-keyword">let</span> flag = <span class="hljs-literal">false</span>;
  snake.forEach(<span class="hljs-function">(<span class="hljs-params">pos: IObjectBody, index: number</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (
      pos.x === currentHeadPos.x &amp;&amp;
      pos.y === currentHeadPos.y &amp;&amp;
      index !== <span class="hljs-number">0</span>
    ) {
      flag = <span class="hljs-literal">true</span>;
    }
  });

  <span class="hljs-keyword">return</span> flag;
};
</code></pre>
<p>We might slightly need to update our useEffect1 by updating the collision detection condition like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (  
      <span class="hljs-comment">//Checks if the snake has collided with itself </span>
      hasSnakeCollided(snake1, snake1[<span class="hljs-number">0</span>]) ||

      <span class="hljs-comment">//Checks if the snake head is out of the boundries of the obox</span>
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    }
</code></pre>
<p>Our useEffect1 will finally look like below:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//useEffect1</span>
useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">//Draw on canvas each time</span>
    setContext(canvasRef.current &amp;&amp; canvasRef.current.getContext(<span class="hljs-string">"2d"</span>));
    clearBoard(context);
    drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>);
    drawObject(context, [pos], <span class="hljs-string">"#676FA3"</span>); <span class="hljs-comment">//Draws object randomly</span>

    <span class="hljs-comment">//When the object is consumed</span>
    <span class="hljs-keyword">if</span> (snake1[<span class="hljs-number">0</span>].x === pos?.x &amp;&amp; snake1[<span class="hljs-number">0</span>].y === pos?.y) {
      setIsConsumed(<span class="hljs-literal">true</span>);
    }

    <span class="hljs-keyword">if</span> (
      hasSnakeCollided(snake1, snake1[<span class="hljs-number">0</span>]) ||
      snake1[<span class="hljs-number">0</span>].x &gt;= width ||
      snake1[<span class="hljs-number">0</span>].x &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &lt;= <span class="hljs-number">0</span> ||
      snake1[<span class="hljs-number">0</span>].y &gt;= height
    ) {
      setGameEnded(<span class="hljs-literal">true</span>);
      dispatch(stopGame());
      <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    } <span class="hljs-keyword">else</span> setGameEnded(<span class="hljs-literal">false</span>);
  }, [context, pos, snake1, height, width, dispatch, handleKeyEvents]);
</code></pre>
<p>Our game will look like below once we add the collision detection system:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--5-.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Collision detection</em></p>
<h2 id="heading-instruction-component">Instruction component</h2>
<p>We are in the end game now! Our final component will be the <code>Instruction</code> component. It will consist of instructions about the game like initial game condition, keys to use, and a reset button. </p>
<p>Let's start by creating a file called <code>components/Instructions.tsx</code>. Place the below code in this file:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> { Box, Button, Flex, Heading, Kbd } <span class="hljs-keyword">from</span> <span class="hljs-string">"@chakra-ui/react"</span>;

<span class="hljs-keyword">export</span> interface IInstructionProps {
  <span class="hljs-attr">resetBoard</span>: <span class="hljs-function">() =&gt;</span> <span class="hljs-keyword">void</span>;
}
<span class="hljs-keyword">const</span> Instruction = <span class="hljs-function">(<span class="hljs-params">{ resetBoard }: IInstructionProps</span>) =&gt;</span> (
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Box</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{3}</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h6"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"lg"</span>&gt;</span>
      How to Play
    <span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Heading</span> <span class="hljs-attr">as</span>=<span class="hljs-string">"h5"</span> <span class="hljs-attr">size</span>=<span class="hljs-string">"sm"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{1}</span>&gt;</span>
    NOTE: Start the game by pressing <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>d<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Heading</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">"row"</span> <span class="hljs-attr">mt</span>=<span class="hljs-string">{3}</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">{</span>"<span class="hljs-attr">column</span>"}&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>w<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Up
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>a<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Left
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>s<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Down
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">Kbd</span>&gt;</span>d<span class="hljs-tag">&lt;/<span class="hljs-name">Kbd</span>&gt;</span> Move Right
        <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Flex</span> <span class="hljs-attr">flexDirection</span>=<span class="hljs-string">"column"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> resetBoard()}&gt;Reset game<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Flex</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">Box</span>&gt;</span></span>
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Instruction;
</code></pre>
<p>The <code>Instruction</code> component will accept <code>resetBoard</code> as a prop which is a function that will help the user when the game is over or when they want to reset the game.</p>
<p>Before we dive into the <code>resetBoard</code> function we need to make the following updates in our Redux store and saga:</p>
<ol>
<li>Add the following action and action creator in the <code>actions/index.ts</code> file:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RESET_SCORE = <span class="hljs-string">"RESET_SCORE"</span>; <span class="hljs-comment">//action</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> RESET = <span class="hljs-string">"RESET"</span>; <span class="hljs-comment">//action</span>

<span class="hljs-comment">//Action creator:</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> resetGame = <span class="hljs-function">() =&gt;</span> ({
  <span class="hljs-attr">type</span>: RESET
});
</code></pre>
<ol start="2">
<li>Then add the following condition into our <code>sagas/index.ts</code>. We are going to make sure that saga discontinues to dispatch actions once the <code>RESET</code> and the <code>STOP_GAME</code> actions are encountered.</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">moveSaga</span>(<span class="hljs-params">params: {
  type: string;
  payload: ISnakeCoord;
}</span>): <span class="hljs-title">Generator</span>&lt;
  | <span class="hljs-title">PutEffect</span>&lt;</span>{ type: string; payload: ISnakeCoord }&gt;
  | PutEffect&lt;{ <span class="hljs-attr">type</span>: string; payload: string }&gt;
  | CallEffect&lt;<span class="hljs-literal">true</span>&gt;
&gt; {
  <span class="hljs-keyword">while</span> (params.type !== RESET &amp;&amp; params.type !== STOP_GAME) {
    <span class="hljs-keyword">yield</span> put({
      <span class="hljs-attr">type</span>: params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>],
      <span class="hljs-attr">payload</span>: params.payload,
    });
    <span class="hljs-keyword">switch</span> (params.type.split(<span class="hljs-string">"_"</span>)[<span class="hljs-number">1</span>]) {
      <span class="hljs-keyword">case</span> RIGHT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(LEFT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> LEFT:
        <span class="hljs-keyword">yield</span> put(setDisDirection(RIGHT));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> UP:
        <span class="hljs-keyword">yield</span> put(setDisDirection(DOWN));
        <span class="hljs-keyword">break</span>;

      <span class="hljs-keyword">case</span> DOWN:
        <span class="hljs-keyword">yield</span> put(setDisDirection(UP));
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-keyword">yield</span> delay(<span class="hljs-number">100</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span>* <span class="hljs-title">watcherSagas</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">yield</span> takeLatest(
    [MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN, RESET, STOP_GAME],
    moveSaga
  );
}
</code></pre>
<ol start="3">
<li>Finally, we update our <code>reducers/index.ts</code> file for the <code>RESET_SCORE</code> case as follows:</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">case</span> RESET_SCORE:
      <span class="hljs-keyword">return</span> { ...state, <span class="hljs-attr">score</span>: <span class="hljs-number">0</span> };
</code></pre>
<p>Once our sagas and reducers are updated we can take a look at what operations the <code>resetBoard</code> callback will perform.</p>
<p>The <code>resetBoard</code> function performs the following operations:</p>
<ol>
<li>Removes the event listener <code>handleKeyEvents</code></li>
<li>dispatches the actions necessary for resetting the game.</li>
<li>Dispatches the action to reset the score.</li>
<li>Clears the canvas.</li>
<li>Draws the snake again at its initial position</li>
<li>Draws the fruit at a new random position.</li>
<li>Finally, adds the event listener <code>handleKeyEvents</code> for the <code>keypress</code> event.</li>
</ol>
<p>Below is how our <code>resetBoard</code> function will look:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> resetBoard = useCallback(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
    dispatch(resetGame());
    dispatch(scoreUpdates(RESET_SCORE));
    clearBoard(context);
    drawObject(context, snake1, <span class="hljs-string">"#91C483"</span>);
    drawObject(
      context,
      [generateRandomPosition(width - <span class="hljs-number">20</span>, height - <span class="hljs-number">20</span>)],
      <span class="hljs-string">"#676FA3"</span>
    ); <span class="hljs-comment">//Draws object randomly</span>
    <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"keypress"</span>, handleKeyEvents);
  }, [context, dispatch, handleKeyEvents, height, snake1, width]);
</code></pre>
<p>You should place this function inside the <code>CanvasBoard</code> component and pass the <code>resetBoard</code> function as a prop to the <code>Instruction</code> function as below:</p>
<pre><code class="lang-jsx">&lt;&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>
        <span class="hljs-attr">ref</span>=<span class="hljs-string">{canvasRef}</span>
        <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span>
          <span class="hljs-attr">border:</span> `<span class="hljs-attr">3px</span> <span class="hljs-attr">solid</span> ${<span class="hljs-attr">gameEnded</span> ? "<span class="hljs-attr">red</span>" <span class="hljs-attr">:</span> "<span class="hljs-attr">black</span>"}`,
        }}
        <span class="hljs-attr">width</span>=<span class="hljs-string">{width}</span>
        <span class="hljs-attr">height</span>=<span class="hljs-string">{height}</span>
      /&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Instruction</span> <span class="hljs-attr">resetBoard</span>=<span class="hljs-string">{resetBoard}</span> /&gt;</span></span>
    &lt;/&gt;
</code></pre>
<p>Once this is placed we will have the Instruction component set up like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/image-17.png" alt="Image" width="600" height="400" loading="lazy">
<em>Instructions with reset button</em></p>
<h2 id="heading-final-game">Final Game</h2>
<p>If you have followed along up to this point, then congrats! You have successfully created a fun Snake game with React, Redux and redux-sagas. Once all of these things are connected your game will look like below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/02/ezgif.com-gif-maker--2--1.gif" alt="Image" width="600" height="400" loading="lazy">
<em>The complete snake game</em></p>
<h2 id="heading-summary">Summary</h2>
<p>So this is how you can build a Snake game from scratch. You can find the entire source code for the game in the below repository:</p>
<p><a target="_blank" href="https://github.com/keyurparalkar/snake-game">https://github.com/keyurparalkar/snake-game</a></p>
<p>If you liked the idea of building your own Snake game from scratch then you can take it up a notch by building these enhancements:</p>
<ul>
<li>Build the snake game with three.js</li>
<li>Add an online score board</li>
</ul>
<p>Thank you for reading!</p>
<p>Follow me on <a target="_blank" href="https://twitter.com/keurplkar">Twitter</a>, <a target="_blank" href="https://github.com/keyurparalkar">GitHub</a>, and <a target="_blank" href="https://www.linkedin.com/in/keyur-paralkar-494415107/">LinkedIn</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 12 Free Coding Games to Learn Programming for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ A lot of beginners can become intimidated when they're learning how to code. But learning through coding games can be fun and educational.  According to True Education Partnerships,  Gamification in learning involves using game-based elements such a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/12-free-coding-games-to-learn-programming-for-beginners/</link>
                <guid isPermaLink="false">66b8d929f0d0708280f13468</guid>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learn to code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Video games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Tue, 03 Aug 2021 15:11:05 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/08/naser-tamimi-yG9pCqSOrAg-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A lot of beginners can become intimidated when they're learning how to code. But learning through coding games can be fun and educational. </p>
<p>According to <a target="_blank" href="https://www.trueeducationpartnerships.com/schools/gamification-in-education/">True Education Partnerships</a>, </p>
<blockquote>
<p><strong>Gamification in learning</strong> involves using game-based elements such as point scoring, peer competition, team work, and score tables to drive engagement, help students assimilate new information and test their knowledge.</p>
</blockquote>
<p>I have curated a list of 12 coding games for beginners. </p>
<p>Here is the complete list. Once you find a website that interests you, click that link and it will jump you down to a more detailed description of that website.</p>
<ol>
<li><a class="post-section-overview" href="#heading-codingame">CodinGame</a></li>
<li><a class="post-section-overview" href="#heading-css-diner">CSS Diner</a></li>
<li><a class="post-section-overview" href="#heading-flexbox-froggy">Flexbox Froggy</a></li>
<li><a class="post-section-overview" href="#heading-flexbox-defense">Flexbox Defense</a></li>
<li><a class="post-section-overview" href="#heading-grid-garden">Grid Garden</a></li>
<li><a class="post-section-overview" href="#heading-codecombat">CodeCombat</a></li>
<li><a class="post-section-overview" href="#heading-scratch">Scratch</a></li>
<li><a class="post-section-overview" href="#heading-tynker">Tynker</a></li>
<li><a class="post-section-overview" href="#heading-sql-murder-mystery">SQL Murder Mystery</a></li>
<li><a class="post-section-overview" href="#heading-untrusted">Untrusted</a></li>
<li><a class="post-section-overview" href="#heading-elevator-saga">Elevator Saga</a></li>
<li><a class="post-section-overview" href="#heading-checkio">CheckiO</a></li>
</ol>
<h2 id="heading-codingame">CodinGame</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-3.19.31-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://www.codingame.com/start">CodinGame</a> is a site that helps you work on problem solving skills and learn programming basics through a turn-based game. </p>
<p>This platform supports over 25 different programming languages and gives players the opportunity to practice, learn, and compete in coding contests.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.44.38-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you create an account, you can get started with the beginner level onboarding section. You will be introduced to standard programming concepts and solve mini challenges. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.44.10-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-css-diner">CSS Diner</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-3.43.56-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In <a target="_blank" href="https://flukeout.github.io/">CSS Diner</a>, you can practice the basics of CSS through a series of 32 challenges. This is a good way to get more familiar with the language and have fun learning it. </p>
<p>The first few challenges are short and focus on working with classes and ids. But as you progress through the levels, you will be introduced to Pseudo-selectors, First of Type Selector, Last of Type Selector, and the Universal Selector.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.55.36-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-flexbox-froggy">Flexbox Froggy</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-4.05.43-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In <a target="_blank" href="https://flexboxfroggy.com/">Flexbox Froggy</a>, you will learn CSS Flexbox by placing the frogs on the correct lillypads. By the time you finish level 24, you should feel comfortable using Flexbox in your next project. </p>
<p>Each challenge provides a description on the Flexbox properties. The first few challenges start off easy but as you progress in the game things get more complicated. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-11.17.03-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-flexbox-defense">Flexbox Defense</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-4.26.01-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="http://www.flexboxdefense.com/">Flexbox Defense</a> is a tower defense game that helps you strengthen your CSS skills. Position the towers to keep out your enemies using CSS Flexbox. </p>
<p>The challenges will provide you with definitions of the Flexbox properties. Once you write your code, press the Start Wave button and see if you were successful in stopping your enemies. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-11.22.57-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-grid-garden">Grid Garden</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-4.17.37-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Learn CSS Grid by going through 28 levels of <a target="_blank" href="https://cssgridgarden.com/">Grid Garden</a>. Some familiarity with CSS Grid is encouraged but not required for getting started with the game.  </p>
<p>Each challenge provides a description on the CSS Grid properties. The first few challenges start off easy but as you progress in the game things get more complicated. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-11.27.18-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-codecombat">CodeCombat</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-1.56.36-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://codecombat.com/">CodeCombat</a> works well for both kids and adult learners. You can create a free account and learn the fundamentals of programming like loops, functions, conditionals, and  variables. </p>
<p>You can choose which programming language to start with and work your way through the games.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.03.07-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You also have the option to upgrade to the premium account if you are interested in having access to more levels. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.05.35-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-scratch">Scratch</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.16.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>MIT's <a target="_blank" href="https://scratch.mit.edu/">Scratch</a> is a block based programming language where you can learn about events, conditionals, variables, and more by building your own games and animations. </p>
<p>Choose from dozens of sprites, sounds and backgrounds to code your own creations and start understanding programming basics. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.28.37-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Scratch is also used during the first week of <a target="_blank" href="https://www.edx.org/course/introduction-computer-science-harvardx-cs50x">Harvard's CS50: Introduction to Computer Science course</a>. </p>
<h2 id="heading-tynker">Tynker</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.43.52-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://www.tynker.com/">Tynker</a> is a site where you can build projects and play games using HTML, CSS, JavaScript, Python, and Java. They have an extensive list of projects, algorithms and data structure challenges. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-2.56.25-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You can build these projects in the online editor and share your creations within the community. This site is aimed at kids between the ages of 5-18. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.23.31-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-sql-murder-mystery">SQL Murder Mystery</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-8.52.08-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://mystery.knightlab.com/">SQL Murder Mystery</a> is great for both beginners and experienced SQL developers. Strengthen your SQL and problem solving skills by trying to track down the killer in this murder mystery. </p>
<p>The game uses SQLite and you will first have to get acquainted with the database structure before starting the game. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.17.01-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>If you are new to SQL, there is a <a target="_blank" href="https://mystery.knightlab.com/walkthrough.html">detailed walk through</a> for beginners. Otherwise, if you are an experienced SQL user then you can dive straight into the game. </p>
<h2 id="heading-untrusted">Untrusted</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-9.16.13-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://alexnisnevich.github.io/untrusted/">Untrusted</a> is an adventure game where you can test your JavaScript and problem solving skills. Help guide Dr. Eval through a series of levels by solving JavaScript challenges. </p>
<p>If you are brand new to JavaScript then this game might be a little advanced for you. But if you have spent some time programming in JavaScript then the challenges will be doable. </p>
<h2 id="heading-elevator-saga">Elevator Saga</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-9.20.11-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="http://play.elevatorsaga.com/">Elevator Saga</a> is a JavaScript game where you will go through a series of challenges trying to transport people in elevators in the most efficient way possible within the time given. </p>
<p>Once you modify the code, you can test the efficiency of your solution by clicking the start button in the top right hand corner. When the program is running, you can check the stats to see if you passed the challenge or not. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-10.08.06-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-checkio">CheckiO</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-9.30.59-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://checkio.org/">CheckiO</a> is a strategy game where you can learn TypeScript or Python through a series of challenges. Once you create a free account, you will start off with the beginner challenges and work your way through to the advanced ones. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-9.48.46-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The game will give you access to hints and other players' solutions if you need help. You will solve each of the challenges in the online editor and move onto the next mission when the task is solved. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/08/Screen-Shot-2021-08-02-at-9.58.49-PM.png" alt="Image" width="600" height="400" loading="lazy"></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Google Doodle Games – Baseball, PacMan, and More ]]>
                </title>
                <description>
                    <![CDATA[ The homepage for the Google Search engine is the most viewed webpage in the world. People conduct billions of searches every day. When you land on the page, right above the search box, you'll see Google's logo. On many occassions the logo will be dif... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/google-doodle-games-baseball-pacman-and-more/</link>
                <guid isPermaLink="false">66b1e40a8f7b9fe685bd6135</guid>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Google ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Dionysia Lemonaki ]]>
                </dc:creator>
                <pubDate>Mon, 26 Jul 2021 23:01:30 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/07/google-doodle-article-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The homepage for the Google Search engine is the most viewed webpage in the world. People conduct billions of searches every day.</p>
<p>When you land on the page, right above the search box, you'll see Google's logo. On many occassions the logo will be different and accompanied by what's called a <em>Doodle</em>.</p>
<p>These Doodles range from small, simple and temporary alterations to the traditional logo. But more often that not, they are very creative and artistic expressions.</p>
<p>They highlight world issues, major historical events, worldwide holidays, local celebrations, anniversaries and important figures' brithdays (including pioneers, artists, and scientists) along with their contributions to society.</p>
<p>When you click on the Doodle animation you can find more information about that specific topic and a little game or interaction sometimes sometimes accompanies the doodle.</p>
<h2 id="heading-the-first-google-doodle">The First Google Doodle</h2>
<p>The first doodle was created when Google co-founders Larry Page and Sergey Brin attended the annual Burning Man Festival in the Nevada desert in the United States on 30 August 1998.</p>
<p>They put a stick figure icon, resembling the Burning Man logo, behind the second "O" as an "Out Of Office" message to let users know of their absence in a fun and creative way.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-10.43.13-AM.png" alt="Screenshot-2021-07-25-at-10.43.13-AM" width="600" height="400" loading="lazy"></p>
<p>Google was very young at the time – it had only been a couple of years since the search engine had been built by these two Stanford students. And this was just less than a week before it would be offically incorporated as a company. </p>
<p>You can also see that the logo was different, with an exclamation mark at the end.</p>
<h2 id="heading-the-development-of-google-doodles">The Development of Google Doodles</h2>
<p>Since then, this new idea of altering the logo when celebrating notable  events was born, and the Doodles progressed.</p>
<p>Nearly two years later, Page and Brin asked Dennis Hwang – an intern at the time – to create a doodle in honor of Bastille Day, on July 14 2000. It was very well received and Dennis Hwang was appointed Chief Doodler.</p>
<p>Doodles started to appear more regularly on the homepage.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-11.03.13-AM.png" alt="Screenshot-2021-07-25-at-11.03.13-AM" width="600" height="400" loading="lazy"></p>
<p>Since then, Google has a whole dedicated team of talented illustrators (called doodlers) responsible for the doodle that appears on Google's homepage for the entire globe.</p>
<p>The early doodles were fairly simple. When you hovered over the doodle, a little pop up text would appear noting what was being commemorated.</p>
<p>For Halloween in 2000, guest artist Lorie Loeb created the very first animated doodle. It featured two jack-o-lanterns in place of the "O"’s and a spider was dangling from the "L".</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/halloween_loop.gif" alt="halloween_loop" width="600" height="400" loading="lazy"></p>
<p>Another notable tech-related, nostalgic doodle was that of March 12 2019, where Google commemorated the 30th anniversary of the World Wide Web.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/30th-anniversary-of-the-world-wide-web-4871946884874240-2xa-1.gif" alt="30th-anniversary-of-the-world-wide-web-4871946884874240-2xa-1" width="600" height="400" loading="lazy"></p>
<p>You can view a <a target="_blank" href="https://www.google.com/doodles#archive">historical archive</a> of all the Google Doodles that have appeared on the homepage, letting you relive any Doodle and discover new ones you may not have seen already.</p>
<h2 id="heading-the-first-google-doodle-game">The First Google Doodle Game</h2>
<p>The doodle technology kept on improving, and on May 21st 2010 Google released its first interactive game – the first ever playable Doodle Google game.</p>
<p>This release celebrated the 30th anniverary of one of the most popular and classic arcade games, Pac Man, which was released in 1980.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-4.57.49-PM.png" alt="Screenshot-2021-07-25-at-4.57.49-PM" width="600" height="400" loading="lazy"></p>
<p>It was an immense development for Google and it must have brightend many peoples' days by bringing back such a fun and addictive throwback game. It was estimated that over 1 billion people played the game in the first three days of its release.</p>
<p>The PacMan doodle game brings up 8-bit nostalgic memories as it uses the same graphics, and the same original colors, sounds, and iconic characters. It even incudes the same original game logic and bugs (!).</p>
<p>If you want to take a trip down memory lane, or be introduced to the game for the first time, you can play it <a target="_blank" href="https://www.google.com/doodles/30th-anniversary-of-pac-man">here</a>.</p>
<p>Just press "Insert Coin" and use the arrow keys on your keyboard. You are a yellow hero aiming to eat all the dots without getting caught by ghosts of different colors.</p>
<p>Be prepared to spend one too many hours on this one.</p>
<h2 id="heading-how-to-play-doodle-google-games">How to Play Doodle Google Games</h2>
<p>Since then there have been many more fun and interactive games and puzzles.</p>
<p>The doodles and games usually stay up for one day to commemorate a specific event. But Google archives all its old doodles and doodle games on the <a target="_blank" href="https://www.google.com/doodles?q=interactive">dedicated archive page</a> instead of just getting rid of them. </p>
<p>Thanks to this, you can play any of the games that have been featured on the search engine's homepage.</p>
<p>Playing them is easy and fuss free.</p>
<p>They are all web based and can be played on both desktop and mobile without needing to download anything or set up a console. You don't need any equipment – just a browser and an internet connection.</p>
<p>Click on the links to go to the page for the specific game and then click to start the game.</p>
<p>In most cases you'll use your mouse or trackpad and keyboard. If you're playing from a mobile you'll be swipping or tapping.</p>
<h2 id="heading-popular-doodle-google-games">Popular Doodle Google Games</h2>
<p>Below is a list of some of the most well known and popular doodle games, grouped together based on different categories.</p>
<h3 id="heading-doodle-brain-teaser-games">Doodle brain teaser games</h3>
<h4 id="heading-rubiks-cube">Rubik's Cube</h4>
<p>The <a target="_blank" href="https://www.google.com/doodles/rubiks-cube">Rubik's cube</a> appeared on the homepage on May 19, 2014 and is one of the biggest and most fascinating mental challenges. </p>
<p>The colors move horizontally, but you can move its pieces by clicking anywhere on the cube to turn it on all its sides. 
<img src="https://www.freecodecamp.org/news/content/images/2021/07/rubik-1.gif" alt="rubik-1" width="600" height="400" loading="lazy"></p>
<h4 id="heading-crossword-puzzles">Crossword puzzles</h4>
<p>On December 21st 2013, Google came out with a tribute to <a target="_blank" href="https://www.google.com/logos/2013/crossword/crossword13.html">crosswords</a> to commemorate 100 years of crossword puzzles. </p>
<p>With the help of Merl Reagle, one of the best and most well known crossword instructors, Google created their own version of a crossword with clues. It also shared bits of puzzle history throughout.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-8.13.01-PM.png" alt="Screenshot-2021-07-25-at-8.13.01-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-coding-games">Doodle coding games</h3>
<h4 id="heading-coding-for-carrots">Coding for carrots</h4>
<p><a target="_blank" href="https://www.google.com/doodles/celebrating-50-years-of-kids-coding">Coding for carrots</a> introduces childern (or you!) to the world of programming by connecting blocks that represent coding concepts. This helps guide a rabbit across 6 levels to get to its favorite food – a carrot – and collect it. </p>
<p>The game was released on 4 December 2017 during Computer Science Education week in collaboration with MIT to celebrate 50 years of Kids Coding and of coding languages for kids. It's based on the Scratch programming language.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/carrot.gif" alt="carrot" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-sports-fans">Doodle games for sports fans</h3>
<h4 id="heading-cricket">Cricket</h4>
<p><a target="_blank" href="https://www.google.com/doodles/icc-champions-trophy-2017-begins">Cricket</a> was introduced to celebrate the 2017 ICC Champions Trophy and you play cricket as an animated cricket.  </p>
<p>Just click on the bat to swing it when you see the ball coming towards you and want to hit it to score. It's a clever re-creation of the sport. 
<img src="https://www.freecodecamp.org/news/content/images/2021/07/cricket.gif" alt="cricket" width="600" height="400" loading="lazy"></p>
<h4 id="heading-baseball">Baseball</h4>
<p><a target="_blank" href="https://www.google.com/doodles/fourth-of-july-2019">Baseball</a> was introduced in honor of 4th of July, US Independence day, in 2019. The players are classic American snacks like hot dogs, fries, and ketchup. </p>
<p>Click to swing the bat and if you're like I am, be prepared to hear "You're Out" too many times (otherwise you'll see plenty of fireworks).
<img src="https://www.freecodecamp.org/news/content/images/2021/07/4th.gif" alt="4th" width="600" height="400" loading="lazy"></p>
<h4 id="heading-basketball">Basketball</h4>
<p><a target="_blank" href="https://www.google.com/doodles/basketball-2012">Basketball</a> came out in 2012, honoring the 2012 Olympic Summer games with this interactive basketball game. You try to make as many baskets as you can in 24 seconds. </p>
<p>Besides this game, for that period Google released three other separate interactive sports games, like <a target="_blank" href="https://www.google.com/doodles/soccer-2012">Soccer</a>. With this one you're a goal keeper, using the space key to stop the incoming ball from reaching the net and the arrow keys to change your position.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-2.48.47-PM.png" alt="Screenshot-2021-07-26-at-2.48.47-PM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-2020-tokyo-olympics">2020 Tokyo Olympics</h4>
<p>In celebration of the <a target="_blank" href="https://www.google.com/doodles/doodle-champion-island-games-july-24">2020 Tokyo Olympics</a>,Google released its most ambitious, elaborate, and complex game to date – a full on anime sports game called the Doodle Champion Island Games. </p>
<p>It's a homage to retro 16-bit Japanese video games, with 7 mini Olympic game sporting event themes to choose from (including table tennis, skateboarding, and artistic swimming among others). It's the largest game Google has released. </p>
<p>You play as a Calico ninja warrior cat named Lucky that arrives on the island where the festival is underway. You can choose from one of 4 teams - the Blue, Red, Yellow, or Green team - represented by Ushi, Karasu, Inari, or Kappa. </p>
<p>To play, use the arrow keys and space bar and pay tribute by celebrating Japanese history, culture, and sports throughtout the game. It was made in partnership with Japanese animation studio Studio 4°C.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-11.01.56-AM.png" alt="Screenshot-2021-07-26-at-11.01.56-AM" width="600" height="400" loading="lazy"> </p>
<h3 id="heading-doodle-games-for-music-lovers">Doodle games for music lovers</h3>
<h4 id="heading-celebrating-oskar-fischinger">Celebrating Oskar Fischinger</h4>
<p><a target="_blank" href="https://www.google.com/doodles/oskar-fischingers-117th-birthday">Fischinger</a> was created on 17 June 2017 to celebrate Oskar Fischinger's 117th birthday. </p>
<p>To honor the filmmaker and visual artist, Google released an interactive design with a visual music composition tool, letting users click and create their own visual pieces of music with the wide variety of settings you can change.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-7.47.35-PM.png" alt="Screenshot-2021-07-25-at-7.47.35-PM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-celebrating-the-birth-of-hip-hop">Celebrating the birth of Hip Hop</h4>
<p><a target="_blank" href="https://www.google.com/doodles/44th-anniversary-of-the-birth-of-hip-hop">Hip Hop</a> was released to commemorate the 44th anniversary of the birth of  hip-hop, on 11th August 2017. </p>
<p>With the crossfader you can mix legendary beats together, change the volume and intensity of playback speed, and pick tracks. The classic DJ interactive turntable will let you cut and scratch tracks and relive hip-hop history. </p>
<p>The graffiti was made by artist Cey Adams, and it's narrated by hip-hop icon Fab Five Freddy. It pays tribute to Kool Herc and Coke La Rock, the two founding fathers of hip hop.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.38.20-AM.png" alt="Screenshot-2021-07-26-at-10.38.20-AM" width="600" height="400" loading="lazy"></p>
<h4 id="heading-rockmore">Rockmore</h4>
<p><a target="_blank" href="https://www.google.com/doodles/clara-rockmores-105th-birthday">Rockmore</a> simulates the experience of the Theremin. This is an electronic musical instrument that works without physical contact – only by gesture controls. </p>
<p>The game celebrates the anniversary of Clara Rockmore’s 105th birthday, the inventor and the instrument's most well known performer, on 9th March 2016. </p>
<p>It will let you create music and experiment with the different settings and replicate different notes. Move your cursor or mouse over the notes on the screen to create music using a virtual Theremin.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-4.07.53-PM.png" alt="Screenshot-2021-07-26-at-4.07.53-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-creatives">Doodle games for creatives</h3>
<h4 id="heading-quick-draw">Quick draw</h4>
<p><a target="_blank" href="https://quickdraw.withgoogle.com/">Quick draw!</a> is a game that got its own website. You are given instructions on the screen about what to draw and a 20 second timeframe to do so. Google's neural network then makes guesses and tells you what your drawing resembles. </p>
<p>The game is built with Machine Learning and is one of the most popular Doodle games.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-25-at-7.53.52-PM.png" alt="Screenshot-2021-07-25-at-7.53.52-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-science-fiction-enthusiasts">Doodle games for science-fiction enthusiasts</h3>
<h4 id="heading-doctor-who">Doctor Who</h4>
<p>The <a target="_blank" href="https://www.google.com/doodles/doctor-whos-50th-anniversary">Doctor Who</a> doodle game, released on 23 November 2013, was created to honor the 50th anniversary of the classic and popular British television show, Doctor Who. </p>
<p>It's a simple but impressive adventure puzzle game, featuring all of the 13 doctors at the time it was made. </p>
<p>The goal is to retrieve all of the 6 letters from Google logo that the Daleks stole from the doctors, going through the 6 levels of the game.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.41.15-AM.png" alt="Screenshot-2021-07-26-at-10.41.15-AM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-food-games">Doodle food games</h3>
<p><a target="_blank" href="https://www.google.com/doodles/wilbur-scovilles-151st-birthday">Scoville</a> was released on 22nd January 2016 to celebrate Wilbur Scoville’s 151st birthday. </p>
<p>The Scoville Scale is a system that measures how hot a pepper is. In this game, you're an ice cream fighting against spicy peppers by throwing scoops at them. Peppers start progressively getting hotter each time.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-10.55.11-AM.png" alt="Screenshot-2021-07-26-at-10.55.11-AM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-people-who-love-halloween">Doodle games for people who love Halloween</h3>
<h4 id="heading-the-magic-cat-academy">The Magic Cat Academy</h4>
<p><a target="_blank" href="https://www.google.com/doodles/halloween-2016">The Magic Cat Academy</a> celebrated Halloween in 2016 and follows a cat named Momo who wants to restore peace at the Magic Cat Academy where she's a student so she can rescue the school. </p>
<p>The muse for this game was a black cat that belongs to the Doodler who built the game, Juliana Chen. </p>
<p>Momo has to go through 5 levels in her school – the library, cafeteria, classroom, gym, and building rooftop. And along the way she has to swipe her wand to trace symbols above the heads of the ghosts that appear! This way, Momo casts spells and won't get her spellbook taken away from her by the ghosts that are lurking. </p>
<p>Use your keypad to swipe above the ghosts's heads, turning them into thin air.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-3.39.40-PM.png" alt="Screenshot-2021-07-26-at-3.39.40-PM" width="600" height="400" loading="lazy"></p>
<h3 id="heading-doodle-games-for-those-who-enjoy-card-games">Doodle games for those who enjoy card games</h3>
<h4 id="heading-loteria">Loteria</h4>
<p><a target="_blank" href="https://www.google.com/doodles/celebrating-loteria">Loteria</a> is a traditional Mexican card game. You can start a match with your friends or with random people from all around the globe. </p>
<p>It was released on 9th December 2019, celebrating this traditional game with a virtual version. There is a tutorial before your first trial round if you've never played Lotería before.
<img src="https://www.freecodecamp.org/news/content/images/2021/07/Screenshot-2021-07-26-at-3.53.58-PM.png" alt="Screenshot-2021-07-26-at-3.53.58-PM" width="600" height="400" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you enjoyed this write-up of some of Google's most popular Doodle Games for you to try.</p>
<p>There are many more available on the dedicated <a target="_blank" href="https://www.google.com/doodles?q=interactive">archive page</a>, so go have a look and see what interests you.</p>
<p>Thanks for reading!</p>
<p>Copyright: All images belong to Google</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Snake Game In JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ By Fakorede Damilola In this article I am going to show you how to build a snake game with JavaScript.  A snake game is a simple game where a snake moves around a box trying to eat an apple. Once it successfully eats the apple, the length of the ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-snake-game-in-javascript/</link>
                <guid isPermaLink="false">66d45edcaad1510d0766b60f</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Game Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ HTML ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 11 Dec 2020 16:13:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/05/joan-gamell-ZS67i1HLllo-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Fakorede Damilola</p>
<p>In this article I am going to show you how to build a snake game with JavaScript. </p>
<p>A snake game is a simple game where a snake moves around a box trying to eat an apple. Once it successfully eats the apple, the length of the snake increases and the movement becomes faster. </p>
<p>Then the game is over when the snake runs into itself or any of the four walls of the box.</p>
<p>Alright, let's start with the HTML and CSS (the skeleton for our game). </p>
<h3 id="heading-html">HTML</h3>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Nokia 3310 snake<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"scoreDisplay"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"grid"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"button"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"top"</span>&gt;</span>top<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"bottom"</span>&gt;</span>bottom<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"left"</span>&gt;</span>left<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"right"</span>&gt;</span>right<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"popup"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"playAgain"</span>&gt;</span>play Again<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>The HTML above is pretty basic. </p>
<ul>
<li>We have a div of class <code>scoreDisplay</code> that will display our scores.</li>
<li>There's a div of class <code>grid</code> that will house the game (this is going to be a 10 by 10 grid)</li>
<li>The class <code>button</code> basically contains a button for users playing the game on a phone (we will automate it with the keyboard for desktop user). </li>
<li>And the <code>popup</code> class will hold our replay button. </li>
</ul>
<p>Now let's add some styling with CSS.</p>
<h3 id="heading-css">CSS</h3>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">212</span>, <span class="hljs-number">211</span>, <span class="hljs-number">211</span>);
}

<span class="hljs-selector-class">.grid</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">200px</span>;
  <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid red;
  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> auto;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">flex-wrap</span>: wrap;
}

<span class="hljs-selector-class">.grid</span> <span class="hljs-selector-tag">div</span> {
  <span class="hljs-attribute">width</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">20px</span>;
  <span class="hljs-comment">/*border:1px black solid;
box-sizing:border-box*/</span>
}

<span class="hljs-selector-class">.snake</span> {
  <span class="hljs-attribute">background</span>: blue;
}

<span class="hljs-selector-class">.apple</span> {
  <span class="hljs-attribute">background</span>: yellow;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">20px</span>;
}

<span class="hljs-selector-class">.popup</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">32</span>, <span class="hljs-number">31</span>, <span class="hljs-number">31</span>);
  <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">position</span>: fixed;
  <span class="hljs-attribute">top</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">left</span>: <span class="hljs-number">100px</span>;
  <span class="hljs-attribute">display</span>: flex;
  <span class="hljs-attribute">justify-content</span>: center;
  <span class="hljs-attribute">align-items</span>: center;
}
</code></pre>
<p>In the CSS, the <code>grid</code> which is the gameboard has a set dimension and a display of <code>flex</code>. This allows the contents (div) of this grid to line up in a horizontal manner as if they were inline elements instead of the normal block display which they possess. </p>
<p>The <code>flex wrap</code> property simply moves the divs to the next line, preventing them from going past the set dimension of their parent element (grid). </p>
<p>We will be dynamically creating the game board contents from JS but we can give a width and height here (with the <code>.grid</code> div). I included the comments here to help you actually see the divs, so as time goes on we will uncomment the code. </p>
<p>The <code>snake</code> and <code>Apple</code> classes are to show us where the snake and bonus is on the game, while the <code>popup</code> class is a fixed div that houses the <code>replay</code> div.</p>
<p>At this point, you should have something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/Screenshot--1710-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Structure with HTML and CSS</em></p>
<p>Now we're ready for the JavaScript.</p>
<h2 id="heading-javascript">JavaScript</h2>
<p>The first thing we need to do is define our variables:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> grid = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".grid"</span>);
<span class="hljs-keyword">let</span> popup = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".popup"</span>);
<span class="hljs-keyword">let</span> playAgain = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".playAgain"</span>);
<span class="hljs-keyword">let</span> scoreDisplay = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".scoreDisplay"</span>);
<span class="hljs-keyword">let</span> left = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".left"</span>);
<span class="hljs-keyword">let</span> bottom = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".bottom"</span>);
<span class="hljs-keyword">let</span> right = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".right"</span>);
<span class="hljs-keyword">let</span> up = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".top"</span>);
<span class="hljs-keyword">let</span> width = <span class="hljs-number">10</span>;
<span class="hljs-keyword">let</span> currentIndex = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> appleIndex = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> currentSnake = [<span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>];
<span class="hljs-keyword">let</span> direction = <span class="hljs-number">1</span>;
<span class="hljs-keyword">let</span> score = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> speed = <span class="hljs-number">0.8</span>;
<span class="hljs-keyword">let</span> intervalTime = <span class="hljs-number">0</span>;
<span class="hljs-keyword">let</span> interval = <span class="hljs-number">0</span>;
</code></pre>
<p>The variable width is exactly what it is (the width of the grid, that is 10). Other variables will make more sense as we go on – but believe it or not our snake is actually an array called <code>currentSnake</code>.</p>
<p>Now let's start with the functions:</p>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
  <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"keyup"</span>, control);
  createBoard();
  startGame();
  playAgain.addEventListener(<span class="hljs-string">"click"</span>, replay);
});
</code></pre>
<p>There is an <code>eventListener</code> on the document object called <code>DomContentLoaded</code> and this event is fired off immediately once the HTML content is loaded on our screen. </p>
<p>Once this happens, we set an eventListener on the document to watch for clicks on the keyboard (more on this later). After that, we want to create the <code>gameBoard</code>, start the game, and watch out for clicks on our replay button.</p>
<h3 id="heading-the-createboard-function">The createBoard function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createBoard</span>(<span class="hljs-params"></span>) </span>{
  popup.style.display = <span class="hljs-string">"none"</span>;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">100</span>; i++) {
    <span class="hljs-keyword">let</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"div"</span>);
    grid.appendChild(div);
  }
}
</code></pre>
<p>Like I said earlier, this is a 10 by 10 grid, meaning we are going to need 100 divs. So from above, we close the div popup and we loop to 100 every time we create a new div and append it to the grid (gameboard). </p>
<p>This will immediately add some of the styling we created from above (the .grid div). You can uncomment the CSS styles and you will see the divs created (uncomment them back).</p>
<h3 id="heading-the-startgame-function">The startGame function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">startGame</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> squares = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".grid div"</span>);
  randomApple(squares);
  <span class="hljs-comment">//random apple</span>
  direction = <span class="hljs-number">1</span>;
  scoreDisplay.innerHTML = score;
  intervalTime = <span class="hljs-number">1000</span>;
  currentSnake = [<span class="hljs-number">2</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>];
  currentIndex = <span class="hljs-number">0</span>;
  currentSnake.forEach(<span class="hljs-function">(<span class="hljs-params">index</span>) =&gt;</span> squares[index].classList.add(<span class="hljs-string">"snake"</span>));
  interval = <span class="hljs-built_in">setInterval</span>(moveOutcome, intervalTime);
}
</code></pre>
<p>The <code>startGame</code> function first gets all the divs (since we are creating the divs at runtime, we can not get them at the top of the code). </p>
<p>Next we select a spot for our apple. We will do that below in the <strong><code>randomApple</code></strong> function. The <code>direction</code> refers to where the snake is headed – 1 for right, -1 for left, and so on. </p>
<p><code>intervalTime</code> sets the time it takes for the snake to move around, while <code>currentSnake</code> defines where exactly on the grid the snake will be (note that the snake is basically a couple of divs given a particular type of color). </p>
<p>To display our snake on the screen, we will loop over <code>currentSnake</code> with <code>forEach</code>. With each value we get, we will use it with <strong>squares</strong>. Remember that we accessed the grid divs with <code>querySelectorAll</code>, and we can then access them like an array, that is using numbers. In our case, these are the values of <code>currentSnake</code>. </p>
<p>After this, we simply append a <code>setInterval</code> call (with function move <code>Outcome</code> and a time of <code>intervalTime</code>, which we set above) to the variable <code>interval</code>. This is so that we can easily call <code>clearInterval</code> on that variable. </p>
<p>The <code>moveOutcome</code> runs every 1000ms (1s) and basically defines what happens when you move the snake.</p>
<h3 id="heading-the-moveoutcome-function">The moveOutcome function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">moveOutcome</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">let</span> squares = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".grid div"</span>);
  <span class="hljs-keyword">if</span> (checkForHits(squares)) {
    alert(<span class="hljs-string">"you hit something"</span>);
    popup.style.display = <span class="hljs-string">"flex"</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">clearInterval</span>(interval);
  } <span class="hljs-keyword">else</span> {
    moveSnake(squares);
  }
}
</code></pre>
<p>So like the <code>startGame</code> function above, we first get all the <code>grid</code> divs, and then we check if the <strong><code>checkForHits</code></strong> function returns true. </p>
<p>If it does, this means we have hit something and then it displays the replay button and it clears the interval. If it returns false, this means we did not hit anything and we move the snake with the <strong><code>moveSnake</code></strong> function. </p>
<p>So basically, every 1sec the game either comes to an end if <code>checkForHits</code> is true or we move the snake a step forward if <code>checkForHits</code> is false. I will talk about the <code>moveSnake</code> function first.</p>
<h3 id="heading-the-movesnake-function">The moveSnake function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">moveSnake</span>(<span class="hljs-params">squares</span>) </span>{
  <span class="hljs-keyword">let</span> tail = currentSnake.pop();
  squares[tail].classList.remove(<span class="hljs-string">"snake"</span>);
  currentSnake.unshift(currentSnake[<span class="hljs-number">0</span>] + direction);
  <span class="hljs-comment">// movement ends here</span>
  eatApple(squares, tail);
  squares[currentSnake[<span class="hljs-number">0</span>]].classList.add(<span class="hljs-string">"snake"</span>);
}
</code></pre>
<p>The <code>moveSnake</code> function receives an argument called <code>squares</code> so that we don't have to get the <strong>.grid div</strong> again in this function.  </p>
<p>The first thing we need to do is remove the last element of the <strong><code>currentSnake</code></strong> array via pop (this is the tail and the first element is always the head). Basically the snake moves a step forward leaving the previous position it was in. After this we simply add a new value to the beginning of the array with <code>unShift</code>. </p>
<p>Let's assume that our snake just started moving and is facing to the right (that is, direction = 1). That direction will be added to the <code>currentSnake</code>'s head and the sum will be pushed as the new <code>snakeHead</code>. </p>
<p>For example, if the snake was in position <strong>[2,1,0]</strong>, we remove the last element leaving it at position [2,1]. Then we take the head which is <strong>2</strong> and add the direction which is <strong>1</strong> and make this value the new value <strong>[3,2,1]</strong> which moves our snake a step forward to the right after one second.  </p>
<p>If we want to move the snake downwards, the direction will be set to the width (which is 10) and added to the first element (that is 12 and pushed) <strong>[12,2,1]</strong>. </p>
<p>After that we simply check if the snake has eaten an apple and display the new snakehead on the DOM.</p>
<h3 id="heading-the-checkforhits-function">The checkForHits function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">checkForHits</span>(<span class="hljs-params">squares</span>) </span>{
  <span class="hljs-keyword">if</span> (
    (currentSnake[<span class="hljs-number">0</span>] + width &gt;= width * width &amp;&amp; direction === width) ||
    (currentSnake[<span class="hljs-number">0</span>] % width === width - <span class="hljs-number">1</span> &amp;&amp; direction === <span class="hljs-number">1</span>) ||
    (currentSnake[<span class="hljs-number">0</span>] % width === <span class="hljs-number">0</span> &amp;&amp; direction === <span class="hljs-number">-1</span>) ||
    (currentSnake[<span class="hljs-number">0</span>] - width &lt;= <span class="hljs-number">0</span> &amp;&amp; direction === -width) ||
    squares[currentSnake[<span class="hljs-number">0</span>] + direction].classList.contains(<span class="hljs-string">"snake"</span>)
  ) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
  }
}
</code></pre>
<p>The <code>checkForHits</code> function has an if statement. Depending on the condition defined, it could either return true (meaning we hit something) or false. </p>
<p>The first condition is if <code>currentSnake</code> [0] (the head of the snake) + width (10) is equal to the total area of the width (that is, width*width = 100) and the direction is equal to the width. </p>
<p>So basically let's assume that the snake's head is at position 97 which is the last layer of our grid. If you were to add 10 to 97 (= 107), that is greater than the whole grid which is 100. If the direction of the snake is still headed downwards, then the snake has hit the bottom border. </p>
<p>If the snake was at 97 , 97+10 =107, but the player was able to change the direction to, say, 1 (like, they pressed the left key), then it would not hit anything.</p>
<p>Or (<strong>||</strong>) if the remainder when the head of the snake divided by the width = <strong>width-1</strong> (for example, 9) and the direction is <strong>1</strong>. Every last div on the right hand side has a value of <strong>9, 19, 29</strong> and so on. So basically it will always remain 9 when you divide by 10. </p>
<p>If the head of our snake is at position 39 and the direction is still 1 (that is, the snake is still moving to the wall), then it has hit something (the right wall). </p>
<p>Every other condition is pretty much the exact opposite of the two above. The final condition allows that if the snake head is headed to a place that already contains a class snake, that simply means the snake is biting itself.</p>
<p>So...if any of the conditions above are true, the snake has hit something and <strong>true</strong> will be returned (else false). And if that's the case, the game is over. But if it is false, move the snake a step forward with <code>moveSnake</code>. </p>
<h3 id="heading-the-eatapple-function">The eatApple function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">eatApple</span>(<span class="hljs-params">squares, tail</span>) </span>{
  <span class="hljs-keyword">if</span> (squares[currentSnake[<span class="hljs-number">0</span>]].classList.contains(<span class="hljs-string">"apple"</span>)) {
    squares[currentSnake[<span class="hljs-number">0</span>]].classList.remove(<span class="hljs-string">"apple"</span>);
    squares[tail].classList.add(<span class="hljs-string">"snake"</span>);
    currentSnake.push(tail);
    randomApple(squares);
    score++;
    scoreDisplay.textContent = score;
    <span class="hljs-built_in">clearInterval</span>(interval);
    intervalTime = intervalTime * speed;
    interval = <span class="hljs-built_in">setInterval</span>(moveOutcome, intervalTime);
  }
}
</code></pre>
<p>The <code>eatApple</code> function is called from the <code>moveSnake</code> function every time the snake moves a step. </p>
<p>It receives two argument squares, <strong>.grid div</strong> and <strong>tail</strong> (basically the value that was popped up from the snake in <code>moveOutcome</code>). It then checks if the next position our snake moves to contains an apple. </p>
<p>If it does, it simply adds that tail we popped up back to the array. This is because every time our snake eats an apple we want to increase the length of the snake by one value – and what better way than to add the tail that was popped off when it moved?</p>
<p>Then we simply select a new position for our apple with <code>randomApple</code> (see below). After that we add a value of <strong>one</strong> to our score and display it to the user, clear the <code>timeInterval</code> (so that we can increase the speed of the snake, that is the time each movement happens) and then we simply set the interval back.</p>
<h3 id="heading-the-randomapple-function">The randomApple function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">randomApple</span>(<span class="hljs-params">squares</span>) </span>{
  <span class="hljs-keyword">do</span> {
    appleIndex = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * squares.length);
  } <span class="hljs-keyword">while</span> (squares[appleIndex].classList.contains(<span class="hljs-string">"snake"</span>));
  squares[appleIndex].classList.add(<span class="hljs-string">"apple"</span>);
}
</code></pre>
<p><code>randomApple</code> simply picks a spot to place our apple by using a <strong>do while</strong> loop. First it picks a random position with <code>Math.random()</code> in the do loop and checks if the spot it picked already contains a snake class. </p>
<p>This means that the condition in the do statement will keep on running until it finds a spot that does not contain a snake (keep doing this while this is true). Once it finds a spot it simply gives that spot a class of apple.</p>
<h3 id="heading-set-up-controls">Set up controls</h3>
<p>Now we need to set up our controls. We will start with keyboard users.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">control</span>(<span class="hljs-params">e</span>) </span>{
  <span class="hljs-keyword">if</span> (e.keycode === <span class="hljs-number">39</span>) {
    direction = <span class="hljs-number">1</span>; <span class="hljs-comment">// right</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (e.keycode === <span class="hljs-number">38</span>) {
    direction = -width; <span class="hljs-comment">//if we press the up arrow, the snake will go ten divs up</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (e.keycode === <span class="hljs-number">37</span>) {
    direction = <span class="hljs-number">-1</span>; <span class="hljs-comment">// left, the snake will go left one div</span>
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (e.keycode === <span class="hljs-number">40</span>) {
    direction = +width; <span class="hljs-comment">// down the snake head will instantly appear 10 divs below from the current div</span>
  }
}
</code></pre>
<p>Remember from above we set an <code>eventListener</code> for <code>**keyup**</code>. This function fires off immediately after your hand presses and. leaves a key on a keyboard. </p>
<p>Now each button on the keyboard has a value called keycode (numbers) which we have access to and let us know which number was clicked. Basically we will be watching for the arrow keys with their respective keycodes. With that we make changes to the direction, for example <strong>-1, 10</strong> and so on. </p>
<p>Alright, I hope you understand how we are able to move the snake now.</p>
<p>Next, this set of buttons is for mobile devices and we are basically doing the same thing:</p>
<pre><code class="lang-js">up.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> (direction = -width));
bottom.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> (direction = +width));
left.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> (direction = <span class="hljs-number">-1</span>));
right.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> (direction = <span class="hljs-number">1</span>));
</code></pre>
<p>The final thing we need to do is create the <strong><code>replay</code> div</strong> which will popup when the snake hits something. The button helps us reset the game.</p>
<h3 id="heading-the-replay-function">The replay function</h3>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">replay</span>(<span class="hljs-params"></span>) </span>{
  grid.innerHTML = <span class="hljs-string">""</span>;
  createBoard();
  startGame();
  popup.style.display = <span class="hljs-string">"none"</span>;
}
</code></pre>
<p>From above, we basically clear the grid (gameboard) and run the previous functions.</p>
<p>Congrats - you made it to the end! Here's the final result:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/12/Screenshot--1709-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Final game</em></p>
<p>I hope you were able to code along and you enjoyed it. </p>
<p>In this tutorial, we learned how to create our own snake game with JavaScript. Some other important concepts we covered include <strong>push, pop, setInterval, clearInterval</strong> and <strong>eventListener</strong>.</p>
<p>You can check out the final game here: <a target="_blank" href="https://codepen.io/Fako29/pen/dyppXZG">https://codepen.io/Fako29/pen/dyppXZG</a>.</p>
<p>Thank you for reading. Follow me on Twitter here: <a target="_blank" href="https://twitter.com/fakoredeDami">https://twitter.com/fakoredeDami</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Learn Web Development by Playing Coding Games ]]>
                </title>
                <description>
                    <![CDATA[ By Thomas Park Today we're lucky to have almost endless resources at our fingertips for learning web development. Among these resources are coding games.  I've created games like Flexbox Froggy and Grid Garden, along with others like CSS Diner and Co... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-web-development-by-playing-coding-games/</link>
                <guid isPermaLink="false">66d4614affe6b1f641b5fa8f</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ education ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ self-improvement  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 02 Nov 2020 23:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/10/codepip-splash-2000x1000.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Thomas Park</p>
<p>Today we're lucky to have almost endless resources at our fingertips for learning web development. Among these resources are coding games. </p>
<p>I've created games like <a target="_blank" href="https://codepip.com/games/flexbox-froggy/">Flexbox Froggy</a> and <a target="_blank" href="https://codepip.com/games/flexbox-froggy/">Grid Garden</a>, along with others like <a target="_blank" href="https://flukeout.github.io/">CSS Diner</a> and <a target="_blank" href="https://codecombat.com/">CodeCombat</a>, that help package an educational experience into a fun, engaging format.</p>
<p>Yet, as with any learning resource, these questions frequently arise:</p>
<ul>
<li>Which coding games should I bother to invest my time in?</li>
<li>How can I use coding games to learn most effectively?</li>
</ul>
<p>In this article, I offer some tips to help you answer these questions based on my experiences as a game developer and educator.</p>
<h2 id="heading-have-a-gameplan">Have a Gameplan</h2>
<p>When you're starting out on a mission to learn web development, whether it involves games or not, you should start with a plan. </p>
<p>Though your plan doesn't need to be set in stone, having a strategy for what you want to accomplish and how you'll do it will already put you a few steps ahead.</p>
<p>When you're enrolled in a course or bootcamp, a lot of this planning is already done for you by experienced facilitators. freeCodeCamp offers a wonderfully organized <a target="_blank" href="https://www.freecodecamp.org/learn">curriculum</a> as well. </p>
<p>But if you're self learning, all of the resources available on the web (which at once feels like a solitary void and a chaotic spectacle) can be overwhelming. So let's break it down.</p>
<p>When forming a plan, there are roughly three modes of learning you should target.</p>
<p>First is instruction. This is where you're introduced to a new concept or skill, whether in the form of videos, books, tutorials, or documentation. In the classroom, this could be a teacher on the whiteboard.</p>
<p>Second is practice, where you get to exercise your cognitive muscles and strengthen your grasp on those new concepts. This can take the form of practice problems, drills, or coding challenges.</p>
<p>Third is integration, where you incorporate your newly gained knowledge and skills into your existing practices. There's nothing better for this than project-based learning, where you apply what you've learned in a more authentic, well-rounded scenario. </p>
<p>An example of this is a web app you start as a weekend project. Even a relatively simple one will draw from all of the different facets of web development (and there are so many), helping you to contextualize what you've learned.</p>
<p>These three modes don't have rigid divisions, and many resources you come across will span more than one of them. Still, it's a useful way of thinking about and planning your learning.</p>
<p>Now when it comes to coding games, they too can fit in any of these modes. Many of the existing code games do have their greatest strength in the second mode — practice, with a small dose of instruction.</p>
<p>For example, in Flexbox Froggy, you're presented with a variety of challenges in how you position frogs using CSS flexbox, with each level ratcheting up the difficulty. </p>
<p>By the end, you'll have applied the Flexbox properties many times, in many combinations, to the point that they start becoming second nature.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/codepip.com_games_flexbox-froggy_.png" alt="codepip.com_games_flexbox-froggy_" width="600" height="400" loading="lazy">
<em>Move the frogs to their lily pads using CSS flexbox.</em></p>
<p>Through this lens, you can see that coding games best serve as a complement to other resources you may use, including freeCodeCamp's lessons.</p>
<h2 id="heading-be-a-critic">Be a Critic</h2>
<p>The next question you might have is which coding games you should play. Rather than provide you a static list, I encourage you to evaluate them yourself the same as you would any reference you come across.</p>
<p>First, consider the game from an entertainment angle. It is a game after all, and should be fun for you. Next, consider the pedagogical angle. That is, what am I learning from the game, and am I learning it effectively?</p>
<p>Educational game designers have to walk a tightrope in balancing fun with learning. For something that leans more on the learning, there are many resources inside and outside of gaming.</p>
<p>But beware the other direction, a game with merely a facade of educational substance. A coding game can fail when the educational content is too shallow or there are too many other game mechanics that distract you from engaging with what you need to learn.</p>
<p>Evaluating a learning resource on your own can be difficult, especially as a beginner. So your evaluation should also weigh the perspectives of others. </p>
<p>Consult with a trusted mentor or blogger. Or look for resources that have positive recommendations in your community: in the freeCodeCamp forums, web dev subreddits, or your favorite Discord or Slack group.</p>
<h2 id="heading-press-start-now">Press Start Now</h2>
<p>Even if you ask yourself the same questions as everyone else about how to best fit coding games into your learning plan, everyone will have a different answer. There is no one-size-fits-all solution. </p>
<p>Your learning style and what sparks your passion will depend on your experiences, preferences, and goals. So what I encourage you to do is start today, have fun with it, and discover what works for you.</p>
<p>Though the idea of coding games that help you learn web dev has been around for years, the genre is still in its infancy. There is so much untapped potential to the idea that you can learn in a fun, interactive, immersive environment, and games are a great vehicle for that.</p>
<p>Fortunately for us, more coding games are becoming available all the time. I welcome you to stop by <a target="_blank" href="https://codepip.com">Codepip</a> and play a coding game for yourself today.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to code your own procedural dungeon map generator using the Random Walk Algorithm ]]>
                </title>
                <description>
                    <![CDATA[ As technology evolves and game contents become more algorithmically generated, it’s not difficult to imagine the creation of a life-like simulation with unique experiences for each player. Technological breakthroughs, patience, and refined skills wil... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-make-your-own-procedural-dungeon-map-generator-using-the-random-walk-algorithm-e0085c8aa9a/</link>
                <guid isPermaLink="false">66ac8af659c54e72c773092e</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ahmad Abdolsaheb ]]>
                </dc:creator>
                <pubDate>Tue, 02 Jun 2020 21:18:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/09/Screen-Shot-2020-09-12-at-11.30.55-PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As technology evolves and game contents become more algorithmically generated, it’s not difficult to imagine the creation of a life-like simulation with unique experiences for each player.</p>
<p>Technological breakthroughs, patience, and refined skills will get us there, but the first step is to understand <strong>procedural content generation</strong>.</p>
<p>Though many out-of-the-box solutions for map generation exist, this tutorial will teach you to make your own two-dimensional dungeon map generator from scratch using JavaScript.</p>
<p>There are many two-dimensional map types, and all have the following characteristics:</p>
<ol>
<li><p>Accessible and inaccessible areas (tunnels and walls).</p>
</li>
<li><p>A connected route the player can navigate.</p>
</li>
</ol>
<p>The algorithm in this tutorial comes from the <a target="_blank" href="https://en.wikipedia.org/wiki/Random_walker_algorithm">Random Walk Algorithm</a>, one of the simplest solutions for map generation.</p>
<p>After making a grid-like map of walls, this algorithm starts from a random place on the map. It keeps making tunnels and taking random turns to complete its desired number of tunnels.</p>
<p>To see a demo, open the CodePen project below, click on the map to create a new map, and change the following values:</p>
<ol>
<li><strong>Dimensions:</strong> the width and height of the map.</li>
<li><strong>MaxTunnels:</strong> the greatest number of turns the algorithm can take while making the map.</li>
<li><strong>MaxLength:</strong> the greatest length of each tunnel the algorithm will choose before making a horizontal or vertical turn.</li>
</ol>
<div class="embed-wrapper"><iframe height="700" style="width:100%" src="https://codepen.io/abdolsa/embed/zEKdop?height=700&amp;theme-id=light&amp;default-tab=result" title="Embedded content" loading="lazy">
  See the Pen <a href="https://codepen.io/abdolsa/pen/zEKdop">CreatMap</a> by Ahmad Abdolsaheb
  (<a href="https://codepen.io/abdolsa">@abdolsa</a>) on <a href="https://codepen.io">CodePen</a>.
</iframe></div>

<p><strong>Note:</strong> the larger the <em>maxTurn</em> is compared to the dimensions, the denser the map will be. The larger the <em>maxLength</em> is compared to the dimensions, the more “tunnel-y” it will look.</p>
<p>Next, let’s go through the map generation algorithm to see how it:</p>
<ol>
<li>Makes a two dimensional map of walls</li>
<li>Chooses a random starting point on the map</li>
<li>While the number of tunnels is not zero</li>
<li>Chooses a random length from maximum allowed length</li>
<li>Chooses a random direction to turn to (right, left, up, down)</li>
<li>Draws a tunnel in that direction while avoiding the edges of the map</li>
<li>Decrements the number of tunnels and repeats the <a target="_blank" href="https://en.wikipedia.org/wiki/While_loop">while loop</a></li>
<li>Returns the map with the changes</li>
</ol>
<p>This loop continues until the number of tunnels is zero.</p>
<h3 id="heading-the-algorithm-in-code">The Algorithm in Code</h3>
<p>Since the map consists of tunnel and wall cells, we could describe it as zeros and ones in a two-dimensional array like the following:</p>
<pre><code class="lang-javascript">map = [[<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>],
       [<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>],
       [<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>],       
       [<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>],       
       [<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>,<span class="hljs-number">1</span>]]
</code></pre>
<p>Since every cell is in a two-dimensional array, we can access its value by knowing its row and column such as map [row][column].</p>
<p>Before writing the algorithm, you need a helper function that takes a character and dimension as arguments and returns a two-dimensional array.</p>
<pre><code class="lang-javascript">createArray(num, dimensions) {
    <span class="hljs-keyword">var</span> array = [];    
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; dimensions; i++) { 
      array.push([]);      
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j &lt; dimensions; j++) {  
         array[i].push(num);      
      }    
    }    
    <span class="hljs-keyword">return</span> array;  
}
</code></pre>
<p>To implement the Random Walk Algorithm, set the dimensions of the map (width and height), the<code>maxTunnels</code> variable, and the<code>maxLength</code> variable.</p>
<pre><code class="lang-javascript">createMap(){
 <span class="hljs-keyword">let</span> dimensions = <span class="hljs-number">5</span>,     
 maxTunnels = <span class="hljs-number">3</span>, 
 maxLength = <span class="hljs-number">3</span>;
</code></pre>
<p>Next, make a two-dimensional array using the predefined helper function (two dimensional array of ones).</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> map = createArray(<span class="hljs-number">1</span>, dimensions);
</code></pre>
<p>Set up a random column and random row to create a random starting point for the first tunnel.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> currentRow = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * dimensions),       
    currentColumn = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * dimensions);
</code></pre>
<p>To avoid the complexity of diagonal turns, the algorithm needs to specify the horizontal and vertical directions. Every cell sits in a two-dimensional array and could be identified with its row and column. Because of this, the directions could be defined as subtractions from and/or additions to the column and row numbers.</p>
<p>For example, to go to a cell around the cell [2][2], you could perform the following operations:</p>
<ul>
<li>to go <strong>up</strong>, subtract 1 from its row [1][2]</li>
<li>to go <strong>down</strong>, add 1 to its row [3][2]</li>
<li>to go <strong>right</strong>, add 1 to its column [2][3]</li>
<li>to go <strong>left</strong>, subtract 1 from its column [2][1]</li>
</ul>
<p>The following map illustrates these operations:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/09/1_P1AfxAKl6SAQMgn8SONUGQ.png" alt="Image" width="600" height="400" loading="lazy">
<em>Operational options grid</em></p>
<p>Now, set the <code>directions</code> variable to the following values that the algorithm will choose from before creating each tunnel:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> directions = [[<span class="hljs-number">-1</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">0</span>, <span class="hljs-number">-1</span>], [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]];
</code></pre>
<p>Finally, initiate <code>randomDirection</code> variable to hold a random value from the directions array, and set the <code>lastDirection</code> variable to an empty array which will hold the older <code>randomDirection</code> value.</p>
<p><strong>Note:</strong> the <code>lastDirection</code> array is empty on the first loop because there is no older <code>randomDirection</code> value.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> lastDirection = [], 
    randomDirection;
</code></pre>
<p>Next, make sure <code>maxTunnel</code> is not zero and the dimensions and <code>maxLength</code>values have been received. Continue finding random directions until you find one that isn’t reverse or identical to <code>lastDirection</code>. This <a target="_blank" href="https://en.wikipedia.org/wiki/Do_while_loop">do while loop</a> helps to prevent overwriting the recently-drawn tunnel or drawing two tunnels back-to-back.</p>
<p>For example, if your <code>lastTurn</code> is [0, 1], the do while loop prevents the function from moving forward until <code>randomDirection</code> is set to a value that is not [0, 1] or the opposite [0, -1].</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">do</span> {         
randomDirection = directions[<span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * directions.length)];      
} <span class="hljs-keyword">while</span> ((randomDirection[<span class="hljs-number">0</span>] === -lastDirection[<span class="hljs-number">0</span>] &amp;&amp;    
          randomDirection[<span class="hljs-number">1</span>] === -lastDirection[<span class="hljs-number">1</span>]) || 
         (randomDirection[<span class="hljs-number">0</span>] === lastDirection[<span class="hljs-number">0</span>] &amp;&amp;  
          randomDirection[<span class="hljs-number">1</span>] === lastDirection[<span class="hljs-number">1</span>]));
</code></pre>
<p>In the do while loop, there are two main conditions that are divided by an || (OR) sign. The first part of the condition also consists of two conditions. The first one checks if the <code>randomDirection</code>’s first item is the reverse of the <code>lastDirection</code><em>’s</em> first item. The second one checks if the <code>randomDirection</code>’s second item is the reverse of the <code>lastTurn</code>’s second item.</p>
<p>To illustrate, if the <code>lastDirection</code> is [0,1] and <code>randomDirection</code> is [0,-1], the first part of the condition checks if <code>randomDirection</code>[0] === — <code>lastDirection</code>[0]), which equates to 0 === — 0, and is true.</p>
<p>Then, it checks if (<code>randomDirection</code>[1] === — <code>lastDirection</code>[1]) which equates to (-1 === -1) and is also true. Since both conditions are true, the algorithm goes back to find another <code>randomDirection</code>.</p>
<p>The second part of the condition checks if the first and second values of both arrays are the same.</p>
<p>After choosing a <code>randomDirection</code> that satisfies the conditions, set a variable to randomly choose a length from <code>maxLength</code>. Set <code>tunnelLength</code> variable to zero to server as an iterator.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> randomLength = <span class="hljs-built_in">Math</span>.ceil(<span class="hljs-built_in">Math</span>.random() * maxLength),       
    tunnelLength = <span class="hljs-number">0</span>;
</code></pre>
<p>Make a tunnel by turning the value of cells from one to zero while the <code>tunnelLength</code> is smaller than <code>randomLength</code><em>.</em> If within the loop the tunnel hits the edges of the map, the loop should break.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">while</span> (tunnelLength &lt; randomLength) { 
 <span class="hljs-keyword">if</span>(((currentRow === <span class="hljs-number">0</span>) &amp;&amp; (randomDirection[<span class="hljs-number">0</span>] === <span class="hljs-number">-1</span>))||  
    ((currentColumn === <span class="hljs-number">0</span>) &amp;&amp; (randomDirection[<span class="hljs-number">1</span>] === <span class="hljs-number">-1</span>))|| 
    ((currentRow === dimensions — <span class="hljs-number">1</span>) &amp;&amp; (randomDirection[<span class="hljs-number">0</span>] ===<span class="hljs-number">1</span>))||
 ((currentColumn === dimensions — <span class="hljs-number">1</span>) &amp;&amp; (randomDirection[<span class="hljs-number">1</span>] === <span class="hljs-number">1</span>)))   
 { <span class="hljs-keyword">break</span>; }
</code></pre>
<p>Else set the current cell of the map to zero using <code>currentRow</code> and <code>currentColumn.</code> Add the values in the <code>randomDirection</code> array by setting <code>currentRow</code> and <code>currentColumn</code> where they need to be in the upcoming iteration of the loop. Now, increment the <code>tunnelLength</code> iterator.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">else</span>{ 
  map[currentRow][currentColumn] = <span class="hljs-number">0</span>; 
  currentRow += randomDirection[<span class="hljs-number">0</span>];
  currentColumn += randomDirection[<span class="hljs-number">1</span>]; 
  tunnelLength++; 
 } 
}
</code></pre>
<p>After the loop makes a tunnel or breaks by hitting an edge of the map, check if the tunnel is at least one block long. If so, set the <code>lastDirection</code> to the <code>randomDirection</code> and decrement <code>maxTunnels</code> and go back to make another tunnel with another <code>randomDirection</code><em>.</em></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (tunnelLength) { 
 lastDirection = randomDirection; 
 maxTunnels--; 
}
</code></pre>
<p>This IF statement prevents the for loop that hit the edge of the map and did not make a tunnel of at least one cell to decrement the <code>maxTunnel</code> and change the <code>lastDirection</code>. When that happens, the algorithm goes to find another <code>randomDirection</code> to continue.</p>
<p>When it finishes drawing tunnels and <code>maxTunnels</code> is zero, return the resulting map with all its turns and tunnels.</p>
<pre><code class="lang-javascript">}
 <span class="hljs-keyword">return</span> map;
};
</code></pre>
<p>You can see the complete algorithm in the following snippet:</p>
<p>Congratulations for reading through this tutorial. You are now well-equipped to make your own map generator or improve upon this version. Check out the project on <a target="_blank" href="https://codepen.io/anon/pen/aLpORx">CodePen</a> and on <a target="_blank" href="https://github.com/ahmadabdolsaheb/mapgen">GitHub</a> as a react application.</p>
<p><em>Thanks for reading! If you liked this story, don't forget to share it on social media.</em></p>
<p>Special thanks to <a target="_blank" href="https://github.com/moT01">Tom</a>  for co-writing this article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Play the No Internet Google Chrome Dinosaur Game - Both Online and Offline ]]>
                </title>
                <description>
                    <![CDATA[ Several years ago, Google added a fun little Easter egg to Chrome: if your internet went down and you tried to visit a web page, you'd see the message "Unable to connect to the Internet"  or "No internet" with a little pixilated dinosaur next to it. ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-play-the-no-internet-google-chrome-dinosaur-game-both-online-and-offline/</link>
                <guid isPermaLink="false">66b1fa4509c44225ad2c3904</guid>
                
                    <category>
                        <![CDATA[ Google Chrome ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ gaming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ internet ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Abigail Rennemeyer ]]>
                </dc:creator>
                <pubDate>Wed, 25 Dec 2019 21:02:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/01/image-27-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Several years ago, Google added a fun little Easter egg to Chrome: if your internet went down and you tried to visit a web page, you'd see the message "Unable to connect to the Internet"  or "No internet" with a little pixilated dinosaur next to it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-26-opt.png" alt="Image" width="600" height="400" loading="lazy">
<em>Dino says no internet today</em></p>
<p>Many people probably just thought the dinosaur was a cute little icon to keep them company while their connection was down. But then someone pressed the space bar. And the dino started running.</p>
<p>This little Easter egg has become a beloved game. But what if you just want to play it (careful, it's addictive) when you're online and need a break? In this article, you'll learn how to play the game when you're both off and online.</p>
<h2 id="heading-how-to-play-the-chrome-dino-or-trex-game-offline">How to play the Chrome dino or Trex game offline</h2>
<p>If your internet is down, just open Chrome. Or if you're already in Chrome, try to visit any web page. You'll see that little dinosaur next to its error message.</p>
<p>Simply press the space bar (or up arrow) and the dino will start running. Press the up arrow to jump over the obstacles (like cacti) in your path. The longer you hold the up arrow, the higher dino will jump.</p>
<p>If you need to duck under something, press the down arrow.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-27-opt.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The longer you play, the faster dino runs/the ground moves. Once you crash into something, the game is over and you have to restart (your score resets, too). You can play again by hitting the space bar.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-28-opt-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-play-the-chrome-dino-or-trex-game-online">How to play the Chrome dino or Trex game online</h2>
<p>Great, you have some entertainment while waiting for your internet to come back up. But what if you want to play it while online? There are a few ways to do so.</p>
<h3 id="heading-visit-the-dino-url">Visit the dino URL</h3>
<p>The simplest way to play the game online is by visiting this URL: <a target="_blank">chrome://dino/</a>. Just access that link and voilà, there's your little dino and "no internet" message.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/01/image-29.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Once you see that message, just hit the spacebar and start jumping over cacti.</p>
<p>There is also an unofficial <a target="_blank" href="https://chromedino.com/">Chrome Dino website</a> where you can play a replica of the game with different sound and graphics themes, such as this Super Mario Bros. theme:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/running-mario-opt.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Or this Batman theme with 1960s Batman sound effects:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/batman-opt.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-bonus-another-way-to-find-the-game">Bonus: Another way to find the game</h3>
<p>Maybe you didn't get the dino error message when your internet was down. Or maybe you don't want to purposely turn off your wifi to play the game. </p>
<p>So, if you have internet but want to disable your connection in Chrome dev tools, hit F12 to open up dev tools.</p>
<p>Click the "Network" tab at the top towards the right, and then look for the Online/Offline tab, second row down:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-30-cropped.png" alt="Image" width="600" height="400" loading="lazy">
<em>Look for the little dropdown arrow next to where it says "online".</em></p>
<p>Look for the little dropdown arrow, click it, and select "Offline" (instead of "Online", where it should be set if you currently have a connection).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-31-cropped.png" alt="Image" width="600" height="400" loading="lazy">
<em>Toggle to "Offline"</em></p>
<p>Once you've done that, if you try to visit a web page, you'll get the dinosaur! You can exit dev tools and hit the space bar, as usual, to get dino running.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/06/image-32-cropped.png" alt="Image" width="600" height="400" loading="lazy">
<em>Play away!</em></p>
<p>Now you know how to find the dino/Trex game without AND with internet connectivity. Have fun!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Introducing CSSBattle — the first CSS code-golfing game ]]>
                </title>
                <description>
                    <![CDATA[ By kushagra gour If you are learning Web development or are already a professional Web developer, there is a very high chance you have written CSS at least once in your life. It is a very basic building block of any webpage. Amidst all the discussion... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introducing-cssbattle-the-first-css-code-golfing-game-88b7518df618/</link>
                <guid isPermaLink="false">66c35840c7095d76345eaf98</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 17 Apr 2019 15:52:06 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*yDgSJrVPPH70Jdh6KUyokA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By kushagra gour</p>
<p>If you are learning Web development or are already a professional Web developer, there is a very high chance you have written CSS at least once in your life. It is a very basic building block of any webpage. Amidst all the discussions and love and hate for CSS, we present to you all — <a target="_blank" href="https://cssbattle.dev">CSSBattle</a> ?⚔️</p>
<p>CSSBattle is the first ever <a target="_blank" href="https://en.wikipedia.org/wiki/Code_golf">code-golfing</a> platform for CSS lovers that I and my friend, <a target="_blank" href="https://twitter.com/kushsolitary">Kushagra Agarwal</a>, have created. The aim of this game is simple — you have an image target which you need to replicate with the smallest possible CSS (and slight HTML if you please) code. More visual match and fewer bytes get you a higher score. And that is how you climb the leaderboards in CSSBattle. Here is an example target screen:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*4Qin5gKKQlk7vJPRi5rKMg.png" alt="Image" width="800" height="467" loading="lazy">
<em>Target #9 play screen</em></p>
<h3 id="heading-some-fun-stats">Some fun stats</h3>
<p>At the time of writing this post, it has been 10 days since we launched. And here are some fun stats we have gathered:</p>
<ul>
<li>13000+ players worldwide</li>
<li>Over 100K code submissions</li>
<li>Minimum bytes used on a target: <a target="_blank" href="https://cssbattle.dev/play/1">just 54 bytes</a>! ?</li>
<li>A lovely <a target="_blank" href="https://spectrum.chat/css-battle">community forum</a> of 140+ players and 40+ conversations</li>
</ul>
<h3 id="heading-product-development">Product development</h3>
<p>We decided to build and launch CSSBattle in one month, to prevent ourselves from getting into an infinite loop of adding and polishing features. We made a list of the absolutely necessary items for launch and focused on it.</p>
<p>During the development, we came up with tons of new ideas to implement in the website, which we kept noting down. I am proud we could resist the urge to work on those exciting ideas and finally launch in one month!</p>
<h4 id="heading-tech-stack">Tech Stack</h4>
<p>Our tech stack is pretty standard for today’s product. We have <a target="_blank" href="https://reactjs.org/">React</a> (using create-react-app as a starter) on the frontend which is deployed on <a target="_blank" href="https://zeit.co/now">Zeit Now</a>. For the backend, we use <a target="_blank" href="https://firebase.google.com/">Firebase</a>. Since we both primarily have frontend/design experience, Firebase turned out to be an amazing option to easily implement everything we had on our mind while getting best in class scalability and security without managing any server!</p>
<h4 id="heading-the-scoring-algorithm">The scoring algorithm</h4>
<p>One of the most interesting things about developing CSSBattle was designing the scoring algorithm. We sat literally for days discussing and trying out various formulas. We wanted that a amore visual match should always result in a higher score. And of course, for the same match percentage, the score should increase with decreasing code bytes. Also, we wanted a faster score progression towards lower bytes once you are at 100% match, to make it more rewarding for the players who sweat it out with each removed byte.</p>
<p>In the end, we are happy with what we came up with. Maybe we’ll write a separate post about just the scoring algorithm :)</p>
<h3 id="heading-the-launch">The Launch</h3>
<p>We originally planned the launch for the 5th of April, but we had to launch it a day before. We had invited many eminent CSS developers to try out CSSBattle before going public. And “fortunately” <a target="_blank" href="https://twitter.com/snookca">Jonathan Snook</a> <a target="_blank" href="https://twitter.com/snookca/status/1113480096713793542?s=20">tweeted about us</a> a day before we planned to launch, sending in a huge stream of developers to the game! And so we decide to prepone our launch :)</p>
<p>We started with the announcement on <a target="_blank" href="https://www.producthunt.com/posts/cssbattle">ProductHunt</a> where CSSBattle was the #1 product of the day. Immediately following it was a <a target="_blank" href="https://www.reddit.com/r/web_design/comments/b9e23w/we_just_launched_cssbattlethe_first_ever_css/">Reddit rush</a>. And then, the massive and really encouraging tweet by Lea Verou:</p>
<p>Since then, it has been a crazy ride for us both seeing the community grow, play, learn and compete! Each day we see players breaking the limits of creativity and imagination with CSS!</p>
<h3 id="heading-come-join-us">Come join us</h3>
<p>We have a <a target="_blank" href="https://spectrum.chat/css-battle">very lovely community</a> of superbly creative and humble developers on Spectrum where you can hang out and learn some CSS Trickery.</p>
<p>So, what are you waiting for? If you have ever written CSS, play now — <a target="_blank" href="https://cssbattle.dev">https://cssbattle.dev</a><br>(We have also seen people wanting to learn CSS just to play this game!)</p>
<h3 id="heading-fair-warning">⚠️ Fair warning</h3>
<p>CSSBattle is highly fun and <a target="_blank" href="https://twitter.com/LeaVerou/status/1114422182246064128">addictive</a>. We have seen people <a target="_blank" href="https://twitter.com/LeaVerou/status/1114735776766595073">losing their sleep</a>, <a target="_blank" href="https://twitter.com/alexzaworski/status/1114742512067862529">having weird dreams</a>, <a target="_blank" href="https://twitter.com/LeaVerou/status/1114953009061072896">being late to meet friends</a>, <a target="_blank" href="https://twitter.com/kevinnewcombe/status/1113808767907295233?s=20">cursing</a>, <a target="_blank" href="https://twitter.com/trangcongthanh/status/1114164655448924160?s=20">skipping project deadlines</a> and <a target="_blank" href="https://twitter.com/hashtag/CSSBattleChallenge">what not</a>. Please enter at your own risk! ?</p>
<p>Also, we feel it’s our responsibility to highlight that apart from creative approaches, CSSBattle requires you to exploit how CSS (and HTML) is parsed by browsers. It’s important to understand that the CSS you write here is not the way you would write in a real project. The tips and tricks you learn while playing here would certainly make you better understand CSS, but always be alert and curious about what’s a hack and what is not.</p>
<p>Have fun CSS-ing!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn advanced React patterns by developing a game with sprite animation ]]>
                </title>
                <description>
                    <![CDATA[ By Pavel Vlasov Have you ever wanted to learn some advanced React patterns? Or build your own game engine? If at least one answer is yes, then this article is for you. In this tutorial, you’ll learn how to build basic sprite animation using React, st... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-advanced-react-patterns-by-developing-a-game-with-sprite-animation-5dc072886975/</link>
                <guid isPermaLink="false">66c359997ef110ecbf367b3a</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 02 Aug 2018 16:04:11 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*p6Q4wwQ2m1D_rGYvRBRPWg.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Pavel Vlasov</p>
<p>Have you ever wanted to learn some advanced React patterns? Or build your own game engine? If at least one answer is yes, then this article is for you.</p>
<p>In this tutorial, you’ll learn how to build basic sprite animation using <a target="_blank" href="https://reactjs.org/"><strong>React</strong></a><strong>, <a target="_blank" href="https://www.styled-components.com/">styles-components</a>,</strong> and <strong>requestAnimationFrame</strong>. At the end you’ll be able to create characters like this:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Ig-pwnKpjNtc2xaM0HMR6A.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>You may ask me <em>why can’t I learn it another way</em>? Well… There’re three reasons for that:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*rBqlCIMpp_nQPy2EEpB0Hw.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>So, let’s do it! ?</p>
<h3 id="heading-lets-start-with-a-bit-of-a-theory"><strong>Let’s start with a bit of a theory</strong></h3>
<p>What is a sprite animation? <a target="_blank" href="https://en.wikipedia.org/wiki/Sprite_(computer_graphics)">Wikipedia</a> says that</p>
<blockquote>
<p>In computer graphics, a <strong>sprite</strong> is a two-dimensional bitmap that is integrated into a larger scene.</p>
</blockquote>
<p>So basically sprite animation is a repeatedly changing two-dimensional bitmap.</p>
<p>Sprite is usually represented like a png image with different states of the animation:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*hbOGCHijQurkW40hwnocDw.png" alt="Image" width="600" height="400" loading="lazy">
<em>Bitmap image</em></p>
<p>We’ll start by creating a tile component that will show us one frame at a time and allow us to change frames with <strong>state</strong> property:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*fuAsHwFdlqR1qUw2b36GlA.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Basically, we’ll need to show one part of the image at a time and hide the rest. Pretty straightforward.</p>
<h3 id="heading-tile">Tile</h3>
<p>First of all, we’ll create a container component to create the shape of our frame:</p>
<p><code>width</code> and <code>height</code> represent the size of the tale, and <code>scale</code> increases the size of the image. <code>overflow: hidden</code> will hide the unused part of the image and <code>transform-origin</code> will make a container to keep its top and left the same when we scale it.</p>
<p>Now we need to adjust the position of the inner image. We’ll use the <code>transform: translate</code> CSS property for that:</p>
<p>Now let’s combine everything together in the tile component:</p>
<ul>
<li><code>src</code> property contains a link to the image</li>
<li><code>tile</code> is the object with <code>width</code> and <code>height</code> fields, represents the size of the tile</li>
<li><code>state</code> frame index</li>
<li><code>scale</code> property to increase the size of the image (For example, <code>scale = 2</code> is 2x image)</li>
</ul>
<p>In the next step, we’ll add some movement to our image.</p>
<h3 id="heading-sprite">Sprite</h3>
<p>We’ll use <strong>requestAnimationFrame</strong> for that. You may ask why we don’t use <strong>setTimeout</strong> or <strong>setInterval.</strong> The problem with timeouts is that the callback will fire somewhere in between frames, that may result in clunky animation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*2UnyL2Wr6r2OIDvogPpNLQ.png" alt="Image" width="600" height="400" loading="lazy">
<em>requestAnimationFrame vs setInterval</em></p>
<p>Also, <strong>requestAnimationFrame</strong> allows us to synchronize animations of different objects on the screen. In the game you’ll have lots of them!</p>
<p>Let’s put together a Sprite component:</p>
<p>In the <code>animate</code> function, we should change the <code>state</code> of the frame and request a new animation frame:</p>
<p>We use the e<code>framesPerStep</code> property to control the number of states per frame, so our animation won’t be too fast.</p>
<h3 id="heading-what-about-a-gun">What about a gun? ?</h3>
<p>Now the only thing we need to do is combine our sprite with the gun image:</p>
<p>And you should get the following result:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Mi4Xn8yPVYO7nDBf5TBXdg.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p>The best way to learn something it to build it by yourself. So I encourage you to use this <a target="_blank" href="https://codesandbox.io/s/github/react-dev-camp/react-game-dev-course/tree/master/lessons/1_sprites/javascript?autoresize=1&amp;hidenavigation=1">codesandbox</a>:</p>
<p>The TypeScript version is <a target="_blank" href="https://codesandbox.io/s/github/react-dev-camp/react-game-dev-course/tree/master/lessons/1_sprites/typescript">available here as well</a>.</p>
<p>As a bonus, you can implement different animations using files from the assets folder.</p>
<p>You can find the source code <a target="_blank" href="https://github.com/react-dev-camp/react-game-dev-course">here</a>. I used game assets made by <a target="_blank" href="https://finalbossblues.itch.io/pixel-shooter-towers-asset-pack">finalbossblues</a>.</p>
<p>Hope you enjoyed the article! ?</p>
<p>Follow me on <a target="_blank" href="https://medium.com/@pvlasov">Medium</a> and <a target="_blank" href="https://twitter.com/pvl4sov">Twitter</a> to get more updates on new articles. Also, share this article to help others know about it. Sharing is caring ?</p>
<p><strong>Destroy this clap button if you want more.</strong></p>
<p><strong>You can clap up to 50 times!</strong> ?</p>
<p>Some more resources about the topic:</p>
<p><a target="_blank" href="http://www.javascriptkit.com/javatutors/requestanimationframe.shtml"><strong>Understanding JavaScript's requestAnimationFrame() method for smooth animations</strong></a><br><a target="_blank" href="http://www.javascriptkit.com/javatutors/requestanimationframe.shtml">_requestAnimationFrame() is a JavaScript method for creating smoother, less resource intensive JavaScript animations…_www.javascriptkit.com</a></p>
<p><em>Originally published at <a target="_blank" href="http://react.camp/posts/advanced-react-patterns-game-engine-1-sprites/">react.camp</a>.</em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Think like a programmer: How to build Snake using only JavaScript, HTML & CSS ]]>
                </title>
                <description>
                    <![CDATA[ By Panayiotis Nicolaou Hello there ? Welcome on board. Today we will embark on an exciting adventure, where we will be making our very own snake game ?. You’ll learn how to work through a problem by breaking it down into smaller simpler steps. By the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/think-like-a-programmer-how-to-build-snake-using-only-javascript-html-and-css-7b1479c3339e/</link>
                <guid isPermaLink="false">66c3630daf2b7c40e7d7eb46</guid>
                
                    <category>
                        <![CDATA[ CSS ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 05 Jul 2018 21:28:34 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*9xRelIyk3BRGfRoArVU6wA.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Panayiotis Nicolaou</p>
<p>Hello there ?</p>
<p>Welcome on board. Today we will embark on an exciting adventure, where we will be making our very own snake game ?. You’ll learn how to work through a problem by breaking it down into smaller simpler steps. By the end of this journey, you will have learned some new things, and you’ll feel confident to explore more on your own.</p>
<p>If you are new to programming, I recommend checking out <a target="_blank" href="https://www.freecodecamp.org/">freeCodeCamp</a>. It’s a great place to learn for…you guessed it…free. That’s how I got started ?</p>
<p>Okay, okay enough messin’ around — are you ready to start?</p>
<blockquote>
<p>You can find the final code <a target="_blank" href="https://github.com/supergoat/snake">here</a> and a live demo <a target="_blank" href="https://snake-cdxejlircg.now.sh">here</a>.</p>
</blockquote>
<h3 id="heading-getting-started">Getting Started</h3>
<p>Let’s begin by creating a file “snake.html” that will contain all our code.</p>
<p>Since this is an HTML file, the first thing we need is the <code>[&lt;!DOCTY](https://www.w3schools.com/tags/tag_doctype.asp)</code>PE&gt; declaration <code>. In snak</code>e.html type the following:</p>
<p>Great, now go ahead and open <code>snake.html</code> in your preferred browser. You should be able to see <strong>Welcome to Snake!</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*PFyqYaApjv8H6-ddH79HaQ.png" alt="Image" width="584" height="156" loading="lazy">
<em><strong>snake.html</strong> opened in chrome</em></p>
<p>We are off to a good start ?</p>
<h3 id="heading-creating-the-canvas">Creating the Canvas</h3>
<p>To be able to create our game, we have to make use of HTML <code>[&lt;canv](https://www.w3schools.com/html/html5_canvas.asp)</code>as&gt; . This is what is used to draw graphics using JavaScript.</p>
<p>Replace the welcome message in <code>snake.html</code> with the following:</p>
<pre><code>&lt;canvas id=<span class="hljs-string">"gameCanvas"</span> width=<span class="hljs-string">"300"</span> height=<span class="hljs-string">"300"</span>&gt;&amp;lt;canvas&gt;
</code></pre><p>The id is what identifies the canvas and should always be specified. We will use it to access the canvas later. The width and height are the dimensions of the canvas, and should also be specified. In this case, 300 x 300 pixels.</p>
<p>Your snake.html file should now look like this.</p>
<p>If you refresh your browser page where you previously opened <code>snake.html</code> you will now see a blank page. This is because, by default, the canvas is empty and has no background. Lets fix that. ?</p>
<h4 id="heading-give-the-canvas-a-background-colour-and-a-border">Give the canvas a background colour and a border</h4>
<p>To make our canvas visible, we can give it a border by writing some JavaScript code. To do that, we need to insert <code>&lt;script&gt;&lt;</code>;/script&gt; tag<code>s after t</code>he , where all our JavaScript code will go.</p>
<blockquote>
<p>If you put the <code>_&lt;scri_</code>pt&gt; tag befor<code>_e the &amp;l_</code>t;canvas&gt; your code won’t work, as the HTML will not be loaded.</p>
</blockquote>
<p>We can now write some JavaScript code, between the enclosing<code>&lt;script&gt;&lt;</code>;/script&gt; tags. Update your code as below.</p>
<p>First we get the canvas element using the id (gameCanvas) we specified earlier. We then get the canvas “2d” context, which means we will be drawing into 2D space.</p>
<p>Finally we draw a 300 x 300 white rectangle with a black border. This covers the entire canvas, starting from the top left corner (0, 0).</p>
<p>If you reload <code>snake.html</code> in your browser, you should see a white box with a black border! Good job, we have a canvas that we can use to create our snake game! ? On to the next challenge!</p>
<h3 id="heading-representing-our-snake">Representing our snake</h3>
<p>For our snake game to work, we need to know the location of the snake on the canvas. To do that, we can represent the snake as an array of coordinates. Thus, to create a horizontal snake in the middle of the canvas (150, 150) we can write the following:</p>
<pre><code><span class="hljs-keyword">let</span> snake = [  {<span class="hljs-attr">x</span>: <span class="hljs-number">150</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">150</span>},  {<span class="hljs-attr">x</span>: <span class="hljs-number">140</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">150</span>},  {<span class="hljs-attr">x</span>: <span class="hljs-number">130</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">150</span>},  {<span class="hljs-attr">x</span>: <span class="hljs-number">120</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">150</span>},  {<span class="hljs-attr">x</span>: <span class="hljs-number">110</span>, <span class="hljs-attr">y</span>: <span class="hljs-number">150</span>},];
</code></pre><p>Notice that the y coordinate for all parts is always 150. The x coordinate of each part is -10px (to the left) of the previous part. The first pair of coordinates in the array <code>{x: 150, y: 150}</code> represents the head at the very right of the snake.</p>
<p>This will become clearer when we draw the snake in the next section.</p>
<h3 id="heading-creating-and-drawing-our-snake">Creating and drawing our snake</h3>
<p>To display the snake on the canvas, we can write a function to draw a rectangle <strong>for each</strong> pair of coordinates.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">drawSnakePart</span>(<span class="hljs-params">snakePart</span>) </span>{  ctx.fillStyle = <span class="hljs-string">'lightgreen'</span>;  ctx.strokestyle = <span class="hljs-string">'darkgreen'</span>;
</code></pre><pre><code>  ctx.fillRect(snakePart.x, snakePart.y, <span class="hljs-number">10</span>, <span class="hljs-number">10</span>);  ctx.strokeRect(snakePart.x, snakePart.y, <span class="hljs-number">10</span>, <span class="hljs-number">10</span>);}
</code></pre><p>Next we can create another function that prints the parts on the canvas.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">drawSnake</span>(<span class="hljs-params"></span>) </span>{  snake.forEach(drawSnakePart);}
</code></pre><p>Our <code>snake.html</code> file should now look like this:</p>
<p>If you refresh your browser page now you will see a green snake in the middle of the canvas. Awesome! ?</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*BLf1mbFS-SCl4M8VQen1Qg.png" alt="Image" width="800" height="393" loading="lazy"></p>
<h3 id="heading-enabling-the-snake-to-move-horizontally">Enabling the snake to move horizontally</h3>
<p>Next we want to give the snake the ability to move. But how do we do that? ?</p>
<p>Well, to make the snake move one step (10px) to the right, we can increase the x-coordinate of <strong>every</strong> part of the snake by 10px (dx = +10px). To make the snake move to the left, we can decrease the x-coordinate of <strong>every</strong> part of the snake by 10px (dx = -10).</p>
<blockquote>
<p><strong>dx</strong> is the horizontal velocity of the snake.</p>
</blockquote>
<p>Creating a snake that has moved 10px to the right should then look like this</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*zytaPha9jcM6N45xrOnyTw.png" alt="Image" width="800" height="221" loading="lazy"></p>
<p>Create a function called <code>advanceSnake</code> that we will use to update the snake.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">advanceSnake</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">const</span> head = {<span class="hljs-attr">x</span>: snake[<span class="hljs-number">0</span>].x + dx, <span class="hljs-attr">y</span>: snake[<span class="hljs-number">0</span>].y};
</code></pre><pre><code>  snake.unshift(head);
</code></pre><pre><code>  snake.pop();}
</code></pre><p>First we create a new head for the snake. We then add the new head to the beginning of <strong>snake</strong> using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift">unshift</a> and remove the last element of <strong>snake</strong> using <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop">pop</a>. This way all the other snake parts shift into place as shown above.</p>
<p>Boom ?, you are getting the hang of this.</p>
<h3 id="heading-enabling-the-snake-to-move-vertically">Enabling the snake to move vertically</h3>
<p>To move our snake up and down, we can’t alter all y-coordinates by 10px. That would shift the whole snake up and down.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*39OySfjontvvtgrLQhyt3A.gif" alt="Image" width="240" height="240" loading="lazy"></p>
<p>Instead we can alter the y-coordinate of the head. Decreasing it by 10px to move the snake down, and increasing it by 10px to move the snake up. This will make the snake move correctly.</p>
<p>Luckily, because of the way we wrote the <code>advanceSnake</code> function, this is very easy to do. Inside <code>advanceSnake</code>, update the head to also increase the y-coordinate of the head by <strong>dy</strong>.</p>
<pre><code><span class="hljs-keyword">const</span> head = {<span class="hljs-attr">x</span>: snake[<span class="hljs-number">0</span>].x + dx, <span class="hljs-attr">y</span>: snake[<span class="hljs-number">0</span>].y + dy};
</code></pre><p>To test how our <code>advanceSnake</code> function works, we can temporarily call it before the <code>drawSnake</code> function.</p>
<pre><code><span class="hljs-comment">// Move on step to the rightadvanceSnake()</span>
</code></pre><pre><code><span class="hljs-comment">// Change vertical velocity to 0dx = 0;// Change horizontal velocity to 10dy = -10;</span>
</code></pre><pre><code><span class="hljs-comment">// Move one step upadvanceSnake();</span>
</code></pre><pre><code><span class="hljs-comment">// Draw snake on the canvasdrawSnake();</span>
</code></pre><p>This is how our <code>snake.html</code> file looks so far.</p>
<p>Refreshing the browser, we can see that our snake has moved. Success!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Qnmxp7sFC4TREwVFYqh2vg.png" alt="Image" width="800" height="378" loading="lazy"></p>
<h3 id="heading-refactoring-our-code">Refactoring our code</h3>
<p>Before we move on, let’s do some refactoring and move the code that draws the canvas inside a function. This will help us in the next section.</p>
<blockquote>
<p><strong>“Code refactoring</strong> is the process of restructuring existing computer <strong>code,</strong> without changing its external behaviour.” -<a target="_blank" href="https://en.wikipedia.org/wiki/Code_refactoring">wikipedia</a></p>
</blockquote>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">clearCanvas</span>(<span class="hljs-params"></span>) </span>{  ctx.fillStyle = <span class="hljs-string">"white"</span>;  ctx.strokeStyle = <span class="hljs-string">"black"</span>;
</code></pre><pre><code>  ctx.fillRect(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, gameCanvas.width, gameCanvas.height);  ctx.strokeRect(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, gameCanvas.width, gameCanvas.height);}
</code></pre><p>We are making great strides! ?</p>
<h3 id="heading-making-our-snake-move-automatically">Making our snake move automatically</h3>
<p>Okay, now that we have successfully refactored our code, we can make our snake move automatically.</p>
<p>Earlier, to test that our <code>advanceSnake</code> function worked, we called it twice. Once to make the snake move to the right, and once to make the snake move up.</p>
<p>Thus if we wanted to make the snake move five steps to the right we would call <code>advanceSnake()</code> five times in a row.</p>
<pre><code>clearCanvas();advanceSnake();advanceSnake();advanceSnake();advanceSnake();advanceSnake();drawSnake();
</code></pre><p>But, calling it five times in a row as shown above, will make the snake jump 50px forward.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*8MMmK5I75eaA_fxHFUiiwQ.gif" alt="Image" width="240" height="240" loading="lazy"></p>
<p>Instead we want to make the snake appear to be moving forward step by step.</p>
<p>To do that, we can add a slight delay between each call, using <a target="_blank" href="https://www.w3schools.com/Jsref/met_win_settimeout.asp">setTimeout</a>. We also need to make sure to call <code>drawSnake</code> every time we call <code>advanceSnake</code>. If we don’t, we won’t be able to see the intermediate steps that show the snake moving.</p>
<pre><code><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{  clearCanvas();  advanceSnake();  drawSnake();}, <span class="hljs-number">100</span>);
</code></pre><pre><code><span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{  clearCanvas();  advanceSnake();  drawSnake();}, <span class="hljs-number">100</span>);
</code></pre><pre><code>...
</code></pre><pre><code>drawSnake();
</code></pre><p>Notice how we also call <code>_clearCanvas()_</code> inside each <code>_setTimeout_</code>. This is to remove all the previous positions of the snake that would leave a trail behind.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*q59cpBnigigbLPslBUkiLw.png" alt="Image" width="800" height="426" loading="lazy"></p>
<p>Although, there is a problem with the above code. There is nothing here to tell the program that it has to wait for <strong>setTimeout</strong> before it moves to the next <strong>setTimeout</strong>. This means that the snake will <strong>still</strong> jump 50px forward but after a <strong>slight delay</strong>.</p>
<p>To fix that, we have to wrap our code inside functions, calling one function at a time.</p>
<pre><code>stepOne();    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stepOne</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{    clearCanvas();    advanceSnake();    drawSnake();   <span class="hljs-comment">// Call the second function   stepTwo();  }, 100)}</span>
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">stepTwo</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{    clearCanvas();    advanceSnake();    drawSnake();    <span class="hljs-comment">// Call the third function    stepThree();  }, 100)}</span>
</code></pre><pre><code>...
</code></pre><p>How do we make our snake keep moving? Instead of creating an infinite number of functions that call each other, we can instead create one function <code>main</code> and call it over and over again.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{    clearCanvas();    advanceSnake();    drawSnake();
</code></pre><pre><code>    <span class="hljs-comment">// Call main again    main();  }, 100)}</span>
</code></pre><p>Voilà! We now have a snake that will keep moving to the right. Although, once it reaches the end of the canvas, it continues its infinite journey into the unknown ?. We will fix that in due time, patience young padawan. ?.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*qr0kvF_aQ2E_n6QcxfkyQA.gif" alt="Image" width="320" height="320" loading="lazy"></p>
<h3 id="heading-changing-the-snakes-direction">Changing the snake’s direction</h3>
<p>Our next task is to change the snake’s direction when one of the arrow keys is pressed. Add the following code after the <code>drawSnakePart</code> function.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeDirection</span>(<span class="hljs-params">event</span>) </span>{  <span class="hljs-keyword">const</span> LEFT_KEY = <span class="hljs-number">37</span>;  <span class="hljs-keyword">const</span> RIGHT_KEY = <span class="hljs-number">39</span>;  <span class="hljs-keyword">const</span> UP_KEY = <span class="hljs-number">38</span>;  <span class="hljs-keyword">const</span> DOWN_KEY = <span class="hljs-number">40</span>;
</code></pre><pre><code>  <span class="hljs-keyword">const</span> keyPressed = event.keyCode;  <span class="hljs-keyword">const</span> goingUp = dy === <span class="hljs-number">-10</span>;  <span class="hljs-keyword">const</span> goingDown = dy === <span class="hljs-number">10</span>;  <span class="hljs-keyword">const</span> goingRight = dx === <span class="hljs-number">10</span>;  <span class="hljs-keyword">const</span> goingLeft = dx === <span class="hljs-number">-10</span>;
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (keyPressed === LEFT_KEY &amp;&amp; !goingRight) {    dx = <span class="hljs-number">-10</span>;    dy = <span class="hljs-number">0</span>;  }
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (keyPressed === UP_KEY &amp;&amp; !goingDown) {    dx = <span class="hljs-number">0</span>;    dy = <span class="hljs-number">-10</span>;  }
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (keyPressed === RIGHT_KEY &amp;&amp; !goingLeft) {    dx = <span class="hljs-number">10</span>;    dy = <span class="hljs-number">0</span>;  }
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (keyPressed === DOWN_KEY &amp;&amp; !goingDown) {    dx = <span class="hljs-number">0</span>;    dy = <span class="hljs-number">10</span>;  }}
</code></pre><p>There is nothing tricky going on here. We check if the key pressed matches one of the arrow keys. If it does, we change the vertical and horizontal velocity as described earlier.</p>
<p>Notice that we also check if the snake is moving in the opposite direction of the new intended direction. This is to prevent our snake from reversing, for example when you press the <strong>right</strong> arrow key when the snake is moving to the <strong>left.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*PxB5A6SCbJlwye4PUj_Bdw.gif" alt="Image" width="320" height="322" loading="lazy">
<em>Snake reversing</em></p>
<p>To connect <code>changeDirection</code> to our game, we can use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener</a> on the <a target="_blank" href="https://www.w3schools.com/Jsref/dom_obj_document.asp">document</a> to ‘listen’ for when a key is pressed. Then we can call <code>changeDirection</code> with the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/Events/keydown">keydown</a> event. Add the following code after the <code>main</code> function.</p>
<pre><code><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"keydown"</span>, changeDirection)
</code></pre><p>You should now be able to change the snake’s direction using the four arrow keys. Great work, you are on fire?!</p>
<p>Next lets see how we can generate food and grow our snake.</p>
<h3 id="heading-generating-food-for-the-snake">Generating food for the snake</h3>
<p>For our snake food, we have to generate a random set of coordinates. We can use a helper function <code>randomTen</code> to produce two numbers. One for the x-coordinate and one for the y-coordinate.</p>
<p>We also have to make sure that the food is not located where the snake currently is. If it is, we have to generate a new food location.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">randomTen</span>(<span class="hljs-params">min, max</span>) </span>{  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.round((<span class="hljs-built_in">Math</span>.random() * (max-min) + min) / <span class="hljs-number">10</span>) * <span class="hljs-number">10</span>;}
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createFood</span>(<span class="hljs-params"></span>) </span>{  foodX = randomTen(<span class="hljs-number">0</span>, gameCanvas.width - <span class="hljs-number">10</span>);  foodY = randomTen(<span class="hljs-number">0</span>, gameCanvas.height - <span class="hljs-number">10</span>);
</code></pre><pre><code>  snake.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isFoodOnSnake</span>(<span class="hljs-params">part</span>) </span>{    <span class="hljs-keyword">const</span> foodIsOnSnake = part.x == foodX &amp;&amp; part.y == foodY    <span class="hljs-keyword">if</span> (foodIsOnSnake)      createFood();  });}
</code></pre><p>We then have to create a function to draw the food on the canvas.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">drawFood</span>(<span class="hljs-params"></span>) </span>{ ctx.fillStyle = <span class="hljs-string">'red'</span>; ctx.strokestyle = <span class="hljs-string">'darkred'</span>; ctx.fillRect(foodX, foodY, <span class="hljs-number">10</span>, <span class="hljs-number">10</span>); ctx.strokeRect(foodX, foodY, <span class="hljs-number">10</span>, <span class="hljs-number">10</span>);}
</code></pre><p>Finally we can call <code>createFood</code> before calling <code>main</code>. Don’t forget to also update <code>main</code> to use the <code>drawFood</code> function.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{    clearCanvas();    drawFood()    advanceSnake();    drawSnake();
</code></pre><pre><code>    main();  }, <span class="hljs-number">100</span>)}
</code></pre><h3 id="heading-growing-the-snake">Growing the snake</h3>
<p>Growing our snake is simple. We can update our <code>advanceSnake</code> function to check if the head of the snake is touching the food. If it is we can skip removing the last part of the snake and create a new food location.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">advanceSnake</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">const</span> head = {<span class="hljs-attr">x</span>: snake[<span class="hljs-number">0</span>].x + dx, <span class="hljs-attr">y</span>: snake[<span class="hljs-number">0</span>].y};
</code></pre><pre><code>  snake.unshift(head);
</code></pre><pre><code>  <span class="hljs-keyword">const</span> didEatFood = snake[<span class="hljs-number">0</span>].x === foodX &amp;&amp; snake[<span class="hljs-number">0</span>].y === foodY;  <span class="hljs-keyword">if</span> (didEatFood) {    createFood();  } <span class="hljs-keyword">else</span> {    snake.pop();  }}
</code></pre><h4 id="heading-keeping-track-of-the-score">Keeping track of the score</h4>
<p>To make the game more enjoyable for the player, we can also add a score that increases when the snake eats food.</p>
<p>Create a new variable score and set it to 0 after the snake declaration.</p>
<pre><code><span class="hljs-keyword">let</span> score = <span class="hljs-number">0</span>;
</code></pre><p>Next add a new div with an id “score” before the canvas. We can use this to display the score.</p>
<pre><code>&lt;div id=<span class="hljs-string">"score"</span>&gt;<span class="hljs-number">0</span>&lt;<span class="hljs-regexp">/div&gt;&lt;canvas id="gameCanvas" width="300" height="300"&gt;&lt;/</span>canvas&gt;
</code></pre><p>Finally update <code>advanceSnake</code> to increase and display the score when the snake eats the food.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">advanceSnake</span>(<span class="hljs-params"></span>) </span>{  ...
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (didEatFood) {    score += <span class="hljs-number">10</span>;    <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'score'</span>).innerHTML = score;
</code></pre><pre><code>    createFood();  } <span class="hljs-keyword">else</span> {    ...  }}
</code></pre><p>Pheew, that was quite a lot, but we have come a long way ?</p>
<h3 id="heading-end-the-game">End the game</h3>
<p>There is one final piece left, and that is to end the game ?. To do that we can create a function d<code>idGameEnd</code> that returns t<strong>rue</strong> when the game has ended or f<strong>alse</strong> otherwise.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">didGameEnd</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">4</span>; i &lt; snake.length; i++) {    <span class="hljs-keyword">const</span> didCollide = snake[i].x === snake[<span class="hljs-number">0</span>].x &amp;&amp;      snake[i].y === snake[<span class="hljs-number">0</span>].y
</code></pre><pre><code>    <span class="hljs-keyword">if</span> (didCollide) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>  }
</code></pre><pre><code>  <span class="hljs-keyword">const</span> hitLeftWall = snake[<span class="hljs-number">0</span>].x &lt; <span class="hljs-number">0</span>;  <span class="hljs-keyword">const</span> hitRightWall = snake[<span class="hljs-number">0</span>].x &gt; gameCanvas.width - <span class="hljs-number">10</span>;  <span class="hljs-keyword">const</span> hitToptWall = snake[<span class="hljs-number">0</span>].y &amp;lt; <span class="hljs-number">0</span>;  <span class="hljs-keyword">const</span> hitBottomWall = snake[<span class="hljs-number">0</span>].y &gt; gameCanvas.height - <span class="hljs-number">10</span>;
</code></pre><pre><code>  <span class="hljs-keyword">return</span> hitLeftWall ||          hitRightWall ||          hitToptWall ||         hitBottomWall}
</code></pre><p>First we check if the snake’s head touches another part of the snake and return <strong>true</strong> if it does.</p>
<blockquote>
<p>Notice that we start our loop from index 4. There are two reasons for that. The first is that <strong>didCollide</strong> would immediately evaluate to true if the index was 0, so the game would end. The second is that, it is impossible for the first three parts to touch each other.</p>
</blockquote>
<p>Next we check if the snake hit any of the canvas walls and return <strong>true</strong> if it did, otherwise we return <strong>false</strong>.</p>
<p>Now we can return early in our <code>main</code> function if <code>didEndGame</code> returns true, thus ending the game.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">if</span> (didGameEnd()) <span class="hljs-keyword">return</span>;
</code></pre><pre><code>  ...}
</code></pre><p>Our snake.html should now look like this:</p>
<p>You now have a functioning snake game that you can play and share with your friends. But before celebrating lets look at one final problem. This will be the last one, I promise.</p>
<h3 id="heading-sneaky-bugs">Sneaky bugs ?</h3>
<p>If you play the game enough times, you might notice that sometimes the game ends unexpectedly. This is a very good example on how bugs can sneak into our programs and cause trouble ?.</p>
<p>When a bug occurs, the best way to solve it is to first have a reliable way of reproducing it. That is, come up with the precise steps that lead to the unexpected behaviour. Then you need to understand why they cause the unexpected behaviour and then come up with a solution.</p>
<h4 id="heading-reproducing-the-bug">Reproducing the bug</h4>
<p>In our case, the steps taken to reproduce the bug are as follows:</p>
<ul>
<li>The snake is moving to the left</li>
<li>The player presses the down arrow key</li>
<li>The player immediately presses the right arrow key (before 100ms have lapsed)</li>
<li>The game ends</li>
</ul>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*rMOAsWJxt8uD2p3dILRHnw.gif" alt="Image" width="320" height="336" loading="lazy"></p>
<h4 id="heading-making-sense-of-the-bug">Making sense of the bug</h4>
<p>Let’s break down what happens step by step.</p>
<p><strong>Snake is moving to the left</strong></p>
<ul>
<li>Horizontal velocity, dx is equal to -10</li>
<li><code>main</code> function is called</li>
<li><code>advanceSnake</code> is called which advances the snake -10px to the left.</li>
</ul>
<p><strong>The player presses the down arrow key</strong></p>
<ul>
<li><code>changeDirection</code> is called</li>
<li><code>keyPressed === DOWN_KEY &amp;&amp; dy !goingUp</code> evaluates to true</li>
<li>dx changes to 0</li>
<li>dy changes to +10</li>
</ul>
<p><strong>Player immediately presses the right arrow (before 100ms have lapsed)</strong></p>
<ul>
<li><code>changeDirection</code> is called</li>
<li><code>keyPressed === RIGHT_KEY &amp;&amp; !goingLeft</code> evaluates to true</li>
<li>dx changes to +10</li>
<li>dy changes to 0</li>
</ul>
<p><strong>The game ends</strong></p>
<ul>
<li><code>main</code> function is called <strong>after 100ms have lapsed.</strong></li>
<li><code>advanceSnake</code> is called which advances the snake 10px to the right.</li>
<li><code>const didCollide = snake[i].x === snake[0].x &amp;&amp; snake[i].y === snake[0].y</code> evaluates to true</li>
<li><code>didGameEnd</code> returns true</li>
<li><code>main</code> function returns early</li>
<li>The game ends</li>
</ul>
<h4 id="heading-fixing-the-bug">Fixing the bug</h4>
<p>After studying what happened, we learn that the game ended because the snake reversed.</p>
<p>That is because when the player pressed the down arrow, dx was set to 0. Thus <code>keyPressed === RIGHT_KEY &amp;&amp; !goingLeft</code> evaluated to true, and dx changed to 10.</p>
<p>It is important to note that the change in direction occurred <strong>before</strong> 100ms had lapsed. If 100ms lapsed, then the snake would have first taken a step down and would not have reversed.</p>
<p>To fix our bug, we have to make sure that we can only change direction after <code>main</code> and <code>advanceSnake</code> have been called. We can create a variable <strong>changingDirection.</strong> This will be set to true when <code>changeDirection</code> is called, and to false when <code>advanceSnake</code> is called.</p>
<p>Inside our <code>changeDirection</code> function, we can return early if <strong>changingDirection</strong> is true.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeDirection</span>(<span class="hljs-params">event</span>) </span>{  <span class="hljs-keyword">const</span> LEFT_KEY = <span class="hljs-number">37</span>;  <span class="hljs-keyword">const</span> RIGHT_KEY = <span class="hljs-number">39</span>;  <span class="hljs-keyword">const</span> UP_KEY = <span class="hljs-number">38</span>;  <span class="hljs-keyword">const</span> DOWN_KEY = <span class="hljs-number">40</span>;
</code></pre><pre><code>  <span class="hljs-keyword">if</span> (changingDirection) <span class="hljs-keyword">return</span>;
</code></pre><pre><code>  changingDirection = <span class="hljs-literal">true</span>;
</code></pre><pre><code>  ...}
</code></pre><pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onTick</span>(<span class="hljs-params"></span>) </span>{    changingDirection = <span class="hljs-literal">false</span>;        ...
</code></pre><pre><code>  }, <span class="hljs-number">100</span>)}
</code></pre><p>Here is our final version of snake.html</p>
<blockquote>
<p>Notice I also added some styles ? between the &amp;<code>_lt;style&gt;&lt;_</code>;/style&gt; tags. That is to make the canvas and score appear in the middle of the screen.</p>
</blockquote>
<h3 id="heading-conclusion">Conclusion</h3>
<p>Congratulations!! ??</p>
<p>We have reached the end of our journey. I hope you enjoyed learning with me and now feel confident to continue on to your next adventure.</p>
<p>But it doesn’t have to end here. My next article will focus on helping you get started with the <strong>very</strong> exciting world of <strong>open source</strong>.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Open-source_software">Open source</a> is a great way to learn <strong>a lot</strong> of new things and get to know amazing people . It is very rewarding but can can be scary at first ?.</p>
<p>To get a notification when my next article is out, you can follow me! ?</p>
<p>It was a pleasure to be on this journey with you.</p>
<p>Till next time. ✨</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn how to manipulate the DOM by building a simple JavaScript color game ]]>
                </title>
                <description>
                    <![CDATA[ By Ashish Nandan Singh What is the DOM ? DOM stands for Document Object Model. It’s nothing more than the block level diagram of all the HTML elements loaded on the page when a browser loads a web page. It is presented as a tree of objects which are ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-how-to-manipulate-the-dom-by-building-a-simple-javascript-color-game-1a3aec1d109a/</link>
                <guid isPermaLink="false">66c359b5cf1314a450f0d70d</guid>
                
                    <category>
                        <![CDATA[ Games ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Wed, 20 Jun 2018 19:01:21 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*5dbaz5S1Buevb-fZQDbYzg.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ashish Nandan Singh</p>
<h3 id="heading-what-is-the-dom">What is the DOM ?</h3>
<p>DOM stands for Document Object Model. It’s nothing more than the block level diagram of all the HTML elements loaded on the page when a browser loads a web page. It is presented as a tree of objects which are HTML elements. Look at the image below and you may get a better idea.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*QTOLCnPd_rg5Fum9l9PNSA.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>DOM representation of a simple .html file</em></p>
<p>A nice clean block diagram of your ugly .html file — isn’t that great! But now you are thinking, how does this help me? What’s the use case? Why do I need to know this?</p>
<p>To put it simply, the DOM enables you to bring dynamics to your static website. With the use of the DOM, you can do a bunch of useful things on the webpage like:</p>
<ul>
<li>adding and deleting HTML elements and attributes</li>
<li>adding and deleting CSS rules on a user fired event</li>
<li>creating new events for synthetic user events</li>
</ul>
<p>And this is exactly what you will learn throughout the course of this article.</p>
<p>To give you an idea of what we will achieve by the end of this article, check out <a target="_blank" href="https://colorgame-f0a09.firebaseapp.com/">this link</a>.</p>
<h3 id="heading-getting-started"><strong>Getting started</strong></h3>
<p>We will build a simple color guessing game. Every time the game is started, a random RGB color code will be selected. Depending on the mode of the game, we will have three (easy) or six (hard) options or color blocks on the screen to choose from. Every time an incorrect color block is selected, the block will disappear until the user selects the correct color (or its the last option left).</p>
<p>Here’s a rough diagram of what we would be building:</p>
<p>This is something I learnt while I was taking a course from <a target="_blank" href="https://www.linkedin.com/in/coltsteele">Colt Steele</a>, phenomenal trainer when it comes to teaching basic concepts. You all should check out his videos on Udemy’s YouTube channel.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ezY7AYaRb8oAbfmjyNeGaw.png" alt="Image" width="600" height="400" loading="lazy">
<em>Mockup diagram</em></p>
<h4 id="heading-part-1">Part 1</h4>
<p>We’ll start by creating a simple web boiler plate, which will be compromised of index.html, app.css, and app.js files. Let’s see how these files look when we’re starting out.</p>
<p>But first, please note: just to keep it simple for anyone who is reading this without any prior development experience, I will keep showing the source code whenever we change something major.</p>
<ul>
<li><strong>index.html</strong></li>
</ul>
<pre><code>&lt;!DOCTYPE html&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span></span>
</code></pre><pre><code>&lt;head&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Color Game<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"app.css"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span></span>
</code></pre><pre><code>&lt;body&gt;
</code></pre><pre><code>&lt;h1&gt;The Great&lt;br&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"colorDisplay"</span>&gt;</span>RGB<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span>Color Game<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span></span>
</code></pre><pre><code>&lt;div id=<span class="hljs-string">"stripe"</span>&gt;
</code></pre><pre><code>&lt;button id=<span class="hljs-string">"reset"</span>&gt;New Colors&lt;<span class="hljs-regexp">/button&gt;&lt;span id="message"&gt;&lt;/</span>span&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mode"</span>&gt;</span>Easy<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"mode selected"</span>&gt;</span>Hard<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
</code></pre><pre><code>&lt;/div&gt;
</code></pre><pre><code>&lt;div id=<span class="hljs-string">"container"</span>&gt;
</code></pre><pre><code>&lt;div <span class="hljs-class"><span class="hljs-keyword">class</span></span>=<span class="hljs-string">"square"</span>&gt;&lt;<span class="hljs-regexp">/div&gt;&lt;div class="square"&gt;&lt;/</span>div&gt;<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"square"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"square"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"square"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"square"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
</code></pre><pre><code>&lt;/div&gt;
</code></pre><pre><code>&lt;script type=<span class="hljs-string">"text/javascript"</span> src=<span class="hljs-string">"app.js"</span>&gt;&lt;<span class="hljs-regexp">/script&gt;&lt;/</span>body&gt;&lt;/html&gt;
</code></pre><p>This is as simple as it gets. We can simply segregate the entire webpage in three primary blocks.</p>
<p>First we have the header section, which has the text and may contain some other information if you want to add it in there.</p>
<p>Next is the control panel, which has buttons to reset the game and to switch between the game modes.</p>
<p>Third — and the most interesting part — is the main game area, which has six divs. These divs serve as the options for every random RGB color code which can be selected by some fancy logic (which we will see in a while).</p>
<ul>
<li><strong>app.css</strong></li>
</ul>
<pre><code>body {
</code></pre><pre><code>background-color: #<span class="hljs-number">232323</span>;margin: <span class="hljs-number">0</span>;font-family: <span class="hljs-string">"Montserrat"</span>, <span class="hljs-string">"Avenir"</span>;}
</code></pre><pre><code>h1 {
</code></pre><pre><code>text-align: center;line-height: <span class="hljs-number">1.1</span>;font-weight: normal;color: white;background: steelblue;margin: <span class="hljs-number">0</span>;text-transform: uppercase;padding: <span class="hljs-number">20</span>px <span class="hljs-number">0</span>;}
</code></pre><pre><code>#container {
</code></pre><pre><code>margin: <span class="hljs-number">20</span>px auto;max-width: <span class="hljs-number">600</span>px;}
</code></pre><pre><code>.square {
</code></pre><pre><code>width: <span class="hljs-number">30</span>%;background: purple;padding-bottom: <span class="hljs-number">30</span>%;float: left;margin: <span class="hljs-number">1.66</span>%;border-radius: <span class="hljs-number">15</span>%;transition: background <span class="hljs-number">0.6</span>s;-webkit-transition: background <span class="hljs-number">0.6</span>s;-moz-transition: background <span class="hljs-number">0.6</span>s;}
</code></pre><p>Some basic styles have been added for the body, text, and squares that serve as the game options.</p>
<ul>
<li><strong>app.js</strong></li>
</ul>
<pre><code><span class="hljs-keyword">var</span> numSquares = <span class="hljs-number">6</span>;<span class="hljs-keyword">var</span> colors = [];<span class="hljs-keyword">var</span> pickedColor;<span class="hljs-keyword">var</span> squares = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".square"</span>);<span class="hljs-keyword">var</span> resetButton = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#reset"</span>);<span class="hljs-keyword">var</span> modeButtons = <span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">".mode"</span>);
</code></pre><p>We have stored all the HTML elements in the form of variables. This will help us perform some actions by adding events to each of these variables, and by calling them inside various logic functions we will create during this article.</p>
<p>In fact, let’s break each of these variables down and see what their significance is:</p>
<ul>
<li>The <strong>numSquares</strong> variable stores the number of squares that will be available in the game as per the mode. For simplicity’s sake, I have hard coded the value to be six always — we can come back to this and add some logic to keep it changing.</li>
<li><strong>colors</strong> is an empty array which contains the random six or three RGB color code generated every time the game is reset or the mode is changed.</li>
<li><strong>pickedColor</strong> is the color/option block selected by the user upon every click.</li>
<li><strong>squares</strong> is an array of all the squares on the page that are available as options. This array may have three or six elements depending on the mode of the game.</li>
<li>The <strong>reset</strong> variable is the “new game” button in the control panel.</li>
<li><strong>modeButtons</strong> is again an array which has easy and hard mode buttons in it.</li>
</ul>
<p>If you have followed up to this point, here you should have a pretty basic version of this game. You may open the index.html file in any browser and check it out. All right, so now that we have the ground set, let’s get to the serious stuff.</p>
<h4 id="heading-part-2">Part 2</h4>
<p>In this section, we will mostly be working with the JavaScript file and a few times with the CSS file.</p>
<p><strong>Generating random colours</strong></p>
<p>Our first goal will generating random colors every time the game is started or restarted or the mode is changed. Let’s see how can do that.</p>
<p>To understand the underlying principle of generating anything randomly, we should start with a hard coded array of six RGB color codes. Let’s try to set those colors as the background colors of the six squares/options available on the webpage.</p>
<pre><code><span class="hljs-keyword">var</span> colors = [
</code></pre><pre><code>    <span class="hljs-string">"rgb(255, 0, 0)"</span>,    <span class="hljs-string">"rgb(255, 0, 255)"</span>,    <span class="hljs-string">"rgb(255, 225, 0)"</span>,    <span class="hljs-string">"rgb(255, 0, 255)"</span>,    <span class="hljs-string">"rgb(0, 255, 255)"</span>,    <span class="hljs-string">"rgb(0, 255, 0)"</span>
</code></pre><pre><code>];
</code></pre><pre><code><span class="hljs-keyword">var</span> squares = <span class="hljs-built_in">document</span>.querySelectorAll(.squares);
</code></pre><pre><code><span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>; i&lt;squares.length; i++) {squares.style.backgroundColor = colors[i]}
</code></pre><ul>
<li>I added six static RGB color codes to the color array</li>
<li>I used the already created squares array to run a loop across all the squares present in the array.</li>
<li>I matched the background color of each square to its corresponding index in the colors array.</li>
</ul>
<p>If you add this to the app.js file and you refresh the browser, you will see that each square is now a unique color.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*LSsJbHhndKH8n7PxPf8UzA.png" alt="Image" width="600" height="400" loading="lazy">
<em>*screenshot form the browser</em></p>
<p>You might notice that the buttons are not yet styled, but leave that for now. We will come to that part later on.</p>
<h4 id="heading-enable-click-functionality">Enable Click Functionality</h4>
<p>So all we need is <strong>event listeners</strong> enabled on each option/color block listening for click events. The easiest way to do that is — again you guessed it right — by looping through the array of squares. This loop would look similar to that which was used to style the background of the color blocks. Let’s take a look at the code:</p>
<pre><code><span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;= squares.length; i++) {  squares[i].addeventListeners(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{    alert(<span class="hljs-string">'option was clicked'</span>);  });}
</code></pre><p>Now every time you click on any block you will get this alert message from the browser. That was easy! Now our options are receptive, and they are responding to user input. All we need to do now is define the logic that tells what happens if the color picked by the game and that chosen by the user are the same.</p>
<p>By now you may already have the solution if you have paid attention to the above parts carefully. So let’s see how we can do it.</p>
<h4 id="heading-checking-if-the-color-is-correct-or-not"><strong>Checking if the color is correct or not</strong></h4>
<p>Let’s explore the possibilities we have with our options/color boxes being receptive and responding back. We can conduct a small test and see if the two colors match or not. Very soon we will have randomly generated colors every time we refresh the page or every time we reset the game or change the mode of game. But for now, we will practice with the set of six RGB color codes we have assigned in the file.</p>
<p>Let’s look at some code and then I would break it down for you.</p>
<pre><code><span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;= squares.length; i++) {  squares[i].addeventListeners(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{    <span class="hljs-comment">//if correct block is clicked do something....    //if wrong block is clicked do something....  });}</span>
</code></pre><p>As you already may know, we will be using a simple <strong>if-else</strong> block.</p>
<pre><code>pickedColor = colors[<span class="hljs-number">3</span>];<span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>; i &lt;= squares.length; i++) { <span class="hljs-comment">//apply background colour to all the squares... squares[i].style.backgroundColor = colors[i]   //enable click event on each square.....     squares[i].addEventListener('click', function() {</span>
</code></pre><pre><code>       <span class="hljs-comment">//if the user selected the right colour....         var clickedColor = this.style.backgroundColor;</span>
</code></pre><pre><code>        <span class="hljs-comment">//check if the selected colour matches the default colour...</span>
</code></pre><pre><code>         <span class="hljs-keyword">if</span>(pickedColor === clickedColor) {             changeColors(pickedColor);           }         <span class="hljs-comment">//if the user user selected wrong colour....         else {           this.style.backgroundColor = "#232323";           messageDisplay.text = "Wrong Choice!";         }    })};</span>
</code></pre><p>I know — it’s a lot of code. But let’s see what it really means:</p>
<ul>
<li>We start with defining what the default color picked by the game will be, with the variable <strong>pickedColour.</strong></li>
<li>Then we run our <strong>for loop</strong> which lets us go through the array of color blocks/options.</li>
<li>Then we enable the <strong>click events</strong> on each and every color bock/option. We do this using a <strong>callback function.</strong> This function does nothing but select the background color of the selected color block/option simply by assigning it to the variable called <strong>clickedColour.</strong></li>
<li>Now we have both colors: one that was selected by the game and the other by the user. All that’s left is to match and see if the choice was correct or not.</li>
<li>We can do this easily using the <strong>if else</strong> block. If the choice is correct, then do this, or else do something else</li>
<li>If the correct color is selected, we add some text on the page to confirm the correct choice and add some visual effect to reconfirm. Else we match the color of that particular color option/block to match the background color of the page. This produces an effect as if the color block/option just disappeared.</li>
<li>Now you have seen that if the same color is selected, then a function is executed. Let’s see what that function is made up of:</li>
</ul>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">changeColors</span>(<span class="hljs-params">color</span>) </span>{ <span class="hljs-keyword">for</span> (i=<span class="hljs-number">0</span>; i &lt;= squares.length; i++) {  squares[i].style.backgroundColor = color;  messageDisplay.text = <span class="hljs-string">"You are good at guessing!"</span>; }}
</code></pre><p>This function goes through the array of color blocks/options and resets the background color to be that of the selected color or the default color.</p>
<p>In case the colors are not the same, we simply set the current selection’s background color to be that of the webpage.</p>
<pre><code><span class="hljs-keyword">else</span> {  <span class="hljs-built_in">this</span>.style.backgroundColor = <span class="hljs-string">"#232323"</span>;  messageDisplay.text = <span class="hljs-string">"Wrong Choice!"</span>;}
</code></pre><p>Alright now that we have the main game set, we just need to worry about minimal design issues and adding the functionality into the control panel.</p>
<p>But first let’s look at what the code folder looks like at this point if you have followed all the steps correctly:</p>
<p><strong>index.html</strong></p>
<p><strong>app.css</strong></p>
<p><strong>app.js</strong></p>
<h4 id="heading-step-3">Step 3</h4>
<p>All is well. But now we need to create new randomly generated RGB color codes in our game that are not the same set of colours that would be assigned in the color blocks/options.</p>
<p>If that makes you think about functions, then that’s the right choice. We will be creating a new function along with totally random (new) color codes, and we will assign them to the colors array. Then we’ll fetch them in the color blocks/options array.</p>
<p>Let’s see what the code looks like, and then we’ll go through it line by line.</p>
<p>A built-in method in JavaScript helps us generate a random number between 0 and 1. Then we make some manipulations to make sure that the range of that random number stays between the digits 0 and 255.</p>
<ul>
<li>First we implement <strong>Math.random,</strong> selecting any random number between 0 and 1, then multiply the number by 256 since we don’t want the number to be any bigger than 255. Once we have a random number, we use <strong>Math.floor</strong> and make sure that we only have the digit before the decimal values (a whole number).</li>
<li>We assign these random numbers generated to variables called r, g, and b. Each signifies its own respective RGB number for the color code.</li>
<li>Lastly, we add up all of these numbers or variables to form a string. We return the string so it looks something like this: <strong>rgb(23, 45, 112).</strong></li>
<li>All that’s left to do is to run this function depending on the mode of the game, and generate three or six random RGB color codes and assign them in the colors array.</li>
</ul>
<p>But this will only return a string which looks like an RGB code. How will this be added to the array of colors we have? How will a random color be selected every time the game is started or reset?</p>
<p>To accomplish both of these things, we’ll create a couple of more functions and see how they help us solve this issue.</p>
<p><strong>Select a random colour from the array</strong></p>
<p>To do this, we will create a new function called <strong>pickColor().</strong> Let’s see how the function will look, and then we will break it down.</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">pickColor</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-keyword">var</span> random = <span class="hljs-built_in">Math</span>.floor(<span class="hljs-built_in">Math</span>.random() * colors.length);  <span class="hljs-keyword">return</span> colors[random];}
</code></pre><p>As simple as it can get, let’s see what these two powerful lines do for us.</p>
<ul>
<li>As we have already seen with the magic of <strong>Math.random</strong> and <strong>Math.floor</strong>, we use the same function to get a random number generated between 0 and the length of the array.</li>
<li>Next, we get the corresponding RGB code in the colors array by using the random number in the index</li>
</ul>
<p><strong>Add six (or three) random RGB codes in the colors array</strong></p>
<p>To do this, we use the above two functions, which are <strong>randomColors()</strong> and <strong>pickColors()</strong>. What the randomColors() function does in particular is that it runs the randomColors() function six or three times (depending on the mode of the game) and adds the corresponding number of RGB color codes to the colors array. We will name this generateRandomColor(num*) function. Let’s see how the code looks and break it down line by line.</p>
<p><em>*num will be decided on the basis of the mode of the game.</em></p>
<ul>
<li>First we’ll make a simple empty array</li>
<li>Next we run a loop as per the mode of the game</li>
<li>Every time this loop gets executed, a new RGB code is pushed into the array created</li>
<li>At last we return this array</li>
</ul>
<p>Now after all these new functions and all this code manipulation, our code base for <strong>app.js</strong> has changed quite a bit. Let’s see what it looks like now:</p>
<h3 id="heading-reset-game">Reset Game</h3>
<p>After almost setting up the primary logic, this may look like a cake walk. It’s all about creating a function and letting that function do its job against any given user input (in this case, a click of the <strong>reset</strong> button).</p>
<p>All we want with the reset button is</p>
<ul>
<li>generate a set of six random colors</li>
<li>pick a random color out of the new created colors array.</li>
</ul>
<p>Let’s see how the pseudo code would look:</p>
<pre><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">reset</span>(<span class="hljs-params"></span>) </span>{  <span class="hljs-comment">//create a new array of 6 random colors  //pick new random color  //fill the squares with new set of generated colors}</span>
</code></pre><p>I strongly recommend writing pseudo code while solving complex problems. This habit of writing pseudo code has helped me save a lot of time whenever I’m stuck on complex algorithmic challenges.</p>
<p>Alright, coming back to our reset button: let’s see how the actual function would look:</p>
<p>Let’s break it down line by line:</p>
<ul>
<li>We start with adding the event listener for the reset button. We then fire a callback function which does a bunch of things when the click event is fired.</li>
<li>When it’s fired, we start by generating a new array of six random colors.</li>
<li>Then we pick a random color.</li>
<li>Lastly, we reset the background color for all the color blocks.</li>
</ul>
<p>This is what the updated <strong>app.js</strong> looks like after all the edits we have made:</p>
<p>This looks pretty good for now! I am not adding the functionality for setting up the mode in this article, as it is already getting to big and I don’t want to bore you all :). But if you liked all of this, I will be more than happy to write another article covering the rest.</p>
<p>Here’s the <a target="_blank" href="https://github.com/ashishcodes4/DOM-manipulation">link</a> for the GitHub repository where the final optimized code can be found.</p>
<p>I hope this article inspires a few of you to learn more about DOM manipulation and this beautiful language of JavaScript. Until the next time!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
