-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver2.js
306 lines (248 loc) · 7.34 KB
/
server2.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
To Do:
Mouseover on cards is too slow
Option to view 'won' black cards? (how to display?)
judge cards stick around
Add a max thing to screen size
show judging cards on other screens
*bug* black cards don't clear out and stay on screen
3rd card in 4th set while judging doesn't fit onscreen
*/
var express = require('express');
var app = express()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '',
});
app.use("/javascript", express.static(__dirname + '/javascript'));
app.use("/images", express.static(__dirname + '/images'));
server.listen(8080);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
var handSize = 7;
var players = [];
var judge = -1;
var currBlack;
var gameScore = 0;
var availableBlack = [];
var availableWhite = [];
var end = false;
connection.connect();
//connect to db
connection.query('USE cah');
//get max white cards
connection.query('SELECT id FROM white_cards', function(err, rows, fields) {
if (err) throw err;
for (var i = 0; i < rows.length; i++) {
availableWhite.push(rows[i].id);
}
});
//get max black cards
connection.query('SELECT id FROM black_cards', function(err, rows, fields) {
if (err) throw err;
for (var i = 0; i < rows.length; i++) {
availableBlack.push(rows[i].id);
}
});
//get index of players item with matching attribute value
function getByAttr(list, attr, value) {
for (var i = 0; i < list.length; i++) {
if (list[i][attr] == value) {
return i;
}
}
return -1;
}
//get list of player object attributes
function getAttrs(list, attr) {
var attrList = [];
for (var i = 0; i < list.length; i++) {
attrList.push(list[i][attr]);
}
return attrList;
}
function drawBlack(callback) {
//currBlack = {text: "Make a Haiku.", blanks: 3}
//callback();
//return;
if (availableBlack.length == 0) {
console.log("Out of black cards!");
callback();
return;
}
var ind = Math.floor((Math.random()*availableBlack.length));
var id = availableBlack[ind];
availableBlack.splice(ind,1);
//console.log("Getting black card " + id);
var text;
var blanks;
connection.query('SELECT * FROM black_cards WHERE id=' + id, function(err, rows, fields) {
if (err) throw err;
currBlack = {text:rows[0].text, blanks:rows[0].blanks}
callback();
});
}
function drawWhite(num, cards, callback) {
for (var i = 0; i < num; i++) {
if (availableWhite.length == 0) {
//wait a sec for the queries to collect then return
console.log("Out of white cards!");
setTimeout(callback, 300);
return;
}
var ind = Math.floor((Math.random()*availableWhite.length));
var id = availableWhite[ind];
availableWhite.splice(ind,1);
//console.log(availableWhite.length + ", " + ind + ", " + id);
(function(last) {
connection.query('SELECT * FROM white_cards WHERE id=' + id, function(err, rows, fields) {
if (err) throw err;
cards.push({text:rows[0].text});
if (last) {
callback();
}
});
})(i == num - 1)
}
}
function endGame() {
//send scores for all players to everyone
end = true;
io.sockets.emit("end", {players: players, game: gameScore});
connection.end();
}
io.sockets.on('connection', function (socket) {
//let the client know we're connected
socket.emit('handshake', { handSize: handSize });
//the client came back after the handshake so we are in business
socket.on('join', function (data) {
if (!end) {
if (getByAttr(players, "name", data.name) == -1) {
//draw the new player some cards
var cards = [];
drawWhite(handSize, cards, function() {
//create new 'player' object
players.push({name: data.name, score: 0, played: [], hand: cards});
//if there isn't a judge yet, make it this player (the first to join)
if (judge < 0) {
judge = players.length - 1;
//draw a black card
drawBlack(function() {
socket.emit("start", {judge: judge, card: currBlack, players: players});
});
} else {
socket.emit("start", {judge: judge, card: currBlack, players: players});
}
});
console.log("player " + data.name + " joined the game");
//emit message to all other connections to let them know someone joined
socket.broadcast.emit("joined", data);
} else {
console.log("player " + data.name + " rejoined the game");
socket.emit("start", {judge: judge, card: currBlack, players: players});
}
}
});
function checkRound() {
//check if everyone has played (except the judge)
var roundTest = true;
for (var i = 0; i < players.length; i++) {
if (i != judge) {
roundTest = roundTest && (players[i].played.length > 0);
}
}
return roundTest;
}
function endRound() {
//add random card(s) for game then emit to players
var cards = [];
drawWhite(currBlack.blanks, cards, function() {
players[judge].played = cards;
var played = getAttrs(players, "played");
io.sockets.emit("round_end", {played: played});
});
}
//when a user plays card(s)
socket.on('play', function(data) {
if (!end) {
//store card(s) user played
players[getByAttr(players, "name", data.name)].played = data.played;
//let the other players know card(s) was played
socket.broadcast.emit("play", data);
//send new card(s) back to player
setTimeout(function() {
var cards = [];
drawWhite(data.played.length, cards, function() {
socket.emit("draw", cards);
});
}, 2000);
if (checkRound()) {
endRound();
}
}
});
socket.on('judge_end', function(data) {
if (!end) {
//find out who won and give them a point
var winner;
for (var i = 0; i < players.length; i++) {
if (players[i].played[0] && players[i].played[0].text == data[0].text) {
if (i != judge) {
players[i].score++;
winner = players[i].name;
} else {
gameScore++;
winner = "\"The Game\"";
}
}
players[i].played = [];
}
io.sockets.emit("judge_end", {winner: winner, winnerCards: data});
if (availableWhite.length > 0 && availableBlack.length > 0) {
//start new round with new judge
judge = (judge + 1) % players.length;
drawBlack(function() {
setTimeout(function() {
io.sockets.emit("round_start", {judge: players[judge].name, card: currBlack});
}, 3000);
});
} else {
endGame();
}
}
});
socket.on('end', function(data) {
endGame();
});
socket.on('quit', function(data) {
var quitInd = getByAttr(players, "name", data.name);
//judge shouldn't be able to quit, just ignore it if they do it anyway somehow
//also ignore if judging is currently going on
if (quitInd != judge && !checkRound()) {
//let everyone know they quit
socket.broadcast.emit("quit", data);
//remove player
players.splice(getByAttr(players, "name", data.name), 1);
console.log("players now: " + getAttrs(players, "name"));
//make sure we still have the right judge recorded
if (quitInd < judge) {
judge -= 1;
}
//if everyone was waiting on them, then end the round and start judging
if (checkRound()) {
endRound();
}
}
});
socket.on('confirm_draw', function(data) {
if (!end) {
console.log("updated " + data.name + "'s hand");
players[getByAttr(players, "name", data.name)].hand = data.cards;
}
});
});