Group 2
Mark Cleo Calbang
Christopher Aluba
Dyna Rose Aragon
Christian Joy Bugtong
online web hosting (link) play with us:
https://markeyoo05.github.io/Tic-Tac-Toe/
OUTPUT
index.html
Multiplayer.html
AI.html
SOURCE CODE
index.html
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="img/png/gif" href="tictactoeLogo.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Finger+Paint&display=swap"
rel="stylesheet">
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1 id="playerText">Tic Tac Toe</h1><br><br>
<div class="GamePPanel">
<button id="multiplayerBtn">Multiplayer</button>
<button id="aiBtn">AI</button>
</div>
</div>
<script src="logical.js"></script>
</body>
</html>
Multiplayer.html
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="img/png/gif" href="../tictactoeLogo.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Finger+Paint&display=swap"
rel="stylesheet">
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1 id="playerText">Tic Tac Toe</h1>
<div class="button-container">
<button id="restartBtn">Restart</button>
<button id="panel">Game Panel</button>
</div>
<div id="gameboard">
<div class="box" id="0"></div>
<div class="box" id="1"></div>
<div class="box" id="2"></div>
<div class="box" id="3"></div>
<div class="box" id="4"></div>
<div class="box" id="5"></div>
<div class="box" id="6"></div>
<div class="box" id="7"></div>
<div class="box" id="8"></div>
</div>
<div id="scoreboard">
<p id="playerScore">Player1(X): 0</p>
<p id="player2Score">Player2(O): 0</p>
</div>
</div>
<script src="MultiplayerMode.js"></script>
</body>
<script>
document.getElementById("panel").addEventListener("click", function() {
window.location.href = "../index.html";
});
</script>
</html>
AI.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="img/png/gif" href="../tictactoeLogo.png">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Finger+Paint&display=swap"
rel="stylesheet">
<title>Tic Tac Toe</title>
<link rel="stylesheet" href="../style.css">
</head>
<body>
<div class="container">
<h1 id="playerText">Tic Tac Toe</h1>
<div class="button-container">
<button id="restartBtn">Restart</button>
<button id="panel">Game Panel</button>
</div>
<div id="gameboard">
<div class="box" id="0"></div>
<div class="box" id="1"></div>
<div class="box" id="2"></div>
<div class="box" id="3"></div>
<div class="box" id="4"></div>
<div class="box" id="5"></div>
<div class="box" id="6"></div>
<div class="box" id="7"></div>
<div class="box" id="8"></div>
</div>
<div id="scoreboard">
<p id="playerScore">Player(X): 0</p>
<p id="computerScore">Computer(O): 0</p>
</div>
</div>
<script src="AiMode.js"></script>
<script>
document.getElementById("panel").addEventListener("click", function() {
window.location.href = "../index.html";
});
</script>
</body>
</html>
styles.css
*{
padding: 0;
margin: 0;
box-sizing: border-box;
}
.GamePPanel {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 10px;
}
#multiplayerBtn, #aiBtn {
padding: 20px 40px;
font-size: 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
:root {
--orange: #170e0e;
--winning-blocks: #ffffff;
}
body {
color: var(--orange);
font-family: 'Finger Paint', cursive;
}
h1 {
font-size: 54px;
text-transform: uppercase;
}
#scoreboard {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
#scoreboard p {
font-size: 18px;
margin: 0 20px;
}
#restartBtn{
color: #ffffff;
}
.container {
padding: 40px;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background-color: #619cb7;
}
#gameboard {
width: 300px;
display: flex;
flex-wrap: wrap;
margin-top: 40px;
}
.box {
height: 100px;
width: 100px;
display: flex;
align-items: center;
justify-content: center;
color: var(--orange);
font-size: 120px;
border-right: 2px solid;
border-bottom: 2px solid;
}
.box:nth-child(3n) {
border-right: none;
}
.box:nth-child(6) ~ .box {
border-bottom: none;
}
button {
padding: 10px 20px;
border-radius: 10px;
background-color: var(--orange);
color: #333;
border-color: var(--orange);
font-size: 18px;
transition: 200ms transform;
font-weight: 600;
}
button:hover {
cursor: pointer;
transform: translateY(-2px);
}
.button-container {
display: flex;
justify-content: space-between;
margin-top: 20px;
gap: 20px;
}
.button-container button {
padding: 10px 20px;
font-size: 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
JavaScript source code
logical.js
document.getElementById('multiplayerBtn').addEventListener('click',
function() {
window.location.href = 'GamePanel/multiplayer.html';
});
document.getElementById('aiBtn').addEventListener('click', function() {
window.location.href = 'GamePanel/AI.html';
});
AIMode.js
let playerText = document.getElementById('playerText');
let restartBtn = document.getElementById('restartBtn');
let boxes = Array.from(document.getElementsByClassName('box'));
let playerScoreDisplay = document.getElementById('playerScore');
let computerScoreDisplay = document.getElementById('computerScore');
let winnerIndicator = getComputedStyle(document.body).getPropertyValue('--
winning-blocks');
const O_TEXT = "O";
const X_TEXT = "X";
const AI_PLAYER = O_TEXT;
const PLAYER = X_TEXT;
let currentPlayer = PLAYER;
let spaces = Array(9).fill(null);
let playerScore = 0;
let computerScore = 0;
const startGame = () => {
boxes.forEach(box => box.addEventListener('click', boxClicked));
};
function boxClicked(e) {
if (currentPlayer === PLAYER) {
const id = e.target.id;
if (!spaces[id]) {
spaces[id] = currentPlayer;
e.target.innerText = currentPlayer;
if (playerHasWon(currentPlayer)) {
playerText.innerHTML = `${currentPlayer} has won!`;
highlightWinningBlocks(playerHasWon(currentPlayer));
updateScore(currentPlayer);
return;
}
if (isDraw()) {
playerText.innerHTML = 'Draw!';
return;
}
currentPlayer = AI_PLAYER;
setTimeout(computerMove, 500);
}
}
}
function computerMove() {
const emptyIndexes = spaces.map((value, index) => value === null ? index :
null).filter(value => value !== null);
const randomIndex = emptyIndexes[Math.floor(Math.random() *
emptyIndexes.length)];
if (randomIndex !== undefined) {
const box = document.getElementById(String(randomIndex));
box.innerText = AI_PLAYER;
spaces[randomIndex] = AI_PLAYER;
if (playerHasWon(AI_PLAYER)) {
playerText.innerHTML = `${AI_PLAYER} has won!`;
highlightWinningBlocks(playerHasWon(AI_PLAYER));
updateScore(AI_PLAYER);
} else if (isDraw()) {
playerText.innerHTML = 'Draw!';
} else {
currentPlayer = PLAYER;
}
}
}
const winningCombos = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function playerHasWon(player) {
for (const condition of winningCombos) {
let [a, b, c] = condition;
if (spaces[a] && spaces[a] === spaces[b] && spaces[a] === spaces[c] &&
spaces[a] === player) {
return condition;
}
}
return false;
}
function highlightWinningBlocks(winningBlocks) {
winningBlocks.forEach(index => {
boxes[index].style.backgroundColor = winnerIndicator;
});
}
function isDraw() {
return spaces.every(cell => cell !== null);
}
function updateScore(winner) {
if (winner === PLAYER) {
playerScore++;
playerScoreDisplay.innerText = `Player(X): ${playerScore}`;
} else if (winner === AI_PLAYER) {
computerScore++;
computerScoreDisplay.innerText = `Computer(O): ${computerScore}`;
}
if (playerScore === 5) {
playerText.innerHTML = 'You Win the Game!';
disableGame();
} else if (computerScore === 5) {
playerText.innerHTML = 'Computer Win the Game!';
disableGame();
} else if (winner === PLAYER) {
playerText.innerHTML = 'You won!';
setTimeout(() => {
restart();
}, 2000);
} else if (winner === AI_PLAYER) {
playerText.innerHTML = 'You Lose!';
setTimeout(() => {
restart();
}, 2000);
} else if (isDraw()) {
playerText.innerHTML = 'Draw!';
setTimeout(() => {
restart();
}, 2000);
}
}
function disableGame() {
boxes.forEach(box => box.removeEventListener('click', boxClicked));
}
restartBtn.addEventListener('click', restart);
function restart() {
spaces.fill(null);
boxes.forEach(box => {
box.innerText = '';
box.style.backgroundColor = '';
});
playerText.innerHTML = 'Tic Tac Toe';
currentPlayer = PLAYER;
if (this.id === 'restartBtn') {
playerScore = 0;
computerScore = 0;
playerScoreDisplay.innerText = `Player(X): ${playerScore}`;
computerScoreDisplay.innerText = `Computer(O): ${computerScore}`;
}
startGame();
}
startGame();
multiplayerMode.js
let playerText = document.getElementById('playerText');
let restartBtn = document.getElementById('restartBtn');
let boxes = Array.from(document.getElementsByClassName('box'));
let playerScoreDisplay = document.getElementById('playerScore');
let player2ScoreDisplay = document.getElementById('player2Score');
let winnerIndicator = getComputedStyle(document.body).getPropertyValue('--
winning-blocks');
const O_TEXT = "O";
const X_TEXT = "X";
let currentPlayer = X_TEXT;
let spaces = Array(9).fill(null);
let player1Score = 0;
let player2Score = 0;
const WINNING_SCORE = 5;
const startGame = () => {
boxes.forEach(box => box.addEventListener('click', boxClicked));
};
function boxClicked(e) {
const id = e.target.id;
// Check if the game is disabled due to reaching the winning score
if (player1Score === WINNING_SCORE || player2Score === WINNING_SCORE) {
return;
}
if (!spaces[id]) {
spaces[id] = currentPlayer;
e.target.innerText = currentPlayer;
if (playerHasWon()) {
playerText.innerHTML = `${currentPlayer} has won!`;
let winning_blocks = playerHasWon();
winning_blocks.map(box => boxes[box].style.backgroundColor =
winnerIndicator);
if (currentPlayer === X_TEXT) {
player1Score++;
playerScoreDisplay.innerText = `Player1(X): ${player1Score}`;
} else {
player2Score++;
player2ScoreDisplay.innerText = `Player2(O): ${player2Score}`;
}
if (player1Score === WINNING_SCORE || player2Score === WINNING_SCORE)
{
playerText.innerHTML = `${currentPlayer} Wins the Game!`;
setTimeout(() => {
restart();
}, 2000);
} else {
setTimeout(() => {
restart();
}, 2000);
}
} else if (isDraw()) {
playerText.innerHTML = 'Draw!';
setTimeout(() => {
restart();
}, 2000);
} else {
currentPlayer = currentPlayer === X_TEXT ? O_TEXT : X_TEXT;
}
}
}
const winningCombos = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function playerHasWon() {
for (const condition of winningCombos) {
let [a, b, c] = condition;
if (spaces[a] && (spaces[a] == spaces[b] && spaces[a] == spaces[c])) {
return condition;
}
}
return false;
}
function isDraw() {
return spaces.every(cell => cell !== null);
}
restartBtn.addEventListener('click', restart);
function restart() {
spaces.fill(null);
boxes.forEach(box => {
box.innerText = '';
box.style.backgroundColor = '';
});
playerText.innerHTML = 'Tic Tac Toe';
currentPlayer = X_TEXT;
if (this.id === 'restartBtn') {
player1Score = 0;
player2Score = 0;
playerScoreDisplay.innerText = `Player1(X): 0`;
player2ScoreDisplay.innerText = `Player2(O): 0`;
}
startGame();
}
startGame();