-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
192 lines (165 loc) · 6.62 KB
/
server.js
File metadata and controls
192 lines (165 loc) · 6.62 KB
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
//utilities functions and classes
const {randRoom, randPiece} = require('./utilities/utils')
const Player = require('./utilities/player')
const Board = require('./utilities/board')
const cors = require('cors')
//set up express server
const express = require('express')
const http = require('http')
const socketio = require('socket.io')
const PORT = process.env.PORT || 4000
const app = express()
const server = http.createServer(app)
const io = socketio(server)
app.use(cors())
//Store the room ids mapping to the room property object
//The room property object looks like this {roomid:str, players:Array(2)}
const rooms = new Map()
//Promise function to make sure room id is unique
const makeRoom = (resolve) =>{
var newRoom = randRoom()
while (rooms.has(newRoom)){
newRoom = randRoom()
}
rooms.set(newRoom, {roomId: newRoom, players:[], board:null})
console.log(rooms)
resolve(newRoom)
}
//Put the newly joined player into a room's player list
const joinRoom = (player, room) => {
currentRoom = rooms.get(room)
console.log(currentRoom)
updatedPlayerList = currentRoom.players.push(player)
updatedRoom = {...currentRoom, players:updatedPlayerList}
}
//Remove the latest player joined from a room's player list
function kick(room){
currentRoom = rooms.get(room)
currentRoom.players.pop()
}
//Check how many player is currently in the room
function getRoomPlayersNum(room){
return rooms.get(room).players.length
}
//Assign x o values to each of the player class
function pieceAssignment(room){
const firstPiece = randPiece()
const lastPiece = firstPiece === 'black'? 'white':'black'
currentRoom = rooms.get(room)
currentRoom.players[0].piece = firstPiece
currentRoom.players[1].piece = lastPiece
}
//Initialize a new board to a room
function newGame(room){
currentRoom = rooms.get(room)
const board = new Board()
currentRoom.board = board
}
io.on('connection', socket =>{
//On the client submit event (on start page) to create a new room
socket.on('newGame', () => {
console.log('hello')
new Promise(makeRoom).then((room) => {
socket.emit('newGameCreated', room)
})
})
//On the client submit event (on start page) to join a room
socket.on('joining', ({room}) => {
if (rooms.has(room)){
socket.emit('joinConfirmed')
}else{
socket.emit('errorMessage', 'No room with that id found')
}
})
socket.on('newRoomJoin', ({room,name})=>{
//If someone tries to go to the game page without a room or name then
//redirect them back to the start page
if (room === '' || name ===''){
io.to(socket.id).emit('joinError')
}
//Put the new player into the room
socket.join(room)
const id = socket.id
const newPlayer = new Player(name, room, id)
joinRoom(newPlayer, room)
//Get the number of player in the room
const peopleInRoom = getRoomPlayersNum(room)
//Need another player so emit the waiting event
//to display the wait screen on the front end
if (peopleInRoom===1){
io.to(room).emit('waiting')
}
//The right amount of people so we start the game
if (peopleInRoom===2){
//Assign the piece to each player in the backend data structure and then
//emit it to each of the player so they can store it in their state
pieceAssignment(room)
currentPlayers = rooms.get(room).players
for (const player of currentPlayers){
io.to(player.id).emit('pieceAssignment', {piece: player.piece, id: player.id})
}
newGame(room)
//When starting, the game state, turn and the list of both players in
//the room are required in the front end to render the correct information
const currentRoom = rooms.get(room)
const gameState = currentRoom.board.board
const turn = currentRoom.board.currPlayer
const players = currentRoom.players.map((player) => [player.id, player.name])
io.to(room).emit('starting', {gameState,players,turn})
}
//Too many people so we kick them out of the room and redirect
//them to the main starting page
if (peopleInRoom===3){
socket.leave(room)
kick(room)
io.to(socket.id).emit('joinError')
}
})
//Listener event for each move and emit different events depending on the state of the game
socket.on('move', ({room, index}) => {
currentBoard = rooms.get(room).board
console.log(currentBoard)
if (currentBoard.movePiece(index[0], index[1])) {
currentBoard.place(index[0], index[1])
currentBoard.switchPlayer()
io.to(room).emit('update', {gameState: currentBoard.board, turn: currentBoard.currPlayer})
} else {
io.to(rooom).emit('moveError', 'Cannot Move Here!')
}
})
//Listener event for a new game
socket.on('playAgainRequest', (room) => {
currentRoom = rooms.get(room)
currentRoom.board.reset()
//Reassign new piece so a player can't always go first
pieceAssignment(room)
currentPlayers = currentRoom.players
for (const player of currentPlayers){
io.to(player.id).emit('pieceAssignment', {piece: player.piece, id: player.id})
}
io.to(room).emit('restart', {gameState:currentRoom.board.board, turn:currentRoom.board.currPlayer})
})
//On disconnect event
socket.on('disconnecting', ()=> {
//Get all the rooms that the socket is currently subscribed to
const currentRooms = Object.keys(socket.rooms)
//In this game an object can only have 2 rooms max so we check for that
if (currentRooms.length === 2){
//The game room is always the second element of the list
const room = currentRooms[1]
const num = getRoomPlayersNum(room)
//If one then no one is left so we remove the room from the mapping
if (num === 1){
rooms.delete(room)
}
//If 2 then there is one person left so we remove the socket leaving from the player list and
//emit a waiting event to the other person
if (num === 2){
currentRoom = rooms.get(room)
currentRoom.players = currentRoom.players.filter((player) => player.id !== socket.id)
io.to(room).emit('waiting')
}
}
})
})
server.listen(PORT, ()=>console.log(`Listening on port ${PORT}`))