Tic Tac Toe en JavaScript

Javascript

El juego Tic Tac Toe o Tres en línea (Tres en raya) está diseñado para 2 jugadores, que de forma alternativa colocan sus fichas en un tablero de 3×3.

Ganará el jugador que logre colocar 3 de sus fichas formando una línea recta.

Hemos realizado este juego utilizando HTML, Css y JavaScript. A continuación mostramos el código:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Tic Tac Toe</title>
</head>
<body>
	<div class="content">
		<h1>Tic Tac Toe</h1>

		<div class="marker">
			<div class="marker-item">
				<div class="header">X</div>
				<span id="marker-X">0</span>
			</div>
			<div class="marker-item">
				<div class="header">O</div>
				<span id="marker-O">0</span>
			</div>
		</div>


		<table id="board">
			<tr>
				<td data-cell="0" class="cell"></td>
				<td data-cell="1" class="cell"></td>
				<td data-cell="2" class="cell"></td>
			</tr>
			<tr>
				<td data-cell="3" class="cell"></td>
				<td data-cell="4" class="cell"></td>
				<td data-cell="5" class="cell"></td>
			</tr>
			<tr>
				<td data-cell="6" class="cell"></td>
				<td data-cell="7" class="cell"></td>
				<td data-cell="8" class="cell"></td>
			</tr>
		</table>

		<div id="result"></div>
		<button id="restart">Restart</button>
	</div>


	<script type="text/javascript">

		/* Definitions */		
		let clicked = [];
		let boardBlocked = false;
		let current_player = "X";

		let player_clicked = [];		
		player_clicked["X"] = [];
		player_clicked["O"] = [];

		let player_counter = [];		
		player_counter["X"] = 0;
		player_counter["O"] = 0;

		const winningCombination = [
		[0, 1, 2], 
		[3, 4, 5], 
		[6, 7, 8], 
		[0, 3, 6], 
		[1, 4, 7], 
		[2, 5, 8], 
		[0, 4, 8], 
		[2, 4, 6]
		];

		
		/* Listeners */
		document.querySelectorAll('.cell').forEach(cell => cell.addEventListener('click', handleCellClick));

		var restartBtn = document.getElementById('restart');
		restartBtn.addEventListener('click', handleRestartClick);


		
		/* Functions */

		/*
		* Check all the possible combinations according 
		* to the cells clicked by the player and see 
		* if any of them are valid to win
		*/
		function check(current_player){
			if(player_clicked[current_player].length < 3){
				return false
			}

			for(let i=0; i<player_clicked[current_player].length; i++) {
				for(let j=0; j<player_clicked[current_player].length; j++) {
					for(let z=0; z<player_clicked[current_player].length; z++) {

						var combination = [
						player_clicked[current_player][i], 
						player_clicked[current_player][j], 
						player_clicked[current_player][z]
						];

						for(let y=0; y<winningCombination.length; y++) {
							if(JSON.stringify(winningCombination[y]) === JSON.stringify(combination)){
								win();
								return true;
							}
						}

					}
				}
			}
			
		}


		/*
		* Detect click in cell and check if it makes win the player. If not, change player.
		*/
		function handleCellClick(clickedCellEvent) {
			if(!boardBlocked){
				const clickedCell = clickedCellEvent.target;
				const clickedCellIndex = clickedCell.getAttribute('data-cell');
				if(!clicked.includes(clickedCellIndex)){
					clicked.push(clickedCellIndex);
					player_clicked[current_player].push(parseInt(clickedCellIndex));
					clickedCell.innerHTML = '<span class="player-' + current_player + '">' + current_player + '</span>';
					check(current_player);
					changePlayer();
				}
			}
		}


		/* 
		* Define player
		*/
		function changePlayer() {
			current_player = current_player === "X" ? "O" : "X";			
		}


		/* 
		* Set win
		*/
		function win(){
			boardBlocked = true;
			document.getElementById('board').classList.add("boardBlocked");
			document.getElementById('result').classList.add("visible");
			document.getElementById('result').innerHTML = current_player + " WIN!";
			updateMarker(current_player);
		}


		/* 
		* Reset all variables, and board for new game
		*/
		function handleRestartClick(){
			clicked = [];
			boardBlocked = false;
			current_player = "X";
			player_clicked["X"] = [];
			player_clicked["O"] = [];
			document.getElementById('result').innerHTML = "";	
			document.getElementById('board').classList.remove("boardBlocked");
			document.getElementById('result').classList.remove("visible");
			document.querySelectorAll('.cell').forEach(cell => cell.textContent='');					
		}


		/* 
		* Update winner marker
		*/
		function updateMarker(current_player){
			player_counter[current_player] ++;
			document.getElementById('marker-' + current_player).innerHTML = player_counter[current_player];
		}

	</script>

	<style type="text/css">
	
	*{
		font-family: 'Verdana';
		padding: 0;
		margin: 0;
	}

	body{
		background-color: #f7f2f2;
		padding-top: 60px;
	}

	.content{
		width: 70%;
		background-color: white;
		display: block;
		margin: 0 auto;
		padding: 15px;
	}

	.marker{
		float: left;
		width: 100%;		
		margin-bottom: 30px;
	}

	.marker .marker-item{
		float: left;
		height: 100px;
		width: 100px;
		line-height: 25px;
		text-align: center;
		margin-right: 30px;
		border: 2px solid gray;
		background-color: white;
	}

	.marker .marker-item .header{
		float: left;
		width: 100%;
		height: auto;
		background-color: #f6f6f6;
		font-size: 20px;
		line-height: 40px;
		text-align: center;
		margin-bottom: 5px;
	}

	.marker .marker-item span{
		float: left;
		width: 100%;
		height: auto;
		font-size: 30px;
		line-height: 40px;
		text-align: center;
	}

	h1,
	table{
		margin-bottom: 30px;
	}

	table,
	table tr,
	table tr td{
		border-collapse: collapse;
		border: 1px solid lightgray;
	}

	table tr td{
		padding: 10px;
		width: 50px;
		height: 50px;
		text-align: center;
	}

	table tr td span{		
		width: 50px;
		height: 50px;
		display: block;
		border-radius: 50%;
		line-height: 50px;
		color: white;
		font-size: 30px;
	}

	table tr td span.player-O{
		background-color: #f6a400;
	}

	table tr td span.player-X{
		background-color: #04AA6D;
	}

	table.boardBlocked tr td{
		opacity: 0.2;
	}

	div#result{
		width: 100%;
		background-color: #4bace6;
		padding: 10px 20px;
		margin-top: 30px;
		margin-bottom: 30px;
		color: white;
		display: none;
	}

	div#result.visible{
		display: inherit;
	}

</style>

</body>
</html>

Ejemplo en funcionamiento

Enlace: https://games.adaweb.es/tictactoe/

Escribe una respuesta