-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7d1a761
Showing
9 changed files
with
335 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# TIC TAC TOE Game | ||
|
||
This is a simple and interactive TIC TAC TOE game built using HTML, CSS, and JavaScript. The game is designed to be played on a 3x3 grid by two players, who take turns marking the spaces in the grid. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner. | ||
|
||
## Features | ||
|
||
- Interactive gameplay for two players | ||
- Visual indication of the winning line | ||
- Responsive design that works on different screen sizes | ||
- Sound effects for game actions | ||
- Game grid is frozen when a player wins to prevent further moves | ||
|
||
## How to Play | ||
|
||
1. Open the game in your web browser. | ||
2. The first player is 'X'. Click on a box to mark it. | ||
3. The turn then passes to the second player, 'O'. | ||
4. The game continues until one player has three marks in a row, column, or diagonal, or until all boxes are filled (a draw). | ||
|
||
Enjoy the game! |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>TIC TAC TOE Game</title> | ||
<link rel="stylesheet" href="style.css"> | ||
<link rel="icon" href="./assets/favicon.ico" type="image/x-icon"> | ||
</head> | ||
<body> | ||
<header> | ||
<nav> | ||
<ul> | ||
<li>MyTicTacToe.com</li> | ||
</ul> | ||
</nav> | ||
</header> | ||
|
||
<main> | ||
<div class="gameContainer"> | ||
<div class="leftContainer"> | ||
<div class="line"></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
<div class="box"><span class="boxtext"></span></div> | ||
</div> | ||
|
||
<div class="infoContainer"> | ||
<h1>Welcome to Tic Tac Toe Game</h1> | ||
<div> | ||
<span class="info">Turn for: X</span> | ||
<button class="reset">Reset Game</button> | ||
</div> | ||
<div class="imgbox"> | ||
<img src="./assets/excited.gif" alt="Excited"> | ||
</div> | ||
</div> | ||
</div> | ||
</main> | ||
</body> | ||
<script src="script.js"></script> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
let turnAudio = new Audio('./assets/turn.mp3'); | ||
let gameoverAudio = new Audio('./assets/gameover.mp3'); | ||
let turn = "X"; | ||
let gameOver = false; | ||
|
||
// Function to change the turn value | ||
const changeTurn = () => { | ||
return turn === "X" ? "O" : "X"; | ||
} | ||
|
||
// Function to check for a win | ||
const checkWin = () => { | ||
let boxtexts = document.getElementsByClassName('boxtext'); | ||
// [position1, position2, position3, translateX, translateY, rotate, translateX(small screens), translateY(small screens), line length] | ||
let wins = [ | ||
[0, 1, 2, 2.5, 5, 0, 5, 10, 25], | ||
[3, 4, 5, 2.5, 15, 0, 5, 30, 25], | ||
[6, 7, 8, 2.5, 25, 0, 5, 50, 25], | ||
[0, 3, 6, -7.5, 15, 90, -15, 30, 25], | ||
[1, 4, 7, 2.5, 15, 90, 5, 30, 25], | ||
[2, 5, 8, 12.5, 15, 90, 25, 30, 25], | ||
[0, 4, 8, 0.5, 15, 45, 0, 30, 30], | ||
[2, 4, 6, -0.5, 15, 135, 0, 30, 30] | ||
]; | ||
wins.forEach(e => { | ||
if ((boxtexts[e[0]].innerText === boxtexts[e[1]].innerText) && (boxtexts[e[2]].innerText === boxtexts[e[1]].innerText) && (boxtexts[e[0]].innerText !== '')) { | ||
document.getElementsByClassName('info')[0].innerText = boxtexts[e[0]].innerText + " Won"; | ||
gameOver = true | ||
gameoverAudio.play(); | ||
drawWinLine(e); | ||
document.querySelector('.imgbox').getElementsByTagName('img')[0].style.width = "200px"; | ||
} | ||
}) | ||
} | ||
// Function to draw a line through the winning combination | ||
// Function to draw a line through the winning combination | ||
function drawWinLine(e) { | ||
let line = document.querySelector('.line'); | ||
let viewportWidth = window.innerWidth; | ||
let lineLength; | ||
|
||
// Adjust the line length based on the viewport width | ||
if (viewportWidth <= 700) { // For small screens | ||
lineLength = e[8] * 2.0; | ||
line.style.width = `${lineLength}vw`; | ||
line.style.transform = `translate(${e[6]}vw, ${e[7]}vw) rotate(${e[5]}deg)`; | ||
} else { | ||
lineLength = e[8]; | ||
line.style.width = `${lineLength}vw`; | ||
line.style.transform = `translate(${e[3]}vw, ${e[4]}vw) rotate(${e[5]}deg)`; | ||
} | ||
|
||
} | ||
|
||
// Game Logic: | ||
let boxes = document.getElementsByClassName('box'); | ||
Array.from(boxes).forEach(element => { | ||
let boxtext = element.querySelector('.boxtext'); | ||
element.addEventListener('click', () => { | ||
if (boxtext.innerText === '' && !gameOver) { // Add gameOver check here | ||
boxtext.innerText = turn; | ||
turn = changeTurn(); | ||
draw(); | ||
checkWin(); | ||
if (!gameOver) { | ||
turnAudio.play(); | ||
document.getElementsByClassName('info')[0].innerText = "Turn for: " + turn; | ||
} | ||
} | ||
}) | ||
}) | ||
|
||
// Reset Button Logic: | ||
let reset = document.querySelector('.reset'); | ||
reset.addEventListener('click', () => { | ||
let boxtexts = document.getElementsByClassName('boxtext'); | ||
Array.from(boxtexts).forEach(element => { | ||
element.innerText = ''; | ||
}); | ||
turn === "X" ? "O" : "X"; | ||
gameOver = false; | ||
document.getElementsByClassName('info')[0].innerText = "Turn for: " + turn; | ||
document.querySelector('.imgbox').getElementsByTagName('img')[0].style.width = "0"; | ||
document.querySelector('.line').style.width = "0"; | ||
}); | ||
|
||
// Draw Logic: | ||
let draw = () => { | ||
let boxtexts = document.getElementsByClassName('boxtext'); | ||
let count = 0; | ||
Array.from(boxtexts).forEach(element => { | ||
if (element.innerText !== '') { | ||
count++; | ||
} | ||
}); | ||
if (count === 9) { | ||
document.getElementsByClassName('info')[0].innerText = "It's a Draw!"; | ||
gameOver = true; | ||
gameoverAudio.play(); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
// By Github Copilot | ||
// // Function to draw a line through the winning combination | ||
// // JavaScript | ||
// function drawWinLine(startBox, endBox) { | ||
// const line = document.querySelector('.line'); | ||
// const startRect = startBox.getBoundingClientRect(); | ||
// const endRect = endBox.getBoundingClientRect(); | ||
// const angle = Math.atan2(endRect.top - startRect.top, endRect.left - startRect.left); | ||
// const length = Math.hypot(endRect.left - startRect.left, endRect.top - startRect.top); | ||
|
||
// line.style.width = `${length}px`; | ||
// line.style.transform = `rotate(${angle}rad)`; | ||
// line.style.left = `${startRect.left}px`; | ||
// line.style.top = `${startRect.top}px`; | ||
// line.style.visibility = 'visible'; | ||
// } | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
* { | ||
margin: 0; | ||
padding: 0; | ||
box-sizing: border-box; | ||
} | ||
|
||
body { | ||
font-family: 'Poppins', sans-serif; | ||
background: #f2f2f2; | ||
} | ||
|
||
nav ul { | ||
list-style: none; | ||
display: flex; | ||
height: 50px; | ||
color: #fff; | ||
background-color: #212121; | ||
justify-content: center; | ||
align-items: center; | ||
font-size: 30px; | ||
font-family: 'Courier New', Courier, monospace; | ||
} | ||
|
||
.gameContainer { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 80vh; | ||
background-color: rgb(67, 195, 255); | ||
margin: 40px; | ||
border-radius: 15px; | ||
} | ||
|
||
.leftContainer { | ||
display: grid; | ||
grid-template-rows: repeat(3, 10vw); | ||
grid-template-columns: repeat(3, 10vw); | ||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | ||
border-radius: 5px; | ||
margin: 10px; | ||
position: relative; | ||
} | ||
|
||
.box { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
font-size: 8vw; | ||
font-weight: 150; | ||
color: #fff; | ||
background-color: #212121; | ||
border: 1px solid #fff; | ||
cursor: pointer; | ||
} | ||
|
||
.box:hover { | ||
background-color: #df75ff; | ||
} | ||
|
||
.infoContainer { | ||
margin: 10px; | ||
padding: 20px; | ||
font-family: 'Courier New', Courier, monospace; | ||
color: #fff; | ||
background-color: #3e3e3e; | ||
border-radius: 10px; | ||
} | ||
|
||
.info { | ||
font-size: 30px; | ||
margin: 10px; | ||
|
||
} | ||
|
||
.reset { | ||
font-size: 20px; | ||
font-weight: bold; | ||
margin: 10px; | ||
padding: 10px; | ||
background-color: #212121; | ||
color: #fff; | ||
border: none; | ||
border-radius: 5px; | ||
cursor: pointer; | ||
transition: all 0.5s ease-in-out; | ||
} | ||
|
||
.reset:hover { | ||
background-color: rgb(255, 255, 255); | ||
color: #212121; | ||
transition: all 0.5s ease-in-out; | ||
} | ||
|
||
.imgbox img { | ||
width: 0; | ||
border-radius: 30%; | ||
transition: width 0.5s ease-in-out; | ||
} | ||
|
||
.line { | ||
position: absolute; | ||
width: 0; | ||
height: 7px; | ||
background: #fbff00; | ||
transform: 0 0; | ||
transition: all 0.5s ease-in-out; | ||
border-radius: 30px; | ||
} | ||
|
||
|
||
/* Media Queries */ | ||
@media only screen and (max-width: 700px) { | ||
.gameContainer { | ||
flex-wrap: wrap; | ||
height: auto; | ||
margin: 10px; | ||
} | ||
|
||
.infoContainer { | ||
margin-top: 20px; | ||
width: 300px; | ||
} | ||
|
||
.infoContainer h1 { | ||
font-size: 20px; | ||
} | ||
|
||
.info { | ||
font-size: 20px; | ||
} | ||
|
||
.leftContainer { | ||
grid-template-rows: repeat(3, 20vw); | ||
grid-template-columns: repeat(3, 20vw); | ||
margin: 20px; | ||
} | ||
|
||
.box { | ||
font-size: 15vw; | ||
} | ||
|
||
.reset { | ||
font-size: 15px; | ||
} | ||
} |