socket.io node.js tic tac toe 逻辑问题

问题描述 投票:0回答:0

我正在使用 socket.io 和 node.js 开发井字游戏服务器端应用程序。 两个客户端通过端口 5050 连接到服务器,服务器也在端口 5050 上运行。 我面临的错误是事件触发器。 每当客户端输入一个值时,“输入”事件就会被多次调用。 下面附上我的代码。

server.js

const express = require("express")
const chalk = require("chalk")
const app  = express();
const http = require("http").createServer(app)
const io = require("socket.io")(http);
const board = require("./client/board")
const checkForWinner = require("./game_logic/logic");



let currentPlayer = 0;
let clients = [];
let isGameActive = false;
function switchPlayer(){
currentPlayer = (currentPlayer+1)%2;
}

function gameOver (){
    socket.emit("error", "Game ended")
}

// io.socket.setMaxListeners(20);
io.on('connection',(socket)=>{
    clients.push(socket.id)
    socket.emit("board",`
    ${board[0]}   ${board[1]}   ${board[2]}\n
    ${board[3]}   ${board[4]}   ${board[5]}\n
    ${board[6]}   ${board[7]}   ${board[8]}
    `)


    if(io.engine.clientsCount===1){
        socket.emit("waiting","Waiting for someone to join")
    }
    if(io.engine.clientsCount===2) isGameActive = true;
    //Emit a message event to know other clients that someone has joined
    socket.broadcast.emit("message", 'A user has connected', 'Game start')
    
    //Add event listeners for custom events
    socket.on('input', (value)=>{
        //value validation
        

        if(!isGameActive)
        {
            socket.emit("error", "wait for other players to join")
            return;
        }
        if(isNaN(value)){
            socket.emit("error", 'Enter a number only')
            return;
        }
        if (board[value-1] ===(chalk.bgGreenBright('X') || chalk.bgRedBright('Y'))){
            
            socket.emit("error", 'This box is already selected')
            return;
        }
        if(value<1 || value>9) {
            socket.emit("error", "Invalid input")
            return;
        }
        else{
            board[value-1] = (currentPlayer===0)? chalk.bgGreenBright('X') : chalk.bgRedBright('Y');
            // console.log(typeof board[value-1])
            console.log("times")
            switchPlayer();  //swich the player
            io.emit("board", `
            ${board[0]}   ${board[1]}   ${board[2]}\n
            ${board[3]}   ${board[4]}   ${board[5]}\n
            ${board[6]}   ${board[7]}   ${board[8]}
            `)
        }
        console.log("player is ", currentPlayer)
        let winner = checkForWinner()
        if(winner!='' && winner!=null && winner!=="tie"){
            io.emit('winner', winner)
        }
        else if (winner=="tie")
        {
            io.emit("tie")
        }
        // currentPlayer = (currentPlayer+1)%2;
    })

    //Add event listener for disconnect event
    socket.on("disconnect",()=>{
        console.log(`User disconnected : ${socket.id}`)
        socket.broadcast.emit('message', 'A user has disconnected')
    })
})



http.listen(5050, ()=>console.log("Node Server.js 5050"))

client.js

const io = require("socket.io-client")
const socket = io('http://localhost:5050')
const chalk = require("chalk")
require('events').EventEmitter.prototype._maxListeners = 100;  
const readline = require("readline")
    const rl =readline.createInterface({
        input:process.stdin
    });

let isInputReceived = false;
//print board on terminal and take the input
socket.on("board", (data)=>{
    // console.clear()
    console.log(chalk.yellow(data));
    if(!isInputReceived){
         rl.once('line', (input)=>{
        //Parse the user input
        // const value = input;
        isInputReceived = true
        socket.emit('input', input)   //emit 'input' event with a value
        // rl.pause()
    })
}
})

//Show if there is any error
socket.on("error", (msg)=>{
    console.log(msg)
})

socket.on('message', (arg,data)=>{
    console.log(arg)
    console.log(chalk.blue(data))
    console.log("Your turn")
})


socket.once("waiting", (data)=>{
    console.log(data)
})

socket.on('winner', (winner)=>{
    console.log(chalk.bold.green(`winner is ${winner}`))
})

socket.on('tie', ()=>{
    console.log(chalk.bold.red("Match is tie"))
})

逻辑.js 此文件包含游戏获胜逻辑

const board = require("../client/board")
// const chalk = require("chalk")

function checkForWinner(){
    const winningPositions=[
        //horizontal
        [0,1,2],
        [3,4,5],
        [6,7,8],
        //vertical
        [0,3,6,],
        [1,4,7],
        [2,5,8],
        //diagonal
        [0,4,8],
        [2,4,6]
    ];

    let winner ='';
    for(let i=0; i<winningPositions.length; i++){
        const [a,b,c]=winningPositions[i]
        if(board[a]===board[b] && board[b]===board[c]){
            winner = board[a]
        }
    }
    if (winner!==''){
        // io.emit('winner', winner)
        return winner;
    }
    else if(boarsIsFull()){
        // io.emit('tie');
        return "tie"
    }
}

function boarsIsFull(){
    return board.every(cell=>typeof cell=="string")
}


module.exports =checkForWinner;

如果您需要更多信息,请告诉我。

我尝试返回 rl.once('input'...) 我也确实删除了变量“isInputReceived”并在没有它的情况下继续。 在那种情况下,它从同一个客户那里获取输入并且没有问题。 但我们希望它能从两个客户那里得到意见。

node.js socket.io server-side tic-tac-toe
© www.soinside.com 2019 - 2024. All rights reserved.