<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: CarloMonroy</title>
    <description>The latest articles on DEV Community by CarloMonroy (@carlomonroy).</description>
    <link>https://dev.to/carlomonroy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F866670%2F192c9ee1-ec41-4ee6-b6e3-f80eefcfc46b.png</url>
      <title>DEV Community: CarloMonroy</title>
      <link>https://dev.to/carlomonroy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carlomonroy"/>
    <language>en</language>
    <item>
      <title>Simple tic-tac-toe AI using minimax</title>
      <dc:creator>CarloMonroy</dc:creator>
      <pubDate>Thu, 02 Jun 2022 16:55:53 +0000</pubDate>
      <link>https://dev.to/carlomonroy/simple-tic-tac-toe-ai-using-minimax-2dfi</link>
      <guid>https://dev.to/carlomonroy/simple-tic-tac-toe-ai-using-minimax-2dfi</guid>
      <description>&lt;p&gt;As I'm learning more about recursive algorithms I found out about minimax.&lt;br&gt;
If you want to learn more about minimax I higly reccommend &lt;a href="https://www.youtube.com/watch?v=l-hh51ncgDI"&gt;Sebastian Lague video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In tic-tac-toe the rules are the following:&lt;/p&gt;

&lt;p&gt;There is a 3x3 board and 2 players&lt;/p&gt;

&lt;p&gt;Each square can be in 3 different states:&lt;br&gt;
'X' for player 1, 'O' for player 2 or it can be blank&lt;/p&gt;

&lt;p&gt;To win you need to align 3 of the same symbol in a horizontal line, vertical line or diagonal line. This means that we have 3 options per square and we have 9 squares.&lt;/p&gt;

&lt;p&gt;3⁹ = 19,683 possible board states.&lt;/p&gt;

&lt;p&gt;This means that we can use minimax to teach our computer how to play &lt;/p&gt;

&lt;p&gt;We can determine the best move by trying out all the moves and figuring out whats the best option.&lt;/p&gt;

&lt;p&gt;First we need to create our webpage.&lt;br&gt;
I created a really basic website just to show the board.&lt;/p&gt;

&lt;p&gt;You can take a look at the finished code in my &lt;a href="https://github.com/CarloMonroy/tic-tac-toe-AI-UI"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/fNWIQKU"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LeptQp0m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/fNWIQKU.png" title="basic page" width="591" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will be using JavaScrip to add a eventlistener to all of our squares and to fill that square when we click on it.&lt;br&gt;
I don't want to write 9 eventlisteners so I will be adding them with a &lt;code&gt;for&lt;/code&gt; loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const posList = [
  document.querySelector(".pos-1"),
  document.querySelector(".pos-2"),
  document.querySelector(".pos-3"),
  document.querySelector(".pos-4"),
  document.querySelector(".pos-5"),
  document.querySelector(".pos-6"),
  document.querySelector(".pos-7"),
  document.querySelector(".pos-8"),
  document.querySelector(".pos-9"),
];


for (let i = 0; i &amp;lt; posList.length; i++) {
  posList[i].addEventListener("click", function () {
    insertLetter(user, i);
    botMove();
  });
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are calling the &lt;code&gt;botMove()&lt;/code&gt; function every time the user makes a move just to avoid using an extra loop, we are working with the event loop only.&lt;/p&gt;

&lt;p&gt;Now that we have all the event listeners ready we now need to create or minimax algorithm &lt;/p&gt;

&lt;p&gt;To do this we need to create a few helper functions.&lt;br&gt;
Such as &lt;code&gt;insertLetter&lt;/code&gt; &lt;code&gt;botMove&lt;/code&gt; &lt;code&gt;checkwin&lt;/code&gt; and &lt;code&gt;checkwinmark&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function is_free(position) {
  if (board[position] == " ") {
    return true;
  } else {
    return false;
  }
}

function check_draw() {
  for (let i = 0; i &amp;lt; board.length; i++) {
    if (board[i] == " ") {
      return false;
    }
  }
  return true;
}

function check_win() {
  if (board[0] == board[1] &amp;amp;&amp;amp; board[0] == board[2] &amp;amp;&amp;amp; board[0] != " ") {
    return true;
  } else if (board[3] == board[4] &amp;amp;&amp;amp; board[3] == board[5] &amp;amp;&amp;amp; board[3] != " ") {
    return true;
  } else if (board[6] == board[7] &amp;amp;&amp;amp; board[6] == board[8] &amp;amp;&amp;amp; board[6] != " ") {
    return true;
  } else if (board[0] == board[3] &amp;amp;&amp;amp; board[0] == board[6] &amp;amp;&amp;amp; board[0] != " ") {
    return true;
  } else if (board[1] == board[4] &amp;amp;&amp;amp; board[1] == board[7] &amp;amp;&amp;amp; board[1] != " ") {
    return true;
  } else if (board[2] == board[5] &amp;amp;&amp;amp; board[2] == board[8] &amp;amp;&amp;amp; board[2] != " ") {
    return true;
  } else if (board[0] == board[4] &amp;amp;&amp;amp; board[0] == board[8] &amp;amp;&amp;amp; board[0] != " ") {
    return true;
  } else if (board[6] == board[4] &amp;amp;&amp;amp; board[6] == board[2] &amp;amp;&amp;amp; board[6] != " ") {
    return true;
  } else {
    return false;
  }
}

function check_win_mark(mark) {
  if (board[0] == board[1] &amp;amp;&amp;amp; board[0] == board[2] &amp;amp;&amp;amp; board[0] == mark) {
    return true;
  } else if (board[3] == board[4] &amp;amp;&amp;amp; board[3] == board[5] &amp;amp;&amp;amp; board[3] == mark) {
    return true;
  } else if (board[6] == board[7] &amp;amp;&amp;amp; board[6] == board[8] &amp;amp;&amp;amp; board[6] == mark) {
    return true;
  } else if (board[0] == board[3] &amp;amp;&amp;amp; board[0] == board[6] &amp;amp;&amp;amp; board[0] == mark) {
    return true;
  } else if (board[1] == board[4] &amp;amp;&amp;amp; board[1] == board[7] &amp;amp;&amp;amp; board[1] == mark) {
    return true;
  } else if (board[2] == board[5] &amp;amp;&amp;amp; board[2] == board[8] &amp;amp;&amp;amp; board[2]) {
    return true;
  } else if (board[0] == board[4] &amp;amp;&amp;amp; board[0] == board[8] &amp;amp;&amp;amp; board[0] == mark) {
    return true;
  } else if (board[6] == board[4] &amp;amp;&amp;amp; board[6] == board[2] &amp;amp;&amp;amp; board[6] == mark) {
    return true;
  } else {
    return false;
  }
}

function showWin() {
  resultModal.style.display = "block";
  resultText.innerHTML = "You Won";
  initialText.style.display = "none";
}

function showLost() {
  resultModal.style.display = "block";
  resultText.innerHTML = "You Lost";
  initialText.style.display = "none";
}

function showDraw() {
  resultModal.style.display = "block";
  resultText.innerHTML = "Draw";
  initialText.style.display = "none";
}

function insertLetter(letter, position) {
  if (is_free(position)) {
    board[position] = letter;
    posList[position].innerHTML = letter;
    if (check_draw()) {
      console.log("Draw");
      showDraw();
    }
    if (check_win()) {
      if (letter == "X") {
        showLost();
        console.log("BOT WINS");
      } else {
        console.log("User wins");
      }
    }
    return;
  } else {
    console.log("That space is not avaialble");
    return;
  }
}

function botMove() {
  var best_score = -800;
  var best_move = 0;

  for (let i = 0; i &amp;lt; board.length; i++) {
    if (board[i] == " ") {
      board[i] = bot;
      var score = minimax(board, 0, false);
      board[i] = " ";
      if (score &amp;gt; best_score) {
        best_score = score;
        best_move = i;
      }
    }
  }
  console.log(score);
  console.log(best_move);
  console.log(board);
  insertLetter(bot, best_move); // Here we insert the final move
  return;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to dive into the minimax algorithm&lt;/p&gt;

&lt;p&gt;Our minimax algorithm will iterate trough every possible combination of moves in our board and will choose the best move available.&lt;/p&gt;

&lt;p&gt;We do this assigning a -800 when the move results in loss and 800 when the move results in win.&lt;/p&gt;

&lt;p&gt;In order for us to iterate trough all posible positions we also need to add inteligence to the user moves.&lt;/p&gt;

&lt;p&gt;We are doing this using an extra &lt;br&gt;
&lt;code&gt;var board = [" ", " ", " ", " ", " ", " ", " ", " ", " "];&lt;/code&gt;&lt;br&gt;
This board is only being used to represent the board in a way that is easier to access its elements.&lt;/p&gt;

&lt;p&gt;Usually with minimax we need to define the depth of the search, however there is not a lot of states that our board can be on. So we can get away not using any depth.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function minimax(board, depth, is_maximizing) {
  if (check_win_mark(bot)) {
    return 1;
  } else if (check_win_mark(user)) {
    return -1;
  } else if (check_draw()) {
    return 0;
  }

  if (is_maximizing) {
    var best_score = -800;
    for (let i = 0; i &amp;lt; board.length; i++) {
      if (board[i] == " ") {
        board[i] = bot;
        var score = minimax(board, 0, false);
        board[i] = " ";
        if (score &amp;gt; best_score) {
          best_score = score;
        }
      }
    }
    return best_score;
  } else {
    best_score = 800;
    for (let i = 0; i &amp;lt; board.length; i++) {
      if (board[i] == " ") {
        board[i] = user;
        score = minimax(board, 0, true);
        board[i] = " ";
        if (score &amp;lt; best_score) {
          best_score = score;
        }
      }
    }
    return best_score;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can take a look a the live version &lt;a href="https://thunderous-kitsune-3cad2f.netlify.app/"&gt;here!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy Hacking!&lt;br&gt;
Carlo Monroy.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>ai</category>
      <category>beginners</category>
    </item>
    <item>
      <title>FizzBuzz Challenge Usando list comprehension!</title>
      <dc:creator>CarloMonroy</dc:creator>
      <pubDate>Mon, 30 May 2022 19:18:51 +0000</pubDate>
      <link>https://dev.to/carlomonroy/fizzbuzz-challenge-usando-list-comprehension-2i97</link>
      <guid>https://dev.to/carlomonroy/fizzbuzz-challenge-usando-list-comprehension-2i97</guid>
      <description>&lt;p&gt;Si eres programador o estas aprendiendo a programar seguramente te has encontrado con el FizzBuzz Challenge o lo encontraras.&lt;br&gt;
A continuación hablaremos acerca de este reto y lo implementaremos utilizando list comprehension de python!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Que es FizzBuzz Challenge&lt;/strong&gt;&lt;br&gt;
Se nos pide escribir un programa el cual nos imprima &lt;em&gt;n&lt;/em&gt; cantidad de numeros.&lt;br&gt;
Si el numero es multiplo de 3 imprimir Fizz&lt;br&gt;
Si el numero es multiplo de 5 imprimir Buzz&lt;br&gt;
Si el numero es multiplo de 3 y de 5 imprimir FuzzBuzz&lt;br&gt;
Si el numero no es multiplo de ninguno imprimir el numero&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementación regular FizzBuzz&lt;/strong&gt;&lt;br&gt;
Para entender como funciona nuestra list comprehension primero necesitamos entender como necesita funcionar nuestro programa.&lt;br&gt;
La forma mas sencilla de implementarlo es con un &lt;code&gt;for&lt;/code&gt; loop y con expresiones &lt;code&gt;if&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Primero necesitamos iterar por la cantidad de numeros&lt;br&gt;
&lt;code&gt;for i in range(1, 15):&lt;/code&gt;&lt;br&gt;
En cada iteracion revisaremos nuestras condiciones utilizando nuestro operador modulus &lt;code&gt;%&lt;/code&gt;&lt;br&gt;
Podemos manejar este operador de forma booleana ya que cuando el resultado de el modulo es 0 nos regresa &lt;code&gt;False&lt;/code&gt;.&lt;br&gt;
Podemos invertir nuestro resultado booleano utilizando &lt;code&gt;not&lt;/code&gt; y de esta forma cuando nuestro numero si sea divisible nos regresara &lt;code&gt;True&lt;/code&gt;, Esta logica la podemos implementar dentro de nuestro &lt;code&gt;for&lt;/code&gt; loop de la siguiente forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for i in range(1, 16):
    if not (i%3 and not i%5):
        print("FizzBuzz")
    elif not (i%3):
        print("Fizz")
    elif not (i%5):
        print("Buzz")
    else:
        print(i)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nuestra respuesta en consola seria:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GR-1KvTJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hs5yui7vi38bocqkfs75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GR-1KvTJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hs5yui7vi38bocqkfs75.png" alt="FizzBuzz console log" width="285" height="244"&gt;&lt;/a&gt;&lt;br&gt;
Felicidades, ya completaste el FizzBuzz Challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FizzBuzz con List Comprehension&lt;/strong&gt;&lt;br&gt;
Para poder aplicar nuestro list comprehension debemos recordar que al utilizar el operador &lt;code&gt;*&lt;/code&gt; se repite esa cantidad de veces.&lt;br&gt;
De esta forma podemos utilizar &lt;code&gt;x = "string"*(not i%5):&lt;/code&gt;&lt;br&gt;
Cuando el Resultado de nuestra evaluación sea False nuestro string no se mostrara.&lt;br&gt;
primero evaluaremos nuestras condiciones.&lt;br&gt;
Ejemplo:&lt;br&gt;
&lt;code&gt;"Fizz"*(not i%3)&lt;/code&gt; Si &lt;code&gt;i==2&lt;/code&gt; entonces nuestra evaluacion seria False, Despues evaluamos con nuestro operador &lt;code&gt;*&lt;/code&gt; y al ser falso ese "String" no se estaria concatenando.&lt;/p&gt;

&lt;p&gt;de esta forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FizzBuzzList = ["Fizz"*(not i%3) + "Buzz"*(not i%5) or i ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hasta aqui tenemos la parte logica de nuestro list comprehension.&lt;br&gt;
Por cada iteracion pasaremos nuestro string en el que si no se cumple nuestra condicion  no se concatena y cuando no se cumple ninguna condicion se concatena el numero de nuestra iteracion.&lt;/p&gt;

&lt;p&gt;Ahora solo nos falta agregar nuestro for loop &lt;code&gt;for i in range(1, 16)&lt;/code&gt;, en &lt;code&gt;range()&lt;/code&gt; nuestro primer parametro es inclusivo y el segundo parametro es exclusivo.&lt;br&gt;
De esta forma si necesitamos numeros de el 1 al 15 debemos ingresarle los parametros &lt;code&gt;1, 16&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nuestro List Comprehension final quedaria de la siguiente forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FizzBuzz = ["Fizz"*(not i%3) + "Buzz"*(not i%5) or i for i in range(1, 16)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Espero les haya sigo de ayuda!&lt;br&gt;
Happy Hacking!&lt;br&gt;
Carlo Monroy&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>fizzbuzz</category>
    </item>
  </channel>
</rss>
