Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 8, 2021 01:45 am GMT

Unbeatable Emoji Tic Tac Toe

Hi Everyone!
In this post, I will show you how to make an unbeatable emoji tic-tac-toe that makes fun of you if you make a move or lose. It is made with HTML, CSS, and Javascript. You cannot win this game. The most you can get is a draw. Follow me if you want more projects.

Let's start with the HTML Design:

<!DOCTYPE html><html>  <head>    <link rel="stylesheet" href="style.css>    <title>Unbeatable Tic Tac Toe | Abhinav Gupta</title>  </head><body><section id="start-select"> <div>  <div>   <h3>Go First or Second?</h3>   <button id="1st" class="active" onclick="pickTurn(true);" style='font-size: 14px;'>1st</button><button id="2nd" onclick="pickTurn(false);" style='font-size: 14px;'>2nd</button>   <h3>Choose Your Character</h3>   <span id="charSymbols"></span>  <button id ="start-btn" onclick="startGame();" style='font-size: 18px;'>Start Game</button>  </div> </div></section><header id="header" style="opacity:0.6;">    <div id="emoji-outer-div">    <div id="emoji">     <img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/win02.png" id="emoji-img">    </div>    <div id="emoji-text">     <span id="aiTalk">"Hi, I'm Unbeatable-AI<br>Wanna Play Against Me?"</span>    </div>  </div></header>  <nav id="menu-nav"> <div>  <div>   <h3>Next Round Go First or Second?</h3>   <button id="1st-next" class="active" onclick="pickTurn(true);">1st</button><button id="2nd-next" onclick="pickTurn(false);">2nd</button>   <h3>Change Your Character</h3>   <span id="menu-chars"></span>  <button id ="menu-close" onclick="openMenu(false);" style="">Close</button>  </div> </div></nav><section id='main-section' style="opacity:0.6;">  <section id="side-section">  <a id="menu-open" href="javascript:void(0);" onclick="openMenu(true);"><div>&#x2630</div></a>  <div id="score">   <div><span>Score</span></div>    <div><table>     <tr>       <th>You</th>      <th style="width: 12px;"></th>       <th>Ai</th>     </tr>     <tr>       <td>0</td>      <td> </td>       <td id="score-ai">0</td>     </tr>      </table></div>   <div style="height: 10px; width:0;"></div>  <div><table>    <tr>      <th>Tie</th>    </tr>    <tr>      <td id="score-tie">0</td>    </tr>  </table></div></div> </section> <div id="outer-grid"><section id="grid">  <div id="pos0"><a href="javascript:void(0);" onclick='playerMove(0);' class="pos"></a></div> <div id="pos1"><a href="javascript:void(0);" onclick='playerMove(1);' class="pos"></a></div> <div id="pos2"><a href="javascript:void(0);" onclick='playerMove(2);' class="pos"></a></div> <div id="pos3"><a href="javascript:void(0);" onclick='playerMove(3);' class="pos"></a></div> <div id="pos4"><a href="javascript:void(0);" onclick='playerMove(4);' class="pos"></a></div> <div id="pos5"><a href="javascript:void(0);" onclick='playerMove(5);' class="pos"></a></div> <div id="pos6"><a href="javascript:void(0);" onclick='playerMove(6);' class="pos"></a></div> <div id="pos7"><a href="javascript:void(0);" onclick='playerMove(7);' class="pos"></a></div> <div id="pos8"><a href="javascript:void(0);" onclick='playerMove(8);' class="pos"></a></div></section> </div></section><script href="script.js"></script>    </body></html>

Next, let's make the CSS for the nice neat look:

* { box-sizing: border-box; font-family: 'Cabin', sans-serif;}a { text-decoration: none; color: inherit;}button:focus {outline:0;}body { margin: 20px auto; padding: 5px; max-width: 510px; background-color: #4ECCB0;}#start-select { position: absolute; width: 100vw; height: 100vh; z-index: 100; left: 50%; top: 40%; transform: translate(-50%,-50%);}#start-select div { position: fixed; display: flex; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 350px; height: 300px; border-radius: 35px; background-color: #5A8BCE; box-shadow: 3px 3px 6px #0B3A97;}#start-select div div { display: flex; justify-content: center; flex-wrap: wrap; left: 50%; top: 50%; transform: translate(-50%,-50%);}#start-select div div h3 { margin: auto; text-align: center; width: 100%;}#start-select div div span { display: flex; flex-wrap: wrap; justify-content: center;}#start-select div div button { background-color: #4ECCB0; border-radius: 8px; margin: 3px; padding: 15px; height: 50px; min-width: 55px; border: none; -webkit-transition: background-color 500ms; /* Safari */ transition: background-color 500ms;}#start-select div div button:hover { background-color: #77E0C9; box-shadow: 0.5px 0.5px 5px black; cursor: pointer; cursor: hand; -webkit-transition: background-color 300ms; /* Safari */ transition: background-color 300ms;}#start-select div div button.active { border: 2px solid; background-color: #2EB798; padding: 13px; -webkit-transition: background-color 500ms; /* Safari */ transition: background-color 500ms;}#start-select div div button.charBtn { min-width: 40px; height: 40px; width: 40px; text-align: center; padding: 6px;}header { display: flex; height: 110px; margin: 0 15px; opacity: 1; -webkit-transition: opacity 750ms; /* Safari */ transition: opacity 750ms;}#emoji-outer-div { flex: 1; display: flex; align-items: center;}#emoji { width: 100px; height: 100px;}#emoji img { height: 100%;}#emoji-text { flex: 1; text-align: center; margin: 0 30px; font-size: 20px;}#aiTalk { font-family: 'Poiret One', Segoe, sans-serif; font-weight: bold;}nav { display: none; position: absolute; width: 100vw; height: 100vh; z-index: 99; left: 50%; top: 50%; transform: translate(-50%,-50%);}nav div { position: fixed; display: flex; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 310px; height: 350px; border-radius: 35px; background-color: #5A8BCE; box-shadow: 3px 3px 6px #0B3A97;}nav div div { display: flex; justify-content: center; flex-wrap: wrap; left: 50%; top: 50%; transform: translate(-50%,-50%);}nav div div h3 { margin: auto; text-align: center; width: 100%;}nav div div span { width: 270px; display: flex; flex-wrap: wrap; justify-content: center;}nav div div button { background-color: #4ECCB0; border-radius: 8px; margin: 3px; padding: 15px; height: 50px; min-width: 55px; border: none; -webkit-transition: background-color 750ms; /* Safari */ transition: background-color 750ms;}nav div div button:hover { background-color: #77E0C9; box-shadow: 0.5px 0.5px 5px black; cursor: pointer; cursor: hand; -webkit-transition: background-color 300ms; /* Safari */ transition: background-color 300ms;}nav div div button.active { border: 2px solid; background-color: #2EB798; padding: 13px; -webkit-transition: background-color 500ms; /* Safari */ transition: background-color 500ms;}nav div div button.charBtn { min-width: 40px; height: 40px; width: 40px; text-align: center; padding: 6px;}#main-section { display: flex; flex-wrap: wrap; margin: auto; opacity: 1; -webkit-transition: opacity 500ms; /* Safari */ transition: opacity 500ms;}#side-section { margin: 15px;}#menu-open div { margin: auto; text-align: center; width: 60px; border-radius: 10px; font-size: 35px; border: solid #009271; margin: 25px; padding: 2.5px; background-color: #1BA485;}#menu-open div:hover { background-color: #28C09E; border: solid #009271;}#score { margin: auto;}#score table, #score div { font-size: 20px; text-align: center; margin: auto; display: flex;}tr, th, td { padding: 1px;}#score div span { font-size: 25px; margin: 10px auto;}@media screen and (max-width: 530px) { body {  margin: 10px auto;  padding: 5px; } header {  margin: auto;  max-width: 400px; } #emoji-text {  margin: 0 10px;  font-size: 20px; } #emoji {  height: 65px;  width: 65px; } #start-select div {  width: 300px;  height: 380px;  padding: 13px; } #score-2 {  position: relative;  right: 15px; } #menu-open div {  margin: 0 5px; } #score {  margin: auto;  display: flex;  flex: 1; } #side-section {  margin: auto;  width: 360px;  display: flex; }}#outer-grid { height: 300px; width: 300px; margin: 8px auto;}@media screen and (min-width: 380px) { #outer-grid {  width: 360px;  height: 360px;  margin: 15px auto; }}#grid { height: 100%; width: 100%; display: flex; flex-wrap: wrap;}#grid div { width: 33.3%; height: 33.3%; padding: 2.5px; display: flex;}#grid div div, #grid div a { background-color: #134DBF; text-shadow: 1px 1px grey; font-size: 45px; width: 100%; height: 100%; text-align: center; border-radius: 15px; display: flex; box-shadow: 2px 2px 4px #008B81;}#grid div div.taken { background-color: #0B3A96; box-shadow: 4px 4px 5px #008B81;}#grid div div.win { background-color: #E26200; box-shadow: 4px 4px 5px #008B81;}#grid div div span { margin: auto;}.pos-span { opacity: 0; display: flex; width: 100%; height: 100%; -webkit-transition: opacity 250ms; /* Safari */ transition: opacity 250ms;}.pos-span span { margin: auto;}.pos-span:hover { opacity: 0.4; -webkit-transition: opacity 550ms; /* Safari */ transition: opacity 550ms;}#grid div div:hover { background-color: #0B3A96; box-shadow: 4px 4px 5px #008B81; -webkit-transition: background-color 300ms; /* Safari */ transition: background-color 300ms;}

Lastly, let's write the Javascript to actually make it "Unbeatable":

 var aiTalksWin = [[["win4"],"Sorry, humans made me to powerful!"], [["win01"],"Honestly, I thought you could win, but I guess I was wrong."], [["win02"],"<del>Win Tic-Tac-Toe?</del> <br>2. First, win against ME!"], [["win3"],"What Did You Expect? You Are Only a Human..."], [["win01"],"Unbeatable Is In My Name, I can't do it is in yours."], [["win3"],"The score counter is pointless."], [["win4"],"Let You Win? I'm Afraid I Can't Do That."], [["win02"],""]];var aiTalksMove = [[["move00"],"..."], [["move00"],"Hmmm..."], [["move05"],"Go AI !!"], [["move08"],"Sadness is Victory"],[["move08"], "Your Defeat Is a WIN for me..."], [["move03"],"Nice Try (not)"], [["move03"],"Knock Knock. Who's there? R O B O T"], [["move4"],"There are 255,168 Possible Board Combinations, Yet You Picked That One?"], [["win4"],"Infinity x Infinity Wins for me, not you!"], [["draw02"],"When Was The Last Time You Rebooted Your Device?"], [["draw04"],"I feel strange..."], [["move01"],"A Wise Computer Once Told Me That The Meaning Of Life Is 42"], [["draw01"],"Whoops, wrong move."], [["win02"],"The end is upon! "], [["move06"], "Can't Touch This!"], [["move07"], "Your Last Move Goes In The loosing Category"]];var aiTalksTie = [[["draw01"],"..."], [["draw02"],"..."], [["draw03"],"..."], [["draw04"],"..."]];// </> Ai Talkingfunction randomEmoji(chance, arr) { var randTest = Math.random() < chance; if (randTest) {  var rand = Math.floor(Math.random()*arr.length);  console.log(rand);  document.getElementById("emoji-img")   .src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/"+arr[rand][0][0]+".png";  document.getElementById("aiTalk")   .innerHTML = '"'+arr[rand][1]+'"'; }}var winCond = [[0,1,2],[3,4,5],[6,7,8],               [0,3,6],[1,4,7],[2,5,8],               [0,4,8],[2,4,6]];var gameMain = ["0", "0", "0",                "0", "0", "0",                "0", "0", "0"]; var chars = ["01","02","03","04","05","06","07","08","09","10","11","12","13"];function charsBtnGen() { for (var i = 0; i < chars.length; i++) {  document.getElementById("charSymbols").innerHTML += '<button id="char'+i+'" class="charBtn" onclick="chrChoose('+i+');"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon'+chars[i]+'.png" style="width: 25px"></button>';  document.getElementById("menu-chars").innerHTML += '<button id="char-chng'+i+'" class="charBtn" onclick="chrChange('+i+');"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon'+chars[i]+'.png" style="width: 25px"></button>'; }} function openMenu(open) { if (open) {  document.getElementById('menu-nav').style.display = 'flex';  document.getElementById('header').style.opacity = '0.6';  document.getElementById('main-section').style.opacity = '0.6'; } else {  document.getElementById('menu-nav').style.display = 'none';  document.getElementById('header').style.opacity = '';  document.getElementById('main-section').style.opacity = ''; }}var aiChar = 'O';var plChar = 'X';var aiScore = 0;var tieScore = 0;var gameStarted = false;// --- \/ \/ \/ Before Game Start \/ \/ \/ ---// </> Player 1st or 2nd plFirst = true;function pickTurn(first) { if (first) {  document.getElementById("1st").className = "active";  document.getElementById("2nd").className = "";  document.getElementById("1st-next").className = "active";  document.getElementById("2nd-next").className = ""; } if (!first) {  document.getElementById("2nd").className = "active";  document.getElementById("1st").className = "";  document.getElementById("2nd-next").className = "active";  document.getElementById("1st-next").className = ""; } plFirst = first;}// </> Character Chooserfunction chrChoose(x) { for (var i = 0; i < chars.length; i++) {  document.getElementById("char"+i).className = "charBtn"; } document.getElementById("char"+x).className += " active"; plChar = chars[x];}// </> Character Changefunction chrChange(x) { for (var i = 0; i < chars.length; i++) {  document.getElementById("char-chng"+i).className = "charBtn"; } document.getElementById("char-chng"+x).className += " active";  if (aiChar === chars[x]) {   var y = -1;   while (y === x || y === -1) {y = Math.floor(Math.random()*chars.length);}   for (var j = 0; j < 9; j++) {    if (gameMain[j] === aiChar) {     gameMain[j] = chars[y];     document.getElementById("div"+j)     .innerHTML = "<span style='display: flex;'><img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon"+chars[y]+".png' style='width: 50px; margin: auto;'></span>";    }   }    aiChar = chars[y]; } // "<span style='display: flex;'><img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon"+chars[x]+".png' style='width: 50px; margin: auto;'></span>" for (var i = 0; i < 9; i++) {  if (gameMain[i] === plChar) {   gameMain[i] = chars[x];   document.getElementById("div"+i)    .innerHTML = "<span style='display: flex;'><img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon"+chars[x]+".png' style='width: 50px; margin: auto;'></span>";  } else if (gameMain[i] === "0") {   document.getElementById("transpChars"+i)    .innerHTML = "<span style='display: flex;'><img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon"+chars[x]+".png' style='width: 50px; margin: auto;'></span>";  } } plChar = chars[x];}// </> Random Ai Charfunction randChar() {  var rand =  Math.floor(Math.random()*chars.length);  aiChar = chars[rand];  if (aiChar === plChar) {return randChar();}  return; }// </> Start Gamevar round = 0;function startGame() { gameStarted = true; plMoveDisable = false; document.getElementById('start-select').style.display = 'none'; document.getElementById('header').style.opacity = ''; document.getElementById('main-section').style.opacity = ''; if (round === 0) {  document.getElementById("aiTalk").innerHTML = '"Have Fun"';  document.getElementById("emoji-img").src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/win3.png"; } round++; !function () {  var randPl =  Math.floor(Math.random()*chars.length);  if (plChar === "X") {plChar = chars[randPl];} }(); randChar(); var pos = document.getElementsByClassName("pos"); for (var i = 0; i < 9; i++) {  pos[i].innerHTML = '<div><span class="pos-span"><span id="transpChars'+i+'"><span style="display: flex;"><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon'+plChar+'.png" style="width: 50px; margin: auto;"></span></span></span></div>'; } if (!plFirst) {  aiTurn(); }}// --- /\ /\ /\  Before Game Start /\ /\ /\ ---// --- \/ \/ \/  After Game Start \/ \/ \/ ---// </> Checks for Victoryfunction checkVictory(who) {   var inx = [], i;   for (i = 0; i < 9; i++) {    if (gameMain[i] === who) {     inx.push(i);     }      }   for (var j = 0; j < 8; j++) {    var win = winCond[j];    if (inx.indexOf(win[0]) !== -1 &&         inx.indexOf(win[1]) !== -1 &&         inx.indexOf(win[2]) !== -1) {     randomEmoji(1, aiTalksWin);     for (let k = 0; k < 3; k++) {      setTimeout(function() {       document.getElementById("div"+win[k]).className = "win";      },350*(k+1));     }      gameStarted = false;      aiScore++;      document.getElementById("score-ai").innerHTML = aiScore;      setTimeout(function() {restart("tie");},2000);      return true;         }      }     if (gameMain.indexOf("0") === -1) {    gameStarted = false;    randomEmoji(1, aiTalksTie);    setTimeout(function() {     for (let k = 0; k < 9; k++) {       setTimeout(function() {        document.getElementById("div"+[k]).innerHTML = "";       },125*(k+1));      }    },500);    setTimeout(function() {restart("tie");},2100);    tieScore++;    document.getElementById("score-tie").innerHTML = tieScore;    return true;   } else if (who === aiChar && gameMain.indexOf(plChar) !== -1) {randomEmoji(0.3, aiTalksMove);}        return false;  }// </> Restart Gamefunction restart(x) { for (var i = 0; i < 9; i++) {  document.getElementById("pos"+i).innerHTML = '<a href="javascript:void('+i+');" onclick="playerMove('+i+');" class="pos"></a>'; } gameMain = ["0", "0", "0",             "0", "0", "0",             "0", "0", "0"];  startGame();  disableRestart = false;}// </> Write a Movefunction writeOnGame(pos, char) { gameMain[pos] = char; document.getElementById("pos"+pos)  .innerHTML = "<div  class='taken' id='div"+pos+"'><span style='display: flex;'><img src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/1134440/icon"+char+".png' style='width: 50px; margin: auto;'></span></div>";}// </> Ai Triger and Equal Value Ai Move Randomizerfunction aiTurn() { var posArr = ai(); var ran = Math.floor(Math.random() * posArr.length); writeOnGame(posArr[ran], aiChar); checkVictory(aiChar);}// </> Player Clickvar plMoveDisable = falsefunction playerMove(pos) { if (gameStarted && !plMoveDisable) {  plMoveDisable = true;  writeOnGame(pos, plChar);  var win = checkVictory(plChar);  if (win) {return;}  setTimeout(function() {   aiTurn();   plMoveDisable = false;  },450); }}// --- /\ /\ /\  After Game Start /\ /\ /\ ---// --- \/ \/ \/ AI \/ \/  \/ ---// </> MinMax algofunction ai() { if (gameStarted) {  function isOpen(gameState,pos) {   return gameState[pos] === "0";  }  function didWin(gameState, val) {   var inx = [], i;   for (i = 0; i < 9; i++) {    if (gameState[i] === val) {     inx.push(i);     }    }   for (var i = 0; i < 8; i++) {     if (inx.indexOf(winCond[i][0]) !== -1 &&          inx.indexOf(winCond[i][1]) !== -1 &&          inx.indexOf(winCond[i][2]) !== -1) {      return true;    }   }    return false;  }  function findScore(scores, x) {   if (scores.indexOf(x) !== -1) {return x;}   else if (scores.indexOf(0) !== -1) {return 0;}   else if (scores.indexOf(x * -1) !== -1) {return x * -1;}   else {return 0;}  }  var scoresMain = ['0','0','0','0','0','0','0','0','0'];  function findBestMove() { // MAIN FUNCTION   for (var i = 0; i < 9; i++) {    if (isOpen(gameMain, i)) {     var simGame = gameMain.slice();     simGame[i] = aiChar;     if (didWin(simGame, aiChar)) {      scoresMain[i] = 1;     } else {      scoresMain[i] = plSim(simGame);     }    }       }   var bigest = -99;   for (var j = 0; j < 9; j++) {    if (scoresMain[j] !== '0' && scoresMain[j] > bigest) {     bigest = scoresMain[j];    }   }   var inx = [], i;   for (i = 0; i < 9; i++) {    if (scoresMain[i] === bigest) {     inx.push(i);     }    }   console.log(gameMain.slice(0,3), scoresMain.slice(0,3));   console.log(gameMain.slice(3,6), scoresMain.slice(3,6));   console.log(gameMain.slice(6,9), scoresMain.slice(6,9));   return inx;  }  function plSim(simGame) { // PL SIM   var simGameTest = simGame.slice();   for (var i = 0; i < 9; i++) {    if (isOpen(simGame, i)) {     simGameTest = simGame.slice();     simGameTest[i] = plChar;     if (didWin(simGameTest, plChar)) {      return -1;     }    }   }   var plScores = ['0','0','0','0','0','0','0','0','0'];   for (var j = 0; j < 9; j++) {    if (isOpen(simGame, j)) {     simGameTest = simGame.slice();     simGameTest[j] = plChar;     plScores[j] = aiSim(simGameTest);    }   }   return findScore(plScores, -1);  }  function aiSim(simGame) { // AI SIM   var simGameTest = simGame.slice();   for (var i = 0; i < 9; i++) {    if (isOpen(simGame, i)) {     simGameTest = simGame.slice();     simGameTest[i] = aiChar;     if (didWin(simGameTest, aiChar)) {      return 1;     }    }   }   var aiScores = ['0','0','0','0','0','0','0','0','0'];   for (var j = 0; j < 9; j++) {    if (isOpen(simGame, j)) {     simGameTest = simGame.slice();     simGameTest[j] = aiChar;     aiScores[j] = plSim(simGameTest);    }   }   return findScore(aiScores, 1);  } // aiSim() return findBestMove(); }} // ai() endcharsBtnGen();

That's It! You have now successfully created an Unbeatable Emoji Tic-Tac-Toe.

Live Demo

Full Code


Original Link: https://dev.to/abhidevelops/unbeatable-emoji-tic-tac-toe-10jh

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To