From 1dca9b592c205740d4e9a7a47dded84cd9446c90 Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 16:58:22 +0530 Subject: [PATCH 1/6] Create readme.md --- tic-tac-toe/readme.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tic-tac-toe/readme.md diff --git a/tic-tac-toe/readme.md b/tic-tac-toe/readme.md new file mode 100644 index 0000000..f901118 --- /dev/null +++ b/tic-tac-toe/readme.md @@ -0,0 +1,5 @@ +# TIC-TAC-TOE Game + +This is a simple tic-tac-toe game built using HTML, CSS and Javascript. + +Link: https://github.com/NitinNair89/simple-tic-tac-toe-game From 7cf235d39e3b6dc5213dcf27363127b9f9121bc7 Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 16:59:57 +0530 Subject: [PATCH 2/6] Create index.html --- tic-tac-toe/index.html | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tic-tac-toe/index.html diff --git a/tic-tac-toe/index.html b/tic-tac-toe/index.html new file mode 100644 index 0000000..fed1071 --- /dev/null +++ b/tic-tac-toe/index.html @@ -0,0 +1,60 @@ + + + + TIC-TAC-TOE Game + + + + + + + + + +
+

Tic-Tac-Toe !

+

+ Player 01: 0     + Player 02: 0 +

+
+ +
+
+

Ready to Play?

+
+ Choose Players:    + 1     + 2 +
+
+ X   or    + O +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+ Player 1 + Player 2 + +
+
+
+ + +
+ + + From aca607f4869446467cd533891e16ce4f340c72a9 Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 17:00:30 +0530 Subject: [PATCH 3/6] Create main.js --- tic-tac-toe/main.js | 532 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 532 insertions(+) create mode 100644 tic-tac-toe/main.js diff --git a/tic-tac-toe/main.js b/tic-tac-toe/main.js new file mode 100644 index 0000000..90cbdf9 --- /dev/null +++ b/tic-tac-toe/main.js @@ -0,0 +1,532 @@ +//hide utility functions +function hide(elem) { + elem.hide(); +} + +//show utility functions +function show(elem) { + elem.fadeIn(500); +} + +//initialize data-blocked attribute for all cells +function initBlockStatus(){ + for(var i=1;i<=9;i++) { + $("#ttt"+i).data("data-blocked", false); + } +} + +//shuffle players +function shufflePlayers(activeTurn, inactiveTurn, player1, player2) { + /*console.log("player1: "+player1.text()); + console.log("player2: "+player2.text()); + console.log("activeTurn: "+activeTurn.text()); + console.log("inactiveTurn: "+inactiveTurn.text());*/ + if (activeTurn == player1) { + activeTurn = player2; + inactiveTurn = player1; + } else { + activeTurn = player1; + inactiveTurn = player2; + } +} + +//display whose turn +function updateTurnDisplay(pactive, pinactive) { + //console.log("TurnDisplay:: " +pactive.text() + " | " + pinactive.text()); + pactive.addClass("active"); + pinactive.removeClass("active"); +} + +//colors cells to visually identify win +function colorCells(o1,o2,o3){ + o1.addClass('win'); + o2.addClass('win'); + o3.addClass('win'); +} + +//decide game mode - hard/easy +function decideGameMode(){ + //console.log("Inside decideGameMode"); + var randomNo = Math.floor(Math.random()*2), + gameMode=""; + if (randomNo === 0) { + gameMode = "easy"; + } else if(randomNo === 1) { + gameMode = "hard"; + } else { + decideGameMode(); + } + //console.log("gameMode: " +gameMode); + return gameMode; +} + +//AI player's random cell +function getRandomCell(){ + var randomCellID="", randomAI="", isBlocked=""; + do { + randomAI = Math.floor(Math.random()*9); + randomAI++; + randomCellID = "ttt" + randomAI; + //console.log("getRandomCell: " +randomCellID); + isBlocked = isCellBlocked(randomCellID); + if (isBlocked===true){ + //console.log("Blocked: " +randomCellID); + } + } while (isBlocked===true); + + if (isBlocked===false){ + //console.log("Not blocked: " +randomCellID); + return randomCellID; + } +} + +//check if game is over and return winner symbol +function gameOver() { + var returnSymbol = ""; + var c1 = $("#ttt1").text(), + c2 = $("#ttt2").text(), + c3 = $("#ttt3").text(), + c4 = $("#ttt4").text(), + c5 = $("#ttt5").text(), + c6 = $("#ttt6").text(), + c7 = $("#ttt7").text(), + c8 = $("#ttt8").text(), + c9 = $("#ttt9").text(); + //console.log("Gameover check"); + + //check all rows + if (c1===c2 && c2===c3 && c1 !== "") { + //console.log("1"); + returnSymbol = $("#ttt1").text(); + colorCells($("#ttt1"),$("#ttt2"),$("#ttt3")); + } else if (c4===c5 && c5===c6 && c4 !== "") { + //console.log("2"); + returnSymbol = $("#ttt4").text(); + colorCells($("#ttt4"),$("#ttt5"),$("#ttt6")); + } else if (c7===c8 && c8===c9 && c7 !== "") { + //console.log("3"); + colorCells($("#ttt7"),$("#ttt8"),$("#ttt9")); + returnSymbol = $("#ttt7").text(); + } + + //check all columns + if (c1===c4 && c4===c7 && c1 !== "") { + //console.log("4"); + colorCells($("#ttt4"),$("#ttt7"),$("#ttt1")); + returnSymbol = $("#ttt1").text(); + } else if (c2===c5 && c5===c8 && c2 !== "") { + //console.log("5"); + colorCells($("#ttt2"),$("#ttt5"),$("#ttt8")); + returnSymbol = $("#ttt2").text(); + } else if (c3===c6 && c6===c9 && c9 !== "") { + //console.log("6"); + colorCells($("#ttt3"),$("#ttt6"),$("#ttt9")); + returnSymbol = $("#ttt3").text(); + } + + //check diagonals + if (c1===c5 && c5===c9 && c1 !== "") { + //console.log("7"); + colorCells($("#ttt1"),$("#ttt5"),$("#ttt9")); + returnSymbol = $("#ttt1").text(); + } else if (c3===c5 && c5===c7 && c3 !== "") { + //console.log("8"); + colorCells($("#ttt3"),$("#ttt5"),$("#ttt7")); + returnSymbol = $("#ttt3").text(); + } + + //Game is not over, check if draw or playable cells + if (returnSymbol==="") { + //console.log("inside for"); + var i=1; + for(i=1;i<=9;i++) + { + //console.log("i:" + i); + //console.log($(("#ttt")+i).text()); + if ((($(("#ttt")+i)).text() == "X") || (($(("#ttt") + i)).text() == "O")) + { + //console.log("inside if of for"); + continue; + } + else { + //console.log("return C"); + returnSymbol = "C"; + break; + // return returnSymbol; + } + } + if (returnSymbol==="") { + //console.log("return D"); + returnSymbol = "D"; + } + } + //console.log("returnSymbol: " + returnSymbol); + return returnSymbol; +} + +//Check if cell is already used +function isCellBlocked(whichCellID) { + var blockTest; + switch (whichCellID) { + case "ttt1": + blockTest = $("#ttt1").data("data-blocked"); + break; + case "ttt2": + blockTest = $("#ttt2").data("data-blocked"); + break; + case "ttt3": + blockTest = $("#ttt3").data("data-blocked"); + break; + case "ttt4": + blockTest = $("#ttt4").data("data-blocked"); + break; + case "ttt5": + blockTest = $("#ttt5").data("data-blocked"); + break; + case "ttt6": + blockTest = $("#ttt6").data("data-blocked"); + break; + case "ttt7": + blockTest = $("#ttt7").data("data-blocked"); + break; + case "ttt8": + blockTest = $("#ttt8").data("data-blocked"); + break; + case "ttt9": + blockTest = $("#ttt9").data("data-blocked"); + break; + } + //console.log("blockTest: " +blockTest); + return blockTest; +} + +//Block cell for reuse until game resets +function blockCell(whichCellID) { + switch (whichCellID) { + case "ttt1": + $("#ttt1").data("data-blocked", true); + break; + case "ttt2": + $("#ttt2").data("data-blocked", true); + break; + case "ttt3": + $("#ttt3").data("data-blocked", true); + break; + case "ttt4": + $("#ttt4").data("data-blocked", true); + break; + case "ttt5": + $("#ttt5").data("data-blocked", true); + break; + case "ttt6": + $("#ttt6").data("data-blocked", true); + break; + case "ttt7": + $("#ttt7").data("data-blocked", true); + break; + case "ttt8": + $("#ttt8").data("data-blocked", true); + break; + case "ttt9": + $("#ttt9").data("data-blocked", true); + break; + } + //console.log("cell blocked: " +whichCellID); +} + +$(document).ready(function() { + var playerCount = 0, + activeTurn = "", + inactiveTurn = "", + player1 = "", + player2 = "", + playerSymbol="", + randomAI=0, + p1Score=0, + p2Score=0, + turnCount=0, + p1Sym = "", + p2Sym = "", + boardArr = ["","","","","","","","",""], + whichCell = "", + whichCellID = "", + gameStatus = "", + winnerName = "", + gameBoardFlag = false, + cell1 = false, + cell2 = false, + cell3 = false, + cell4 = false, + cell5 = false, + cell6 = false, + cell7 = false, + cell8 = false, + cell9 = false, + AITurn = false, + p1Turn = $("#p1Turn"), + p2Turn = $("#p2Turn"), + info = $("#info"), + start = $("#start"), + chooseSymbol = $("#chooseSymbol"), + gameBoard = $("#board"), + scoreBox = $("#scoreBox"), + p1ScoreSpan = $("#p1Score"), + p2ScoreSpan = $("#p2Score"), + square = $(".square"), + turnDiv = $("#turns"), + startGameButton = $("#startGameButton"), + restartBtn = $("#restartBtn"), + playAgainBtn = $("#playAgainBtn"), + gamefinalStatus = $("#gamefinalStatus"), + p1 = $("#p1"), + p2 = $("#p2"), + symX = $("#x"), + symO = $("#o"); + + //choose 1-player game + p1.click(function(){ + playerCount=1; + p2Turn.text("AI"); + player1 = "human"; + player2 = "ai"; + hide(start); + show(chooseSymbol); + }); + + //choose 2-players game + p2.click(function() { + playerCount = 2; + p1Sym = "X"; + p2Sym = "O"; + player1 = "human"; + player2 = "human"; + activeTurn = p1Turn; + inactiveTurn = p2Turn; + p2Turn.text("Player 2"); + hide(start); + show(startGameButton); + }); + + //choose "X" + symX.click(function() { + p1Sym = symX.text(); + p2Sym = "O"; + activeTurn = p1Turn; + inactiveTurn = p2Turn; + hide(chooseSymbol); + show(startGameButton); + }); + + //choose "O" + symO.click(function() { + p1Sym = symO.text(); + p2Sym = "X"; + activeTurn = p2Turn; + inactiveTurn = p1Turn; + hide(chooseSymbol); + show(startGameButton); + }); + + //reset game + function restart() { + activeTurn = ""; + inactiveTurn = ""; + whichCell = ""; + whichCellID = ""; + gameStatus = ""; + winnerName = ""; + turnCount = 0; + gameBoardFlag = false; + boardArr = []; + cell1 = false; + cell2 = false; + cell3 = false; + cell4 = false; + cell5 = false; + cell6 = false; + cell7 = false; + cell8 = false; + cell9 = false; + + square.removeClass("win"); + hide(gamefinalStatus); + show(p1Turn); + show(p2Turn); + + for(var i=1;i<=9;i++) { + $("#ttt"+i).text(""); + $("#ttt"+i).data("data-blocked", false); + } + } + + //restarts the game, new players + restartBtn.click(function() { + restart(); + playerCount = 0; + player1 = ""; + player2 = ""; + p1Sym = ""; + p2Sym = ""; + playerSymbol = ""; + p1Score = 0; + p2Score = 0; + p1ScoreSpan.text(p1Score); + p2ScoreSpan.text(p2Score); + hide(gameBoard); + hide(turnDiv); + hide(playAgainBtn); + hide(restartBtn); + hide(scoreBox); + show(start); + }); + + //play again, same players + playAgainBtn.click(function() { + restart(); + activeTurn = p1Turn; + inactiveTurn = p2Turn; + hide(playAgainBtn); + hide(restartBtn); + updateTurnDisplay(p1Turn, p2Turn); + }); + + //starts the game + startGameButton.click(function() { + gameBoardFlag = true; + //boardArr.fill("_"); + //alert(boardArr); + hide(startGameButton); + show(gameBoard); + show(turnDiv); + initBlockStatus(); + updateTurnDisplay(activeTurn, inactiveTurn); + + if(playerCount===1) { + //console.log("activeTurn: " +activeTurn.text()); + if(activeTurn === p1Turn) { + //Human plays first, wait for click event; Do nothing + } else if(activeTurn === p2Turn) { + //AI plays first; randomly decide gamemodx=easy or hard + var gameMode = decideGameMode(); + //for testing + gameMode = "easy"; + if(gameMode === "easy") { + //use random numbers + randomAI = Math.floor(Math.random()*9); + //console.log("randomAI: " +randomAI); + whichCellID = "ttt" + randomAI; + AITurn = false; + updateBoard(activeTurn, whichCellID, p2Sym); + } else if(gameMode === "hard") { + //use minimax algorithm + } + } + } + }); + + //click of a cell (player's turn) + square.click(function() { + if (gameStatus === true) { + gamefinalStatus.text("GAME OVER!"); + } else { + whichCellID = $(this).attr("id"); + if (!isCellBlocked(whichCellID)) { + if(playerCount==1) { + AITurn = true; + updateBoard(activeTurn, whichCellID, p1Sym); + } else if (playerCount==2) { + console.log("square click"); + console.log("activeTurn: " +activeTurn.text()); + console.log("p1Turn: " +p1Turn.text()); + if(activeTurn == p1Turn) { + playerSymbol = "X"; + } else { + playerSymbol = "O"; + } + updateBoard(activeTurn, whichCellID, playerSymbol); + if(activeTurn == p1Turn) { + activeTurn = p2Turn; + inactiveTurn = p1Turn; + } else { + activeTurn = p1Turn; + inactiveTurn = p2Turn; + } + + + } + } else { + alert("You can't play that. Choose another cell."); + } + } + }); + + //updates the game board + function updateBoard(whoseTurn, whichCellID, playerSymbol) { + turnCount++; + whichCell = $("#" + whichCellID); + //console.log("updateBoard: " +whoseTurn.text()+ " | Symbol: " +playerSymbol+ "| Cell: "+whichCellID); + whichCell.text(playerSymbol); + //alert(whichCellID); + + //block cell for further use unless reset + blockCell(whichCellID); + + //update turn notifications + updateTurnDisplay(inactiveTurn, whoseTurn); + + //evaluate game + winnerName = gameOver(); + if (winnerName == p1Sym) { + p1Score++; + p1ScoreSpan.text(p1Score); + gamefinalStatus.text('"' +p1Sym+ "\" WINS!"); + gameStatus = true; + hide(p1Turn); + hide(p2Turn); + show(restartBtn); + show(playAgainBtn); + show(gamefinalStatus); + show(scoreBox); + } else if (winnerName == p2Sym) { + p2Score++; + p2ScoreSpan.text(p2Score); + gamefinalStatus.text('"' +p2Sym+ "\" WINS!"); + gameStatus = true; + hide(p1Turn); + hide(p2Turn); + show(restartBtn); + show(playAgainBtn); + show(gamefinalStatus); + show(scoreBox); + } else if (winnerName == "D") { + gamefinalStatus.text("IT'S A DRAW!"); + gameStatus = true; + hide(p1Turn); + hide(p2Turn); + show(restartBtn); + show(playAgainBtn); + show(gamefinalStatus); + show(scoreBox); + } else if (winnerName == "C") { + //console.log("activeTurn: " + activeTurn.text()); + //console.log("inactiveTurn: " + inactiveTurn.text()); + gameStatus = false; + + //shuffle players + /*if (playerCount==2) { + shufflePlayers(activeTurn, inactiveTurn, p1Turn, p2Turn); + }*/ + + //AI Turn + if(playerCount == 1) { + if (AITurn) { + AITurn = false; + whichCellID = getRandomCell(); + //console.log("Cell returned: "+whichCellID); + updateTurnDisplay(activeTurn, inactiveTurn); + updateBoard(inactiveTurn, whichCellID, p2Sym); + } + } + } + } +}); From 15dc3b44c9926baa7885ec0dfab0c23a72e701ad Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 17:00:51 +0530 Subject: [PATCH 4/6] Create style.css --- tic-tac-toe/style.css | 130 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 tic-tac-toe/style.css diff --git a/tic-tac-toe/style.css b/tic-tac-toe/style.css new file mode 100644 index 0000000..1bc0c47 --- /dev/null +++ b/tic-tac-toe/style.css @@ -0,0 +1,130 @@ +body { + color: white;; +} +body, +#board { + background-color: #212121; +} +#scoreBox, +#board, +#chooseSymbol, +#turns, +#startGameButton, +#restartBtn, +#playAgainBtn, +#gamefinalStatus { + display: none; +} +#game { + top:-40px; +} +#start span:hover, +#chooseSymbol span:hover { + color: orange; + border-bottom: 2px dashed orange; +} +#game, +#info, +#board, +#turns, +#startGameButton { + position: relative; +} +#info, +#startGameButton { + top: 130px; +} +#turns { + top: 20px; +} +#gamefinalStatus { + border: 2px solid orange; + background-color: green; +} +#p1Turn, #p2Turn, #gamefinalStatus { + padding: 5px 10px; + border-radius: 5px; +} +#p1Turn, #p2Turn { + background-color: black; + transition: background-color 700ms ease; +} +#p1Turn.active, #p2Turn.active { + background-color: darkred; +} +#board { + height: 350px; + width: 350px; + margin: 0 auto; +} +#p1Score, +#p2Score { + font-weight: bold; + color: orange; +} +h3, +.square, +#info { + font-family: "Finger Paint", cursive; +} +#p1, +#p2, +#chooseSymbol span { + font-size: 25px; + cursor: pointer; +} +.square { + width: 33.33%; + height: 33.33%; + font-size: 40px; + content: ""; + cursor: pointer; + float: left; + border-width: 2px; + border-color: white; + padding-top: 20px; +} +.square.top { + border-bottom-style: solid; +} +.square.left { + clear: both; + border-right-style: solid; +} +.square.right { + border-left-style: solid; +} +.square.bottom { + border-top-style: solid; +} +#playAgainBtn, +#restartBtn { + margin:0 auto; +} +#playAgainBtn { bottom: 50px; } +#restartBtn { bottom: 5px; } + +#ttt1.win, +#ttt2.win, +#ttt3.win, +#ttt4.win, +#ttt5.win, +#ttt6.win, +#ttt7.win, +#ttt8.win, +#ttt9.win +{ + animation: blink 0.7s linear 2; + background-color: green; +} +@keyframes blink { + 0%{ + background-color: transparent; + } + 50%{ + background-color: green; + } + 100%{ + background-color: transparent; + } +} From e7ac8dfef8c339047ca8bd64d6e1badaa9865c25 Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 17:02:17 +0530 Subject: [PATCH 5/6] Update readme.md --- tic-tac-toe/readme.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tic-tac-toe/readme.md b/tic-tac-toe/readme.md index f901118..532d0ff 100644 --- a/tic-tac-toe/readme.md +++ b/tic-tac-toe/readme.md @@ -1,5 +1,8 @@ -# TIC-TAC-TOE Game +# Simple TIC-TAC-TOE +A simple Tic-Tac-Toe game built using HTML, CSS and JavaScript -This is a simple tic-tac-toe game built using HTML, CSS and Javascript. +## LIVE +https://nitinnair89.github.io/simple-tic-tac-toe-game/ -Link: https://github.com/NitinNair89/simple-tic-tac-toe-game +## Codepen +https://codepen.io/Nitin-Chandran-Nair/full/KoYmgb/ From 7cc13abb60814b10e58162ed0bbf9e9599ad695e Mon Sep 17 00:00:00 2001 From: Nitin Chandran Nair Date: Wed, 24 Oct 2018 17:05:15 +0530 Subject: [PATCH 6/6] Added link for TIC-TAC-TOE Added link for TIC-TAC-TOE --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86a0d43..44f2b20 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ It works on web users’ computers — even when they are offline and allows you ### Projects for Beginners -* Make a Tic Tac Toe Board +* Make a [Tic Tac Toe Board](https://github.com/NitinNair89/JavaScriptProjects/tree/master/tic-tac-toe) * Make a web based [calculator](https://github.com/Cybros/JavaScriptProjects/tree/master/calculator) * Make a Todo List with persisting browser storage using localStorage api * Make a unit converter (time, distance, currency, etc)