219 lines
7.1 KiB
JavaScript
219 lines
7.1 KiB
JavaScript
const express = require('express')
|
||
const 应用 = express()
|
||
应用.use(require('compression')())
|
||
应用.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 = [] // 所有玩家
|
||
let cardsOnTable = [] // 桌上的牌
|
||
let currentPlayerNumber = -1 // 当前玩家序号
|
||
|
||
IO.on('connection', (client) => {
|
||
addClient(client)
|
||
client.on('disconnect', () => removeClient(client))
|
||
client.on('join', () => playerJoin(client))
|
||
client.on('go', () => go(client))
|
||
})
|
||
|
||
function addClient(client) {
|
||
client.cards = []
|
||
clients.push(client)
|
||
IO.emit('onlineNumber', clients.length)
|
||
client.emit('playersNumber', players.length)
|
||
client.emit('join', 0)
|
||
gameStatus() // TODO:只告诉当前加入的客户端
|
||
console.info(`新客户端已连接,当前客户端${clients.length}个`)
|
||
}
|
||
|
||
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}掉线了`)
|
||
}
|
||
}
|
||
}
|
||
|
||
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('游戏开始')
|
||
cardsOnTable.length = 0
|
||
currentPlayerNumber = 0
|
||
// 洗牌,每玩家发18张
|
||
const deck = [
|
||
{ suit: 's', rank: '2' },
|
||
{ suit: 's', rank: '3' },
|
||
{ suit: 's', rank: '4' },
|
||
{ suit: 's', rank: '5' },
|
||
{ suit: 's', rank: '6' },
|
||
{ suit: 's', rank: '7' },
|
||
{ suit: 's', rank: '8' },
|
||
{ suit: 's', rank: '9' },
|
||
{ suit: 's', rank: 'T' },
|
||
{ suit: 's', rank: 'J' },
|
||
{ suit: 's', rank: 'Q' },
|
||
{ suit: 's', rank: 'K' },
|
||
{ suit: 's', rank: 'A' },
|
||
{ suit: 'h', rank: '2' },
|
||
{ suit: 'h', rank: '3' },
|
||
{ suit: 'h', rank: '4' },
|
||
{ suit: 'h', rank: '5' },
|
||
{ suit: 'h', rank: '6' },
|
||
{ suit: 'h', rank: '7' },
|
||
{ suit: 'h', rank: '8' },
|
||
{ suit: 'h', rank: '9' },
|
||
{ suit: 'h', rank: 'T' },
|
||
{ suit: 'h', rank: 'J' },
|
||
{ suit: 'h', rank: 'Q' },
|
||
{ suit: 'h', rank: 'K' },
|
||
{ suit: 'h', rank: 'A' },
|
||
{ suit: 'c', rank: '2' },
|
||
{ suit: 'c', rank: '3' },
|
||
{ suit: 'c', rank: '4' },
|
||
{ suit: 'c', rank: '5' },
|
||
{ suit: 'c', rank: '6' },
|
||
{ suit: 'c', rank: '7' },
|
||
{ suit: 'c', rank: '8' },
|
||
{ suit: 'c', rank: '9' },
|
||
{ suit: 'c', rank: 'T' },
|
||
{ suit: 'c', rank: 'J' },
|
||
{ suit: 'c', rank: 'Q' },
|
||
{ suit: 'c', rank: 'K' },
|
||
{ suit: 'c', rank: 'A' },
|
||
{ suit: 'd', rank: '2' },
|
||
{ suit: 'd', rank: '3' },
|
||
{ suit: 'd', rank: '4' },
|
||
{ suit: 'd', rank: '5' },
|
||
{ suit: 'd', rank: '6' },
|
||
{ suit: 'd', rank: '7' },
|
||
{ suit: 'd', rank: '8' },
|
||
{ suit: 'd', rank: '9' },
|
||
{ suit: 'd', rank: 'T' },
|
||
{ suit: 'd', rank: 'J' },
|
||
{ suit: 'd', rank: 'Q' },
|
||
{ suit: 'd', rank: 'K' },
|
||
{ suit: 'd', rank: 'A' },
|
||
{ suit: '1', rank: '0' },
|
||
{ suit: '2', rank: '0' },
|
||
]
|
||
|
||
while (deck.length > 0) {
|
||
let index = Math.floor(Math.random() * deck.length)
|
||
let card = deck[index]
|
||
players[currentPlayerNumber].cards.push(card)
|
||
deck.splice(index, 1)
|
||
currentPlayerNumber = (currentPlayerNumber + 1) % 3
|
||
}
|
||
|
||
gameStatus()
|
||
}
|
||
|
||
function gameStatus() {
|
||
const cardsNumbers = []
|
||
|
||
for (let player of players) {
|
||
cardsNumbers.push(player.cards.length)
|
||
}
|
||
|
||
const cardsStrings = []
|
||
for (let card of cardsOnTable) {
|
||
cardsStrings.push(`${card.rank}${card.suit}`)
|
||
}
|
||
|
||
IO.emit('status', {
|
||
players: cardsNumbers,
|
||
cards: cardsStrings,
|
||
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.rank}${card.suit}]`)
|
||
|
||
// 判断有没有钓到
|
||
let i = 0
|
||
let getit = false
|
||
for (i = 0; i < cardsOnTable.length; i++) {
|
||
if (cardsOnTable[i].rank == card.rank) {
|
||
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) {
|
||
players[winner - 1].emit('alert', '你赢了!')
|
||
players[winner - 1].broadcast.emit('alert', `玩家${winner} 获胜了!`)
|
||
gameFinished()
|
||
}
|
||
}
|
||
}
|
||
|
||
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 })
|
||
}
|