var $side = 'w';
var $piece = null;
var $chess = new Chess();
function selectPiece(el) {
el.addClass('selected');
}
function unselectPiece(el) {
el.removeClass('selected');
}
function isSelected(el) {
return el ? el.hasClass('selected') : false;
}
function movePiece(from, to, promotion, rcvd) {
var move = $chess.move({
'from': from,
'to': to,
promotion: promotion
});
if (move) {
var tdFrom = $('td.' + from.toUpperCase());
var tdTo = $('td.' + to.toUpperCase());
//highlight moves
if ($('td').hasClass('last-target')){
$('td').removeClass('last-target last-origin');
}
tdFrom.addClass('last-origin');
tdTo.addClass('last-target');
var piece = tdFrom.find('a'); // find out what piece is being moved
var moveSnd = $("#moveSnd")[0]; // sound file variable
unselectPiece(piece.parent());
tdTo.html(piece); // replace td attributes
$piece = null;
// en passant move
if (move.flags === 'e'){
var enpassant = move.to.charAt(0) + move.from.charAt(1);
$('td.' + enpassant.toUpperCase()).html('');
}
//kingside castling
var rook;
if (move.flags === 'k'){
if (move.to === 'g1'){
rook = $('td.H1').find('a');
$('td.F1').html(rook);
}
else if (move.to === 'g8'){
rook = $('td.H8').find('a');
$('td.F8').html(rook);
}
}
//queenside castling
if (move.flags === 'q'){
if (move.to === 'c1'){
rook = $('td.A1').find('a');
$('td.D1').html(rook);
}
else if (move.to === 'c8'){
rook = $('td.A8').find('a');
$('td.D8').html(rook);
}
}
//promotion
if (move.flags === 'np' || move.flags === 'cp'){
var square = $('td.' + move.to.toUpperCase()).find('a');
var option = move.promotion;
var promotion_w = {
'q': '♕',
'r': '♖',
'n': '♘',
'b': '♗'
};
var promotion_b = {
'q': '♛',
'r': '♜',
'n': '♞',
'b': '♝'
};
if (square.hasClass('white')){
square.html(promotion_w[option]);
} else {
square.html(promotion_b[option]);
}
}
if ($('#sounds').is(':checked')) {
moveSnd.play();
}
//feedback
var fm = $('.feedback-move');
var fs = $('.feedback-status');
$chess.turn() === 'b' ? fm.text('Black to move.') : fm.text('White to move.');
fm.parent().toggleClass('blackfeedback whitefeedback');
$chess.in_check() ? fs.text(' Check.') : fs.text('');
//game over
if ($chess.game_over()) {
fm.text('');
var result = "";
if ($chess.in_checkmate())
result = $chess.turn() === 'b' ? 'Checkmate. White wins!' : 'Checkmate. Black wins!'
else if ($chess.in_draw())
result = "Draw.";
else if ($chess.in_stalemate())
result = "Stalemate.";
else if ($chess.in_threefold_repetition())
result = "Draw. (Threefold Repetition)";
else if ($chess.insufficient_material())
result = "Draw. (Insufficient Material)";
fs.text(result);
}
/* Add all moves to the table */
var pgn = $chess.pgn({ max_width: 5, newline_char: ',' });
var moves = pgn.split(',');
var last_move = moves.pop().split('.');
var move_number = last_move[0];
var move_pgn = $.trim(last_move[1]);
if (move_pgn.indexOf(' ') != -1) {
var moves = move_pgn.split(' ');
move_pgn = moves[1];
}
$('#moves tbody tr').append('
' + move_number + '. ' + move_pgn + ' | ');
if (rcvd === undefined) {
$socket.emit('new-move', {
'token': $token,
'move': move
});
}
if ($chess.game_over()) {
$('.resign').hide();
alert(result);
}
}
}
/* socket.io */
$(document).ready(function () {
$socket.emit('join', {
'token': $token
});
$socket.on('joined', function (data) {
if (data.color === 'white') {
$side = 'w';
$('.chess_board.black').remove();
} else {
$side = 'b';
$('.chess_board.white').remove();
$('.chess_board.black').show();
}
$('#sendMessage').find('input').addClass($side === 'b' ? 'black' : 'white');
});
$socket.on('move', function (data) {
movePiece(from=data.move.from, to=data.move.to, promotion=data.move.promotion, rcvd=true);
});
$socket.on('opponent-disconnected', function (data) {
alert("Your opponent has disconnected.");
window.location = '/';
});
$socket.on('opponent-resigned', function (data) {
alert("Your opponent has resigned. You won!");
window.location = '/';
});
$socket.on('full', function (data) {
alert("This game already has two players. You have to create a new one.");
window.location = '/';
});
$socket.on('receive-message', function (data) {
var chat = $('ul#chat');
var chat_node = $('ul#chat')[0];
var messageSnd = $("#messageSnd")[0];
chat.append('' + data.message + '');
if (chat.is(':visible') && chat_node.scrollHeight > 300) {
setTimeout(function() { chat_node.scrollTop = chat_node.scrollHeight; }, 50);
} else if (!chat.is(':visible') && !$('.new-message').is(':visible')) {
$('#bubble').before('You have a new message!');
}
if ($('#sounds').is(':checked')) {
messageSnd.play();
}
});
});
/* gameplay */
$(document).ready(function () {
$('.chess_board a').click(function (e) {
var piece = $(this);
if ((piece.hasClass('white') && $side != 'w') ||
(piece.hasClass('black') && $side != 'b')) {
if ($piece) {
movePiece(
from=$piece.parent().data('id').toLowerCase(),
to=$(this).parent().data('id').toLowerCase(),
promotion=$('#promotion option:selected').val()
)
}
} else {
if ($chess.turn() != $side) {
return false;
}
if ($piece && isSelected($(this).parent())) {
unselectPiece($piece.parent());
$piece = null;
} else {
if ($piece) {
unselectPiece($piece.parent());
$piece = null;
}
$piece = $(this);
selectPiece($piece.parent());
}
}
e.stopImmediatePropagation();
e.preventDefault();
});
$('.chess_board td').click(function (e) {
if ($piece) {
movePiece(
from=$piece.parent().data('id').toLowerCase(),
to=$(this).data('id').toLowerCase(),
promotion=$('#promotion option:selected').val()
)
}
});
$('.resign').click(function (e) {
$socket.emit('resign');
alert('You resigned.');
window.location = '/';
});
$('a.chat').click(function (e) {
$('#chat-wrapper').toggle();
$('.new-message').remove();
var chat_node = $('ul#chat')[0];
if (chat_node.scrollHeight > 300) {
setTimeout(function() { chat_node.scrollTop = chat_node.scrollHeight; }, 50);
}
});
$('#chat-wrapper .close').click(function (e) {
$('#chat-wrapper').hide();
});
$('#sendMessage').submit(function (e) {
e.preventDefault();
var input = $(this).find('input');
var message = input.val();
var color = $side === 'b' ? 'black' : 'white';
if (!/^\W*$/.test(message)) {
input.val('');
$('ul#chat').append('' + message + '');
var chat_node = $('ul#chat')[0];
if (chat_node.scrollHeight > 300) {
setTimeout(function() { chat_node.scrollTop = chat_node.scrollHeight; }, 50);
}
$socket.emit('send-message', { 'message': message, 'color': color });
}
});
});