Skip to content

Instantly share code, notes, and snippets.

@fabsk7
Created April 25, 2020 21:41
Show Gist options
  • Save fabsk7/b30828c409568f3224cf52d9d94e2e98 to your computer and use it in GitHub Desktop.
Save fabsk7/b30828c409568f3224cf52d9d94e2e98 to your computer and use it in GitHub Desktop.
Jogo da velha - tic tac toe
<table id="scoreboard" align="center">
<tr>
<td id=nomeP1>Player 1</td>
<td width="30"> &nbsp; </td>
<td id=nomeP2>Player 2</td>
</tr>
<tr>
<td class="score" id="player1">
0
</td>
<td> &nbsp; </td>
<td class="score" id="player2">
0
</td>
</tr>
</table>
<div id="info">
esperando outro jogador...
</div>
<div id="placeholder"></div>
<button onclick="restart()">
Reset
</button>
var info = document.getElementById("info");
var suaVez = false;
var gameId = -1;
var jogadas = "";
var jogador1 = "";
var jogador2 = "";
//SE ENTRAR COM PARAMETRO NO gameId ELE EH O PLAYER2 POIS JA TEM O ID DO GAME.
if(gameId == -1)
{
startNewGame("Fabolas");
}
else
{
conectaGame(gameId, "MAJO");
}
function TicTacToe(placeholder, grid_size, callback) {
// Save the placeholder element
this.placeholder = placeholder;
// Paint the placeholder with board
this.paint(grid_size);
// Save the callback
this.callback = callback;
// Save player scores
this.scores = {
X: 0,
O: 0
};
this.marks = {
X: "X", // Player 1 mark
O: "O", // Player 2 mark
count: 0 // Number of moves made by player
};
return this;
}
//cria a partida e nos retorna o id dela.
function startNewGame(nomeP1)
{
jogador1 = nomeP1;
var data = {
jogador1: jogador1
};
$.ajax({
method: "POST",
data: data,
url: "https://postalwp.com/jdv/criador.php",
dataType: "json",
success: function (response) {
console.log("criador diz: ", response);
//alert("game id= " + response.id);
gameId = response.id;
//criou o game no bd agora libera aqui pra jogar.
//aguarda o p2 aceitar.
setTimeout(aguardaP2aceitar, 2000);
},
error: function (request, status, error) {
console.log("There was an error: ", request.responseText);
}
});
};
//conectaGame(1,"Majo");
//quando o jogador aceitar um desafio ele se conecta ao game e envia seu nome para o bd.
function conectaGame(id, nomeP2)
{
jogador2 = nomeP2;
gameId = id;
var data = {
jogador2: jogador2,
gameId: gameId
};
$.ajax({
method: "POST",
data: data,
url: "https://postalwp.com/jdv/aceitador.php",
dataType: "json",
success: function (response) {
console.log("aceitador diz: ", response);
//se ja aceitou jogar espera a vez do outro jogador.
//recebe o nome do player 1.
jogador1 = response.jogador1;
updateUI();
//espera outro jogador jogar.
setTimeout(tictactoe.verificaJogada, 2000);
},
error: function (request, status, error) {
console.log("There was an error: ", request.responseText);
}
});
}
function updateUI()
{
document.querySelector("#scoreboard #nomeP1").innerHTML = jogador1;
document.querySelector("#scoreboard #nomeP2").innerHTML = jogador2;
}
TicTacToe.prototype.paint = function (grid_size) {
var self = this;
// Get number of columns, considering board as N x N board (3 x 3)
self.grid_size = grid_size;
var html = '<table id="tic-tac-toe" align="center">';
var countIndex = 0;
for (var i = 0; i < grid_size; i++) {
html += "<tr>";
for (var j = 0; j < grid_size; j++) {
html += "<td id=c" + countIndex + "></td>";
//console.log('<td id=c'+countIndex+'></td>');
countIndex++;
}
html += "</tr>";
}
html += "</table>";
self.placeholder.innerHTML = html;
// Find all columns from the board
self.columns = self.placeholder.getElementsByTagName("td");
// Go through all the columns and add click event
for (i = 0; i < this.columns.length; i++) {
self.columns[i].addEventListener("click", markHandler);
}
// on click mark the column "<td>"
function markHandler(e) {
self.mark(e.target);
}
};
//update em:
//gameId | jogadas | jogador1 | jogador2 | pontosP1 | pontosP2
TicTacToe.prototype.sendToServer = function (column) {
//alert("preenche coluna " + column.id + " com " + column.innerHTML);
//manda coluna id para servidor guardar no bd do gameId=001 | c0;c1;c2;
jogadas += column.id + ";";
var data = {
gameId: gameId,
jogadas: jogadas
};
$.ajax({
method: "POST",
data: data,
url: "https://postalwp.com/jdv/server.php",
dataType: "json",
success: function (response) {
console.log("server diz: ", response);
var json;
$.each(response, function (index, element) {
json = element;
});
//fica esperando resposta do servidor ate outro jogador jogar.
setTimeout(tictactoe.verificaJogada, 2000);
},
error: function (request, status, error) {
console.log("There was an error: ", request.responseText);
},
complete: function () {
}
});
//this.receiveFromServer(column);
};
//caso ele pegue o nome do p2 no banco significa q ele aceitou.
function aguardaP2aceitar()
{
var data = {
gameId: gameId
};
$.ajax({
method: "POST",
data: data,
url: "https://postalwp.com/jdv/verificador.php",
dataType: "json",
success: function (response) {
console.log("verificador diz: ", response);
var json;
$.each(response, function (index, element) {
json = element;
});
//compara as jogadas do bd com a q tem aqui
//se for igual continua esperando o outro jogador jogar.
if (!json.jogador2) {
setTimeout(aguardaP2aceitar, 2000);
info.innerHTML = "esperando outro jogador aceitar";
} else {
//alert("jogador2 " + json.jogador2);
//se ele pegar o nome no banco ele libera para o p1 jogar.
jogador2 = json.jogador2;
suaVez = true;
info.innerHTML = "Sua Vez";
}
},
error: function (request, status, error) {
console.log("There was an error: ", request.responseText);
},
//recursivo fica esperando resposta do servidor ate outro jogador jogar.
complete: function () {
// setTimeout(TicTacToe.prototype.verificaJogada.bind(this), 2000);
}
});
}
TicTacToe.prototype.verificaJogada = function () {
//alert("chamou");
//se as jogadas q vierem do servidor forem diferentes da q tem aqui
//entao atualiza a q tem e o outro jogador fica esperando esse.
var data = {
gameId: gameId
};
$.ajax({
method: "POST",
data: data,
url: "https://postalwp.com/jdv/verificador.php",
dataType: "json",
success: function (response) {
console.log("verificador diz: ", response);
var json;
$.each(response, function (index, element) {
json = element;
});
//compara as jogadas do bd com a q tem aqui
//se for igual continua esperando o outro jogador jogar.
if (jogadas == json.jogadas) {
setTimeout(tictactoe.verificaJogada, 2000);
info.innerHTML = "esperando oponente jogar";
} else {
//se for diferente do servidor ele atualiza as jogadas e preenche onde o jogador jogou.
//alert(jogadas + " - " + json.jogadas);
jogadas = json.jogadas;
tictactoe.receiveFromServer(json.jogadas);
}
},
error: function (request, status, error) {
console.log("There was an error: ", request.responseText);
},
//recursivo fica esperando resposta do servidor ate outro jogador jogar.
complete: function () {
// setTimeout(TicTacToe.prototype.verificaJogada.bind(this), 2000);
}
});
};
TicTacToe.prototype.receiveFromServer = function (dataJogadas) {
// var dataFake = "c0;c1;c2;c7;";
var ultimaCasa = dataJogadas.slice(0, -1).split(";").pop();
//preenche td correspondente a id jogada pelo adversario.
var column = document.getElementById(ultimaCasa);
// Count the move
this.marks.count++;
var current_mark = this.marks.count % 2 === 1 ? this.marks.X : this.marks.O;
column.innerHTML = current_mark;
suaVez = true;
info.innerHTML = "Sua Vez!";
};
//aqui eh onde clica.
TicTacToe.prototype.mark = function (column) {
// Stop if column is not empty
if (column.innerHTML || !suaVez) {
return;
}
// Count the move
this.marks.count++;
// Get the mark based on the count
var current_mark = this.marks.count % 2 === 1 ? this.marks.X : this.marks.O;
// Fill the column with mark
column.innerHTML = current_mark;
column.classList.add(current_mark);
// Check if this player (X or O) won
if (this.didWin(current_mark)) {
// Increment the player score
if (this.marks.count % 2 === 1) {
this.scores.X++;
} else {
this.scores.O++;
}
// Send current mark and scores
this.callback(current_mark, this.scores);
} else if (this.marks.count === this.columns.length) {
// Send result as draw
this.callback("draw");
}
//vez do outro jogador.
info.innerHTML = "esperando " + jogador2 + " jogar";
suaVez = false;
//envia info para o servidor sobre a jogada.
this.sendToServer(column);
};
// Board:
// _____________
// | 0 | 1 | 2 |
// |---|---|---|
// | 3 | 4 | 5 |
// |---|---|---|
// | 6 | 7 | 8 |
// -------------
//
// We need to go through all columns like
//
// 012, 345, 678 - Horizontal
// 036, 147, 258 - Vertical
// 048, 246 - Diagonal
//
// If mark is present in all columns of any combinations then user won
//
// Instead of going through each combination manually we can make use of loops,
// So that it can be used for any grids like 7 X 7
//
TicTacToe.prototype.didWin = function (mark) {
// Take count of columns
var grid_size = this.grid_size;
// Declare variables to count the presence of the mark
var horizontal_count,
vertical_count,
right_to_left_count = 0,
left_to_right_count = 0;
// Loop 1
for (var i = 0; i < grid_size; i++) {
// Empty the count
horizontal_count = vertical_count = 0;
// Loop 2
for (var j = 0; j < grid_size; j++) {
// i * grid_size + j ===> "0,1,2", "3,4,5", "6,7,8"
if (this.columns[i * grid_size + j].innerHTML == mark) {
horizontal_count++;
}
// j * grid_size + i ===> "0,3,6", "1,4,7", "2,5,8"
if (this.columns[j * grid_size + i].innerHTML == mark) {
vertical_count++;
}
}
// If horizontal or vertical combination is found the return true
if (horizontal_count == grid_size || vertical_count == grid_size) {
return true;
}
// i * grid_size + i ===> "0,4,8"
if (this.columns[i * grid_size + i].innerHTML == mark) {
right_to_left_count++;
}
// (grid_size - 1) * (i+1) ===> "2,4,6"
if (this.columns[(grid_size - 1) * (i + 1)].innerHTML == mark) {
left_to_right_count++;
}
} // End of loop
// If mark is present diagnolly
if (right_to_left_count == grid_size || left_to_right_count == grid_size) {
return true;
}
return false;
};
TicTacToe.prototype.empty = function () {
// Go through all columns and empty them
for (var i = 0; i < this.columns.length; i++) {
this.columns[i].innerHTML = "";
this.columns[i].classList.remove(this.marks.X);
this.columns[i].classList.remove(this.marks.O);
}
// Reset the count
this.marks.count = 0;
};
TicTacToe.prototype.reset = function () {
this.empty();
this.scores = {
X: 0,
O: 0
};
};
var placeholder = document.getElementById("placeholder");
var tictactoe = new TicTacToe(placeholder, 3, onResult);
function onResult(result, scores) {
if (result == "draw") {
alert("It's a draw !");
} else {
alert(result + " has won");
updateScores(scores.X, scores.O);
}
tictactoe.empty();
}
function updateScores(X, O) {
document.querySelector("#scoreboard #player1").innerHTML = X;
document.querySelector("#scoreboard #player2").innerHTML = O;
}
function restart(grid_size) {
tictactoe.reset();
updateScores(0, 0);
if (grid_size) {
tictactoe.paint(grid_size);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json2/20160511/json2.min.js"></script>
body {
font: normal 16px comic sans ms;
text-align: center;
background-color: #DAF7A6;
}
#tic-tac-toe {
cell-spacing: 0px;
border-spacing: 0px;
border-collapse: separate;
margin: 30px auto;
}
#tic-tac-toe td {
border: 2px solid #000;
height: 100px;
width: 100px;
text-align: center;
font: bold 60px comic sans ms;
}
#tic-tac-toe tr:first-child td {
border-top: none
}
#tic-tac-toe tr:last-child td {
border-bottom: none
}
#tic-tac-toe tr td:first-child {
border-left: none;
}
#tic-tac-toe tr td:last-child {
border-right: none;
}
#tic-tac-toe td.X {
color: #ED676B;
}
#tic-tac-toe td.O {
color: #23916B;
}
#scoreboard .score {
text-align: center;
font-size: 30px
}
#scoreboard .score#player1 {
color: #ED676B;
}
#scoreboard .score#player2 {
color: #23916B;
}
#info
{
position: relative;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment