From 4a4cd67e466b23f1ac8438c92854488c9a9d8f82 Mon Sep 17 00:00:00 2001 From: Vishnu Prakash <75669541+Visthebeast@users.noreply.github.com> Date: Sat, 30 Sep 2023 15:54:08 +0530 Subject: [PATCH] Tic-Tac-Toe game Added a tic-tac-toe game in Frontend Projects --- Frontend Projects/Tic-Tac-Toe/.gitattributes | 2 + Frontend Projects/Tic-Tac-Toe/README.md | 2 + Frontend Projects/Tic-Tac-Toe/index.html | 28 ++++ Frontend Projects/Tic-Tac-Toe/script.js | 103 +++++++++++++ Frontend Projects/Tic-Tac-Toe/style.css | 153 +++++++++++++++++++ 5 files changed, 288 insertions(+) create mode 100644 Frontend Projects/Tic-Tac-Toe/.gitattributes create mode 100644 Frontend Projects/Tic-Tac-Toe/README.md create mode 100644 Frontend Projects/Tic-Tac-Toe/index.html create mode 100644 Frontend Projects/Tic-Tac-Toe/script.js create mode 100644 Frontend Projects/Tic-Tac-Toe/style.css diff --git a/Frontend Projects/Tic-Tac-Toe/.gitattributes b/Frontend Projects/Tic-Tac-Toe/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/Frontend Projects/Tic-Tac-Toe/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/Frontend Projects/Tic-Tac-Toe/README.md b/Frontend Projects/Tic-Tac-Toe/README.md new file mode 100644 index 0000000..4715e4b --- /dev/null +++ b/Frontend Projects/Tic-Tac-Toe/README.md @@ -0,0 +1,2 @@ +# Tic-Tac-Toe +A very basic tic-tac-toe game diff --git a/Frontend Projects/Tic-Tac-Toe/index.html b/Frontend Projects/Tic-Tac-Toe/index.html new file mode 100644 index 0000000..7fde833 --- /dev/null +++ b/Frontend Projects/Tic-Tac-Toe/index.html @@ -0,0 +1,28 @@ + + + + + + + + Tic-Tac-Toe + + +
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+ + \ No newline at end of file diff --git a/Frontend Projects/Tic-Tac-Toe/script.js b/Frontend Projects/Tic-Tac-Toe/script.js new file mode 100644 index 0000000..d874199 --- /dev/null +++ b/Frontend Projects/Tic-Tac-Toe/script.js @@ -0,0 +1,103 @@ +const x_class = 'x' +const o_class = 'o' +const winning_Combinations=[ + //horizontal winning combos + [0,1,2], [3,4,5], [6,7,8], + //vertical winning combos + [0,3,6], [1,4,7], [2,5,8], + //diagonal winning combos + [0,4,8], [2,4,6] +] +const winningMessage = document.getElementById('winning') +const winningMessageText = document.querySelector('[data-winning-message]') +const cellElements = document.querySelectorAll('[data-cell]') +const restartButton = document.getElementById('restartbutton') +const board = document.getElementById('board') +let circleTurn + +//startgame +startGame() + +restartButton.addEventListener('click', startGame) + +function startGame(){ + circleTurn = false + cellElements.forEach(cell => { + cell.classList.remove(x_class) + cell.classList.remove(o_class) + cell.removeEventListener('click', handleClick) + cell.addEventListener('click', handleClick, { once: true }) + }) + setBoardHoverClass() + winningMessage.classList.remove('show') +} +//console.log('hello') + +function handleClick(e){ + console.log('clicked') + const cell = e.target + const currentClass = circleTurn ? o_class : x_class + //place mark + placeMark(cell,currentClass) + + //when someone wins + if(checkWin(currentClass)){ + console.log(currentClass + ' winner') + endGame(false) + } + else if(isDraw()){ + endGame(true) + } + else{ + //switch turns + swapTurns() + + //add hover + setBoardHoverClass() + } + +} + +function placeMark(cell,currentClass){ + cell.classList.add(currentClass) +} + +function setBoardHoverClass(){ + board.classList.remove(x_class) + board.classList.remove(o_class) + if(circleTurn){ + board.classList.add(o_class) + } + else{ + board.classList.add(x_class) + } + +} + +function swapTurns(){ + circleTurn = !circleTurn +} + +function checkWin(currentClass){ + return winning_Combinations.some(combination => { + return combination.every(index =>{ + return cellElements[index].classList.contains(currentClass) + }) + }) +} + +function endGame(draw){ + if(draw){ + winningMessageText.innerText = `Draw!!` + } + else{ + winningMessageText.innerText = `${circleTurn? "O" : "X"} wins!` + } + winningMessage.classList.add('show') +} + +function isDraw(){ + return [...cellElements].every(cell =>{ + return cell.classList.contains(x_class) || cell.classList.contains(o_class) + }) +} \ No newline at end of file diff --git a/Frontend Projects/Tic-Tac-Toe/style.css b/Frontend Projects/Tic-Tac-Toe/style.css new file mode 100644 index 0000000..4e74c82 --- /dev/null +++ b/Frontend Projects/Tic-Tac-Toe/style.css @@ -0,0 +1,153 @@ +*, *::after, *::before{ + box-sizing: border-box; +} + +:root{ + --cell-size: 100px; + --mark-size: calc(var(--cell-size)*.9); +} + +body{ + margin: 0; +} + +.board{ + width: 100vw; + height: 100vh; + display: grid; + justify-content: center; + align-content: center; + justify-items: center; + align-items: center; + grid-template-columns: repeat(3, auto); +} + +.cell{ + width: var(--cell-size); + height: var(--cell-size); + background-color: white; + border: 1px solid black ; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; +} + +.cell.x, +.cell.o { + cursor:not-allowed; +} + +.cell:first-child, +.cell:nth-child(2), +.cell:nth-child(3) { + border-top: none; +} + +.cell:nth-child(3n + 1) { + border-left: none; +} + +.cell:nth-child(3n) { + border-right: none; +} + +.cell:nth-child(7), +.cell:nth-child(8), +.cell:nth-child(9) { + border-bottom: none; +} + +.cell.x::after, +.cell.x::before { + background-color: black; +} + +.cell.o::before { + background-color: black; +} + +.board.x .cell:not(.x):not(.o):hover::after, +.board.x .cell:not(.x):not(.o):hover::before, +.board.o .cell:not(.x):not(.o):hover::before { + background-color: rgb(188, 188, 188) ; +} + +.cell.x::after, +.cell.x::before, +.board.x .cell:not(.x):not(.o):hover::before, +.board.x .cell:not(.x):not(.o):hover::after { + content: ''; + width: calc(var(--mark-size)*.15); + height: var(--mark-size); + position: absolute; +} + +.cell.x::after, +.board.x .cell:not(.x):not(.o):hover::after { + transform: rotate(45deg); +} + +.cell.x::before, +.board.x .cell:not(.x):not(.o):hover::before { + transform: rotate(-45deg); +} + + +.cell.o::after, +.cell.o::before, +.board.o .cell:not(.x):not(.o):hover::after, +.board.o .cell:not(.x):not(.o):hover::before { + content: ''; + width: var(--mark-size); + height: var(--mark-size); + position: absolute; + border-radius: 50%; +} + +.cell.o::before, +.board.o .cell:not(.x):not(.o):hover::before { + width: var(--mark-size); + height: var(--mark-size); +} + +.cell.o::after, +.board.o .cell:not(.x):not(.o):hover::after { + width: calc(var(--mark-size)*.7); + height: calc(var(--mark-size)*.7); + background-color: white; +} + +.winning { + display: none; + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; + background-color: rgba(0,0,0,.9); + justify-content: center; + align-items: center;color: aliceblue; + font-size: 4rem; + flex-direction: column; +} + + +.winning button{ + font-size: 2rem; + background-color: white; + border: 2px solid black; + padding: .25em .5em ; + cursor: pointer; + border-radius: 5%; +} + +.winning button:hover { + background-color: aliceblue; + border-color: aliceblue; + color:rgb(31, 148, 161); +} + +.winning.show { + display: flex; +}