<?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[ Houssein Badra - 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[ Houssein Badra - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 31 May 2026 22:32:06 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/HousseinBadra/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Photo Encryption App using Steganography ]]>
                </title>
                <description>
                    <![CDATA[ In this digital age, data flows freely across networks and devices. So protecting sensitive information from unauthorized access is crucial. That's where encryption comes in.  Encryption involves converting plain, readable data into an incomprehensib... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-photo-encryption-app/</link>
                <guid isPermaLink="false">66c5a25d3d77fae9eb82a46c</guid>
                
                    <category>
                        <![CDATA[ encryption ]]>
                    </category>
                
                    <category>
                        <![CDATA[ information security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Houssein Badra ]]>
                </dc:creator>
                <pubDate>Wed, 23 Aug 2023 21:06:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--122-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this digital age, data flows freely across networks and devices. So protecting sensitive information from unauthorized access is crucial. That's where encryption comes in. </p>
<p>Encryption involves converting plain, readable data into an incomprehensible form. It's also essential to have a way to convert the data back into a readable form – otherwise the whole process makes no sense and isn't useful.</p>
<p>There are various popular encryption algorithms, each with its strengths and weaknesses. Understanding how these algorithms work is essential for programmers, as they need to choose the most appropriate one for their applications. </p>
<p>In this article, we will be build an application where users can encrypt images, and also revert the process using HTML, CSS, and JavaScript. </p>
<p>You will learn about working with images and how to encrypt them. The approach we will be using involves hiding one image inside another one, which is called <strong>Steganography.</strong> You will also practice some basic web development skills. It will be fun for sure!</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ul>
<li>How images are represented on your computer</li>
<li>How to create the encryption algorithm </li>
<li>How to create the decryption algorithm</li>
<li>Photo encryption app code</li>
</ul>
<h2 id="heading-how-images-are-represented-on-your-computer">How Images Are Represented on Your Computer</h2>
<p>Understanding the way images are stored is critical before diving into encrypting them. </p>
<p>Images are represented on computers using a combination of pixels. A pixel is the smallest unit of an image and serves as the building block for displaying visuals on digital screens. </p>
<p>In memory, an image is an array of pixels. But now you're probably wondering, what is a pixel?</p>
<p>A pixel is assigned a specific color value which determines its appearance. The color values are typically represented using a combination of three primary colors: red, green, and blue – commonly known as RGB. </p>
<p>Each color channel is represented by a number value, ranging from 0 to 255, which determines the intensity of that color in the pixel. </p>
<p>For example:</p>
<ul>
<li>(0, 0, 0) represents black (absence of all colors)</li>
<li>(255, 255, 255) represents white (maximum intensity of all colors)</li>
<li>(255, 0, 0) represents pure red (maximum intensity of red, absence of green and blue)</li>
<li>(0, 255, 0) represents pure green (maximum intensity of green, absence of red and blue)</li>
<li>(0, 0, 255) represents pure blue (maximum intensity of blue, absence of red and green)</li>
</ul>
<p>By combining different intensities of red, green, and blue, we can represent a wide range of colors. This color information for each pixel is stored in memory, forming a digital image. For example to get yellow, we can combine red and green – (255, 255, 0) represents a yellow pixel.</p>
<h2 id="heading-how-to-use-the-encryption-algorithm">How to Use the Encryption Algorithm</h2>
<p>The key idea behind the algorithm we're going to use is that it uses 2 images: the image we want to encrypt and an image that will play the role of mask used to hide the image we want to encrypt. So we're going to combine these two images in a way that hides our main image and allows its extraction.</p>
<p>Since an image is made of pixels, what works for a single pixel works for an entire image. We will discuss how we will be combining 2 pixels in a way that hides one and allows reverting the process.</p>
<p>Now for the interesting part: if we look at numbers from 0 to 255, they all can be written as follows: a <em> 16 + b. For example 241 can be written as 15 </em> 16 + 1. But why we are doing this? </p>
<p>We will be using this to divide each pixel into two parts: first the a * 16 part and second b. The first part holds way more information than the second, since when a color degree goes up its intensity goes up. For example a (245, 137, 200) pixel can be split into (240, 128, 192) and (5, 9, 8). </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--114-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image splitting</em></p>
<p>Now by comparing the high value pixel and the original one, you can see clearly that using the higher value pixel instead of the original one isn't going to change much of the information the original pixel holds.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--115-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Comparing a higher value pixel and an original pixel's values</em></p>
<p>Now we will be using two pixels – one we're going to encrypt (the target pixel), and one we're going to hide the target pixel within (the encryption pixel), which can be random as we will see later. </p>
<p>First we will get the high value pixel from our target and encryption pixels. Then for the pixel we're trying to encrypt, we'll divide each number degree by 16. </p>
<p>For example if the original target pixel was (245, 137, 200) then the high value pixel will be (240, 128, 192) which will become (15, 8, 12) after applying a division by 16. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--121-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Getting initial values and applying division</em></p>
<p>Now we have two new pixels: the high value pixel of the encryption pixel, and our target pixel high value pixel that got divided by 16. </p>
<p>Finally, to get an encrypted pixel, we'll sum up the values of these two pixels to get what we're looking for. </p>
<p>Take, for example, (26, 98, 234) and (245, 137, 200) as our encryption and target pixels, respectively. Let's first get the high value pixels. We will have (16, 96, 224) and (240, 128, 192), respectively. </p>
<p>Now divide the target pixel high value pixel by 16 and you'll have (15, 8, 12). Now add these two up and you'll be left with (31, 104, 236). And that's our encrypted pixel. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--118-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Encrypted image</em></p>
<p>Now you know how to encrypt a pixel. By applying this to all the pixels of an image we will get an encrypted image. </p>
<p>To make this clearer, we will be hiding an image of Quincy Larson playing guitar within the freeCodeCamp logo 😂.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--126-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image showing how we were able to hide Quincy Larson image in the freeCodeCamp logo</em></p>
<p>So to make this work we need two images: the one we need to encrypt and a random image to use as the encryption image. Also the two images should have the same dimensions to get the same number of pixels. </p>
<p>The reason we're using a random image to hide our image is to make it look like a very random image that will make no one suspicious.</p>
<h2 id="heading-how-to-use-the-decryption-algorithm">How to Use the Decryption Algorithm</h2>
<p>Now we need a way to revert the process, so to extract the target pixel from an encrypted pixel. Then we will have accomplished our goal.</p>
<p>Like we did earlier by combining 2 pixels to get an encrypted pixel, we will split back the encrypted pixel to get our target.</p>
<p>Every pixel can be split into two parts – the high value part (a * 16) and the low value part (b). Now we care about the b part since it comes from our target pixel. So we need to extract the b part from an encrypted pixel.</p>
<p>We can do this easily by mapping each number with its corresponding remainder of division by 16. We can do this using the modulo operator <strong>%</strong> which is a mathematical operator to get the remainder of the division of a number by another. For example 241 % 16 is 1 since since 241 is equal to 15 * 16 + 1.</p>
<p>By taking (31, 104, 236) and applying the modulo, we will be left with (15, 8, 12). As discussed earlier an encrypted pixel is the sum of the high value pixel of our encryption pixel or the mask pixel and the high value pixel of our target divided by 16. After the modulo is applied, the left value is the high value pixel of our target divided by 16.</p>
<p>Now multiply each number by 16 and you'll get exactly (240, 128, 192) which is the high value pixel of our target pixel.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/08/Screenshot--117-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Decryption</em></p>
<p>Now as you can see, <strong>Steganography</strong> involves a small loss of each target pixel's information – but it's ok as you can see that it doesn't matter much in how the final image looks.</p>
<h2 id="heading-photo-encryption-app-code">Photo Encryption App Code</h2>
<p>And now since our toolkit is ready, let's code this image encryption application. All the code is available in this <a target="_blank" href="https://github.com/HousseinBadra/image-Encryption.git">GitHub repo</a>. The code itself is very straightforward. </p>
<p>First, create three files: an HTML file, a CSS file, and a JavaScript file. </p>
<p>For the HTML file we just need a canvas where we can see the resulting image. We also need two inputs of type file so we can upload our target and encryption images. And finally we need a button to save our encrypted image. </p>
<p>Also we will be using a small library to manage images created by Duke University, so we will have to include a script tag in the end of the body for this.</p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Image encryption app<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <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">href</span>=<span class="hljs-string">"index.css"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">canvas</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">canvas</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">"input-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"Target"</span>&gt;</span>Upload target image<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"target"</span> <span class="hljs-attr">mltiple</span>=<span class="hljs-string">'false'</span> <span class="hljs-attr">accept</span>=<span class="hljs-string">'image/*'</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">"input-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"Encryption"</span>&gt;</span>Upload encryption image<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"encryption"</span> <span class="hljs-attr">multiple</span>=<span class="hljs-string">'false'</span> <span class="hljs-attr">accept</span>=<span class="hljs-string">'image/*'</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">button</span>&gt;</span>Save image<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'https://www.dukelearntoprogram.com/course1/common/js/image/SimpleImage.js'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"index.js"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/javascript"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>The CSS is simple too. We will give the div wrapping the canvas a width and height of 300px, the canvas a width and height of 100%, and it'll have a black border. Now the div tags wrapping our inputs will get a slight margin of 10px on the top, and that's it.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.container</span>{
  <span class="hljs-attribute">width</span>:<span class="hljs-number">300px</span>;
  <span class="hljs-attribute">height</span>: <span class="hljs-number">300px</span>;
}

<span class="hljs-selector-tag">canvas</span>{
  <span class="hljs-attribute">width</span>:<span class="hljs-number">100%</span>;
  <span class="hljs-attribute">height</span>:<span class="hljs-number">100%</span>;
  <span class="hljs-attribute">border</span>:<span class="hljs-number">1px</span> solid black;
}

<span class="hljs-selector-class">.input-container</span>{
    <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">10px</span>;
}
</code></pre>
<p>Now for the JavaScript file. We will first select the two inputs, the canvas and the save button, and store them in four different variables. Then we will set the canvas width and height to 300px with JavaScript to avoid any future problems. And finally we'll set two variables, target and encryption, to store our encryption and target images.</p>
<pre><code class="lang-js"><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> targetInput = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#target"</span>);
<span class="hljs-keyword">const</span> encryptionInput = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"#encryption"</span>);
<span class="hljs-keyword">const</span> saveButton = <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">"button"</span>);
<span class="hljs-keyword">let</span> target;
<span class="hljs-keyword">let</span> encryption;

canvas.width = <span class="hljs-number">300</span>;
canvas.height = <span class="hljs-number">300</span>;
</code></pre>
<p>Now we need to store the encryption and target images on user upload in the two variables we created earlier. Also set the <strong>onClick</strong> event of our save button to a function called <strong>save</strong> that we will create next. Finally, we'll create a function that takes a number as an argument and returns its high value as discussed in the encryption algorithm section.  </p>
<pre><code class="lang-js">targetInput.onchange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> img = <span class="hljs-keyword">new</span> SimpleImage(targetInput);
  img.setSize(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>);
  target = img;
};

encryptionInput.onchange = <span class="hljs-function">(<span class="hljs-params">e</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> img = <span class="hljs-keyword">new</span> SimpleImage(encryptionInput);
  img.setSize(<span class="hljs-number">300</span>, <span class="hljs-number">300</span>);
  encryption = img;
};

saveButton.onclick = save;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getValue</span>(<span class="hljs-params">x</span>) </span>{
  <span class="hljs-keyword">return</span> x - (x % <span class="hljs-number">16</span>);
}
</code></pre>
<p>All that's left is to create the save function. First we will create a new image object with dimensions of 300 * 300. An image with these dimensions will have 90000 pixels. All of them have x and y coordinates from 0-299, since indexing starts from 0 in arrays. Looping from 0 to 300 twice will allow us to get all possible coordinates which means all pixels.</p>
<p>Now for each coordinate we will use the corresponding pixel of our encryption, target, and newly created image. Now we can set each pixel of our newly created image to the sum of the high value pixel of the encryption pixel and the high value pixel of our target divided by 16.</p>
<p>Now we will draw the newly created pixel on the canvas. And we'll need to get the URL of the image drawn into the canvas. We will be applying a small modification to the URL otherwise it will not work because we will get blocked by the browser for security reasons.</p>
<p>Finally, navigate to this URL by setting the window location to that URL. Then the encrypted image will be downloaded.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">save</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> img = <span class="hljs-keyword">new</span> SimpleImage(<span class="hljs-number">300</span>, <span class="hljs-number">300</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">300</span>; i++) {
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = <span class="hljs-number">0</span>; j &lt; <span class="hljs-number">300</span>; j++) {
      <span class="hljs-keyword">const</span> targetPixel = target.getPixel(i, j);
      <span class="hljs-keyword">const</span> encryptionPixel = encryption.getPixel(i, j);
      <span class="hljs-keyword">const</span> pixel = img.getPixel(i, j);
      pixel.setRed(
        getValue(targetPixel.getRed()) / <span class="hljs-number">16</span> + getValue(encryptionPixel.getRed())
      );
      pixel.setGreen(
        getValue(targetPixel.getGreen()) / <span class="hljs-number">16</span> +
          getValue(encryptionPixel.getGreen())
      );
      pixel.setBlue(
        getValue(targetPixel.getBlue()) / <span class="hljs-number">16</span> +
          getValue(encryptionPixel.getBlue())
      );
    }
  }
  img.drawTo(canvas);
  <span class="hljs-keyword">let</span> url = canvas
    .toDataURL(<span class="hljs-string">"image/png"</span>)
    .replace(<span class="hljs-string">"image/png"</span>, <span class="hljs-string">"image/octet-stream"</span>);
  <span class="hljs-built_in">window</span>.location.href = url;
}
</code></pre>
<p>And that's it for the code 😇.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we've learned a simple algorithm for image encryption. Modern algorithms are way more robust, as they use techniques like matrix multiplication to get solid hashing algorithms but they are very complex and require way more time and math knowledge than this one. </p>
<p>If you find this content enjoyable, <a target="_blank" href="https://www.linkedin.com/in/houssein-badra-943879214/">follow me on LinkedIn</a> as I post great content there 😉.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JavaScript Basics – How to Work with Strings, Arrays, and Objects in JS ]]>
                </title>
                <description>
                    <![CDATA[ JavaScript is a popular programming language that 78% of developers use. You can build almost anything with JavaScript. The problem is that many developers learn JavaScript in a very short period of time, without understanding some of the most essent... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/javascript-basics-strings-arrays-objects/</link>
                <guid isPermaLink="false">66c5a2678232868a133f432a</guid>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Houssein Badra ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 20:12:35 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/js.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>JavaScript is a popular programming language that 78% of developers use. You can build almost anything with JavaScript.</p>
<p>The problem is that many developers learn JavaScript in a very short period of time, without understanding some of the most essential features of the language.</p>
<p>In this article, we will cover JavaScript arrays, strings, and objects in depth so you can benefit from some of the most effective static and instance methods that the language offers.</p>
<h3 id="heading-heres-what-well-cover-in-this-guide">Here's what we'll cover in this guide:</h3>
<ul>
<li>Instance and class methods</li>
<li>How to use strings in JavaScript </li>
<li>How to use arrays in JavaScript</li>
<li>How to use objects in JavaScript</li>
</ul>
<h2 id="heading-instance-and-class-methods">Instance and Class Methods</h2>
<p>JavaScript is heavily object-oriented. It follows a prototype-based model, but it also offers a class syntax to enable typical OOP paradigms. </p>
<p>In JavaScript, strings and arrays are objects, and every object in JavaScript is a template which has its methods and properties. Every object inherits methods and properties from its prototype. In JavaScript, every object has access to the <strong>Object prototype</strong>.</p>
<p>Static methods are methods that are available on the class level – for example the <strong>Object.freeze()</strong> method. Instance methods are available on the instance level – for example a created instance of an <strong>Array</strong> object has access to the instance methods such as <strong>.join()</strong>, but not the static methods.</p>
<h2 id="heading-how-to-use-strings-in-javascript">How to Use Strings in JavaScript</h2>
<p>Strings are used to hold data that can be represented in text form. To create a string you can use the <strong>String()</strong> constructor or a string literal. Here's an example of both ways:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// Using a constructor</span>

<span class="hljs-keyword">let</span> string1 = <span class="hljs-built_in">String</span>(<span class="hljs-string">'String Creation'</span>);

 <span class="hljs-comment">// Using a string literal</span>

<span class="hljs-keyword">let</span> string2 = <span class="hljs-string">'String Creation'</span>;
</code></pre>
<p>Now let's learn more about instance methods. There are many instance methods, but here I'll discuss seven methods that I consider the most important.</p>
<h3 id="heading-the-charat-method">The .charAt() method</h3>
<p>A lot of the time when working with strings, we want to access a character at a certain index of the string. You can do this either with the <strong>charAt()</strong> method or with indexing, the same way we treat an array.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// Let's say we want to access the first character of a given string</span>

 <span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello World'</span>;

  <span class="hljs-comment">// using indexing</span>

 <span class="hljs-keyword">let</span> first1 = string[<span class="hljs-number">0</span>]; <span class="hljs-comment">// output 'H' and remember that indexing starts at 0</span>

  <span class="hljs-comment">// using the charAt() method</span>

 <span class="hljs-keyword">let</span> first2 = string.charAt(<span class="hljs-number">0</span>); <span class="hljs-comment">// output 'H'</span>
</code></pre>
<p>In JavaScript, the indexing system starts at 0 – for example the first character of a string has index of 0 and so on.</p>
<h3 id="heading-the-touppercase-and-tolowercase-methods">The .toUpperCase() and .toLowerCase() methods</h3>
<p>Now let's say we want to uppercase or lowercase a string. You can do this using the <strong>toUpperCase()</strong> and the <strong>toLowerCase()</strong> instance methods.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello'</span>;

  <span class="hljs-comment">// Let's lowercase a string</span>

 <span class="hljs-keyword">let</span> lowerCase = string.toLowerCase(); <span class="hljs-comment">// output 'hello'</span>

  <span class="hljs-comment">// Let's upperCase a string</span>

 <span class="hljs-keyword">let</span> upperCase = string.toUpperCase(); <span class="hljs-comment">// output 'HELLO'</span>
</code></pre>
<p>You might use these to see if two strings hold the same word, for example 'Sam' and 'sam'. Actually 'sam' === 'Sam' evaluates to false, while  'sam'.toLowerCase() === 'Sam'.toLowerCase() evaluates to true.</p>
<h3 id="heading-the-concat-method">The .concat()  method</h3>
<p>It is often necessary to join text strings together in a program to make a new text string. This is called <strong>concatenation</strong>.</p>
<p>Now for string concatenation we can use the <strong>concat()</strong> method. It looks like the following. An important note is that this method returns a new string without mutating the original one.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello'</span>;

 <span class="hljs-comment">// String concatenation using the concat method</span>

<span class="hljs-keyword">let</span> string1 = string.concat(<span class="hljs-string">' World'</span>); <span class="hljs-comment">// output 'Hello World'</span>
</code></pre>
<h3 id="heading-the-indexof-method">The .indexOf() method</h3>
<p>Now to find the index of a certain character or a set of characters of a string, we can use the <strong>indexOf()</strong> method. This will return the index of the first index where the passed character or set of characters occurs.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello World'</span>;

 <span class="hljs-comment">// Let's find the index where 'H' occurs for the first time</span>

<span class="hljs-keyword">let</span> firstH = string.indexOf(<span class="hljs-string">'H'</span>); <span class="hljs-comment">// output 0</span>

 <span class="hljs-comment">// Let's find the first index where 'World' occurs for the first time</span>

<span class="hljs-keyword">let</span> firstWorld = string.indexOf(<span class="hljs-string">'World'</span>); <span class="hljs-comment">// output 6</span>

 <span class="hljs-comment">// In case a character or a set of characters   </span>
 <span class="hljs-comment">// doesn't occur in the string this method returns -1</span>

<span class="hljs-keyword">let</span> notThere = string.indexOf(<span class="hljs-string">'Z'</span>); <span class="hljs-comment">// output -1</span>
</code></pre>
<h3 id="heading-the-slice-method">The .slice() method</h3>
<p>A substring is a subset or part of another string, or it is a contiguous sequence of characters within a string. For example, "Substring" is a substring of "Substring in JavaScript".</p>
<p>Now let's say we want to get a substring of a given string. We can use the <strong>slice()</strong> method. Slice is actually one of the most important string methods. You use it to get substrings and also to copy strings. </p>
<p>Slice takes two optional parameters: the first one is where we want to start slicing and the second one is where we want to finish the slicing operation.</p>
<p>Let's assume that we passed <strong>1</strong> and <strong>10</strong> as parameters for the slice method. The method will then return a substring starting at index <strong>1</strong> and ending at index <strong>9.</strong> </p>
<p>This means that the substring never includes the character at the ending index. An important note is to never pass an ending index higher than the string length.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello World'</span>;

 <span class="hljs-comment">// to check the string length we can use the length instance property</span>

<span class="hljs-keyword">let</span> length = string.length; <span class="hljs-comment">// output 11</span>

 <span class="hljs-comment">// slicing to get the substring from index 1 -&gt; 9</span>

<span class="hljs-keyword">let</span> string1 = string.slice(<span class="hljs-number">1</span> , <span class="hljs-number">10</span>); <span class="hljs-comment">// output 'ello Worl'</span>

 <span class="hljs-comment">// not passing any parameters will generate </span>
 <span class="hljs-comment">// a copy of the ariginal string with no mutation</span>

<span class="hljs-keyword">let</span> copy = string.slice(); <span class="hljs-comment">// output 'Hello World'</span>
</code></pre>
<h3 id="heading-the-split-method">The .split() method</h3>
<p>The last string method that we will cover is the <strong>split()</strong> method. This method takes a pattern as an argument and divides the string into multiple substrings. The pattern describes where the splits occurs. This method returns an array of these substrings.</p>
<p>You might find yourself using this method to parse a URL or certain strings.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> string = <span class="hljs-string">'Hello World'</span>;

 <span class="hljs-comment">// Divide a string into words</span>
 <span class="hljs-comment">// This can be done when the passed pattern is a space</span>

<span class="hljs-keyword">let</span> words = string.split(<span class="hljs-string">' '</span>); <span class="hljs-comment">// output ['Hello' , 'World']</span>

 <span class="hljs-comment">// When the passed parameter is an empty string, the output array</span>
 <span class="hljs-comment">// will carry each of the characters of the given string</span>

<span class="hljs-keyword">let</span> chars = string.split(<span class="hljs-string">''</span>); 

 <span class="hljs-comment">// output ["H","e","l","l","o"," ","W","o","r","l","d"]</span>
</code></pre>
<p>There are many more methods you can learn about, but these are the ones that you will work with the most. You can learn more by reading through the official <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">MDN web documents</a>.</p>
<h2 id="heading-how-to-use-arrays-in-javascript">How to Use Arrays in JavaScript</h2>
<p>Like other programming languages, JavaScript arrays let you store a collection of data under one variable. But unlike C or C++, arrays can be returned from function calls. </p>
<p>JavaScript arrays are dynamic, so you can add to or delete elements from an array. You can also have elements of multiple data types in a single array. </p>
<p>Let's talk about how to create arrays in JavaScript. You can easily create an array by assigning a variable to empty brackets [ ] or by using the <strong>Array()</strong> constructor.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// Creating an array from constructor</span>

<span class="hljs-keyword">let</span> arr1 = <span class="hljs-built_in">Array</span>();

 <span class="hljs-comment">// Prefered method</span>

<span class="hljs-keyword">let</span> arr2 = [];
</code></pre>
<p>Now let's talk about seven array instance and class methods that I consider to be the most useful. </p>
<h3 id="heading-the-indexof-method-1">The .indexOf() method</h3>
<p>To get the first index of a given array where an element occurs, we can use the <strong>indexOf()</strong> method. It'll look like this. If the argument passed to this method doesn't occur in the array, it will return -1.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];

 <span class="hljs-comment">// Let's find the index where 1 occurs for thwe first time</span>

<span class="hljs-keyword">let</span> first1 = array.indexOf(<span class="hljs-number">1</span>); <span class="hljs-comment">// output 0</span>

 <span class="hljs-comment">// Now let's try to find 4 in the array</span>

<span class="hljs-keyword">let</span> first4 = array.indexOf(<span class="hljs-number">4</span>); <span class="hljs-comment">// output -1</span>
</code></pre>
<h3 id="heading-the-push-and-pop-methods">The .push() and .pop() methods</h3>
<p>As I mentioned earlier, JavaScript arrays are dynamic. So we can add elements using the <strong>push()</strong> method and remove the last element using the <strong>pop()</strong> method. An important note is that both of those methods mutate the original array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];

 <span class="hljs-comment">// let's add 4 to the array</span>

array.push(<span class="hljs-number">4</span>)

<span class="hljs-built_in">console</span>.log(array) <span class="hljs-comment">// output [1, 2, 3, 4]</span>

 <span class="hljs-comment">// let's now make the array the same as before</span>

<span class="hljs-keyword">let</span> removedElement = array.pop() <span class="hljs-comment">// output 4</span>

<span class="hljs-built_in">console</span>.log(array) <span class="hljs-comment">// output [1, 2, 3]</span>
</code></pre>
<p>Now we'll discuss some more advanced methods – the ones introduced by the ES6 update. </p>
<h3 id="heading-the-map-method">The .map() method</h3>
<p>First, let's say that you want to create an array using data from another existing array – for example if you have an array of objects representing employees. </p>
<p>Each employee object has a name property. And you want to create an array where each element is the value of the name property of the employee object at the same index of the array you have.</p>
<p>This is where the <strong>map()</strong> method comes in. It takes a callback function. Map creates a new array and never mutates the old one, and the callback expresses what you want to do with the data from the original array. It will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> arr= [{<span class="hljs-attr">name</span> : <span class="hljs-string">'joe'</span>} , {<span class="hljs-attr">name</span> : <span class="hljs-string">'john'</span>}];

 <span class="hljs-comment">// It is preffered to use an arrow function</span>

<span class="hljs-keyword">let</span> namesArr = arr.map(<span class="hljs-function"><span class="hljs-params">elem</span> =&gt;</span> elem.name); <span class="hljs-comment">// output ['joe' , 'john']</span>
</code></pre>
<h3 id="heading-the-foreach-method">The .forEach() method</h3>
<p>Are you tired of the usual for loops? They are kind of boring, I know. Luckily the <strong>forEach()</strong> method is here to help. </p>
<p>This method takes a callback as an argument and returns nothing. It iterates over the array and runs a certain task on every element of the array. The callback expresses the task. The code for this will look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> arr= [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];

 <span class="hljs-comment">// let's output each element on the console</span>

arr.forEach(<span class="hljs-function"><span class="hljs-params">elem</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(elem));

 <span class="hljs-comment">// output </span>
 <span class="hljs-comment">// 1</span>
 <span class="hljs-comment">// 2</span>
 <span class="hljs-comment">// 3</span>
</code></pre>
<h3 id="heading-the-filter-method">The .filter() method</h3>
<p>Now let's say that we have an array of numbers and that we want to create an array of only the numbers that pass a certain condition. </p>
<p>In this case we can use the <strong>filter()</strong> method which also takes a callback as an argument. The callback returns a Boolean – true if the element passes the test, otherwise false. Only elements that pass will be in the generated array and the callback expresses the test. Here's how it works:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];

 <span class="hljs-comment">// Let's create an array of numbers bigger than 3</span>

<span class="hljs-keyword">let</span> filteredArray = arr.filter(<span class="hljs-function"><span class="hljs-params">elem</span> =&gt;</span> elem &gt; <span class="hljs-number">3</span>); <span class="hljs-comment">// output [4, 5]</span>
</code></pre>
<h3 id="heading-the-some-method">The .some() method</h3>
<p>Now let's say we have an array, and we want to check if there is at least one number that passes a certain test. Here comes the <strong>some()</strong> method. </p>
<p>This method takes a callback as an argument and returns a Boolean which is true if at least one element of the array passes the test, and otherwise is false. The callback expresses the test and it will look as follows:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];

 <span class="hljs-comment">// Let's check if at least one element is bigger than 4</span>

<span class="hljs-keyword">let</span> bool = arr.some(<span class="hljs-function"><span class="hljs-params">elem</span> =&gt;</span> elem &gt; <span class="hljs-number">4</span>); <span class="hljs-comment">// output true</span>
</code></pre>
<h3 id="heading-the-sort-method">The .sort() method</h3>
<p>Sorting is the process of arranging data into a meaningful order so that you can analyze it more effectively.</p>
<p>When talking about arrays we have to mention sorting. In JavaScript the <strong>sort()</strong> method sorts arrays in place and returns the reference to the same array. This method mutates the array and the default sorting order is ascending.</p>
<p>You can implement your own sorting logic by passing a callback which expresses a comparison between two elements and returns a number. If the returned number is positive then the first of the two compared elements will occur first in the sorted array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">3</span>];

 <span class="hljs-comment">// sorting in ascending order</span>

arr.sort();

<span class="hljs-built_in">console</span>.log(arr); <span class="hljs-comment">// [1, 2, 3, 4]</span>

 <span class="hljs-comment">// using custom sort to sort in descending order</span>

arr.sort(<span class="hljs-function">(<span class="hljs-params">elem1 , elem2</span>) =&gt;</span> elem2 - elem1);

<span class="hljs-built_in">console</span>.log(arr); <span class="hljs-comment">// output [4, 3, 2, 1]</span>
</code></pre>
<p>There are plenty of interesting string methods that I didn't mention and they are worth investing time in learning. If you want to do so, you can visit the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">MDN official documents</a>.</p>
<h2 id="heading-how-to-use-objects-in-javascript">How to Use Objects in JavaScript</h2>
<p>If you want to be a good JavaScript developer, you should really have a decent understanding of objects and the way they work. </p>
<p>Almost every object you create in JavaScript inherits methods from the global <strong><code>Object</code></strong> prototype which is available globally for every object in JavaScript. An exception is null prototype objects which we're not going to talk about. All the methods I am going to talk about are mostly static.</p>
<p>First let's talk about how to create objects using a set of curly braces <strong>{ }</strong> or the <strong>object</strong> constructor. Here's what that looks like:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// Creating an object from an constructor</span>

<span class="hljs-keyword">let</span> obj1 = <span class="hljs-built_in">Object</span>();

 <span class="hljs-comment">// Creating an object using curly braces</span>

<span class="hljs-keyword">let</span> obj2 = {};
</code></pre>
<h3 id="heading-the-assign-method">The .assign() method</h3>
<p>Now let's say we want to copy an object. Here comes the <strong>assign()</strong> static method to help us do this. I will show you how this works and a better way to do it. I'll also discuss some common mistakes many devs make when trying to copy objects.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> obj = {<span class="hljs-attr">age</span> : <span class="hljs-number">18</span>};

 <span class="hljs-comment">// Copying using the assign method</span>

<span class="hljs-keyword">let</span> new1 = {};

<span class="hljs-built_in">Object</span>.assign(new1 , obj);

<span class="hljs-built_in">console</span>.log(new1); <span class="hljs-comment">// output {age : 18}</span>

 <span class="hljs-comment">// We can do the same with the spread operator</span>

<span class="hljs-keyword">let</span> new2 = {...obj}; <span class="hljs-comment">// output {age : 18}</span>
</code></pre>
<p>A common mistake is to assign a variable to an object directly. The problem with this is that objects are assigned by reference and not by value. So any changes will mutate the original object.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> obj = {<span class="hljs-attr">age</span> : <span class="hljs-number">18</span>};

<span class="hljs-keyword">let</span> obj1 = obj;

obj1.age = <span class="hljs-number">17</span>;

<span class="hljs-built_in">console</span>.log(obj); <span class="hljs-comment">// output {age : 17}</span>
</code></pre>
<h3 id="heading-the-freeze-and-isfrozen-methods">The .freeze() and .isFrozen() methods</h3>
<p>Let's now say that we want to make an object immutable. For this we can use the <strong>freeze()</strong> static method which makes it impossible to add properties, modify, or delete any of the frozen object's prototypes, methods, and properties. </p>
<p>To see if an object if frozen, we can use the <strong>isfrozen()</strong> static method.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> obj = {<span class="hljs-attr">age</span> : <span class="hljs-number">18</span>};

<span class="hljs-built_in">Object</span>.freeze(obj);

 <span class="hljs-comment">// Let's try to mutate this object</span>

obj.age = <span class="hljs-number">17</span>; <span class="hljs-comment">// Throws an error in strict mode</span>

<span class="hljs-keyword">let</span> isFrozen = <span class="hljs-built_in">Object</span>.isFreezed(obj); <span class="hljs-comment">// output true</span>
</code></pre>
<h3 id="heading-the-keys-and-values-methods">The .keys() and .values() methods</h3>
<p>Now to get a list of a certain object properties we can call the <strong>keys()</strong> static method. To get a list of the values corresponding to its properties, we can call the <strong>values()</strong> static method. An important note is that the list is an array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> obj = {<span class="hljs-attr">name</span> : <span class="hljs-string">'John Doe'</span> ,<span class="hljs-attr">age</span> : <span class="hljs-number">45</span>};

<span class="hljs-keyword">let</span> keys = <span class="hljs-built_in">Object</span>.keys(obj); <span class="hljs-comment">// output ['name', 'age']</span>

<span class="hljs-keyword">let</span> values = <span class="hljs-built_in">Object</span>.values(obj); <span class="hljs-comment">// output ['John Doe', 45]</span>
</code></pre>
<p>You can check the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">MDN web documents</a> to dive deeper into the topic.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this tutorial, we talked about arrays, strings, and objects, along with the methods they offer. Hopefully you learned something new today.</p>
<p>In case you're interested in more great content like this, follow me on <a target="_blank" href="https://www.linkedin.com/in/houssein-badra-943879214">LinkedIn</a> where I share a lot of great content.</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 Search Works Under the Hood – Data Structures and Search Algorithms Explained ]]>
                </title>
                <description>
                    <![CDATA[ Searching is something people do every day. Whether they're word searching in documents and databases, or pattern matching in bioinformatics to detect anomalies in DNA, the applications for search are pretty much endless. And these applications requi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-searching-works-under-the-hood/</link>
                <guid isPermaLink="false">66c5a2635e24e23ff2251589</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data structures ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Houssein Badra ]]>
                </dc:creator>
                <pubDate>Wed, 30 Nov 2022 16:33:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/182786404-56a9f6725f9b58b7d00038e0.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Searching is something people do every day. Whether they're word searching in documents and databases, or pattern matching in bioinformatics to detect anomalies in DNA, the applications for search are pretty much endless.</p>
<p>And these applications require a lot of computation. Imagine searching for a particular DNA sequence out of millions, or searching for a user in Google's database. </p>
<p>That's why we need an algorithm that runs very fast without consuming lots of memory. And that's what you'll learn about here.</p>
<p>In this tutorial, we will be diving deep into two famous search algorithms: Rabin-Karp's algorithm and the Knuth-Morris-Pratt algorithm. We'll also discuss their time and space complexity, which is equivalent to the time and space an algorithm consumes, depending on its input size. You will also learn about common data structures for searching.</p>
<p>A very basic knowledge of programming is required to follow along. We'll be using Python examples in this tutorial.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-data-structures-for-bioinformatics-and-searching">Data structures for bioinformatics and searching</a></li>
<li><a class="post-section-overview" href="#heading-naive-search-algorithm">Naïve search algorithm</a></li>
<li><a class="post-section-overview" href="#heading-rabin-karps-algorithm">Rabin-Karp's algorithm</a></li>
<li><a class="post-section-overview" href="#heading-knuth-morris-pratt-algorithm">Knuth-Morris-Pratt algorithm</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-data-structures-for-bioinformatics-and-searching">Data Structures for Bioinformatics and Searching</h2>
<p>Let's first discuss some data structures that you should know even if we weren't diving too deeply into the topic. </p>
<h3 id="heading-the-trie-data-structure">The Trie Data Structure</h3>
<p>A <strong>trie</strong> is a tree-like data structure where each nodes stores a letter of an alphabet. You can structure the nodes in a certain way so that words and strings can be retrieved from the structure by traversing down a branch (path) of the tree.</p>
<p>Let's take the words <strong>ANA</strong>, <strong>AND</strong>, and <strong>BOT</strong> for example – their prefix tree or trie will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--80-.png" alt="Image" width="600" height="400" loading="lazy">
<em>How a trie looks like</em></p>
<p>Tries are widely used for:</p>
<ul>
<li>Auto complete</li>
<li>Spell Checkers</li>
<li>Longest prefix matching</li>
<li>Browser history</li>
</ul>
<h3 id="heading-suffix-trees"><strong>Suffix trees</strong></h3>
<p>Suffix trees are tree-based data structures, but instead of taking multiple words to build the tree we will be using the suffixes of a single world. </p>
<p>If we consider the string <strong>AABA</strong>, we will first add a <strong>$</strong> sign to the end of the string. That <strong>$</strong> will make string comparison easier. Now the string is <strong>AABA$</strong>.</p>
<p>We will consider all of it's suffixes and the tree will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--82-.png" alt="Image" width="600" height="400" loading="lazy">
<em><strong>A suffix tree</strong></em></p>
<h3 id="heading-burrows-wheeler-transform">Burrows Wheeler transform</h3>
<p>Now we will discuss the burrows wheeler transform which is very useful data structure fort string compression. </p>
<p>This data structure is widely used in bioinformatics for a very specific reason. I want you to imagine a string representing a genome. It maybe very long, like 20 million characters. </p>
<p>But there is actually a way to store genomes efficiently. Imagine the string <strong>AAAAABBBAAA</strong>. This string has many repeats and we can actually compress this string to be something like this: <strong>A5B3A3</strong>. This is very useful for genomes as well which have many repeated characters. </p>
<p>Now let's take the string <strong>BANANA</strong>. We will first add a <strong>$</strong> sign to the start of the string then compute all the cyclic rotations of <strong>$BANANA</strong>. Then will sort the cyclic rotations – and here is the importance of the dollar sign: that value, when sorting, is less than all alphabet values, so it will make sorting way easier. </p>
<p>After we sort the cyclic rotations, the string formed by the last characters of the sorted cyclic rotations is the burrows wheeler transform. It will look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--83-.png" alt="Image" width="600" height="400" loading="lazy">
<em><strong>Burrows wheeler transform</strong></em></p>
<p>Now as you can see, the burrows wheeler transform tends to have lots of repeats. You might also ask how to reverse the operation. To do that, look at the first characters of the sorted cyclic rotations. They are the same as the characters in the burrows wheeler transform but in sorted order. </p>
<p>So by sorting the burrows wheeler transform, we will get the first and the last letters and compute the original string.</p>
<h2 id="heading-naive-search-algorithm">Naïve Search Algorithm</h2>
<p>Now let's look at a brute force solution for finding a pattern in a string. This approach is not optimal, as it runs with <strong>O(n*m)</strong> time complexity (where m is the length of the pattern and n is the length of the string). </p>
<p>We will consider two pointers, <strong>I</strong> and <strong>J</strong>. First we'll initialize <strong>I</strong> and <strong>J</strong> to be 0. Then we will run a while loop that will keep running while I is less than the length of the string. </p>
<p>Every time the loop runs we will compare the characters at the index <strong>I+J</strong> in the string and the character at the index <strong>J</strong> in the pattern. If they are equal, we will increment <strong>J</strong>, but of mpt. we will increment <strong>I</strong> and reset <strong>J</strong> to be <strong>0</strong>. If j ever exceeds the length of the pattern, then there's a match. </p>
<p>The code for this will look like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">Find_Match</span>(<span class="hljs-params">pattern,string</span>):</span> 

  <span class="hljs-comment">#initialise i and j</span>
  i=<span class="hljs-number">0</span>
  j=<span class="hljs-number">0</span>

  <span class="hljs-keyword">while</span> i&lt;len(string):
   <span class="hljs-keyword">if</span> string[i+j] == pattern[j]:
     j+=<span class="hljs-number">1</span>
   <span class="hljs-keyword">if</span> string[i] != pattern[j]:
     j=<span class="hljs-number">0</span>  
     i+=<span class="hljs-number">1</span>
   <span class="hljs-comment">#Let's say j is equal to the length of the pattern. Then to reach the first match index we can go back a number of steps equal to the length of the pattern.</span>
   <span class="hljs-keyword">if</span> j==len(pattern):
    <span class="hljs-keyword">return</span> i-j

  <span class="hljs-comment">#Incase there is no match  </span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>
</code></pre>
<h2 id="heading-rabin-karps-algorithm">Rabin-Karp's Algorithm</h2>
<p>The problem with the naïve approach is that it runs in O(n**2) time complexity which is horrible when it comes to large inputs like genomes. This means we need something better. </p>
<p>Comparing two strings is linear time, because we need to compare each character for each index. But what if we don't need to do that – what if we transformed the strings into numbers? </p>
<p>Here is the main idea of this algorithm. Let's say there is a function that returns a number associated with each string in the alphabet. We will use the ASCII value of the strings for that. </p>
<p>And then to transform a string into a number we will compute the sum of the ASCII values of all its characters. This a simple hashing function:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">hash</span>(<span class="hljs-params">string</span>):</span>
 count=<span class="hljs-number">0</span>
 <span class="hljs-comment"># in python ord return the ascii value of a character</span>
 <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> string:
  count+=ord(i)

 <span class="hljs-keyword">return</span> count
</code></pre>
<p>Now let's say we want to find <strong>an</strong> in <strong>banana</strong>. Then we will first compare <strong>hash(an)</strong> to <strong>hash(ba)</strong> then to hash(an) and so on till we reach the end of the string. When the hash values match, we can then compare the pattern and the substring because <strong>hash(na)</strong> and <strong>hash(an)</strong> are equal so we need an extra check.</p>
<p>You might be thinking this is silly – why do we need to do all of this? Computing the hash function needs to iterate over the string so we didn't achieve any better time complexity. And you're completely right. </p>
<p>But what if we can compute the hash value of a substring from its previous substring? The difference is in the starting and ending characters – and that's called a rolling hash. That's what makes this algorithm run at <strong>O(n*m)</strong>  worst case and <strong>O(n+m)</strong> average case: because of collisions. </p>
<p>For example, <strong>hash(na)</strong> is equal to <strong>hash(an)</strong>, so here we need to compare na and an. The hash function I showed you is a very simple one. The better the hash function, the fewer collisions we will have. But I don't want to make this too fancy, so I will be using this hash function.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--84-.png" alt="Image" width="600" height="400" loading="lazy">
<em>rolling hash</em></p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">Rabin_Karp</span>(<span class="hljs-params">string, pattern</span>):</span>
 <span class="hljs-comment">#compute the hash value of the pattern</span>
 hashed_pattern=hash(pattern)

 <span class="hljs-comment">#compute the hash value of the first substring with length equal to the length of the pattern</span>

 first_hash=hash(string[<span class="hljs-number">0</span>:len(pattern)])

 <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(len(string)-len(pattern)+<span class="hljs-number">1</span>):
  <span class="hljs-keyword">if</span> i !=<span class="hljs-number">0</span>:
   first_hash-= hash(string[i<span class="hljs-number">-1</span>])
   first_hash+= hash(string[i+len(pattern)<span class="hljs-number">-1</span>])

  <span class="hljs-keyword">if</span> hashed_pattern == first_hash:
   <span class="hljs-comment">#second check</span>
   <span class="hljs-keyword">if</span> pattern == string[i:len(pattern)]:
    <span class="hljs-keyword">return</span> i

 <span class="hljs-comment">#in case no matches are found </span>
 <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>
</code></pre>
<h2 id="heading-knuth-morris-pratt-algorithm">Knuth-Morris-Pratt Algorithm</h2>
<p>Now we will discuss the last algorithm for today. This one is very complicated but I will try to make it as simple as possible. </p>
<p>The idea behind this algorithm is that the naïve approach is great unless the string and the pattern have many repeats – like for example searching for <strong>AAAB</strong> in <strong>AAAXAAA</strong>. In this case do we really need to reset the j pointer to 0 after the first mismatch? Actually no we don't, and I will show you why.</p>
<p>When we analyze this pattern, we can see that it's quite special. Let's say we started at i=0 and we reached j=3. Then the next iteration we got a mismatch. </p>
<p>We don't really need to reset j, since for this given pattern we have the two first characters equal to the second and third characters. And since j already was 3, then the first 3 characters in the string are equal the first three characters in the pattern. And the second and third characters in the string are equal to the first and second characters in the pattern. So we can skip two positions by resetting j to 2 instead of 0.</p>
<p>Now you might ask how we'll know the value of  j after the mismatch. Well, the answer depends on the pattern. For example <strong>abac</strong> if we got a mismatch when we reached j=3 (when we reached c) and since <strong>ab</strong> is equal to <strong>ba</strong>, we can actually skip b for the next iteration. </p>
<p>As you can see this works when we have a common suffix and prefix in a substring of a pattern, so we need to preprocess the string. And for each index of that substring, we can compute the number of skips and store it in an array known as the longest suffix prefix array.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--85-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now we'll write the function for computing the <strong>LSP</strong> array. But first I will explain what I will be doing: </p>
<ul>
<li>the first element in the array is always 0</li>
<li>we will create an array LSP with the same length as the pattern</li>
<li>we will have twp pointers i and prevlps. i is an iteration variable initially set to 1, since the first element in the array is always 0. prevlps keeps track of the previous longest prefix suffix.</li>
<li>we will run a while loop which will keep running while i is less then the length of the pattern. It will compare pattern[i] and pattern[prevLps]. If they match, we will set LCP[i] to prevlps +1, and we'll increment i and prevlps by 1.</li>
<li>if they don't match and prevlps was 0 already, we will set LCP[i] to 0 and increment i.</li>
<li>if prevlps was not 0, we will set prevlps to LCP[prevlcp-1].</li>
</ul>
<p>Let's take an example using the string ANAN. First i was 1 and prevlps was 0. The first iteration happens, and A is not equal n and prevlps is 0 – so the LCP is now [0,0,0,0]. </p>
<p>Now for the second iteration we will compare pattern[prevlps] which is A and A which evaluates to true. So now i is 3, prevlps is 1, and LCP is [0,0,1,0]. </p>
<p>And finally, in the final iteration we will compare N and N. The same thing happens as in the past iteration, and LCP is [0,0,1,2]. </p>
<p>The code for LCP is the following:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">LCP</span>(<span class="hljs-params">pattern</span>):</span>
 LCP_array=[<span class="hljs-number">0</span>]* len(pattern)

 i=<span class="hljs-number">1</span>
 prevlcp=<span class="hljs-number">0</span>

 <span class="hljs-keyword">while</span> i&lt;len(pattern):
  <span class="hljs-keyword">if</span> pattern[i]==pattern[prevlcp]:
   LCP_array[i]=prevlcp+<span class="hljs-number">1</span>
   i+=<span class="hljs-number">1</span>
   prevlcp+=<span class="hljs-number">1</span>

  <span class="hljs-keyword">elif</span> prevlcp == <span class="hljs-number">0</span>:
   LCP_array[i]=<span class="hljs-number">0</span>

  <span class="hljs-keyword">else</span>:
   prevlcp=LCP_array[prevlcp<span class="hljs-number">-1</span>]

 <span class="hljs-keyword">return</span> LCP_array
</code></pre>
<p>Now since we have the LCP array we can run the KMP algorithm. It's similar to the naïve algorithm but with some improvements. It will look like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">KMP</span>(<span class="hljs-params">pattern,string</span>):</span> 

  LCP_array=LCP(pattern)

  <span class="hljs-comment">#initialise i and j</span>
  i=<span class="hljs-number">0</span>
  j=<span class="hljs-number">0</span>

  <span class="hljs-keyword">while</span> i&lt;len(string):
   <span class="hljs-keyword">if</span> string[i+j] == pattern[j]:
     j+=<span class="hljs-number">1</span>
   <span class="hljs-keyword">if</span> string[i] != pattern[j]:
     <span class="hljs-comment">#The line that changed</span>
     j=LCP_array[j<span class="hljs-number">-1</span>] 
     i+=<span class="hljs-number">1</span>
   <span class="hljs-comment">#Let's say j is equal to the length of the pattern. Then to reach the first match index we can go back a number of steps equal to tje length of the pattern.</span>
   <span class="hljs-keyword">if</span> j==len(pattern):
    <span class="hljs-keyword">return</span> i-j

  <span class="hljs-comment">#In case there is no match  </span>
  <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>
</code></pre>
<p>This algorithm runs with O(n+m) time complexity which is great – but it's little bit complicated. If you noticed, almost nothing changed (just in computing the LCP and a single line changed). This single line is what makes the algorithm so efficient.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In the end I hope you learned something new from this article. We learned about data structures for searching as well as some famous algorithms for searching.</p>
<p>This tutorial was the result of two weeks of research. There are a lot of things that I wanted to cover but I wanted to keep this manageable.</p>
<p>If you found this useful and want to get more awesome content, <a target="_blank" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;cad=rja&amp;uact=8&amp;ved=2ahUKEwjn_af-zsr7AhX3Q_EDHbA5AqQQFnoECBEQAQ&amp;url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fhoussein-badra-943879214&amp;usg=AOvVaw09JtGqwagE8pQSOWm7MoPW">follow me on LinkedIn.</a> It will help a lot.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Path-Finding Algorithm Visualizer with React ]]>
                </title>
                <description>
                    <![CDATA[ Path-finding algorithms are algorithms used to find optimal path between two locations. These algorithms are widely used in map applications like Google Maps, for example. In this tutorial we will be building a path finding algorithm visualizer with ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/path-finding-algorithm-visualizer-tutorial/</link>
                <guid isPermaLink="false">66c5a2695e24e23ff225158b</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Houssein Badra ]]>
                </dc:creator>
                <pubDate>Thu, 17 Nov 2022 21:07:02 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--67--1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Path-finding algorithms are algorithms used to find optimal path between two locations. These algorithms are widely used in map applications like Google Maps, for example.</p>
<p>In this tutorial we will be building a path finding algorithm visualizer with React. It will support Breadth-First Search (BFS), Depth-First Search (DFS), adding walls, and weighting nodes for weighted graph algorithms like Dijkstra's. This will help us identify features like streets with high traffic that you don't want to take. </p>
<p>To go through this tutorial, you should have a basic understanding of <a target="_blank" href="https://www.freecodecamp.org/news/breadth-first-search-a-bfs-graph-traversal-guide-with-3-leetcodeexamples/">BFS</a> and <a target="_blank" href="https://www.freecodecamp.org/news/dfs-for-your-next-tech-giant-interview/">DFS</a>. In case you need to review, I will leave a link for a YouTube video explaining the two algorithms. </p>
<p>You should also have a basic understanding of React. </p>
<p>Here's the <a target="_blank" href="https://houssein-algo-visualizer.netlify.app/">final version of what we're going to build</a> and here's <a target="_blank" href="https://github.com/HousseinBadra/Algo-visualizer.git">the source code</a> on my GitHub account.</p>
<p>In this tutorial we will be using Visual Studio Code (but you can use any editor you want), a command line prompt, some basic React, ES6 JavaScript, and HTML and CSS.</p>
<p>So let's start coding! </p>
<h2 id="heading-project-setup">Project Setup</h2>
<p>For this tutorial I will be using Vite, which is a tool that helps you start projects way faster than npm create-react-app. </p>
<p>First, install Vite if you haven't done that yet. Create a folder in a well-known directory on your machine. Then using the terminal, navigate to this directory and run these commands:</p>
<pre><code>$ npm create vite@latest my-app
$ cd my-app
$ npm install
</code></pre><p>Now inside the src folder, create a components folder, a contexts folder, and a utils folder – and you're done. Here's a screenshot of what your project should look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--68-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Project folder structure</em></p>
<h2 id="heading-how-to-add-bootstrap">How to Add Bootstrap</h2>
<p>Now we need to add bootstrap to our project for the buttons and icons we're going to add, since we need to focus on the JavaScript part.</p>
<p>To do this, just add the Bootstrap CDN to the head tag in your HTML file. After adding these links you should notice the font changing.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">integrity</span>=<span class="hljs-string">"sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi"</span> <span class="hljs-attr">crossorigin</span>=<span class="hljs-string">"anonymous"</span>&gt;</span>
<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">href</span>=<span class="hljs-string">"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css"</span>&gt;</span>
</code></pre>
<h2 id="heading-how-to-represent-the-cells">How to Represent the Cells</h2>
<p>For the representation of the grid and the cells, I will be building a two dimensional array of objects containing all the properties we need to represent a certain cell.</p>
<p>Now in the utils folder, create a startingGrid.js file. Here, you'll write a function that returns a grid which is a two dimensional array of objects representing the cells. </p>
<p>Each object will have these properties: <strong>x</strong>, <strong>y</strong>, <strong>isstarting</strong>, <strong>istarget</strong>, <strong>iswall</strong>, and <strong>weight</strong>. </p>
<p><strong>x</strong> and <strong>y</strong> represent the coordinates of the cell. <strong>isstarting</strong> is a Boolean that's only true for the starting cell. <strong>istarget</strong> is similar, but for the target node. <strong>iswall</strong> is a Boolean that's only true for walls. And <strong>weight</strong> is an integer. </p>
<p>All normal cells have a weight of 1, and the weighted cells have a weight of 5. The function should look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getGrid</span>(<span class="hljs-params">width,height</span>)</span>{
    <span class="hljs-keyword">let</span> grid=[]
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i =<span class="hljs-number">0</span> ; i&lt;height ; i++){
      <span class="hljs-keyword">let</span> local=[]
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j =<span class="hljs-number">0</span> ; j&lt;width ; j++){
          local.push({<span class="hljs-attr">x</span>:j,<span class="hljs-attr">y</span>:i,<span class="hljs-attr">isstart</span>:<span class="hljs-literal">false</span>,<span class="hljs-attr">istarget</span>:<span class="hljs-literal">false</span>,<span class="hljs-attr">weight</span>:<span class="hljs-number">1</span>,
          <span class="hljs-attr">iswall</span>:<span class="hljs-literal">false</span>})
          }
      grid.push(local)
      }
    grid[<span class="hljs-built_in">Math</span>.floor(height/<span class="hljs-number">2</span>)][<span class="hljs-built_in">Math</span>.floor(width/<span class="hljs-number">2</span>)].isstart=<span class="hljs-literal">true</span>
    grid[height<span class="hljs-number">-2</span>][width<span class="hljs-number">-2</span>].istarget=<span class="hljs-literal">true</span>
    <span class="hljs-keyword">return</span>  grid
    }
</code></pre>
<h2 id="heading-how-to-create-the-context">How to Create the Context</h2>
<p>In React, passing props from parent to child may become unmaintainable. For this reason, it's better to store all of our state in a single place where state will be accessible to all elements. That's what a context is. </p>
<p>In React we can create a context with <code>createContext</code> and access all its variables using the <code>useContext</code> hook. </p>
<p>Now let's create a context with everything we need. When we hover over a cell we will control the behavior of the event listener based on a variable called mode. For example, if the mode is <code>addwalls</code>, then hovering over a cell makes it a wall. </p>
<p>We will use the same logic for adding weighted cells, and also for setting the starting and ending cells. </p>
<p>The structure I will be using for creating the context is very simple. You can make use of it in all of your projects, and it will look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useContext,createContext } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> context = createContext()

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useParams=<span class="hljs-function">()=&gt;</span>{
    <span class="hljs-keyword">return</span> useContext(context)
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ParamsProvider = <span class="hljs-function">(<span class="hljs-params">{children}</span>) =&gt;</span> {

      <span class="hljs-keyword">return</span> (<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">context.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{}</span>&gt;</span>
        {children}
       <span class="hljs-tag">&lt;/<span class="hljs-name">context.Provider</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>)

}
</code></pre>
<p>Now we will create state for:</p>
<ul>
<li>The <strong>mode</strong> we're in, either building walls or setting the starting cell.</li>
<li>The <strong>algorithm</strong> that we will run.</li>
<li>The <strong>grid</strong> which we will equal by default to the grid returned by the function we already created.</li>
<li>Determining if we're <strong>editing</strong> or not.</li>
<li>For the <strong>starting</strong> and <strong>target</strong> node coordinates.</li>
<li>Determining that we want to <strong>run the algorithm</strong> and <strong>clear the grid</strong> when changed using <code>useEffect</code> (A separate state for each that, when we change its value, we run a useEffect with an appropriate side effect).</li>
</ul>
<p>The code will look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> { useContext, useState,createContext, useEffect, useRef } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { getGrid } <span class="hljs-keyword">from</span> <span class="hljs-string">"../utils/startinggrid"</span>;

<span class="hljs-keyword">const</span> context = createContext()

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> useParams=<span class="hljs-function">()=&gt;</span>{
    <span class="hljs-keyword">return</span> useContext(context)
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ParamsProvider = <span class="hljs-function">(<span class="hljs-params">{children}</span>) =&gt;</span> {

     <span class="hljs-keyword">const</span> [mode,setmode] = useState(<span class="hljs-literal">null</span>)
     <span class="hljs-keyword">const</span> [algo,setalgo] = useState(<span class="hljs-string">''</span>)
     <span class="hljs-keyword">const</span> [run,setrun] = useState(<span class="hljs-literal">false</span>)
     <span class="hljs-keyword">const</span> [grid,setgrid] = useState(getGrid(<span class="hljs-number">50</span>,<span class="hljs-number">25</span>))
     <span class="hljs-keyword">const</span> [editing,seteditFlag] = useState(<span class="hljs-literal">false</span>)
     <span class="hljs-keyword">const</span> [res,setres] = useState(<span class="hljs-literal">false</span>)
     <span class="hljs-keyword">const</span> start=useRef({<span class="hljs-attr">x</span>:<span class="hljs-number">25</span>,<span class="hljs-attr">y</span>:<span class="hljs-number">12</span>})
     <span class="hljs-keyword">const</span> end=useRef({<span class="hljs-attr">x</span>:<span class="hljs-number">48</span>,<span class="hljs-attr">y</span>:<span class="hljs-number">23</span>})

     useEffect(<span class="hljs-function">()=&gt;</span>{    
      restart()
     },[res])


     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">restart</span>(<span class="hljs-params"></span>)</span>{
      setgrid(getGrid(<span class="hljs-number">50</span>,<span class="hljs-number">25</span>))
     }


      <span class="hljs-keyword">return</span> (<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">context.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{{mode,</span>
        <span class="hljs-attr">setmode</span>,
        <span class="hljs-attr">algo</span>,
        <span class="hljs-attr">setalgo</span>,
        <span class="hljs-attr">grid</span>,
        <span class="hljs-attr">setgrid</span>,
        <span class="hljs-attr">setres</span>,
        <span class="hljs-attr">editing</span>,
        <span class="hljs-attr">seteditFlag</span>,
        <span class="hljs-attr">start</span>,
        <span class="hljs-attr">end</span>,
        <span class="hljs-attr">run</span>,
        <span class="hljs-attr">setrun</span>,
        <span class="hljs-attr">res</span>}}&gt;</span>
         {children}
       <span class="hljs-tag">&lt;/<span class="hljs-name">context.Provider</span>&gt;</span>
       <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>)

     }
</code></pre>
<p>And finally, we'll wrap the app component with the ParamsProvider like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>
<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom/client'</span>
<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>
<span class="hljs-keyword">import</span> {ParamsProvider} <span class="hljs-keyword">from</span> <span class="hljs-string">'./context/context'</span>

ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>)).render(
  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">ParamsProvider</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">ParamsProvider</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>

)
</code></pre>
<p> Now to make sure everything is working, import the useParams custom hook to your any components. Now use the console to check its return value. It should return an object with all the variables we've added to the store.</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> <span class="hljs-string">'./App.css'</span>
<span class="hljs-keyword">import</span> {useParams} <span class="hljs-keyword">from</span> <span class="hljs-string">'./context/context'</span>


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

<span class="hljs-built_in">console</span>.log(useParams())

<span class="hljs-keyword">return</span> ( <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>)

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--75-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-create-the-navbar">How to Create the Navbar</h2>
<p>Now it's time for the navbar which we'll use to control the modes. First, create a Navbar folder with two files: Navbar.jsx and Navbar.css. This structure is very useful, especially when using Sass (so each component and its CSS can be found in the same folder).</p>
<p>The navbar will consist of six buttons: two for setting the mode for starting/ending node editing, two for setting the mode for building blocks/adding weighted cells, and two for clearing the board and running the algorithm. </p>
<p>The code will look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'./Navbar.css'</span>
<span class="hljs-keyword">import</span> { useParams } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../context/context'</span>


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

  <span class="hljs-comment">// const [algo,setalgo] = useState('')</span>
  <span class="hljs-keyword">const</span> {mode,setmode,algo,setalgo,setres,setrun}=useParams()



  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'navbar'</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'container'</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{[</span>'<span class="hljs-attr">btn</span>' ,'<span class="hljs-attr">btn-primary</span>', <span class="hljs-attr">mode</span>==<span class="hljs-string">'setstart'</span>? '<span class="hljs-attr">selected</span>' <span class="hljs-attr">:</span> '']<span class="hljs-attr">.join</span>(' ')} <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{
        if(mode == 'setstart') setmode(null)
        else {setmode('setstart')}
       }}&gt;
        <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo-alt"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
       <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">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{[</span>'<span class="hljs-attr">btn</span>' ,'<span class="hljs-attr">btn-primary</span>', <span class="hljs-attr">mode</span>==<span class="hljs-string">'settarget'</span>? '<span class="hljs-attr">selected</span>' <span class="hljs-attr">:</span> '']<span class="hljs-attr">.join</span>(' ')} <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{
        if(mode == 'settarget') setmode(null)
        else {setmode('settarget')}
       }}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
       <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">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{[</span>'<span class="hljs-attr">btn</span>' ,'<span class="hljs-attr">btn-primary</span>', <span class="hljs-attr">mode</span>==<span class="hljs-string">'addbricks'</span>? '<span class="hljs-attr">selected</span>' <span class="hljs-attr">:</span> '']<span class="hljs-attr">.join</span>(' ')} <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{
        if(mode == 'addbricks') setmode(null)
        else {setmode('addbricks')}
       }}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-bricks"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
       <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">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{[</span>'<span class="hljs-attr">btn</span>' ,'<span class="hljs-attr">btn-primary</span>', <span class="hljs-attr">mode</span>==<span class="hljs-string">'addweight'</span>? '<span class="hljs-attr">selected</span>' <span class="hljs-attr">:</span> '']<span class="hljs-attr">.join</span>(' ')} <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{
        if(mode == 'addweight') setmode(null)
        else {setmode('addweight')}
       }}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-virus"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
       <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">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn btn-primary"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{setres((old)=&gt;{ return !old})}}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-arrow-counterclockwise"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> 
       <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">type</span>=<span class="hljs-string">"button"</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"btn btn-primary"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span>=&gt;</span>{setrun((old)=&gt;{return !old})}}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-caret-right"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> 
       <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">select</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"form-select"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Default select example"</span>  <span class="hljs-attr">value</span>=<span class="hljs-string">{algo}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span>=&gt;</span>{
        setalgo(e.target.value)
       }}&gt;
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">''</span>&gt;</span>Choose your algorithm<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"dijkstra"</span>&gt;</span>dijkstra<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"BDS"</span>&gt;</span>BDS<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"BFS"</span>&gt;</span>BFS<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">select</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>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>Each button sets the mode to the desired value – or to null if it's already set to the button's mode. </p>
<p>The run and restart button change the values of the state context variables <code>res</code> and <code>run</code>. We'll use these with a useEffect hook to run the algorithm or clear the board. The <code>select</code> input element is to select the algorithm. </p>
<p>Now, for example, if the building blocks mode button is selected, we want this button to have a different styling from other buttons. We'll do that by using the selected class that will be added for the button depending on which mode is selected. The CSS will look like this:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.navbar</span>{
    <span class="hljs-attribute">width</span>:<span class="hljs-number">100%</span>;  
    <span class="hljs-attribute">height</span>:<span class="hljs-built_in">min</span>(<span class="hljs-number">20vh</span> , <span class="hljs-number">100px</span>);
    <span class="hljs-attribute">background</span>:black;
}

<span class="hljs-selector-class">.navbar</span> <span class="hljs-selector-class">.selected</span> {
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">204</span>, <span class="hljs-number">219</span>, <span class="hljs-number">232</span>) <span class="hljs-number">3px</span> <span class="hljs-number">3px</span> <span class="hljs-number">6px</span> <span class="hljs-number">0px</span> inset, <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>, <span class="hljs-number">255</span>, <span class="hljs-number">255</span>,     <span class="hljs-number">0.5</span>) -<span class="hljs-number">3px</span> -<span class="hljs-number">3px</span> <span class="hljs-number">6px</span> <span class="hljs-number">1px</span> inset;
}
</code></pre>
<p>This is how the app is going to look right now. To test it out, you can check for context variable changes on button clicks:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--76-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Current state of the app</em></p>
<h2 id="heading-how-to-create-the-grid">How to Create the Grid</h2>
<p>Now the cells are divs contained in a div with the class of board which will contain all the cells. The grid will look like an Excel sheet where each cell has an x and y coordinate.</p>
<p>First, create a Grid folder in the components folder. Then add two files in it: Grid.jsx and Grid.css.</p>
<p>Now let's create the grid. First we will create a function that takes the grid and returns an array of refs for each cell. </p>
<p>When we run the algorithms, there will be a lot of state changes if we use regular state and the application will crash. So the solution is to create a ref for each cell, and when we render the cells, each will have its corresponding ref. This lets us manipulate the div without re-rendering the component. </p>
<p>This approach comes with a cost, though, which is unexpected behavior – because this is not the way React is supposed to work. But if we don't use this approach, the application will crash because of the re-renders. </p>
<p>We will create a state to save the ref array. The algorithm will look like this:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">const</span> {grid,setgrid,editing,seteditFlag,mode,start,end,run,res,algo}  =       useParams()

  <span class="hljs-keyword">const</span> [refarray,mm]=useState(getrefarray(grid))

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getrefarray</span>(<span class="hljs-params">grid</span>)</span>{
    <span class="hljs-keyword">let</span> array=[]
    grid.forEach(<span class="hljs-function">(<span class="hljs-params">elem</span>)=&gt;</span>{
     elem.forEach(<span class="hljs-function">(<span class="hljs-params">child</span>)=&gt;</span>{
      array.push(useRef())
    })
   })
   <span class="hljs-keyword">return</span> array
   }
</code></pre>
<p>First we will render a div with class of <code>board</code>. Inside the board and for each element of <code>refarray</code> we will render a div with a ref property (the element itself) so we can access and modify it without rendering the component again. </p>
<p>Each div will have the cell class and the wall class if its corresponding cell object in the grid has the <code>iswall</code> property equal to true. Also we will add the corresponding icon to the cell based on its cell object.</p>
<pre><code class="lang-js">{refarray.map(<span class="hljs-function">(<span class="hljs-params">elem,index</span>)=&gt;</span> {
        <span class="hljs-keyword">let</span> classList=[<span class="hljs-string">'cell'</span>]

        <span class="hljs-keyword">let</span> yindex=<span class="hljs-built_in">Math</span>.floor(index/<span class="hljs-number">50</span>)
        <span class="hljs-keyword">let</span> xindex=index % <span class="hljs-number">50</span>
        <span class="hljs-keyword">let</span> cell=grid[yindex][xindex]

        <span class="hljs-keyword">if</span> (cell.iswall) {
          classList.push(<span class="hljs-string">'wall'</span>)
        }

        <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">index</span>}`} <span class="hljs-attr">ref</span>=<span class="hljs-string">{elem}</span>  <span class="hljs-attr">className</span>=<span class="hljs-string">{classList.join(</span>'         ')} &gt;</span>


          {cell.weight &gt; 1 ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-virus"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null}
          {cell.isstart ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo-alt"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null }
          {cell.istarget ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null }

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> 
})
</code></pre>
<p>This is how the grid is going to look:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--77-.png" alt="Image" width="600" height="400" loading="lazy">
<em>App showing the grid</em></p>
<p>Now we need to add three event listeners to each cell. First, we'll add onMouseDown and onMouseUp event listeners – we use these to set the editing context variable. Then we'll add an onMouseOver which will determine – based on the mode and that editing flag – what changes are being applied to the grid. </p>
<p>We will be updating the grid as usual – we will only use the ref method when running the algorithm. The code will look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">'board'</span>&gt;</span>
      {refarray.map((elem,index)=&gt; {
        let classList=['cell']
        let yindex=Math.floor(index/50)
        let xindex=index % 50
        let cell=grid[yindex][xindex]

        if (cell.iswall) {
          classList.push('wall')
        }

        return <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{</span>`${<span class="hljs-attr">index</span>}`} <span class="hljs-attr">ref</span>=<span class="hljs-string">{elem}</span>  <span class="hljs-attr">className</span>=<span class="hljs-string">{classList.join(</span>' ')} 
        <span class="hljs-attr">onMouseDown</span>=<span class="hljs-string">{()</span>=&gt;</span>{seteditFlag(true)}} 
        onMouseUp={()=&gt; {seteditFlag(false)}}
        onMouseMove={()=&gt;{
          if (!editing) return
          const current= grid[yindex][xindex]
          if (current.isstart || current.istarget ) return
          switch(mode){
            case 'setstart':
              var newgrid=grid.map((elem)=&gt;{
              return elem.map((elem)=&gt;{
                if (!elem.isstart) return elem
                return {...elem,isstart:false}
              }) 
              })
              newgrid[yindex][xindex]={...newgrid[yindex][xindex],isstart:true,istarget:false,weight:1,iswall:false}
             start.current={x:xindex,y:yindex}
             setgrid(newgrid)
             break;

           case 'settarget':
                var newgrid=grid.map((elem)=&gt;{
                return elem.map((elem)=&gt;{
                  if (!elem.istarget) return elem
                  return {...elem,istarget:false}
                }) 
               })
               newgrid[yindex][xindex]={...newgrid[yindex][xindex],isstart:false,istarget:true,weight:1,iswall:false}
               end.current={x:xindex,y:yindex}
               setgrid(newgrid)
               break;

             case 'addbricks':
                var newgrid=grid.slice()
               newgrid[yindex][xindex]={...newgrid[yindex][xindex],weight:1,iswall:true}
               setgrid(newgrid)
               break;

            case 'addweight':
                var newgrid=grid.slice()
               newgrid[yindex][xindex]={...newgrid[yindex][xindex],weight:5,iswall:false}
               setgrid(newgrid)
               break;
           default:
             return 
            }}}&gt;


          {cell.weight &gt; 1 ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-virus"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null}
          {cell.isstart ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo-alt"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null }
          {cell.istarget ? <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"bi bi-geo"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> : null }

         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      })}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
</code></pre>
<p>If the editing flag is false, we will return. The same applies if the cell is a starting cell or a target one – then we don't want to modify them. Else if the mode is equal to <code>addwalls</code>, then we will modify the corresponding cell in the grid and set the <code>iswall</code> property to true. </p>
<p>Also if the mode is equal to <code>addweight</code> we will modify the corresponding cell in the grid and set the weight property to 5 instead of 1. </p>
<p>For the <code>setstart</code> we will create a copy of the grid where all the cells have the <code>isstart</code> set to false. Then we'll set the corresponding cell for the new start cell to true. The same goes for the settarget mode.</p>
<p>Now you should be able to add walls, weights and change the position of the starting and ending node:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--78-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-the-algorithms">The Algorithms</h2>
<p>We can find the shortest path using the algorithms we will implement. Each algorithm finds a path in a unique way and, depending on the algorithm, the output will change.</p>
<p>Let's start with the breath-first search (or BFS) algorithm. We will create a function <strong>BFS</strong> that takes 5 arguments: </p>
<ul>
<li>the <strong>graph</strong></li>
<li>the start and end point coordinates, <strong>start</strong> and <strong>target</strong></li>
<li><strong>prevmap</strong>, which is a hashmap used to track the previous cell for each cell in the grid when the algorithm runs</li>
<li><strong>hashmap</strong>, which is a hashmap that we will use to track visited cells. A hashmap is an object with key value pairs, like a dictionary in Python. </li>
</ul>
<p>For each cell in the graph, we will create an id x-y which will be unique. We'll set its value to false for <strong>hashmap</strong> and null for <strong>prevmap</strong>. Here is how we will implement those in a useEffect later:</p>
<pre><code class="lang-js">  <span class="hljs-keyword">let</span> hashmap={}
  <span class="hljs-keyword">let</span> prevmap={}
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j=<span class="hljs-number">0</span>;j&lt;<span class="hljs-number">25</span>;j++){
   <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">50</span>;i++){
     hashmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">false</span>
     prevmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">null</span>
   }
 }
</code></pre>
<p>Now we will start with an array with one element – the starting node's coordinates – and a counter set initially to zero. While the length of the array is not zero, we will pop the last element off the array and increment the counter. </p>
<p>Now using the coordinates of the element, we will access its ref and add the visited class with a transition delay proportional to the counter. </p>
<p>Then we will access the siblings of the element from the grid and check if they are visited or not from the <strong>hashmap.</strong> If they are visited we will ignore them, but if they are not visited we will mark them as visited and add them to the top of the array. Then we'll mark their value in the <strong>prevmap</strong> to the current element. </p>
<p>When popping elements off, if we come to an element with x and y coordinates equal to those of the target, we will return this object with the current counter. </p>
<p>Depth-first search is very similar: with small changes in the order, we can remove and add elements to the array. <a target="_blank" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=&amp;ved=2ahUKEwjp_Y66x5T7AhWIH-wKHWcBBpAQwqsBegQICRAB&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DtWVWeAqZ0WU&amp;usg=AOvVaw1zYTobguFNgtE86akRVrNf">Here is Alvin's YouTube video which explains the topic in a helpful way</a>. </p>
<p>Finally, if there is no path from a to b – for example if a is surrounded by walls – we will return null. This will happen only when the array gets empty before returning a value. The code will look like this:</p>
<pre><code class="lang-js">
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BFS</span>(<span class="hljs-params">graph,hashmap,prevmap,start,target</span>)</span>{
    <span class="hljs-keyword">let</span> queue=[start]
    <span class="hljs-keyword">let</span> count=<span class="hljs-number">0</span>
    hashmap[<span class="hljs-string">`<span class="hljs-subst">${start.x}</span>-<span class="hljs-subst">${start.y}</span>`</span>]=<span class="hljs-literal">true</span>
    <span class="hljs-keyword">while</span> (queue.length &gt; <span class="hljs-number">0</span>){
      count+=<span class="hljs-number">1</span>
      <span class="hljs-keyword">let</span> c=queue.pop()
      refarray[c.x+c.y*<span class="hljs-number">50</span>].current.style[<span class="hljs-string">'transition-delay'</span>]=<span class="hljs-string">`<span class="hljs-subst">${count * <span class="hljs-number">8</span>}</span>ms`</span>
      refarray[c.x+c.y*<span class="hljs-number">50</span>].current.classList.add(<span class="hljs-string">'visited'</span>)
      <span class="hljs-keyword">if</span> (c.x == target.x &amp;&amp; c.y == target.y) <span class="hljs-keyword">return</span> [c,count]

      <span class="hljs-keyword">if</span>(c.x+<span class="hljs-number">1</span> &lt; <span class="hljs-number">50</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>] &amp;&amp; !graph[c.y][c.x+<span class="hljs-number">1</span>].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x +<span class="hljs-number">1</span>,<span class="hljs-attr">y</span>:c.y})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.x<span class="hljs-number">-1</span> &gt;=<span class="hljs-number">0</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>] &amp;&amp; !graph[c.y][c.x<span class="hljs-number">-1</span>].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x <span class="hljs-number">-1</span>,<span class="hljs-attr">y</span>:c.y})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.y+<span class="hljs-number">1</span> &lt; <span class="hljs-number">25</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>] &amp;&amp; !graph[c.y+<span class="hljs-number">1</span>][c.x].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x ,<span class="hljs-attr">y</span>:c.y+<span class="hljs-number">1</span>})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.y<span class="hljs-number">-1</span> &gt;=<span class="hljs-number">0</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>] &amp;&amp; !graph[c.y<span class="hljs-number">-1</span>][c.x].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x ,<span class="hljs-attr">y</span>:c.y<span class="hljs-number">-1</span>})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>]=<span class="hljs-literal">true</span>
      }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BDS</span>(<span class="hljs-params">graph,hashmap,prevmap,start,target</span>)</span>{
    <span class="hljs-keyword">let</span> queue=[start]
    <span class="hljs-keyword">let</span> count=<span class="hljs-number">0</span>
    hashmap[<span class="hljs-string">`<span class="hljs-subst">${start.x}</span>-<span class="hljs-subst">${start.y}</span>`</span>]=<span class="hljs-literal">true</span>
    <span class="hljs-keyword">while</span> (queue.length &gt; <span class="hljs-number">0</span>){
      count+=<span class="hljs-number">1</span>
      <span class="hljs-keyword">let</span> c=queue[<span class="hljs-number">0</span>]
      queue.shift()
      refarray[c.x+c.y*<span class="hljs-number">50</span>].current.style[<span class="hljs-string">'transition-delay'</span>]=<span class="hljs-string">`<span class="hljs-subst">${count * <span class="hljs-number">8</span>}</span>ms`</span>
      refarray[c.x+c.y*<span class="hljs-number">50</span>].current.classList.add(<span class="hljs-string">'visited'</span>)
      <span class="hljs-keyword">if</span> (c.x == target.x &amp;&amp; c.y == target.y) <span class="hljs-keyword">return</span> [c,count]



      <span class="hljs-keyword">if</span>(c.y+<span class="hljs-number">1</span> &lt; <span class="hljs-number">25</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>] &amp;&amp; !graph[c.y+<span class="hljs-number">1</span>][c.x].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x ,<span class="hljs-attr">y</span>:c.y+<span class="hljs-number">1</span>})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y+<span class="hljs-number">1</span>}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.x<span class="hljs-number">-1</span> &gt;=<span class="hljs-number">0</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>] &amp;&amp; !graph[c.y][c.x<span class="hljs-number">-1</span>].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x <span class="hljs-number">-1</span>,<span class="hljs-attr">y</span>:c.y})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x<span class="hljs-number">-1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.y<span class="hljs-number">-1</span> &gt;=<span class="hljs-number">0</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>] &amp;&amp; !graph[c.y<span class="hljs-number">-1</span>][c.x].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x ,<span class="hljs-attr">y</span>:c.y<span class="hljs-number">-1</span>})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x}</span>-<span class="hljs-subst">${c.y<span class="hljs-number">-1</span>}</span>`</span>]=<span class="hljs-literal">true</span>
      }
      <span class="hljs-keyword">if</span>(c.x+<span class="hljs-number">1</span> &lt; <span class="hljs-number">50</span> &amp;&amp; !hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>] &amp;&amp; !graph[c.y][c.x+<span class="hljs-number">1</span>].iswall){
        queue.unshift({<span class="hljs-attr">x</span>:c.x +<span class="hljs-number">1</span>,<span class="hljs-attr">y</span>:c.y})
        prevmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]={...c}
        hashmap[<span class="hljs-string">`<span class="hljs-subst">${c.x+<span class="hljs-number">1</span>}</span>-<span class="hljs-subst">${c.y}</span>`</span>]=<span class="hljs-literal">true</span>
      }
    }
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>
  }
</code></pre>
<p>We will be running the algorithm only when the run button in the navbar is clicked. That will change the value of run, so we will run a useEffect for this with the context variable run in its dependency array. </p>
<p>We will save the return value in a <strong>result</strong> variable. If the result is null, we will do nothing and there will be no path. Otherwise, we will use the coordinates of the target and the prevmap to get the path from the starting point and the target. Then we will run a timeout with a callback that will add the path class and the corresponding transition delay to each cell.</p>
<p>This is how the code will look:</p>
<pre><code class="lang-js"> useEffect(<span class="hljs-function">()=&gt;</span>{

<span class="hljs-keyword">if</span> (algo == <span class="hljs-string">'BFS'</span>){
  <span class="hljs-keyword">let</span> hashmap={}
  <span class="hljs-keyword">let</span> prevmap={}
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j=<span class="hljs-number">0</span>;j&lt;<span class="hljs-number">25</span>;j++){
   <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">50</span>;i++){
     hashmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">false</span>
     prevmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">null</span>
   }
 }
 <span class="hljs-keyword">let</span> result=BFS(grid,hashmap,prevmap,start.current,end.current)
 <span class="hljs-keyword">let</span> path=[]
 <span class="hljs-keyword">if</span> (result !=<span class="hljs-literal">null</span>){
  <span class="hljs-keyword">let</span> current=result[<span class="hljs-number">0</span>]
  <span class="hljs-keyword">while</span> (prevmap[<span class="hljs-string">`<span class="hljs-subst">${current.x}</span>-<span class="hljs-subst">${current.y}</span>`</span>] != <span class="hljs-literal">null</span>){
    path.push(current)
    current=prevmap[<span class="hljs-string">`<span class="hljs-subst">${current.x}</span>-<span class="hljs-subst">${current.y}</span>`</span>]
  }
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=&gt;</span>{path.reverse().forEach(<span class="hljs-function">(<span class="hljs-params">elem,index</span>)=&gt;</span>{
    refarray[elem.x+elem.y*<span class="hljs-number">50</span>].current.style[<span class="hljs-string">'transition-delay'</span>]=<span class="hljs-string">`<span class="hljs-subst">${( index) * <span class="hljs-number">15</span>}</span>ms`</span>
      refarray[elem.x+elem.y*<span class="hljs-number">50</span>].current.classList.add(<span class="hljs-string">'path'</span>)
  })},result[<span class="hljs-number">1</span>]*<span class="hljs-number">9</span>)

 }


}
<span class="hljs-keyword">if</span> (algo == <span class="hljs-string">'BDS'</span>){
  <span class="hljs-keyword">let</span> hashmap={}
  <span class="hljs-keyword">let</span> prevmap={}
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j=<span class="hljs-number">0</span>;j&lt;<span class="hljs-number">25</span>;j++){
   <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">50</span>;i++){
     hashmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">false</span>
     prevmap[<span class="hljs-string">`<span class="hljs-subst">${i}</span>-<span class="hljs-subst">${j}</span>`</span>]=<span class="hljs-literal">null</span>
   }
 }
  <span class="hljs-keyword">let</span> result=BDS(grid,hashmap,prevmap,start.current,end.current)
  <span class="hljs-keyword">let</span> path=[]
  <span class="hljs-keyword">if</span> (result !=<span class="hljs-literal">null</span>){
   <span class="hljs-keyword">let</span> current=result[<span class="hljs-number">0</span>]
   <span class="hljs-keyword">while</span> (prevmap[<span class="hljs-string">`<span class="hljs-subst">${current.x}</span>-<span class="hljs-subst">${current.y}</span>`</span>] != <span class="hljs-literal">null</span>){
     path.push(current)
     current=prevmap[<span class="hljs-string">`<span class="hljs-subst">${current.x}</span>-<span class="hljs-subst">${current.y}</span>`</span>]
   }
   <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">()=&gt;</span>{path.reverse().forEach(<span class="hljs-function">(<span class="hljs-params">elem,index</span>)=&gt;</span>{
     refarray[elem.x+elem.y*<span class="hljs-number">50</span>].current.style[<span class="hljs-string">'transition-delay'</span>]=<span class="hljs-string">`<span class="hljs-subst">${( index) * <span class="hljs-number">15</span>}</span>ms`</span>
       refarray[elem.x+elem.y*<span class="hljs-number">50</span>].current.classList.add(<span class="hljs-string">'path'</span>)
   })},result[<span class="hljs-number">1</span>]*<span class="hljs-number">9</span>)

  }


 }
 },[run])
</code></pre>
<p>Now after pressing the start button this is the output we're going to get:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2022/11/Screenshot--79-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-clear-the-board">How to Clear the Board</h2>
<p>The side effects of running these algorithms are the classes we've added and the transition delay property (which we need to clear before running the algorithm once again). That's what we're going to do to reset the grid.</p>
<p>The last thing we need to worry about is clearing the board. This will happen when the clear button in the navbar gets clicked, and it will change the value of the res context variable. </p>
<p>So the final useEffect will iterate over every ref of the refarray and reset its classes and transition delay. Also in the context there is another useEffect that will regenerate a new grid (you can check the context code out). It will look like this:</p>
<pre><code class="lang-js"> useEffect(<span class="hljs-function">()=&gt;</span>{
  refarray.forEach(<span class="hljs-function">(<span class="hljs-params">elem</span>)=&gt;</span>{elem.current.style[<span class="hljs-string">'transition-delay'</span>]=<span class="hljs-string">'0ms'</span>})
  refarray.forEach(<span class="hljs-function">(<span class="hljs-params">elem</span>)=&gt;</span>{elem.current.classList.remove(<span class="hljs-string">'visited'</span>);elem.current.classList.remove(<span class="hljs-string">'path'</span>)})
 },[res])
</code></pre>
<p>Here's the CSS for the grid:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.board</span>{
    <span class="hljs-attribute">width</span>:<span class="hljs-number">100%</span>;
    <span class="hljs-attribute">height</span>:<span class="hljs-built_in">calc</span>(<span class="hljs-number">100vh</span> - min(<span class="hljs-number">20vh</span> , <span class="hljs-number">100px</span>));
    <span class="hljs-attribute">background</span>:black;
    <span class="hljs-attribute">display</span>:grid;
    <span class="hljs-attribute">grid-template-rows</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">25</span> , <span class="hljs-number">1</span>fr);
    <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(<span class="hljs-number">50</span> , <span class="hljs-number">1</span>fr);
    <span class="hljs-attribute">gap</span>: <span class="hljs-number">1px</span>;

}

<span class="hljs-selector-class">.board</span> <span class="hljs-selector-class">.cell</span>{
    <span class="hljs-attribute">display</span>:flex;
    <span class="hljs-attribute">justify-content</span>: center;
    <span class="hljs-attribute">align-items</span>: center;
    <span class="hljs-attribute">background</span>: white;
}

<span class="hljs-selector-class">.wall</span> {
    <span class="hljs-attribute">background</span>:black <span class="hljs-meta">!important</span>
}

<span class="hljs-selector-class">.visited</span>{
    <span class="hljs-attribute">background</span>:<span class="hljs-built_in">rgb</span>(<span class="hljs-number">33</span>, <span class="hljs-number">85</span>, <span class="hljs-number">228</span>) <span class="hljs-meta">!important</span>;
    <span class="hljs-attribute">transition</span>:all <span class="hljs-number">8ms</span> <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.075</span>, <span class="hljs-number">0.82</span>, <span class="hljs-number">0.165</span>, <span class="hljs-number">1</span>);

}

<span class="hljs-selector-class">.path</span>{
    <span class="hljs-attribute">background</span>:<span class="hljs-built_in">rgb</span>(<span class="hljs-number">244</span>, <span class="hljs-number">255</span>, <span class="hljs-number">87</span>) <span class="hljs-meta">!important</span> ;
    <span class="hljs-attribute">transition</span>:all <span class="hljs-number">8ms</span> <span class="hljs-built_in">cubic-bezier</span>(<span class="hljs-number">0.075</span>, <span class="hljs-number">0.82</span>, <span class="hljs-number">0.165</span>, <span class="hljs-number">1</span>);


}
</code></pre>
<p>Now when you click the restart button the board will be back to normal.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Finally in this tutorial we've learned a lot about path finding algorithms, React, contexts, refs, algorithmic thinking and much more.</p>
<p>Hopefully you enjoyed this tutorial as much as I enjoyed writing it. This is one of many tutorials that I will be creating for freeCodeCamp. </p>
<p>You will find the code for this project on my <a target="_blank" href="https://github.com/housseinbadra">GitHub</a> and here's the <a target="_blank" href="https://houssein-algo-visualizer.netlify.app/">hosted version</a>. If you want to support me, <a target="_blank" href="https://www.linkedin.com/in/houssein-badra-943879214">follow me on LinkedIn</a> It means a lot for me. </p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
