-
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.
Tic Tac Toe JS vanilla made as practice, 2P mode & Vs cpu mode
- Loading branch information
0 parents
commit 890822f
Showing
3 changed files
with
321 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,29 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<link rel="stylesheet" href="style.css"> | ||
<title>Ta Te Ti</title> | ||
</head> | ||
<body> | ||
<header> | ||
<div class="checkbox-wrapper-25" > | ||
<input type="checkbox" > | ||
</div> | ||
</header> | ||
<h1>Ta Te Ti</h1> | ||
|
||
<div id="status">Jugaror X turno</div> | ||
|
||
<div id="board"></div> | ||
|
||
<div class="reset-container"> | ||
<button class="btn-reset"> | ||
Reset | ||
</button> | ||
</div> | ||
|
||
<script src="main.js"></script> | ||
</body> | ||
</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,128 @@ | ||
document.addEventListener('DOMContentLoaded', () => { | ||
const gameModeCheckbox = document.querySelector('.checkbox-wrapper-25 input'); | ||
const gameModeButton = document.getElementById('game-mode'); | ||
|
||
const board = document.getElementById('board'); | ||
const status = document.getElementById('status'); | ||
const cells = []; | ||
|
||
let currentPlayer = 'X'; | ||
let winner = null; | ||
let singlePlayerMode = false; | ||
|
||
function startSinglePlayerGame() { | ||
singlePlayerMode = true; | ||
resetGame(); | ||
} | ||
|
||
function resetGame() { | ||
currentPlayer = 'X'; | ||
winner = null; | ||
|
||
// Limpiar el tablero y reiniciar las celdas | ||
cells.forEach(cell => { | ||
cell.textContent = ''; | ||
cell.classList.remove('cell-winner'); | ||
}); | ||
|
||
status.textContent = singlePlayerMode ? 'Tu turno "X"' : 'Turno "X"'; | ||
|
||
// Si es el modo de un solo jugador y es el turno de la CPU, que realice su movimiento | ||
if (singlePlayerMode && currentPlayer === 'O') { | ||
makeCPUMove(); | ||
} | ||
} | ||
|
||
function handleCellClick(event) { | ||
const clickedCell = event.target; | ||
const index = clickedCell.dataset.index; | ||
|
||
// Check if the cell is already taken or if there is a winner | ||
if (!cells[index].textContent && !winner) { | ||
cells[index].textContent = currentPlayer; | ||
|
||
// Check for a winner after each move | ||
if (checkWinner()) { | ||
status.textContent = `Jugador ${winner} Gana!`; | ||
} else if (isBoardFull()) { | ||
status.textContent = "Es Empate!"; | ||
} else { | ||
currentPlayer = currentPlayer === 'X' ? 'O' : 'X'; | ||
status.textContent = singlePlayerMode ? `Turno "${currentPlayer}"` : `Turno "${currentPlayer}"`; | ||
|
||
if (singlePlayerMode && currentPlayer === 'O') { | ||
// Es el turno de la CPU en el modo de un solo jugador | ||
setTimeout(() => { | ||
makeCPUMove(); | ||
}, 1000); | ||
} | ||
} | ||
} | ||
} | ||
|
||
function makeCPUMove() { | ||
// Filtra las celdas disponibles | ||
const availableCells = cells.filter(cell => !cell.textContent); | ||
|
||
if (availableCells.length > 0) { | ||
// Elige una celda aleatoria para la CPU | ||
const randomIndex = Math.floor(Math.random() * availableCells.length); | ||
const selectedCell = availableCells[randomIndex]; | ||
|
||
// Simula el clic en la celda seleccionada por la CPU | ||
selectedCell.click(); | ||
} | ||
} | ||
|
||
function checkWinner() { | ||
const winningCombos = [ | ||
[0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows | ||
[0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns | ||
[0, 4, 8], [2, 4, 6] // Diagonals | ||
]; | ||
|
||
for (const combo of winningCombos) { | ||
const [a, b, c] = combo; | ||
if (cells[a].textContent && cells[a].textContent === cells[b].textContent && cells[a].textContent === cells[c].textContent) { | ||
winner = cells[a].textContent; | ||
highlightWinnerCells(combo); | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
function isBoardFull() { | ||
return cells.every(cell => cell.textContent); | ||
} | ||
|
||
function highlightWinnerCells(cellsToHighlight) { | ||
cellsToHighlight.forEach(index => { | ||
cells[index].classList.add('cell-winner'); | ||
}); | ||
} | ||
|
||
// Inicializar el tablero de juego | ||
for (let i = 0; i < 9; i++) { | ||
const cell = document.createElement('div'); | ||
cell.classList.add('cell'); | ||
cell.dataset.index = i; | ||
cell.addEventListener('click', handleCellClick); | ||
board.appendChild(cell); | ||
cells.push(cell); | ||
} | ||
|
||
// Agregar evento de cambio al checkbox | ||
gameModeCheckbox.addEventListener('change', function () { | ||
singlePlayerMode = this.checked; | ||
resetGame(); | ||
}); | ||
|
||
// Agregar evento de clic al botón de reinicio | ||
const btnReset = document.querySelector('.btn-reset'); | ||
btnReset.addEventListener('click', resetGame); | ||
|
||
// Agregar evento de clic al botón de modo de juego | ||
gameModeButton.addEventListener('click', startSinglePlayerGame); | ||
}); |
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,164 @@ | ||
* { | ||
padding: 0; | ||
margin: 0; | ||
font-family: 'Itim', cursive; | ||
} | ||
|
||
body { | ||
font-family: 'Arial', sans-serif; | ||
text-align: center; | ||
background-color: #ffffff; | ||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='900' height='600' viewBox='0 0 900 600'%3E%3Cg %3E%3Cpath fill='%232E163B' d='M306.9 210.2c-1.2-22.8-13.5-42.7-40.8-41.1c-18.3 1.1-35.9 3.6-47.5 20.1c-5.2 7.4-10.6 15.6-11.4 24.9c-0.5 5.8 0.2 12 1.2 17.7c9 49.6 85.3 46.7 96.4 0.2C306.6 224.9 307.3 217.4 306.9 210.2z'/%3E%3Cpath fill='%2338194a' d='M137.2 481.3c-13.2-9.9-31.2-13.3-48.5-3.2c-12.6 7.3-19.1 17.4-21.1 28.2c-0.7 2.4-1.2 4.7-1.5 7c-8.2 35.4 33.7 78.9 72.6 48.6C167.6 539.3 164.4 501.6 137.2 481.3z'/%3E%3Cg fill='%23411c59' %3E%3Cpath d='M547.9 588.3c-7.1-34.2-61.6-52.7-87.5-16.9c-11.2 11.3-12.7 26.3-7.6 39.7c1.8 7.5 5.5 13.9 10.4 19.1c19.4 20.3 53.4 26.2 72.8 1.9C545.9 619.7 553.9 604.2 547.9 588.3z'/%3E%3Cpath d='M547.9-11.7c-7.1-34.2-61.6-52.7-87.5-16.9c-11.2 11.3-12.7 26.3-7.6 39.7c1.8 7.5 5.5 13.9 10.4 19.1c19.4 20.3 53.4 26.2 72.8 1.9C545.9 19.7 553.9 4.2 547.9-11.7z'/%3E%3C/g%3E%3Cpath fill='%234b1e69' d='M849.7 498c-22.3 1.3-43.2 7.5-52.7 29.5c-3.3 7.7-7.3 15.7-7 24.3c2 55.6 86.1 63.4 98.8 10.1C890.6 554.6 877.3 496.4 849.7 498z'/%3E%3Cpath fill='%23532079' d='M762 291.1c-8.2-6.1-19.1-1.9-27.3 2.2c-7.4 3.7-14.4 8.2-21.6 12.1c-6.6 3.6-13.7 7-19.8 11.5c-18.3 13.5-2.5 45.1 10.6 56.4c17 14.6 41.6 15.9 59.6 2.1C794.1 351.8 790.7 312.4 762 291.1z'/%3E%3Cpath fill='%235c218a' d='M863.3 170.3c-4.5-15.7-17.9-28.8-33.4-34.4c-16.2-5.8-38.4-2.9-51.8 8.1c-14.9 12.2-14.5 31.7-11.4 49c9.6 53.9 84.3 47.7 97-1.3C865.6 184.4 865.3 177.1 863.3 170.3z'/%3E%3Cpath fill='%2363219c' d='M598.4 86.1c-10.2 15.5-9.3 34.2-0.9 50.4c2.6 5 6.2 9.5 10.4 13.2c14.2 12.6 35.5 17.1 53.2 9.5c14.3-6.1 23.9-19.8 26.7-34.7C707.4 75.6 629.7 38.5 598.4 86.1z'/%3E%3Cpath fill='%236b21ae' d='M509.8 413.3c-17.3 22.6-11.8 59 17.5 75.3c22.6 12.6 52.2 1.7 63.8-20.9c21.4-42-9.2-85-56.5-71C523.8 399.9 515.6 405.8 509.8 413.3z'/%3E%3Cpath fill='%237120c1' d='M607.4 232.3c-0.5-0.4-1-0.8-1.4-1.2c-16.5-12.8-30.2-22.1-50.3-8.4c-15.5 10.6-29 30.3-31.4 49.1c-4.2 33.6 30.6 46.9 58.6 40.6C619.6 304.2 640.6 259.5 607.4 232.3z'/%3E%3Cpath fill='%23771fd4' d='M410.6 95c-36.5 1.3-74.1 41.8-43.1 74.3c19.8 20.9 54.4 20.7 74.6 0.5c20.5-20.4 18.4-53.1-6.9-68.6C427.7 96.6 419.2 94.7 410.6 95z'/%3E%3Cpath fill='%237c22e3' d='M291.3 23c-0.1-0.1-0.1-0.1-0.2-0.2c-14.2-16.9-38.3-25.6-61.4-12.3c-13.5 7.8-20.5 18.7-22.7 30.2c-5.7 18 1.5 34.2 14.2 44.8c15.4 16.8 40.3 24.1 64.2 5.5c9.6-7.4 15-16.3 17.2-25.4C308.6 48.8 302.7 33.6 291.3 23z'/%3E%3Cpath fill='%23822ee9' d='M419.1 440.6c-16.9-14.5-41.8-21.5-61.7-9.5c-18.3 11.1-1 100.1 32.2 93.5c23.8-4.7 45.3-22.4 48.1-44.3C439.6 466.1 431.5 451.3 419.1 440.6z'/%3E%3Cpath fill='%23883bee' d='M127 227c-12-4.3-25.4-2.1-38.7 11.4C71 255.9 61.4 286.1 80.4 306c21.3 22.3 86.9 27.5 89.6-14.9c0.5-8.9-2.7-17.9-6.5-25.8C155.1 248.3 142.1 232.5 127 227z'/%3E%3Cpath fill='%238f48f3' d='M281.5 407.6c-0.3-0.4-0.7-0.7-1-1c-19.3-17.6-59.1-0.6-78.1 10.3c-23.8 13.7-8.2 41.1 5.4 55.8c16.3 17.6 42.7 25.2 68 5.8C291.3 466.6 295.5 422.7 281.5 407.6z'/%3E%3Cpath fill='%239656f7' d='M137.9 110.2c-10.4-25.7-43.3-32.1-67-23.6C60.1 90.4 50 97.8 45.1 108.6c-21.2 47.3 44.9 81.1 78.5 51c9.5-8.5 17.3-18.9 17.4-32.4C141 120.8 139.9 115.1 137.9 110.2z'/%3E%3Cpath fill='%239d65fa' d='M344.3 284.7c-10 14.9-9.2 34.1-0.9 49.5c3.4 6.3 8.6 13.8 16.1 15.8c7.1 1.9 15.1 0.7 22.1-0.6c15.7-3 45.6-10.5 52.3-26.8C453.5 274.4 375.6 237.9 344.3 284.7z'/%3E%3Cg fill='%23a574fd' %3E%3Cpath d='M-29.2 431.8c23.4 12.4 54.1 1.7 66.1-20.6c9.6-17.8 10.4-40.4-3.3-56.5c-10.5-12.4-44.2-25.8-58.5-11.3c-3 3.1-5.1 7.1-6.9 10.9C-41.1 373.2-55 418.1-29.2 431.8z'/%3E%3Cpath d='M870.8 431.8c23.4 12.4 54.1 1.7 66.1-20.6c9.6-17.8 10.4-40.4-3.3-56.5c-10.5-12.4-44.2-25.8-58.5-11.3c-3 3.1-5.1 7.1-6.9 10.9C858.9 373.2 845 418.1 870.8 431.8z'/%3E%3C/g%3E%3Cpath fill='%23AE84FF' d='M671.4 460.5c-10.7 1.7-20.2 8.3-26.2 22.2c-21.5 49.5 45.4 84.9 79.4 53.3c16.3-15.2 24-31 6.5-48.1c-5.9-5.8-12.3-11-19.1-15.6C699.5 463.7 684.5 458.4 671.4 460.5z'/%3E%3C/g%3E%3C/svg%3E"); | ||
background-attachment: fixed; | ||
} | ||
|
||
header { | ||
display: flex; | ||
height: 30px; | ||
align-items: center; | ||
justify-content: flex-end; | ||
} | ||
|
||
.reset-container { | ||
margin-top: 1rem; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
#board { | ||
margin: 0 auto; | ||
display: grid; | ||
grid-template-columns: 33% 33% 33%; | ||
grid-template-rows: 33% 33% 33%; | ||
max-width: 300px; | ||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); | ||
backdrop-filter: blur(10px); | ||
-webkit-backdrop-filter: blur(10px); | ||
border-radius: 20px; | ||
border: 1px solid rgba(255, 255, 255, 0.18); | ||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.37); | ||
} | ||
|
||
.cell { | ||
border-radius: 6px; | ||
width: 98px; | ||
height: 98px; | ||
font-size: 24px; | ||
border: 2px solid #333; | ||
cursor: pointer; | ||
} | ||
|
||
.cell:hover { | ||
background-color: #a7a6a6; | ||
} | ||
|
||
#status { | ||
margin-top: 20px; | ||
font-size: 18px; | ||
} | ||
|
||
.cell-winner { | ||
background-color: #d2aaff; | ||
} | ||
|
||
.checkbox-wrapper-25 input[type="checkbox"] { | ||
background-image: -webkit-linear-gradient(hsla(0, 0%, 0%, .1), hsla(0, 0%, 100%, .1)), | ||
-webkit-linear-gradient(left, #f66 50%, #6cf 50%); | ||
background-size: 100% 100%, 200% 100%; | ||
background-position: 0 0, 15px 0; | ||
border-radius: 25px; | ||
box-shadow: inset 0 1px 4px hsla(0, 0%, 0%, .5), | ||
inset 0 0 10px hsla(0, 0%, 0%, .5), | ||
0 0 0 1px hsla(0, 0%, 0%, .1), | ||
0 -1px 2px 2px hsla(0, 0%, 0%, .25), | ||
0 2px 2px 2px hsla(0, 0%, 100%, .75); | ||
cursor: pointer; | ||
height: 25px; | ||
padding-right: 25px; | ||
width: 75px; | ||
appearance: none; | ||
transition: .25s; | ||
} | ||
|
||
.checkbox-wrapper-25 input[type="checkbox"]:after { | ||
background-color: #eee; | ||
background-image: -webkit-linear-gradient(hsla(0, 0%, 100%, .1), hsla(0, 0%, 0%, .1)); | ||
border-radius: 25px; | ||
box-shadow: inset 0 1px 1px 1px hsla(0, 0%, 100%, 1), | ||
inset 0 -1px 1px 1px hsla(0, 0%, 0%, .25), | ||
0 1px 3px 1px hsla(0, 0%, 0%, .5), | ||
0 0 2px hsla(0, 0%, 0%, .25); | ||
width: 50px; | ||
height: 25px; | ||
display: block; | ||
content: 'VS'; | ||
font-weight: bold; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.checkbox-wrapper-25 input[type="checkbox"]:checked { | ||
background-position: 0 0, 35px 0; | ||
padding-left: 25px; | ||
padding-right: 0; | ||
} | ||
|
||
.checkbox-wrapper-25 input[type="checkbox"]:checked:after { | ||
content: 'CPU'; /* Contenido cuando el checkbox está marcado */ | ||
} | ||
.btn-reset { | ||
position: relative; | ||
width: 120px; | ||
height: 40px; | ||
background-color: #000; | ||
display: flex; | ||
align-items: center; | ||
color: white; | ||
flex-direction: column; | ||
justify-content: center; | ||
border: none; | ||
padding: 12px; | ||
gap: 12px; | ||
border-radius: 8px; | ||
cursor: pointer; | ||
} | ||
|
||
.btn-reset::before { | ||
content: ''; | ||
position: absolute; | ||
inset: 0; | ||
left: -4px; | ||
top: -1px; | ||
margin: auto; | ||
width: 128px; | ||
height: 48px; | ||
border-radius: 10px; | ||
background: linear-gradient(-45deg, #e81cff 0%, #40c9ff 100%); | ||
z-index: -10; | ||
pointer-events: none; | ||
transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275); | ||
} | ||
|
||
.btn-reset::after { | ||
content: ""; | ||
z-index: -1; | ||
position: absolute; | ||
inset: 0; | ||
background: linear-gradient(-45deg, #fc00ff 0%, #00dbde 100%); | ||
transform: translate3d(0, 0, 0) scale(0.95); | ||
filter: blur(20px); | ||
} | ||
|
||
.btn-reset:hover::after { | ||
filter: blur(30px); | ||
} | ||
|
||
.btn-reset:hover::before { | ||
transform: rotate(-180deg); | ||
} | ||
|
||
.btn-reset:active::before { | ||
scale: 0.7; | ||
} |