const express = require('express') const application = express() application.use(require('compression')()) application.use(express.static('public')) const host = process.env.HOST || '0.0.0.0' const port = process.env.PORT || 3000 const server = application.listen(port, host, () => console.log(`小猫钓鱼游戏服务运行在 http://${host}:${port}/`)) const io = require('socket.io')(server) const clients = [] // 所有客户 const players = [] // 所有玩家 let current = -1 // 当前玩家序号 let cards = [] // 桌上的牌 io.on('connection', (client) => { // 初始化客户端 client.cards = [] clients.push(client) console.info(`新连接,当前客户端${clients.length}个`) // 广播新的客户端数量 io.emit('online', clients.length) // 通知客户当前游戏状态 update_status(client) client.emit('join', 0) client.emit('players', players.length) // 其它客户事件处理 client.on('disconnect', () => disconnect(client)) client.on('join', () => join(client)) client.on('go', () => go(client)) }) function disconnect(client) { // 移除客户端 let index = clients.indexOf(client) clients.splice(index, 1) io.emit('online', clients.length) console.log(`已断开,当前客户端${clients.length}个`) // 移除玩家 if (players.includes(client)) { index = players.indexOf(client) players.splice(index, 1) io.emit('players', players.length) // 游戏被迫结束 if (players.length == 2) { io.emit('alert', `玩家${index + 1}掉线了,游戏被迫结束!`) finish() } } } function join(player) { if (players.length < 3) { let player_index = players.indexOf(player) let player_number = player_index + 1 if (player_number > 0) { players.splice(player_index, 1) player.broadcast.emit('alert', `玩家${player_number}退出了游戏`) console.log(`玩家${player_number}退出了,当前玩家${players.length}个`) player.emit('alert', '你退出了游戏') player.emit('join', 0) player_number = 0 for (let i = 0; i < players.length; i++) { players[i].emit('join', i + 1) players[i].emit('alert', `你现在是玩家${i + 1}`) } } else { player.cards = [] players.push(player) player_number = players.indexOf(player) + 1 player.emit('join', player_number) player.emit('alert', `你现在是玩家${player_number}`) player.broadcast.emit('alert', `玩家${player_number}加入了游戏`) console.log(`玩家${player_number}加入了,当前玩家${players.length}个`) if (players.length === 3) start() } io.emit('players', players.length) } } function start() { console.log('新游戏开始') io.emit('alert', '游戏开始了!') // 初始化游戏状态 current = 0 cards = [] players[0].cards = [] players[1].cards = [] players[2].cards = [] // 三个玩家每人发18张牌 let deck = [ '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'Ts', 'Js', 'Qs', 'Ks', 'As', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'Th', 'Jh', 'Qh', 'Kh', 'Ah', '2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'Tc', 'Jc', 'Qc', 'Kc', 'Ac', '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'Td', 'Jd', 'Qd', 'Kd', 'Ad', '01', '02', ] while (deck.length > 0) { let index = Math.floor(Math.random() * deck.length) let card = deck[index] deck.splice(index, 1) players[current].cards.push(card) current = (current + 1) % 3 } update_status() } function update_status(client = null) { ;(client || io).emit('status', { players: players.length == 3 ? [players[0].cards.length, players[1].cards.length, players[2].cards.length] : [0, 0, 0], cards, current: current + 1, }) } function go(player) { if (current != -1 && players.indexOf(player) == current) { let card = players[current].cards[0] players[current].cards.splice(0, 1) console.log(`玩家${current + 1} 出牌 [${card}]`) // 判断有没有钓到 let i = 0 let getit = false for (i = 0; i < cards.length; i++) { if (cards[i][0] == card[0]) { getit = true break } } if (getit) { // 将第i张牌后面的牌和玩家刚出的牌一起拿走放回玩家手中的牌后面 const fishes = [...cards.slice(i), card] console.log(`玩家${current + 1} 钓到了 ${fishes.length} 条鱼`) io.emit('alert', `玩家${current + 1} 钓到了 ${fishes.length} 条鱼`) players[current].cards = players[current].cards.concat(fishes) cards = cards.slice(0, i) } else { cards.push(card) if (players[current].cards.length == 0) { player.emit('alert', '你输了') player.broadcast.emit('alert', `玩家${current + 1}输了`) } current = (current + 1) % 3 while (players[current].cards.length == 0) { current = (current + 1) % 3 } } // 游戏结束了? let looser = 0 let winner = 0 for (let index = 0; index < players.length; index++) { if (players[index].cards.length == 0) looser++ else winner = index + 1 } if (looser >= 2) { io.emit('alert', '游戏结束了~~~') players[winner - 1].emit('alert', '恭喜,你赢了!') players[winner - 1].broadcast.emit('alert', `你失败了,玩家${winner}获胜了!`) finish() } update_status() } } function finish() { current = -1 cards.length = 0 players.length = 0 update_status() io.emit('join', 0) io.emit('players', 0) }