-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
182 lines (152 loc) · 5.07 KB
/
Copy pathserver.js
File metadata and controls
182 lines (152 loc) · 5.07 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
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const cors = require('cors');
const { Chess } = require('chess.js');
const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
cors: {
origin: process.env.ENV === "production"? "https://chess-alpha-blond.vercel.app": "http://localhost:3000",
methods: ["GET", "POST"]
}
});
app.use(cors());
// Store waiting players and active games information on the server
const waitingPlayers = [];
const activeGames = new Map();
io.on('connection', (socket) => {
console.log('Player connected:', socket.id);
// Handle player looking for a game
socket.on('find-game', (playerData) => {
console.log('Player looking for game:', playerData.displayName);
// Store player data on socket
socket.playerData = playerData;
if (waitingPlayers.length > 0) {
// Match with waiting player
const opponent = waitingPlayers.shift();
startGame(socket, opponent);
} else {
// Add to waiting list
waitingPlayers.push(socket);
socket.emit('waiting-for-opponent');
console.log('Player added to waiting list. Total waiting:', waitingPlayers.length);
}
});
// Handle moves
socket.on('make-move', (data) => {
const { gameId, move } = data;
const game = activeGames.get(gameId);
if (!game) {
console.log('Game not found:', gameId);
return;
}
// Validate it's the player's turn
const isWhitePlayer = game.white.id === socket.id;
const isBlackPlayer = game.black.id === socket.id;
const currentTurn = game.chess.turn();
if ((currentTurn === 'w' && !isWhitePlayer) || (currentTurn === 'b' && !isBlackPlayer)) {
socket.emit('invalid-move', { reason: 'Not your turn' });
return;
}
// Try to make the move
try {
const moveResult = game.chess.move(move);
if (moveResult) {
console.log('Move made:', moveResult.san, 'in game', gameId);
// Send move to both players
io.to(gameId).emit('move-made', {
move: moveResult,
fen: game.chess.fen(),
turn: game.chess.turn(),
isGameOver: game.chess.isGameOver()
});
// Check if game is over
if (game.chess.isGameOver()) {
handleGameEnd(game, gameId);
}
} else {
socket.emit('invalid-move', { reason: 'Illegal move' });
}
} catch (error) {
console.log('Invalid move attempt:', error.message);
socket.emit('invalid-move', { reason: error.message });
}
});
// Handle disconnect
socket.on('disconnect', () => {
console.log('Player disconnected:', socket.id);
// Remove from waiting list
const waitingIndex = waitingPlayers.findIndex(p => p.id === socket.id);
if (waitingIndex !== -1) {
waitingPlayers.splice(waitingIndex, 1);
console.log('Player removed from waiting list. Total waiting:', waitingPlayers.length);
}
// Handle game disconnect
activeGames.forEach((game, gameId) => {
if (game.white.id === socket.id || game.black.id === socket.id) {
console.log('Player disconnected from game:', gameId);
socket.to(gameId).emit('opponent-disconnected');
activeGames.delete(gameId);
}
});
});
});
// Start a new game between two players
function startGame(player1, player2) {
const gameId = `game_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
// Randomly assign colors
const isPlayer1White = Math.random() < 0.5;
const white = isPlayer1White ? player1 : player2;
const black = isPlayer1White ? player2 : player1;
const game = {
id: gameId,
white: white,
black: black,
chess: new Chess(),
startTime: new Date()
};
activeGames.set(gameId, game);
// Join both players to the game room
white.join(gameId);
black.join(gameId);
// Notify both players
white.emit('game-started', {
gameId: gameId,
color: 'white',
opponent: black.playerData,
fen: game.chess.fen()
});
black.emit('game-started', {
gameId: gameId,
color: 'black',
opponent: white.playerData,
fen: game.chess.fen()
});
console.log(`Game started: ${gameId} - ${white.playerData.displayName} (white) vs ${black.playerData.displayName} (black)`);
}
// Handle game end
function handleGameEnd(game, gameId) {
let winner = null;
let reason = '';
if (game.chess.isCheckmate()) {
winner = game.chess.turn() === 'w' ? 'black' : 'white';
reason = 'checkmate';
} else if (game.chess.isStalemate()) {
reason = 'stalemate';
} else if (game.chess.isDraw()) {
reason = 'draw';
}
io.to(gameId).emit('game-ended', {
winner: winner,
reason: reason
});
console.log(`Game ended: ${gameId} - Winner: ${winner || 'draw'} (${reason})`);
activeGames.delete(gameId);
}
const PORT = process.env.PORT || 3001;
server.listen(PORT, () => {
console.log(`Socket.io server running on port ${PORT}`);
console.log(`running in ${process.env.ENV} environment`)
console.log('Waiting for players to connect...');
});