aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Voss <thomasvoss@live.com> 2022-01-14 20:32:28 +0100
committerThomas Voss <thomasvoss@live.com> 2022-01-14 20:32:28 +0100
commitc8218c35f88eb9addfac6aad605b8e98349a987b (patch)
tree265c5483776a85e162c9b989efeb88e5e076fc17
parent005396c2d3d7f2b9254a783e72038b09581c23d6 (diff)
Add support for game history
-rw-r--r--draughts/app.js3
-rw-r--r--draughts/game.js16
-rw-r--r--draughts/public/game.html6
-rw-r--r--draughts/public/javascripts/game.js40
4 files changed, 58 insertions, 7 deletions
diff --git a/draughts/app.js b/draughts/app.js
index 64ce815..b5a9fa5 100644
--- a/draughts/app.js
+++ b/draughts/app.js
@@ -75,7 +75,8 @@ wss.on("connection", ws => {
id: msg.body.id,
position: msg.body.new,
captures: msg.body.captures,
- king: msg.body.king
+ king: msg.body.king,
+ history: msg.body.history
}
}, ws)
game.move(msg.body)
diff --git a/draughts/game.js b/draughts/game.js
index 107cd3d..819a98d 100644
--- a/draughts/game.js
+++ b/draughts/game.js
@@ -313,8 +313,10 @@ Game.prototype.nextTurn = function() {
else
this.currentTurn = this.currentTurn == Color.BLUE ? Color.RED : Color.BLUE
- this.messageClient({ head: Messages.COMMENCE, body: this.legalMoves() },
+ this.messageClient({ head: Messages.COMMENCE,
+ body: { moves: this.legalMoves(), history: this.history } },
this.currentTurn == Color.BLUE ? this.bluePlayer : this.redPlayer)
+ return true
}
/*
@@ -328,6 +330,8 @@ Game.prototype.nextTurn = function() {
* fields. The `old' and `new' fields contain the old and new positions of the piece that was
* moved. The `captures' field holds an array of `Piece' objects that were captures and need to
* be removed from the game. The `king' field tells us if the piece got promoted to a king.
+ *
+ * This function also updates the game history according to the official syntax.
*/
Game.prototype.move = function(msg) {
this.board[msg.new.y][msg.new.x] = this.board[msg.old.y][msg.old.x]
@@ -335,6 +339,16 @@ Game.prototype.move = function(msg) {
this.board[msg.new.y][msg.new.x].isKing = msg.king
this.board[msg.old.y][msg.old.x] = null
msg.captures.forEach(c => this.board[c.position.y][c.position.x] = null)
+
+ if (this.history.length == 0 || this.history[this.history.length - 1].red)
+ this.history.push({ blue: moveToHistory(msg.old, msg.new, msg.captures) })
+ else
+ this.history[this.history.length - 1].red = moveToHistory(msg.old, msg.new, msg.captures)
}
+const coordToSquare = (x, y) => 51 - Math.ceil((x + 1) / 2 + 5 * y)
+
+const moveToHistory = (o, n, c) =>
+ `${coordToSquare(o.x, o.y)}${c.length == 0 ? "-" : "x"}${coordToSquare(n.x, n.y)}`
+
module.exports = Game
diff --git a/draughts/public/game.html b/draughts/public/game.html
index 42c52c2..435344d 100644
--- a/draughts/public/game.html
+++ b/draughts/public/game.html
@@ -88,11 +88,11 @@
<td><div id="red-bar"></div></td>
</tr>
</thead>
- <tbody>
+ <tbody id="history-body">
<tr>
<td class="turn-no">8</td>
- <td>37-32</td>
- <td>22-28</td>
+ <td></td>
+ <td></td>
</tr>
<tr>
<td class="turn-no">7</td>
diff --git a/draughts/public/javascripts/game.js b/draughts/public/javascripts/game.js
index 6fe82dd..20cceb8 100644
--- a/draughts/public/javascripts/game.js
+++ b/draughts/public/javascripts/game.js
@@ -40,6 +40,12 @@ const addMarker = ({ x, y, captures, king }) => {
/* Get the ID of the selected piece so we can include it in the message to the server */
let id = selectedPiece.id.slice(1)
+ let [o, n] = [{ x: ox, y: oy }, { x: x, y: y }]
+ if (gameHistory.length == 0 || gameHistory[gameHistory.length - 1].red)
+ gameHistory.push({ blue: moveToHistory(o, n, captures) })
+ else
+ gameHistory[gameHistory.length - 1].red = moveToHistory(o, n, captures)
+ drawHistory()
removeCaptures(captures, opponentPrefix())
/* Move the selected piece, unselect it, remove the markers, and end our turn */
@@ -60,7 +66,8 @@ const addMarker = ({ x, y, captures, king }) => {
old: { x: ox, y: oy },
new: { x: x, y: y },
captures: captures,
- king: king
+ king: king,
+ history: gameHistory
}
}))
})
@@ -106,6 +113,31 @@ const setupPieceEventListeners = () => {
}))
}
+/*
+ * Signature:
+ * () => Nothing
+ *
+ * Description:
+ * Draw the game history to the history table on the right. This is done in a bit of a hacky way
+ * where we effectively generate the HTML on the spot. The history information is read from the
+ * `gameHistory' global variable.
+ */
+const drawHistory = () => {
+ /* Get a short list of the history array, which only contains the last 8 turns that were played */
+ const shortList = gameHistory.slice(-8).map(h => ({
+ blue: h.blue,
+ red: (typeof(h.red) == "undefined" ? "" : h.red)
+ }))
+
+ let html = ""
+ for (let i = 7; i >= shortList.length; i--)
+ html += `<tr><td class="turn-no">${i + 1}</td><td></td><td></td></tr>`
+ for (let i = shortList.length - 1; i >= 0; i--)
+ html += `<tr><td class="turn-no">${i + 1 + gameHistory.length - shortList.length}</td><td>
+ ${shortList[i].blue}</td><td>${shortList[i].red}</td></tr>`
+ document.getElementById("history-body").innerHTML = html
+}
+
/* Listen for a message from the client, and perform a different action based on the message.
* The `public/javascripts/game.js' file explains what each of the message headers mean.
*/
@@ -127,10 +159,14 @@ ws.addEventListener("message", ({ data }) => {
break
case Messages.COMMENCE:
ourTurn = true
- legalMoves = data.body
+ legalMoves = data.body.moves
+ gameHistory = data.body.history
break
case Messages.MOVED:
movePiece(data.body)
+ gameHistory = data.body.history
+ drawHistory()
+ break
break
}
})