const CELL_WIDTH = 47;
const CELL_HEIGHT = 47;
const CASILLAS = 9;
class ChessGoal extends Juego {
constructor(jugador, url) {
super(jugador, url);
this.portero = {}; // { 'blancas', 'negras' }
this.chess_figures;
this.chess_figures_9 = [
{ name: "bK", data: "negras", id: "blackKing", x: 4, y: 1 },
{ name: "bP", data: "negras", id: "blackPawn1", x: 3, y: 2 },
{ name: "bP", data: "negras", id: "blackPawn2", x: 4, y: 2 },
{ name: "bP", data: "negras", id: "blackPawn3", x: 5, y: 2 },
{ name: "bB", data: "negras", id: "blackBishop1", x: 2, y: 2 },
{ name: "bB", data: "negras", id: "blackBishop2", x: 6, y: 2 },
{ name: "bR", data: "negras", id: "blackRook1", x: 0, y: 2 },
{ name: "bR", data: "negras", id: "blackRook2", x: 8, y: 2 },
{ name: "bN", data: "negras", id: "blackKnight1", x: 1, y: 2 },
{ name: "bN", data: "negras", id: "blackKnight2", x: 7, y: 2 },
{ name: "bQ", data: "negras", id: "blackQueen", x: 4, y: 3 },
{ name: "wK", data: "blancas", id: "whiteKing", x: 4, y: 9 },
{ name: "wP", data: "blancas", id: "whitePawn1", x: 3, y: 8 },
{ name: "wP", data: "blancas", id: "whitePawn2", x: 4, y: 8 },
{ name: "wP", data: "blancas", id: "whitePawn3", x: 5, y: 8 },
{ name: "wB", data: "blancas", id: "whiteBishop1", x: 2, y: 8 },
{ name: "wB", data: "blancas", id: "whiteBishop2", x: 6, y: 8 },
{ name: "wR", data: "blancas", id: "whiteRook1", x: 0, y: 8 },
{ name: "wR", data: "blancas", id: "whiteRook2", x: 8, y: 8 },
{ name: "wN", data: "blancas", id: "whiteKnight1", x: 1, y: 8 },
{ name: "wN", data: "blancas", id: "whiteKnight2", x: 7, y: 8 },
{ name: "wQ", data: "blancas", id: "whiteQueen", x: 4, y: 7 },
{ name: "pelota", data: null, id: "pelota", x: 4, y: 5 }
];
this.redes = [
{ name: "red", data: '', id: "red1", x: 3, y: 0 },
{ name: "red", data: '', id: "red2", x: 4, y: 0 },
{ name: "red", data: '', id: "red3", x: 5, y: 0 },
{ name: "red", data: 'invertida_v', id: "red4", x: 3, y: 10 },
{ name: "red", data: 'invertida_v', id: "red5", x: 4, y: 10 },
{ name: "red", data: 'invertida_v', id: "red6", x: 5, y: 10 },
];
this.sala.mostrar_sonido();
}
// @Override
pintar_tablero() {
// Mostramos el tablero
$('#juego').removeClass('hidden');
var board = $("#chess_board");
// De 0 a 98
// Necesitamos que la fila de las porterías esté dentro de chess_board para poder depositar la pelota en ellas
for (var i = 0; i < (CASILLAS * (CASILLAS + 2)); i++) {
let fila = parseInt(i / CASILLAS);
let columna = parseInt(i % CASILLAS);
// Las casillas a los lados de las porterías no tienen fondo
let clase = 'chess_cell ' + (i % 2 ? 'bg0' : 'bg1');
if (fila == 0 || fila == CASILLAS + 1) {
if (columna < 3 || columna > 5) {
clase += " invisible";
} else {
clase += " semitransparente";
}
}
var html = '
';
board.append(html);
}
// Esquinas de la red
$(".chess_cell")[3].id = 'red1';
$(".chess_cell")[5].id = 'red3';
$(".chess_cell")[93].id = 'fondo_red4';
$(".chess_cell")[95].id = 'fondo_red6';
}
vaciar_tablero() {
// Borramos los relojes
$("#capa_tiempo").children(":not(#chess_board)").remove();
// Borramos todo menos las líneas del campo
$("#chess_board").find("*:not(object)").remove();
// Vaciamos el chat
$('#chat').empty();
$('#texto').val('');
}
// @Override
pintar_figuras() {
// Figuras
// Las tengo que clonar para que las piezas se coloquen en su posición al iniciar un nuevo partido
this.chess_figures = JSON.parse(JSON.stringify(this.chess_figures_9));
for (let i = 0; i < this.chess_figures.length; i++) {
if (this.chess_figures[i].name == 'pelota') {
var figureHTML = '';
} else {
var figureHTML = '';
}
this.chess_figures[i].figureHTML = $(figureHTML);
$("#chess_board").append($(this.chess_figures[i].figureHTML));
if (this.chess_figures[i].name == 'bK' || this.chess_figures[i].name == 'wK') {
this.poner_guantes(this.chess_figures[i]);
}
}
// Redes
for (let i = 0; i < this.redes.length; i++) {
var figureHTML = '
';
$("#chess_board").append(figureHTML);
}
// Letras y nºs
for (let i = 0; i < CASILLAS; i++) {
let num = this.color == 'blancas' ? CASILLAS - i : i + 1;
let letra = String.fromCharCode('J'.charCodeAt(0) - num);
let color = i >= 3 && i<= 5 ? 'black' : 'white';
$("#chess_board").append(
'' + letra + '
'
);
$("#chess_board").append(
'' + letra + '
'
);
$("#chess_board").append(
'' + num + '
'
);
$("#chess_board").append(
'' + num + '
'
);
}
// Rival
$("#nombre_rival").html(this.rival.mostrar_jugador());
$("#capa_tiempo").append(``);
// Jugador
$("#nombre_jugador").html(this.jugador.mostrar_jugador());
$("#capa_tiempo").append(``);
}
coordenada_x(x) {
return this.color == 'blancas' ? x : CASILLAS - 1 - x;
}
coordenada_y(y) {
return this.color == 'blancas' ? y : CASILLAS + 1 - y;
}
casilla_over(casilla) {
if ($('.seleccion').length > 0) {
$(casilla).addClass('sombra');
}
}
casilla_out(casilla) {
if ($('.seleccion').length > 0) {
$(casilla).removeClass('sombra');
}
}
// La pelota será siempre la última de las figuras
getPelota() {
return this.chess_figures[this.chess_figures.length - 1];
}
getFigure(id) {
for (var i = 0; i < this.chess_figures.length; ++i) {
if (this.chess_figures[i].id == id) {
return this.chess_figures[i];
};
}
return;
}
getFigureInCell(x, y) {
var figura;
for (var i = 0; i < this.chess_figures.length; ++i) {
if (x == this.chess_figures[i].x && y == this.chess_figures[i].y) {
// Damos prioridad a las piezas sobre la pelota
if (!figura || !figura.data) {
figura = this.chess_figures[i];
}
};
}
return figura;
}
checkValidMove(figura, newX, newY) {
var invalid = false;
if (this.estado < 2) {
// Sin iniciar
if (!figura.data) {
// La pelota no puede moverse
invalid = true;
} else {
// Comprobamos que las fichas no pasen de su campo
if (figura.data == 'negras' && newY >= (CASILLAS + 1) / 2) {
invalid = true;
} else if (figura.data == 'blancas' && (newY < (CASILLAS + 1) / 2 || newY == (CASILLAS + 1) / 2 && newX != (CASILLAS - 1) / 2)) {
invalid = true;
}
}
} else if (this.estado == 2) {
//console.log('checkValidMove');
if (figura.data) {
// Comprobar si es una figura blanca
invalid |= figura.data != 'blancas';
// La figura que saca no puede moverse hasta que saque
if (figura.x == (CASILLAS - 1) / 2 && figura.y == (CASILLAS + 1) / 2 && this.getPelota().x == (CASILLAS - 1) / 2 && this.getPelota().y == (CASILLAS + 1) / 2) {
invalid = true;
}
}
//check figure can move
invalid |= !this.movimiento_correcto(figura, newX, newY);
} else if (this.turno == this.color) {
if (figura.data) {
// Comprobar si es su turno
invalid |= this.turno != figura.data;
} else {
// Comprobar fuera de juego
const figura_con_pelota = this.getFigureInCell(figura.x, figura.y);
invalid |= this.comprobar_fuera_de_juego(figura_con_pelota, newY);
}
//check figure can move
invalid |= !this.movimiento_correcto(figura, newX, newY);
} else {
invalid = true;
}
// Líneas de gol
invalid |= (newY == 0 || newY == CASILLAS + 1) && (newX < (CASILLAS + 1) / 2 - 2 || newX > (CASILLAS + 1) / 2);
// Si movemos una pieza sobre otra...
var figureInCell = this.getFigureInCell(newX, newY);
if (figureInCell && figureInCell.data && figura.data) {
// No permitimos mover una pieza sobre otra del mismo color
invalid |= figura.data == figureInCell.data;
// Ni sobre una figura rival ya movida
invalid |= $(figureInCell.figureHTML).find('img:first').hasClass('figura_movida');
// Ni sobre una rival, siendo torre, si no se puede empujar
invalid |= this.comprobar_empujon(figura, figureInCell);
}
// Ni sobre si misma (ni siquiera la pelota)
invalid |= figura.x == newX && figura.y == newY;
return invalid;
}
comprobar_empujon(torre, rival) {
if (torre.name == 'bR' || torre.name == 'wR') {
// Las torres empujan al rival hacia atrás
const newX = rival.x * 2 - torre.x;
const newY = rival.y * 2 - torre.y;
// Comprobamos que sea dentro del tablero
if (newX >= 0 && newX <= CASILLAS && newY >= 0 && newY <= CASILLAS + 2) {
if (!$($('.chess_cell')[newX + newY * CASILLAS]).hasClass('invisible')) {
// Y que la casilla esté vacía
if (!this.getFigureInCell(newX, newY)) {
return false;
}
}
}
return true;
}
return false;
}
comprobar_fuera_de_juego(figura, newY) {
// 1. Comprobamos si se pasa la pelota detrás de la defensa
var defensas_detras = 0;
var ys = [];
for (var i = 0; i < this.chess_figures.length; ++i) {
if (this.chess_figures[i].data == this.cambiar_color(this.color)) {
ys.push(this.chess_figures[i].y);
if (this.color == 'blancas' && this.chess_figures[i].y <= newY
|| this.color == 'negras' && this.chess_figures[i].y >= newY) {
defensas_detras++;
}
}
}
if (defensas_detras <= 1) {
// 2. Vemos si hay algún jugador en fuera de juego
ys.sort();
// El límite será la menor altura entre la posición del 2º jugador rival y la altura de la pelota
const limite = this.color == 'blancas' ? Math.min(ys[1], figura.y) : Math.max(ys[ys.length - 2], figura.y);
for (var i = 0; i < this.chess_figures.length; i++) {
if (this.chess_figures[i].id != figura.id
&& this.chess_figures[i].data == this.color
&& (this.color == 'blancas' && this.chess_figures[i].y < limite
|| this.color == 'negras' && this.chess_figures[i].y > limite)) {
return true;
}
}
}
return false;
}
piezas_entre(figura, x, y) {
const incrX = Math.sign(figura.x - x);//4-2
const incrY = Math.sign(figura.y - y);//5-7
x += incrX;
y += incrY;
while (figura.x != x || figura.y != y) {
if (this.getFigureInCell(x, y)) {
return true;
}
x += incrX;
y += incrY;
}
return false;
}
movimiento_correcto(figura, newX, newY) {
if (figura.name == 'pelota') {
// La pelota solo se puede mover si la tiene una pieza del jugador que tiene el turno
const figura_con_pelota = this.getFigureInCell(figura.x, figura.y);
if (!figura_con_pelota || this.estado != 2 && figura_con_pelota.data != this.turno) {
return false;
} else {
switch (figura_con_pelota.name) {
case 'bK':
case 'wK':
// Si la diferencia en valor absoluto de la casilla destino y la origen es mayor que 1 -> error
if (Math.abs(newX - figura_con_pelota.x) > 1 || Math.abs(newY - figura_con_pelota.y) > 1) {
return false;
} else {
return true;
}
case "wB":
case "bB":
// Si no está en la diagonal
if (Math.abs(figura_con_pelota.x - newX) != Math.abs(figura_con_pelota.y - newY)) {
return false;
}
if (this.piezas_entre(figura_con_pelota, newX, newY)) {
return false;
} else {
return true;
}
case 'bR':
case 'wR':
// Si no está en la vertical u horizontal
if (newX != figura_con_pelota.x && newY != figura_con_pelota.y) {
return false;
}
if (this.piezas_entre(figura_con_pelota, newX, newY)) {
return false;
} else {
return true;
}
case 'bQ':
case 'wQ':
// Si está en la diagonal
if (Math.abs(figura_con_pelota.x - newX) == Math.abs(figura_con_pelota.y - newY)
// Si está en la vertical u horizontal
|| (newX == figura_con_pelota.x || newY == figura_con_pelota.y)) {
if (this.piezas_entre(figura_con_pelota, newX, newY)) {
return false;
} else {
return true;
}
}
case 'bP':
case 'wP':
// Las blancas mueven hacia arriba y las negras hacia abajo
if (newY == figura_con_pelota.y + (this.color == 'blancas' ? -1 : 1) && Math.abs(newX - figura_con_pelota.x) <= 1) {
return true;
} else {
return false;
}
case 'bN':
case 'wN':
const difY = Math.abs(newY - figura_con_pelota.y);
const difX = Math.abs(newX - figura_con_pelota.x);
if (difY == 2 && difX == 1 || difY == 1 && difX == 2) {
return true;
} else {
return false;
}
}
}
} else {
// Si la diferencia en valor absoluto de la casilla destino y la origen es mayor que 1 -> error
if (Math.abs(newX - figura.x) > 1 || Math.abs(newY - figura.y) > 1) {
return false;
} else {
return true;
}
}
}
// Limpio el tablero de figuras movidas, seleccionadas, sombras...
limpiar_tablero() {
// Borro las piezas movidas del rival
$('.chess_figure, .chess_figure img').removeClass('figura_rival_movida');
// Cambio las movidas del jugador
$('.chess_figure img.figura_movida, .chess_figure.figura_movida').removeClass('figura_movida').addClass('figura_rival_movida');
$('.chess_figure.pelota_movida').removeClass('pelota_movida').addClass('figura_rival_movida');
$('.chess_figure img').removeClass('seleccion');
$('.chess_cell').removeClass('sombra');
}
habilitar_color(habilitar) {
if (this.soy_observador()) {
habilitar = false;
}
// Habilito las fichas del color del turno
for (var i = 0; i < this.chess_figures.length; ++i) {
$(this.chess_figures[i].figureHTML).draggable(habilitar && this.color && (this.chess_figures[i].data == null || this.chess_figures[i].data == this.color) ? "enable" : "disable");
}
}
// Acción de mover del usuario
mover(figura, newX, newY) {
$('.chess_figure img').removeClass('seleccion');
$('.chess_cell').removeClass('sombra');
if (juego.checkValidMove(figura, newX, newY)) {
return false;
} else {
// Saque inicial
if (this.estado == 2 && figura.name == 'pelota') {
this.estado = 4;
juego.turno = juego.color;
}
// ¿Parada del portero?
const figureInCell = juego.getFigureInCell(newX, newY);
const parada = juego.comprobar_parada(figura, newX, newY, juego.portero[juego.cambiar_color(juego.color)]);
if (parada) {
newX = parada.x;
newY = parada.y;
juego.hacer_parada(newX, juego.cambiar_color(juego.color), 250);
}
juego.movimientos.push({id: figura.id, x: newX, y: newY });
juego.hacer_movimiento(figura, newX, newY, 250, null);
if (this.sala.sonido()) {
if (figura.id == 'pelota') {
$('#audio_pase')[0].play();
} else if (figureInCell && figureInCell.id != 'pelota') {
if (figura.name == 'bR' || figura.name == 'wR') {
$('#audio_empujon')[0].play();
} else {
$('#audio_regate')[0].play();
}
} else {
$('#audio_movimiento')[0].play();
}
}
// Si la partida ya ha comenzado...
if (juego.estado >= 2) {
if (figura.data || figura.figureHTML.hasClass("pelota_movida")) {
// Las piezas solo se pueden mover una vez por jugada
if (figura.data) {
figura.figureHTML.find('img:first').removeClass("figura_rival_movida").addClass("figura_movida");
} else {
figura.figureHTML.removeClass("pelota_movida").addClass("figura_movida");
}
figura.figureHTML.draggable("disable");
if (figureInCell && figureInCell.data) {
// Solo dejamos que se muevan una vez las figuras rivales
figureInCell.figureHTML.find('img:first').removeClass("figura_rival_movida").addClass("figura_movida");
}
} else {
// Excepto la pelota
figura.figureHTML.removeClass("figura_rival_movida").addClass("pelota_movida");
}
if (!figura.data) {
// Si movemos la pelota, deshabilitamos a la figura que la recibe
const figura_con_pelota = juego.getFigureInCell(newX, newY);
if (figura_con_pelota && figura_con_pelota.data) {
figura_con_pelota.figureHTML.find('img:first').removeClass("figura_rival_movida").addClass("figura_movida");
figura_con_pelota.figureHTML.draggable("disable");
}
}
}
return true;
}
}
// ignorar_tamanyo: si estamos pintando únicamente, no queremos que se produzcan transiciones con el tamaño de la pelota
mover_figura(figura, x, y, duration, callback, ignorar_tamanyo) {
let figura_destino = this.getFigureInCell(x, y);
const pelota = this.getPelota();
const tiene_pelota = pelota.x == figura.x && pelota.y == figura.y;
figura.x = x;
figura.y = y;
// Solo aplicamos las clases si la figura no está ya en el destino
if (!ignorar_tamanyo && (!figura_destino || figura.name != figura_destino.name)) {
if (figura.name == 'pelota') {
if (figura_destino) {
$(figura.figureHTML).find('img').addClass('pequenya', duration);
} else {
$(figura.figureHTML).find('img').removeClass('pequenya', duration);
}
$(figura.figureHTML).animate({
"margin-top": figura_destino ? "28px" : "0",
"margin-left": figura_destino ? "-2px" : "0"
}, {
duration: 100,
queue: false
});
} else if (figura_destino && figura_destino.name == 'pelota') {
$(figura_destino.figureHTML).find('img').addClass('pequenya', duration);
$(figura_destino.figureHTML).animate({
"margin-top": "28px",
"margin-left": "-2px"
}, {
duration: 100,
queue: false
});
} else if (this.turno == null && tiene_pelota) {
// La partida no ha empezado, se coloca una figura en el centro y luego se quita
$(pelota.figureHTML).find('img').removeClass('pequenya', duration);
$(pelota.figureHTML).animate({
"margin-top": "0",
"margin-left": "0"
}, {
duration: 100,
queue: false
});
}
}
figura.figureHTML.animate({
top: this.coordenada_y(y) * CELL_HEIGHT,
left: this.coordenada_x(x) * CELL_WIDTH
}, duration, null, callback);
}
// Aplica las consecuencias de hacer el movimiento (intercambios, empujones...)
hacer_movimiento(figura, x, y, duration, callback) {
// Si hay una figura en el destino y ninguna de las dos es la pelota...
var figureInCell = this.getFigureInCell(x, y);
if (figura.data && figureInCell && figureInCell.data) {
// Si es una torre...
if (figura.name == 'bR' || figura.name == 'wR') {
// La empujamos
const newX = figureInCell.x * 2 - figura.x;
const newY = figureInCell.y * 2 - figura.y;
setTimeout(() => {
this.mover_figura(figureInCell, newX, newY, duration, null, false);
}, duration / 2);
} else {
// Si no, las intercambiamos
this.mover_figura(figureInCell, figura.x, figura.y, duration, null, false);
}
}
// Si no es la pelota
if (figura.data) {
// Si el juego ha comenzado y la figura tiene la pelota, la movemos con ella
const pelota = this.getPelota();
if (this.turno && pelota.x == figura.x && pelota.y == figura.y) {
this.mover_figura(pelota, x, y, duration, null, true);
}
}
this.mover_figura(figura, x, y, duration, callback, false);
}
empezar(c, duracion) {
super.empezar(c, duracion);
this.duracion = duracion;
this.tiempo['blancas'] = duracion * 60;
this.tiempo['negras'] = duracion * 60;
this.estado = 0; // sin iniciar
// Establecemos el color
this.color = c;
// Pintamos el tablero
this.pintar_ui();
this.actualizar_turno(null, false);
this.pintar_tiempos();
this.escribir_servidor(null, '???msg.chooseTactic???');
showToast.show('???msg.chooseTactic???');
$('#boton_nuevo').prop('disabled', false);
$('#boton_nuevo').hide();
// Ya podemos ir haciendo la táctica
this.habilitar_color(true);
if (this.sala.sonido()) {
$('#audio_partido')[0].play();
}
}
// Lo separo para que el observador pueda ver el tablero con las piezas sin que le afecte lo demás
pintar_ui() {
this.vaciar_tablero();
this.pintar_tablero();
this.pintar_figuras();
$('.chess_figure').draggable({
containment: "parent",
zIndex: 1,
revert: true,
refreshPositions: true
});
$('.chess_figure').click(function() {
juego.figura_click(this);
});
$('.chess_cell').droppable({
accept: ".chess_figure",
tolerance: 'intersect',
classes: { "ui-droppable-hover" : "sombra" },
drop: function(event, ui) {
// Utilizo "juego" en lugar de "this" porque "this" tiene que apuntar a la figura que se ha movido
var figura = juego.getFigure($(ui.draggable).attr('data-figureId'));
var newX = parseInt($(this).attr('data-x'));
var newY = parseInt($(this).attr('data-y'));
if (juego.mover(figura, newX, newY)) {
if (juego.estado != null && juego.estado >= 2) {
// Informo al rival y observadores del movimiento
juego.sala.conexion.enviar('hacer_movimiento', juego.getUltimoMovimiento());
}
return $(ui.draggable).draggable('option', 'revert', false);
} else {
return $(ui.draggable).draggable('option', 'revert', true);
}
}
});
}
manda_tactica(movs) {
this.estado = 2;
this.limpiar_tablero();
this.actualizar_turno('blancas', true);
this.iniciar_cronometros();
this.escribir_servidor(null, '???msg.gameStarts???');
this.pintar_movimientos(movs, 0, 800, () => {
this.habilitar_color(this.color == 'blancas');
if (this.sala.sonido()) {
$('#audio_inicio')[0].play();
}
});
}
getMovimientos() {
return JSON.stringify(this.movimientos);
}
// Devuielve el último movimiento y lo elimina
getUltimoMovimiento() {
return JSON.stringify(this.movimientos.pop());
}
// Solo pinta los movimientos
// Si me acaba de mandar la táctica, sí que movemos las figuras con suavidad
pintar_movimientos(movs, i, duration, funcion) {
if (movs.length > i) {
var figura = this.getFigure(movs[i].id);
// Pintamos la figura
if (movs[i].estado == 'MOVIDA_DOS_VECES') {
figura.figureHTML.addClass('pelota_movida');
} else if (movs[i].estado == 'MOVIDA') {
if (figura.data) {
figura.figureHTML.find('img:first').addClass('figura_movida');
} else {
figura.figureHTML.addClass('figura_movida');
}
figura.figureHTML.draggable("disable");
} else if (movs[i].estado == 'MOVIDA_RIVAL') {
if (figura.data) {
figura.figureHTML.find('img:first').addClass('figura_rival_movida');
} else {
figura.figureHTML.addClass('figura_rival_movida');
}
}
// Llamada recursiva hasta que se acaben los movimientos
this.mover_figura(figura, movs[i].x, movs[i].y, duration, () => {
this.pintar_movimientos(movs, i + 1, duration, funcion);
}, false);
} else {
if (funcion) {
funcion();
}
}
}
// Pinta los movimientos del rival y aplica las consecuencias (intercambios, empujones...)
hacer_movimientos(movs, i, funcion) {
if (movs.length > i) {
var figura = this.getFigure(movs[i].id);
// ¿Parada del portero?
const parada = this.comprobar_parada(figura, movs[i].x, movs[i].y, this.portero[this.cambiar_color(this.turno)]);
if (parada) {
movs[i].x = parada.x;
movs[i].y = parada.y;
setTimeout(() => {
this.hacer_parada(movs[i].x, this.color, 250);
}, 750);
}
// Pintamos la figura
if (figura.data) {
figura.figureHTML.find('img:first').removeClass('figura_rival_movida').addClass('figura_movida');
} else if (figura.figureHTML.hasClass('pelota_movida')) {
// 2º movimiento pelota
figura.figureHTML.removeClass('pelota_movida').addClass('figura_movida');
} else {
// 1er movimiento pelota
figura.figureHTML.removeClass('figura_rival_movida').addClass('pelota_movida');
}
// Si ha habido intercambio o empujón (excluyo la pelota), tb pinto la mía
let figura_destino = this.getFigureInCell(movs[i].x, movs[i].y);
if (figura_destino && figura_destino.data) {
figura_destino.figureHTML.find('img:first').removeClass('figura_rival_movida').addClass('figura_movida');
}
// Llamada recursiva hasta que se acaben los movimientos
this.hacer_movimiento(figura, movs[i].x, movs[i].y, 1000, () => {
this.hacer_movimientos(movs, i + 1, funcion);
});
} else {
if (funcion) {
funcion();
}
}
}
movimientos_turno_rival(tiempo_blancas, tiempo_negras, estado, movs) {
this.estado = parseInt(estado);
this.actualizar_tiempos(tiempo_blancas, tiempo_negras);
this.pintar_movimientos(movs, 0, this.rival_bot() ? 800 : 0, () => {
if (!this.soy_observador()) {
// Los observadores no tienen color pero sí tienen turno
this.actualizar_turno(this.cambiar_color(this.turno), false);
this.habilitar_color(true);
} else {
this.actualizar_turno(this.color, this.estado != null);
}
this.limpiar_tablero();
if (this.sala.sonido()) {
$('#audio_turno')[0].play();
}
});
}
movimientos_turno_bot(tiempo_blancas, tiempo_negras, estado, movs) {
this.estado = parseInt(estado);
this.actualizar_tiempos(tiempo_blancas, tiempo_negras);
this.hacer_movimientos(movs, 0, () => {
if (!this.soy_observador()) {
// Los observadores no tienen color pero sí tienen turno
this.actualizar_turno(this.cambiar_color(this.turno), false);
this.habilitar_color(true);
} else {
this.actualizar_turno(this.color, this.estado != null);
}
this.limpiar_tablero();
if (this.sala.sonido()) {
$('#audio_turno')[0].play();
}
});
}
movimiento_rival(mov) {
this.hacer_movimientos([mov], 0, null);
}
poner_guantes(quien) {
this.portero[quien.data] = quien;
quien.figureHTML.append('
');
quien.figureHTML.append('
');
}
// Comprueba si la pelota ha entrado en la portería, y de ser así, si el portero la ha podido parar
// En caso de parada, devuelve las coordenadas donde ha ocurrido
// NOTA: tb consideramos parada la pelota si cae al lado del portero. De esta forma evitamos mandar al servidor el movimiento de que la pelota ha entrado en la portería
comprobar_parada(figura, newX, newY, port) {
// Parada del portero?
if (figura.name == 'pelota') {
if (newY == 0 || newY == CASILLAS + 1) {
// Posición de la pelota antes de entrar en la portería
var x = newX - Math.sign(newX - figura.x);
var y = newY - Math.sign(newY - figura.y);
} else if (newY == 1 || newY == CASILLAS) {
var x = newX;
var y = newY
} else {
return null;
}
// Si el que remata es un caballo, es imparable
const figura_con_pelota = this.getFigureInCell(figura.x, figura.y);
if (figura_con_pelota.name != 'bN' && figura_con_pelota.name != 'wN') {
// Si no hay nadie en la celda...
if (!this.getFigureInCell(x, y)) {
// y el portero está cerca...
if (Math.abs(x - port.x) == 1 && y == port.y) {
return { 'x' : x, 'y' : y };
}
}
}
}
return null;
}
encoger_guantes(duracion) {
$('.chess_figure').find('.guante:not(.invertida_h)').animate({width: "20px", right: '40px', top: '13px'}, duracion);
$('.chess_figure').find('.guante.invertida_h').animate({width: "20px", left: '40px', top: '13px'}, duracion);
}
hacer_parada(newX, quien, duracion) {
if (newX < this.portero[quien].x) {
this.portero[quien].figureHTML.find('.guante:not(.invertida_h)').animate({width: CELL_WIDTH + "px", transformOrigin: "right", top: "-5px"}, duracion);
} else {
this.portero[quien].figureHTML.find('.guante.invertida_h').animate({width: CELL_WIDTH + "px", transformOrigin: "left", top: "-5px"}, duracion);
}
setTimeout(() => {
this.encoger_guantes(duracion);
}, duracion * 2);
}
actualizar_texto_turno() {
switch (this.estado) {
case 0: // Sin iniciar
$('#finalizar').show();
$('#boton_otro').hide();
$('#boton_otro_cancelar').hide();
$('#finalizar').text('???msg.sendTactic???');
$('#finalizar').prop('disabled', this.soy_observador());
break;
case 1: // Táctica mandada
$('#finalizar').html('???msg.waitingTactic???');
$('#finalizar').prop('disabled', true);
break;
case 2: // Esperando saque inicial
case 3: // partido iniciado, turno blancas
case 4: // partido iniciado, turno negras
if (this.soy_observador()) {
$('#finalizar').hide();
} else {
if (this.turno == this.color || this.turno == null && this.color == 'blancas') {
$('#finalizar').text('???msg.endTurn???');
$('#finalizar').prop('disabled', false);
} else {
$('#finalizar').html('???msg.opponentTurn???');
$('#finalizar').prop('disabled', true);
}
}
break;
default:
// Fin partido
$('#boton_otro').text('???game.playAgain???');
$('#boton_otro').show();
$('#finalizar').hide();
if (this.soy_observador()) {
$('#boton_otro').prop('disabled', true);
$('#boton_otro_cancelar').hide();
} else {
$('#boton_otro').prop('disabled', false);
$('#boton_otro_cancelar').show();
}
}
}
partido_finalizado(tiempo_blancas, tiempo_negras, ganador, puntos_blancas, puntos_negras) {
this.estado = null;
this.actualizar_turno(null, false);
this.actualizar_tiempos(tiempo_blancas, tiempo_negras);
this.pintar_tiempos();
setTimeout(() => {
if (tiempo_blancas <= 0 || tiempo_negras <= 0) {
showToast.show("???msg.timeOut???");
if (this.sala.sonido()) {
$('#audio_timeout')[0].play();
}
} else {
showToast.show("???msg.goal???");
if (this.sala.sonido()) {
$('#audio_gol')[0].play();
}
}
if (this.soy_observador()) {
this.escribir_servidor(null, '???msg.endOfGame???'.replace('{0}', ganador == 'blancas' ? this.jugador.nombre : this.rival.nombre));
} else {
this.escribir_servidor(null, ganador == this.color ? '???msg.youWin???' : '???msg.youLose???');
}
let puntos_rival = this.color == 'negras' ? puntos_blancas : puntos_negras;
let puntos_jugador = this.color == 'negras' ? puntos_negras : puntos_blancas;
if ((this.jugador.puntos || '') != (puntos_jugador || '')) {
var mensaje1 = this.jugador.mostrar_jugador();
this.jugador.puntos = puntos_jugador;
mensaje1 += ' pasa a ' + this.jugador.mostrar_jugador();
this.escribir_servidor(null, mensaje1);
}
if ((this.rival.puntos || '') != (puntos_rival || '')) {
var mensaje2 = this.rival.mostrar_jugador();
this.rival.puntos = puntos_rival;
mensaje2 += ' pasa a ' + this.rival.mostrar_jugador();
this.escribir_servidor(null, mensaje2);
}
// Borrar partido
this.sala.borrar_partido('partido_' + this.jugador.nombre + '-' + this.rival.nombre);
// Actualizar usuarios
this.sala.borrar_usuario(this.jugador.nombre);
this.sala.borrar_usuario(this.rival.nombre);
this.sala.crear_usuario(this.jugador);
this.sala.crear_usuario(this.rival);
}, 500);
clearInterval(this.timer);
this.timer = null;
}
////////////
// EVENTOS
////////////
figura_click(figura) {
const seleccion = juego.getFigure($('.seleccion').closest('.chess_figure').attr('data-figureid'));
const destino = juego.getFigure($(figura).attr('data-figureid'));
if (seleccion) {
// Si ya hay una figura seleccionada
this.mover(seleccion, parseInt(destino.x), parseInt(destino.y));
} else {
// Si no, si es nuestra, la seleccionamos
if (!$(figura).draggable("option", "disabled")) {
$(figura).find('img:first').addClass('seleccion');
if (this.sala.sonido()) {
$('#audio_seleccion')[0].play();
}
}
}
}
casilla_click(casilla) {
const seleccion = juego.getFigure($('.seleccion').closest('.chess_figure').attr('data-figureid'));
if (seleccion) {
this.mover(seleccion, parseInt($(casilla).attr('data-x')), parseInt($(casilla).attr('data-y')));
}
}
finalizar_click() {
switch (this.estado) {
case 0: // sin iniciar
if (this.color == 'blancas') {
if (!this.getFigureInCell((CASILLAS - 1) / 2, (CASILLAS + 1) / 2).data) {
showToast.show('???msg.placeCentralPlayer???');
return;
}
}
break;
// 1: esperando táctica del rival
case 2: // saque inicial
if (this.getPelota().x == (CASILLAS - 1) / 2 && this.getPelota().y == (CASILLAS + 1) / 2 && !this.getFigureInCell((CASILLAS - 1) / 2, (CASILLAS + 1) / 2).figureHTML.find('img:first').hasClass("figura_movida")) {
showToast.show('???msg.moveTheBall???');
return;
} else {
// Este caso no debnería darse porque el estado sería el 3 al mover la pelota?
this.estado = 4;
}
break;
case 3: // partido iniciado, turno blancas
this.estado = 4;
break;
case 4: // partido iniciado, turno negras
this.estado = 3;
break;
}
if (this.estado == 0) {
// Mando táctica
this.sala.conexion.enviar('mandar_tactica', this.getMovimientos());
this.estado = 1;
this.actualizar_texto_turno();
} else if (this.turno) {
// Fin turno
this.actualizar_turno(this.cambiar_color(this.turno), true);
this.sala.conexion.enviar('fin_turno', null);
} else {
this.actualizar_texto_turno();
}
this.movimientos = []; // Vacío los movimientos
this.limpiar_tablero();
this.habilitar_color(false);
if (this.sala.sonido()) {
$('#audio_boton')[0].play();
}
}
mostrar_reglas_click() {
let reglasHtml = `
???rules.rule1???
???rules.rule2???
???rules.rule3???
???rules.rule4???
???rules.rule5???
???rules.rule6???
???rules.rule7???
???rules.rule8???
???rules.rule9???
???rules.rule10???
Previous
Next
`;
const box = bootbox.alert({
title: 'help ???rules.title???',
locale: 'en',
scrollable: true,
backdrop: true,
closeButton: false,
message: reglasHtml,
buttons: {
ok: {
className: 'button azul'
}
}
});
box.on('shown.bs.modal', () => {
// Inicia el carousel después de que se haya mostrado el diálogo
try {
$('#carouselControls').carousel();
} catch (error) {
// No hacemos nada. Da un error en la consola pero funciona bien
}
});
}
}