xiaomaodiaoyu/server.js
2022-08-18 16:38:43 +08:00

218 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const express = require('express')
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 = [] // 所有玩家
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 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 gameStatus() {
const cardsNumbers = []
for (let player of players) {
cardsNumbers.push(player.cards.length)
}
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 })
}