summaryrefslogtreecommitdiff
path: root/index.html
diff options
context:
space:
mode:
authornea <romangraef@gmail.com>2022-11-27 18:37:28 +0100
committernea <romangraef@gmail.com>2022-11-27 18:37:28 +0100
commit30e7386f0d7d43497195bb6c66bc0f9a0176822f (patch)
tree4ded162f17dc7bde58707d979a08e55c5f93fb51 /index.html
downloadchess-30e7386f0d7d43497195bb6c66bc0f9a0176822f.tar.gz
chess-30e7386f0d7d43497195bb6c66bc0f9a0176822f.tar.bz2
chess-30e7386f0d7d43497195bb6c66bc0f9a0176822f.zip
Hehehe
Diffstat (limited to 'index.html')
-rw-r--r--index.html190
1 files changed, 190 insertions, 0 deletions
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..7da348e
--- /dev/null
+++ b/index.html
@@ -0,0 +1,190 @@
+<!doctype html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport"
+ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>Awesome Chess</title>
+</head>
+<style>
+ * {
+ padding: 0;
+ margin: 0;
+ }
+
+ .board {
+ border: 2px solid black;
+ font-size: 20px;
+ }
+
+ .board-field.black {
+ background: chocolate;
+ }
+
+ .board-field.white {
+ background: bisque;
+ }
+
+ .board-field {
+ text-align: center;
+ width: 1.5em;
+ height: 1.5em;
+ }
+
+ #warn {
+ display: block;
+ position: fixed;
+ top: 25%;
+ left: 25%;
+ z-index: 10;
+ margin: 0 auto;
+ width: 50%;
+ background: coral;
+ border: crimson solid 1px;
+ }
+
+ .invisible {
+ display: none !important;
+ }
+</style>
+<body>
+
+<div id="app"></div>
+<div id="warn" class="invisible">
+ Connection closed
+</div>
+<script>
+ class Board {
+ constructor(elem) {
+ this.socket = new WebSocket('ws://localhost:8000/socket')
+ this.exiting = false
+ this.boardState = {}
+ window.addEventListener('beforeunload', () => {
+ this.exiting = true
+ })
+ this.socket.addEventListener('message', ev => {
+ const message = JSON.parse(ev.data)
+ console.log(message)
+ this.playerColor = message.player_color || this.playerColor
+ this.boardState = parseFEN(message.board)
+ this.synchronizeBoard()
+ })
+ this.socket.addEventListener('close', () => {
+ if (!this.exiting)
+ document.getElementById('warn').classList.remove('invisible')
+ })
+ let board = document.createElement("table")
+ board.className = "board"
+ this.fields = {};
+ for (let i = 0; i < 8; i++) {
+ let row = document.createElement("tr")
+ row.className = "board-row"
+ for (let j = 0; j < 8; j++) {
+ let field = document.createElement("td")
+ field.className = "board-field " + (((i + j) % 2) === 0 ? 'black' : 'white');
+ let name = indiciesToFieldName(i, j)
+ field.innerText = name;
+ field.addEventListener("dragover", ev => ev.preventDefault())
+ field.addEventListener("drop", ev => {
+ ev.preventDefault()
+ let data = ev.dataTransfer.getData("text")
+ let fromField = data
+ let toField = name
+ this.playMove(fromField, toField)
+ })
+ this.fields [name] = field
+ row.appendChild(field)
+ }
+ board.appendChild(row)
+ }
+ elem.appendChild(board)
+ }
+
+ playMove(fromField, toField) {
+ let uci = fromField + toField
+ if ((toField[1] === '8' && this.playerColor === 'white')
+ || (toField[2] === '1' && this.playerColor === 'black')) {
+ uci += window.prompt('promote to what')
+ }
+ this.socket.send(JSON.stringify({
+ method: "move",
+ params: {
+ move: uci
+ }
+ }))
+ }
+
+ get isPlayerTurn() {
+ return this.playerColor === this.boardState.turn
+ }
+
+ synchronizeBoard() {
+ for (let field in this.fields) {
+ this.fields[field].innerHTML = ""
+ if (this.boardState[field]) {
+ let piece = document.createElement("span")
+ piece.innerText = notationToPieceUnicode(this.boardState[field])
+ piece.addEventListener("dragstart", ev => {
+ ev.dataTransfer.setData("text", field)
+ })
+ piece.draggable = this.isPlayerTurn
+ this.fields[field].appendChild(piece)
+ }
+ }
+ }
+ }
+
+ function indiciesToFieldName(row, col) {
+ return "abcdefgh".at(col) + (row + 1)
+ }
+
+ function parseFEN(notation) {
+ let row = 7;
+ let col = 0;
+ let board = {}
+ for (let c of notation) {
+ if (c === '/') { // Next row on /
+ if (col !== 8) {
+ throw "Row not finished"
+ }
+ row--
+ col = 0
+ } else if ((c | 0) > 0) { // Skip n places on a number
+ col += (c | 0)
+ } else if (c === ' ') {
+ if (board.turn)
+ break
+ } else if ("KQRBNP".includes(c.toUpperCase())) {
+ board[indiciesToFieldName(row, col)] = c
+ col += 1
+ } else if (c === 'b') {
+ board.turn = 'black'
+ } else if (c === 'w') {
+ board.turn = 'white'
+ } else {
+ throw "Could not parse notation: " + c
+ }
+ }
+ return board
+ }
+
+ function notationToPieceUnicode(notation) {
+ let white = "♔♕♖♗♘♙"
+ let black = "♚♛♜♝♞♟︎"
+ let names = "KQRBNP"
+ let index = names.indexOf(notation.toUpperCase())
+ if (index < 0) {
+ return null
+ }
+ return (notation < 'Z' ? white : black)[index];
+ }
+
+
+ const board = new Board(document.getElementById("app"));
+
+</script>
+
+
+</body>
+</html> \ No newline at end of file