diff --git a/public/client.js b/public/client.js new file mode 100644 index 0000000..9214428 --- /dev/null +++ b/public/client.js @@ -0,0 +1,36 @@ +const player = io() +let myNumber = 0 + +player.on('alert', (message) => { + alert(message) +}) + +player.on('onlineNumber', (number) => { + onlineNumber.innerText = number +}) + +player.on('playersNumber', (number) => { + playersNumber.innerText = number +}) + +player.on('join', (number) => { + myNumber = number + playerNumber.innerText = number + buttonJoin.innerText = number == 0 ? '加入' : '退出' + buttonJoin.style.color = number == 0 ? 'red' : 'black' +}) + +player.on('status', (status) => { + const { players, cards, current } = status + player1.innerText = makeCards(players[0] || 0) + player2.innerText = makeCards(players[1] || 0) + player3.innerText = makeCards(players[2] || 0) + currentPlayerNumber.innerText = current + 1 + buttonGo.style.color = myNumber > 0 && myNumber === current + 1 ? 'red' : 'black' + cardsDisplay.innerText = cards +}) + +function makeCards(n) { + if (n == 0) return '' + return '['.repeat(n) + ']' +} diff --git a/public/game.js b/public/game.js deleted file mode 100644 index e69de29..0000000 diff --git a/public/index.html b/public/index.html index 5b55f21..28f4f35 100644 --- a/public/index.html +++ b/public/index.html @@ -5,47 +5,25 @@ - 小猫钓鱼 -

小猫钓鱼

-

在线人数:0

-

玩家人数:0

- -
-
+

[ 在线 0 ] [ 玩家 0 ] [ 我是 玩家0 + ]

+

玩家1

+

玩家2

+

玩家3

+

当前 = 玩家0

+

+ + +

+

- + diff --git a/server.js b/server.js index a94497a..d3b90a4 100644 --- a/server.js +++ b/server.js @@ -1,71 +1,217 @@ const express = require('express') -const game = express() -game.use(express.static('public')) -const host = process.env.HOST || '0.0.0.0' -const port = process.env.PORT || 3000 -const server = game.listen(port, host, () => console.log(`小猫钓鱼游戏服务运行在 http://${host}:${port}/`)) -const io = require('socket.io')(server) +const 游戏 = express() +游戏.use(express.static('public')) +const 主机 = process.env.HOST || '0.0.0.0' +const 端口 = process.env.PORT || 3000 +const 服务器 = 游戏.listen(端口, 主机, () => console.log(`小猫钓鱼游戏服务运行在 http://${主机}:${端口}/`)) +const IO = require('socket.io')(服务器) -const clients = [] -const players = [] -const cards = [] -let current = 0 -let started = false +const clients = [] // 所有客户 +const players = [] // 所有玩家 +let cardsOnTable = [] // 桌上的牌 +let currentPlayerNumber = -1 // 当前玩家序号 -function isGameStarted() { - if (players.length < 2) return false - for (let player of players) { - if (!player.ready) return false - } - return true -} +IO.on('connection', (client) => { + addClient(client) + client.on('disconnect', () => removeClient(client)) + client.on('join', () => playerJoin(client)) + client.on('go', () => go(client)) +}) -io.on('connection', (client) => { - client.ready = false +function addClient(client) { client.cards = [] clients.push(client) - io.emit('onlineNumber', clients.length) - io.emit('playersNumber', players.length) + IO.emit('onlineNumber', clients.length) + client.emit('playersNumber', players.length) + client.emit('join', 0) + gameStatus() // TODO:只告诉当前加入的客户端 + console.info(`新客户端已连接,当前客户端${clients.length}个`) +} - client.on('ready', () => { - if (!isGameStarted()) { - client.ready = !client.ready - if (client.ready) { - players.push(client) - } else { - const index = players.indexOf(client) - players.splice(index, 1) - } - io.emit('playersNumber', players.length) - client.emit('ready', client.ready) - if (isGameStarted()) gameStart() +function removeClient(client) { + let index = clients.indexOf(client) + clients.splice(index, 1) + IO.emit('onlineNumber', clients.length) + console.log(`已断开,当前客户端${clients.length}个`) + if (players.includes(client)) { + index = players.indexOf(client) + players.splice(index, 1) + IO.emit('playersNumber', players.length) + // 游戏被迫结束? + if (players.length == 2) { + gameFinished() + IO.emit('alert', `玩家${index + 1}掉线了`) } - }) + } +} - client.on('disconnect', () => { - const index = clients.indexOf(client) - clients.splice(index, 1) - io.emit('onlineNumber', clients.length) - }) -}) +function playerJoin(player) { + if (players.length < 3) { + let playerIndex = players.indexOf(player) + let playerNumber = playerIndex + 1 + if (playerNumber > 0) { + playerNumber = 0 + players.splice(playerIndex, 1) + console.log(`玩家${playerNumber} 已退出,当前玩家数:${players.length}`) + } else { + players.push(player) + playerNumber = players.indexOf(player) + 1 + console.log(`玩家${playerNumber} 已加入,当前玩家数:${players.length}`) + player.cards = [] + if (players.length === 3) gameStart() + } + player.emit('join', playerNumber) + IO.emit('playersNumber', players.length) + } +} function gameStart() { console.log('游戏开始') - // cards = [] - cards.length = 0 - current = 0 - // 洗牌 -> players.cards 每家18张 - // players[0].cards = [1, 2, 3] - // players[1].cards = [1, 2, 3, 4] - // players[2].cards = [1, 2, 3, 4, 5] - // ... - emitStatus() + cardsOnTable.length = 0 + currentPlayerNumber = 0 + // 洗牌,每玩家发18张 + const drawer = [ + { color: '♠️', value: '2' }, + { color: '♠️', value: '3' }, + { color: '♠️', value: '4' }, + { color: '♠️', value: '5' }, + { color: '♠️', value: '6' }, + { color: '♠️', value: '7' }, + { color: '♠️', value: '8' }, + { color: '♠️', value: '9' }, + { color: '♠️', value: '10' }, + { color: '♠️', value: 'J' }, + { color: '♠️', value: 'Q' }, + { color: '♠️', value: 'K' }, + { color: '♠️', value: 'A' }, + { color: '♥️', value: '2' }, + { color: '♥️', value: '3' }, + { color: '♥️', value: '4' }, + { color: '♥️', value: '5' }, + { color: '♥️', value: '6' }, + { color: '♥️', value: '7' }, + { color: '♥️', value: '8' }, + { color: '♥️', value: '9' }, + { color: '♥️', value: '10' }, + { color: '♥️', value: 'J' }, + { color: '♥️', value: 'Q' }, + { color: '♥️', value: 'K' }, + { color: '♥️', value: 'A' }, + { color: '♣️', value: '2' }, + { color: '♣️', value: '3' }, + { color: '♣️', value: '4' }, + { color: '♣️', value: '5' }, + { color: '♣️', value: '6' }, + { color: '♣️', value: '7' }, + { color: '♣️', value: '8' }, + { color: '♣️', value: '9' }, + { color: '♣️', value: '10' }, + { color: '♣️', value: 'J' }, + { color: '♣️', value: 'Q' }, + { color: '♣️', value: 'K' }, + { color: '♣️', value: 'A' }, + { color: '♦️', value: '2' }, + { color: '♦️', value: '3' }, + { color: '♦️', value: '4' }, + { color: '♦️', value: '5' }, + { color: '♦️', value: '6' }, + { color: '♦️', value: '7' }, + { color: '♦️', value: '8' }, + { color: '♦️', value: '9' }, + { color: '♦️', value: '10' }, + { color: '♦️', value: 'J' }, + { color: '♦️', value: 'Q' }, + { color: '♦️', value: 'K' }, + { color: '♦️', value: 'A' }, + { color: '小', value: 'Joker' }, + { color: '大', value: 'Joker' }, + ] + + while (drawer.length > 0) { + let index = Math.floor(Math.random() * drawer.length) + let card = drawer[index] + players[currentPlayerNumber].cards.push(card) + drawer.splice(index, 1) + currentPlayerNumber = (currentPlayerNumber + 1) % 3 + } + + gameStatus() } -function emitStatus() { +function gameStatus() { const cardsNumbers = [] - for (let p of players) { - cardsNumbers.push(p.cards.length) + + for (let player of players) { + cardsNumbers.push(player.cards.length) } - io.emit('status', { players: cardsNumbers, cards, current }) + + const cardsStrings = [] + for (let card of cardsOnTable) { + cardsStrings.push(`[${card.color}${card.value}]`) + } + + IO.emit('status', { + players: cardsNumbers, + cards: cardsStrings.join(''), + current: currentPlayerNumber, + }) +} + +function go(client) { + if (currentPlayerNumber != -1 && players.indexOf(client) === currentPlayerNumber) { + let card = players[currentPlayerNumber].cards[0] + players[currentPlayerNumber].cards.splice(0, 1) + console.log(`玩家${currentPlayerNumber + 1} 出牌 [${card.color} ${card.value}]`) + + // 判断有没有钓到 + let i = 0 + let getit = false + for (i = 0; i < cardsOnTable.length; i++) { + if (cardsOnTable[i].value == card.value) { + getit = true + break + } + } + if (getit) { + // 将第i张牌后面的牌和玩家刚出的牌一起拿走放回玩家手中的牌后面 + const fishes = [...cardsOnTable.slice(i), card] + console.log(`玩家${currentPlayerNumber + 1} 钓到 ${fishes.length} 条鱼`) + players[currentPlayerNumber].cards = players[currentPlayerNumber].cards.concat(fishes) + cardsOnTable = cardsOnTable.slice(0, i) + } else { + cardsOnTable.push(card) + if (players[currentPlayerNumber].cards.length == 0) { + client.emit('alert', '你输了') + } + currentPlayerNumber = (currentPlayerNumber + 1) % 3 + while (players[currentPlayerNumber].cards.length == 0) { + currentPlayerNumber = (currentPlayerNumber + 1) % 3 + } + } + + gameStatus() + + // 游戏结束了? + let looser = 0 + let winner = 0 + for (let index = 0; index < players.length; index++) { + const player = players[index] + if (player.cards.length == 0) looser++ + else winner = index + 1 + } + if (looser >= 2) { + gameFinished() + players[index].emit('alert', '你赢了!') + players[index].broadcast.emit('alert', `玩家${winner} 获胜了!`) + } + } +} + +function gameFinished() { + players.length = 0 + cardsOnTable.length = 0 + currentPlayerNumber = -1 + IO.emit('join', 0) + IO.emit('playersNumber', 0) + IO.emit('status', { players: [0, 0, 0], cards: '', current: currentPlayerNumber }) }