2020-12-30 02:35:31 +00:00
|
|
|
<!DOCTYPE html>
|
2020-12-30 02:44:11 +00:00
|
|
|
<html lang="en">
|
2020-12-30 02:35:31 +00:00
|
|
|
<head>
|
|
|
|
<meta charset="utf-8">
|
|
|
|
<title>Shatrizualizer</title>
|
|
|
|
<style>
|
|
|
|
tr :nth-child(1) {
|
|
|
|
height: 1em;
|
|
|
|
width: 1em;
|
|
|
|
}
|
|
|
|
td {
|
|
|
|
font-size: 200%;
|
|
|
|
}
|
|
|
|
.board tbody :nth-child(odd) :nth-child(even) {
|
|
|
|
background-color: #fff;
|
|
|
|
}
|
|
|
|
.board tbody :nth-child(even) :nth-child(odd) {
|
|
|
|
background-color: #fff;
|
|
|
|
}
|
|
|
|
.board tbody :nth-child(odd) :nth-child(odd) {
|
|
|
|
background-color: #999;
|
|
|
|
}
|
|
|
|
.board tbody :nth-child(even) :nth-child(even) {
|
|
|
|
background-color: #999;
|
|
|
|
}
|
|
|
|
.board tbody :last-child :nth-child(n) {
|
|
|
|
background-color: unset;
|
|
|
|
}
|
|
|
|
.board tbody :nth-child(n) :first-child {
|
|
|
|
background-color: unset;
|
|
|
|
}
|
|
|
|
body {
|
|
|
|
display: flex;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
color: #000;
|
|
|
|
}
|
|
|
|
#movelist {
|
|
|
|
display: grid;
|
|
|
|
grid-template-columns: 1fr 1fr;
|
|
|
|
}
|
|
|
|
#movelist :nth-child(odd) {
|
|
|
|
background-color: #fff;
|
|
|
|
}
|
|
|
|
#movelist :nth-child(even) {
|
|
|
|
margin-left: 1em;
|
|
|
|
background-color: #999;
|
|
|
|
}
|
|
|
|
li {
|
|
|
|
padding-left: 0.2em;
|
|
|
|
padding-right: 0.2em;
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<section>
|
|
|
|
<table class="board">
|
|
|
|
<tbody>
|
|
|
|
<tr id="row8">
|
|
|
|
<th class="coords">8</th>
|
|
|
|
<td><div id="a8">♜</div></td>
|
|
|
|
<td><div id="b8">♞</div></td>
|
|
|
|
<td><div id="c8">♜</div></td>
|
|
|
|
<td><div id="d8">♚</div></td>
|
|
|
|
<td><div id="e8">♛</div></td>
|
|
|
|
<td><div id="f8">♝</div></td>
|
|
|
|
<td><div id="g8">♞</div></td>
|
|
|
|
<td><div id="h8">♜</div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row7">
|
|
|
|
<th class="coords">7</th>
|
|
|
|
<td><div id="a7">♟</div></td>
|
|
|
|
<td><div id="b7">♟</div></td>
|
|
|
|
<td><div id="c7">♟</div></td>
|
|
|
|
<td><div id="d7">♟</div></td>
|
|
|
|
<td><div id="e7">♟</div></td>
|
|
|
|
<td><div id="f7">♟</div></td>
|
|
|
|
<td><div id="g7">♟</div></td>
|
|
|
|
<td><div id="h7">♟</div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row6">
|
|
|
|
<th class="coords">6</th>
|
|
|
|
<td><div id="a6"></div></td>
|
|
|
|
<td><div id="b6"></div></td>
|
|
|
|
<td><div id="c6"></div></td>
|
|
|
|
<td><div id="d6"></div></td>
|
|
|
|
<td><div id="e6"></div></td>
|
|
|
|
<td><div id="f6"></div></td>
|
|
|
|
<td><div id="g6"></div></td>
|
|
|
|
<td><div id="h6"></div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row5">
|
|
|
|
<th class="coords">5</th>
|
|
|
|
<td><div id="a5"></div></td>
|
|
|
|
<td><div id="b5"></div></td>
|
|
|
|
<td><div id="c5"></div></td>
|
|
|
|
<td><div id="d5"></div></td>
|
|
|
|
<td><div id="e5"></div></td>
|
|
|
|
<td><div id="f5"></div></td>
|
|
|
|
<td><div id="g5"></div></td>
|
|
|
|
<td><div id="h5"></div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row4">
|
|
|
|
<th class="coords">4</th>
|
|
|
|
<td><div id="a4"></div></td>
|
|
|
|
<td><div id="b4"></div></td>
|
|
|
|
<td><div id="c4"></div></td>
|
|
|
|
<td><div id="d4"></div></td>
|
|
|
|
<td><div id="e4"></div></td>
|
|
|
|
<td><div id="f4"></div></td>
|
|
|
|
<td><div id="g4"></div></td>
|
|
|
|
<td><div id="h4"></div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row3">
|
|
|
|
<th class="coords">3</th>
|
|
|
|
<td><div id="a3"></div></td>
|
|
|
|
<td><div id="b3"></div></td>
|
|
|
|
<td><div id="c3"></div></td>
|
|
|
|
<td><div id="d3"></div></td>
|
|
|
|
<td><div id="e3"></div></td>
|
|
|
|
<td><div id="f3"></div></td>
|
|
|
|
<td><div id="g3"></div></td>
|
|
|
|
<td><div id="h3"></div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row2">
|
|
|
|
<th class="coords">2</th>
|
|
|
|
<td><div id="a2">♙</div></td>
|
|
|
|
<td><div id="b2">♙</div></td>
|
|
|
|
<td><div id="c2">♙</div></td>
|
|
|
|
<td><div id="d2">♙</div></td>
|
|
|
|
<td><div id="e2">♙</div></td>
|
|
|
|
<td><div id="f2">♙</div></td>
|
|
|
|
<td><div id="g2">♙</div></td>
|
|
|
|
<td><div id="h2">♙</div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr id="row1">
|
|
|
|
<th class="coords">1</th>
|
|
|
|
<td><div id="a1">♖</div></td>
|
|
|
|
<td><div id="b1">♘</div></td>
|
|
|
|
<td><div id="c1">♗</div></td>
|
|
|
|
<td><div id="d1">♔</div></td>
|
|
|
|
<td><div id="e1">♕</div></td>
|
|
|
|
<td><div id="f1">♗</div></td>
|
|
|
|
<td><div id="g1">♘</div></td>
|
|
|
|
<td><div id="h1">♖</div></td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr class="coords">
|
|
|
|
<th></th>
|
|
|
|
<th>A</th>
|
|
|
|
<th>B</th>
|
|
|
|
<th>C</th>
|
|
|
|
<th>D</th>
|
|
|
|
<th>E</th>
|
|
|
|
<th>F</th>
|
|
|
|
<th>G</th>
|
|
|
|
<th>H</th>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
|
|
|
<form id="form">
|
|
|
|
<label><span id="tomove">White</span>'s move
|
|
|
|
<input id="move" type="text" autocomplete="off">
|
|
|
|
</label>
|
|
|
|
<input type="submit" value="Move">
|
|
|
|
<input type="button" value="Undo" onclick="undoMove()">
|
|
|
|
</form>
|
|
|
|
</section>
|
|
|
|
<section id="moves">
|
|
|
|
<p>Moves thus far</p>
|
|
|
|
<ul id="movelist">
|
|
|
|
</ul>
|
|
|
|
</section>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
'use strict';
|
|
|
|
let form = document.getElementById('form');
|
|
|
|
form.onsubmit = moveEvent;
|
|
|
|
|
|
|
|
let moveHistory = [];
|
|
|
|
|
|
|
|
function moveEvent(event) {
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
|
|
let move = document.getElementById('move').value;
|
|
|
|
if (move === '') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let piece = move.slice(0, 1);
|
|
|
|
let index = 0;
|
|
|
|
switch(piece) {
|
|
|
|
case 'K':
|
|
|
|
case 'Q':
|
|
|
|
case 'B':
|
|
|
|
case 'N':
|
|
|
|
case 'R':
|
|
|
|
case 'P':
|
|
|
|
index++;
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
case 'b':
|
|
|
|
case 'c':
|
|
|
|
case 'd':
|
|
|
|
case 'e':
|
|
|
|
case 'f':
|
|
|
|
case 'g':
|
|
|
|
case 'h':
|
|
|
|
piece = 'P';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
alert('Not a valid piece: ' + piece);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let startLetter = move.slice(index, index + 1);
|
|
|
|
let startNumber = move.slice(index + 1, index + 2);
|
|
|
|
index += 2;
|
|
|
|
if (
|
|
|
|
startLetter === '' || !'abcdefgh'.includes(startLetter) ||
|
|
|
|
startNumber === '' || !'12345678'.includes(startNumber)
|
|
|
|
) {
|
|
|
|
alert('Not a valid coordinate: ' + startLetter + startNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let captures = false;
|
|
|
|
if (move.slice(index, index + 1) === 'x') {
|
|
|
|
captures = true;
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
let endLetter = move.slice(index, index + 1);
|
|
|
|
let endNumber = move.slice(index + 1, index + 2);
|
|
|
|
index += 2;
|
|
|
|
if (
|
|
|
|
endLetter === '' || !'abcdefgh'.includes(endLetter) ||
|
|
|
|
endNumber === '' || !'12345678'.includes(endNumber)
|
|
|
|
) {
|
|
|
|
alert('Not a valid coordinate: ' + endLetter + endNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(move.slice(index)) {
|
|
|
|
case '':
|
|
|
|
// nothing
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
// TODO: Check
|
|
|
|
break;
|
|
|
|
case '++':
|
|
|
|
// TODO: Checkmate'
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
alert('Unexpected contents at the end of the move: ' + move.slice(index));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let whitePieces = {'K': '♔', 'Q': '♕', 'R': '♖', 'B': '♗', 'N': '♘', 'P': '♙'};
|
|
|
|
let blackPieces = {'K': '♚', 'Q': '♛', 'R': '♜', 'B': '♝', 'N': '♞', 'P': '♟'};
|
|
|
|
|
|
|
|
let whiteMove = document.getElementById('tomove').childNodes[0].data == 'White';
|
|
|
|
|
|
|
|
let renderedPiece = null;
|
|
|
|
if (whiteMove) {
|
|
|
|
renderedPiece = whitePieces[piece];
|
|
|
|
} else {
|
|
|
|
renderedPiece = blackPieces[piece];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Are we moving the piece from where it is located?
|
|
|
|
let startSquare = document.getElementById(startLetter + startNumber);
|
|
|
|
if (startSquare.childNodes.length === 0) {
|
|
|
|
alert('No piece on square ' + startLetter + startNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (startSquare.childNodes[0].data !== renderedPiece) {
|
|
|
|
let pieceNames = {'K': 'King', 'Q': 'Vizier', 'R': 'Rook', 'B': 'Elephant', 'N': 'Horse', 'P': 'Pawn'};
|
|
|
|
alert((whiteMove ? 'White' : 'Black') + ' ' + pieceNames[piece] + ' not on square ' + startLetter + startNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Check piece is allowed to move like that
|
|
|
|
|
|
|
|
// Can the piece move to this location?
|
|
|
|
let endSquare = document.getElementById(endLetter + endNumber);
|
|
|
|
if (endSquare.childNodes.length !== 0 && !captures) {
|
|
|
|
alert('Square ' + endLetter + endNumber + ' is occupied, did you mean to capture?');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (endSquare.childNodes.length === 0 && captures) {
|
|
|
|
alert('Square ' + endLetter + endNumber + ' empty even though capture was specified');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Record our alterations to the table
|
|
|
|
let movedPiece = {start: startLetter + startNumber, end: endLetter + endNumber, piece: renderedPiece};
|
|
|
|
let capturedPiece = captures ? endSquare.childNodes[0].data : null;
|
|
|
|
moveHistory.push({move: movedPiece, capture: capturedPiece});
|
|
|
|
console.log(moveHistory);
|
|
|
|
|
|
|
|
// Apply move
|
|
|
|
if (captures) {
|
|
|
|
endSquare.removeChild(endSquare.childNodes[0]);
|
|
|
|
}
|
|
|
|
startSquare.removeChild(startSquare.childNodes[0]);
|
|
|
|
endSquare.appendChild(document.createTextNode(renderedPiece))
|
|
|
|
|
|
|
|
// Flip whose turn it is
|
|
|
|
document.getElementById('tomove').childNodes[0].data = whiteMove ? 'Black' : 'White';
|
|
|
|
|
|
|
|
// List the move
|
|
|
|
let listElement = document.createElement('li');
|
|
|
|
listElement.appendChild(document.createTextNode(move));
|
|
|
|
document.getElementById('movelist').appendChild(listElement);
|
|
|
|
|
|
|
|
// Empty input field
|
|
|
|
document.getElementById('move').value = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
function undoMove() {
|
|
|
|
if (moveHistory.length === 0) {
|
|
|
|
alert('No moves to undo');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Undo move on the board
|
|
|
|
let {move, capture} = moveHistory.pop();
|
|
|
|
let startSquare = document.getElementById(move.start);
|
|
|
|
let endSquare = document.getElementById(move.end);
|
|
|
|
endSquare.removeChild(endSquare.childNodes[0]);
|
|
|
|
startSquare.appendChild(document.createTextNode(move.piece));
|
|
|
|
if (capture) {
|
|
|
|
endSquare.appendChild(document.createTextNode(capture));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flip whose turn it is
|
|
|
|
let whiteMove = document.getElementById('tomove').childNodes[0].data == 'White';
|
|
|
|
document.getElementById('tomove').childNodes[0].data = whiteMove ? 'Black' : 'White';
|
|
|
|
|
|
|
|
// Remove from list of moves
|
|
|
|
document.getElementById('movelist').removeChild(document.getElementById('movelist').lastChild);
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
|
|
</html>
|