初步测试完毕

This commit is contained in:
赵鑫 2022-08-20 16:10:01 +08:00
parent dfc3d1759d
commit 204729d5d9
3 changed files with 193 additions and 192 deletions

View File

@ -1,50 +1,51 @@
const player = io() const player = io()
let myNumber = 0 let my_number = 0
let autoPlayer = 0 let auto_play = false
buttonAuto.addEventListener('click', () => {
auto_play = !auto_play
if (auto_play) player.emit('go')
buttonAuto.style.color = auto_play ? 'red' : 'black'
})
player.on('online', (number) => (online.innerText = number))
player.on('players', (number) => (players.innerText = number))
player.on('alert', (message) => { player.on('alert', (message) => {
alert(message) const alert = document.createElement('li')
}) alert.innerText = message
messages.appendChild(alert)
player.on('onlineNumber', (number) => { while (messages.childElementCount > 5) messages.childNodes[0].remove()
onlineNumber.innerText = number
})
player.on('playersNumber', (number) => {
playersNumber.innerText = number
}) })
player.on('join', (number) => { player.on('join', (number) => {
myNumber = number my_number = number
playerNumber.innerText = number player_number.innerText = number
buttonJoin.innerText = number == 0 ? '加入' : '退出' buttonJoin.innerText = number ? '退出' : '加入'
buttonJoin.style.color = number == 0 ? 'red' : 'black' buttonJoin.style.color = number ? 'black' : 'red'
}) })
player.on('status', (status) => { player.on('status', (status) => {
const { players, cards, current } = status const { players, cards, current } = status
// 更新玩家剩余牌数的显示
player1.innerText = '🎴'.repeat(players[0] || 0) player1.innerText = '🎴'.repeat(players[0] || 0)
player2.innerText = '🎴'.repeat(players[1] || 0) player2.innerText = '🎴'.repeat(players[1] || 0)
player3.innerText = '🎴'.repeat(players[2] || 0) player3.innerText = '🎴'.repeat(players[2] || 0)
currentPlayerNumber.innerText = current + 1 // 更新桌面上牌的显示
buttonGo.style.color = myNumber > 0 && myNumber === current + 1 ? 'red' : 'black' table.innerHTML = ''
cardsDisplay.innerHTML = ''
for (let cid of cards) { for (let cid of cards) {
let card = document.createElement('card-t') let card = document.createElement('card-t')
card.setAttribute('cid', cid) card.setAttribute('cid', cid)
card.setAttribute('backcolor', cid[1] == 1 ? 'black' : 'red')
card.setAttribute('backtext', 'JOKER') card.setAttribute('backtext', 'JOKER')
cardsDisplay.appendChild(card) card.setAttribute('backcolor', cid[1] == 1 ? 'black' : 'red')
table.appendChild(card)
} }
}) // 依据当前玩家更新相关显示
currentPlayerNumber.innerText = current
buttonAuto.addEventListener('click', () => { if (my_number > 0 && my_number == current) {
if (autoPlayer != 0) { if (auto_play) player.emit('go')
clearInterval(autoPlayer) else buttonGo.style.color = 'red'
autoPlayer = 0
buttonAuto.style.color = 'black'
} else { } else {
autoPlayer = setInterval(() => player.emit('go'), 1000) buttonGo.style.color = 'black'
buttonAuto.style.color = 'red'
} }
}) })

View File

@ -4,12 +4,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" ,content="width=device-width, initial-scale=1.0"> <meta name="viewport" ,content="width=device-width, initial-scale=1.0">
<link <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
href="data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAANDQ0AHFxcQBPT08AjIyMAAsLCwAUFBQA0tLSAHNzcwDb29sAJiYmAOTk5AAvLy8A7e3tAMLCwgAEBAQA9vb2AMvLywD///8AqampALu7uwCQkJAAMTExAAYGBgD4+PgA1tbWAImJiQDx8fEAMzMzADw8PAD6+voApKSkAOHh4QABAQEANTU1AAoKCgD8/PwAPj4+ABMTEwDa2toA4+PjAOzs7ACNjY0AYmJiAAMDAwDBwcEAysrKAAwMDAD+/v4AUlJSAOXl5QCGhoYAurq6AFtbWwAwMDAA7u7uAPf39wDV1dUA3t7eAOfn5wAyMjIAxcXFAAcHBwCampoAzs7OABkZGQDX19cAtbW1ACsrKwDp6ekAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEhIQEwgdCjY8RBYrKhsSEhISEhIkCQMAAEQ9GyQSEhISEhISEhIbAQUgEhISEhISEhISOhQnEh8VEjIuKRISEhISLSMhLCoJOTQ+IQYOEhISN0EAAAAACAQ+AAAALygkEjQAAAAAAA8XAAAAAAA/CxJFIwAAAAAAAAAAAAAABx4SEjMAAAAAAAAAAAAAIh4SEhIYMQAAAAAAAAAAJkASEhISEjgCAAAAAAAADEISEhISEhISMBoAAAAAJTsSEhISEhISEhISMwAAFkUSEhISEhISEhISEh4cABESEhISEhISEhISEhISQzUSEhISEhISEhISEhISEg0ZEhISEhISEgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
rel="icon" type="image/x-icon" />
<!-- <link rel="shortcut icon" href="data:" type="image/x-icon"> -->
<title>小猫钓鱼</title> <title>小猫钓鱼</title>
<style> <style>
card-t { card-t {
display: inline-block; display: inline-block;
@ -22,9 +18,7 @@
<body> <body>
<h1>小猫钓鱼</h1> <h1>小猫钓鱼</h1>
<!-- <card-t cid="Qs"></card-t> --> <p>[ 在线 <var id="online">0</var> ] [ 玩家 <var id="players">0</var> ] [ 我是 玩家<var id="player_number">0</var>
<p>[ 在线 <var id="onlineNumber">0</var> ] [ 玩家 <var id="playersNumber">0</var> ] [ 我是 玩家<var
id="playerNumber">0</var>
] [ 当前 玩家<var id="currentPlayerNumber">0</var> ] [ 当前 玩家<var id="currentPlayerNumber">0</var>
]</p> ]</p>
<p>玩家1 <var id="player1"></var></p> <p>玩家1 <var id="player1"></var></p>
@ -36,8 +30,8 @@
<button id="buttonAuto">自动</button> <button id="buttonAuto">自动</button>
</p> </p>
<p id="cardsDisplay"></p> <p id="table"></p>
<ul id="messages" style="color:red;"></ul>
<!-- https://github.com/cardmeister/cardmeister.github.io --> <!-- https://github.com/cardmeister/cardmeister.github.io -->
<script src="/elements.cardmeister.min.js"></script> <script src="/elements.cardmeister.min.js"></script>

316
server.js
View File

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