-
Notifications
You must be signed in to change notification settings - Fork 0
/
gameboard.js
111 lines (86 loc) · 2.48 KB
/
gameboard.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"use strict";
// FIXME: Really hating how I implemented "white" and "black" here. :(
var sequence = 1;
const crypto = require('crypto');
const hash_algorithm = 'sha256';
const STATUS_CREATED = 1;
const STATUS_IN_PROGRESS = 2;
const STATUS_FINISHED = 3;
class GameBoard {
constructor(options) {
this.seq = sequence++;
this._salt = this.make_salt();
this.black_secret = null;
this.white_secret = null;
this.status = STATUS_CREATED;
}
join(player) { // Ugly function. :(
// Join as 'player', returns new player's secret key
this._check_player(player);
var secret = null;
if (player == "black") {
if (this.black_secret) {
throw "Black already joined";
}
this.black_secret = this.make_secret("black");
secret = this.black_secret;
}
else if (player == "white") {
if (this.white_secret) {
throw "White already joined";
}
this.white_secret = this.make_secret("white");
secret = this.white_secret;
}
if (this.black_secret && this.white_secret) {
this.status = STATUS_IN_PROGRESS;
}
return secret;
}
is_available(player) {
this._check_player(player);
if (player == "white") {
return Boolean(! this.white_secret);
}
return Boolean(! this.black_secret);
}
opposite_color(player) {
this._check_player(player);
if (player == "white") {
return "black";
}
return "white";
}
make_salt() {
// Make a random salt value
const letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var salt = "";
for (var i=0; i<32; i++) {
salt += letters.charAt(Math.floor((Math.random() * letters.length)));
}
return salt;
}
make_secret(player) {
// Make a secret string based on the player, sequence, and salt
this._check_player(player);
const hash = crypto.createHash(hash_algorithm);
hash.update(this._salt + this.seq.toString() + player);
return hash.digest('hex');
}
check_secret(player, proposed) {
// Check the proposed secret against the saved on
this._check_player(player);
var secret = this.make_secret(player);
return Boolean(secret == proposed);
}
_check_player(player) {
if (! ((player == "white") || (player == "black"))) {
throw "Invalid player";
}
return;
}
};
exports.GameBoard = GameBoard;
exports.STATUS_CREATED = STATUS_CREATED;
exports.STATUS_IN_PROGRESS = STATUS_IN_PROGRESS;
exports.STATUS_FINISHED = STATUS_FINISHED;