const express = require('express'); const cors = require('cors') var app = express() var http = require('http').Server(app); var io = require('socket.io')(http); const jwtSecret = 'AjnjLhjxM' const { verify } = require('jsonwebtoken') app.use(express.static('public')) app.use(cors()) let gamers = [] let cleanSocket = gamer => { let {socket, ...copy} = gamer return copy } let emitGamers = () => io.emit('gamers', gamers.map(cleanSocket)) let thisGamer = s => gamers.filter(g => g.socket === s) [0] let gamerById = id => gamers.filter(g => g.id === id)[0] const dice = () => Math.ceil(Math.random()*6) const startBoard = () => [ {color: 'white', count: 15}, {color: 'white', count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, {color: 'black', count: 15}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, ] const turnValidate = (before, dice, after) => { dice.sort() const from = [] const to = [] //count check: const moveCalc = (column, dice) => (column + dice) % 24; const countChecker = (arr) => { const stats = arr.reduce((a, b) => ((b.color && (a[b.color]+=b.count)), a), {white: 0, black: 0}) console.log(stats) return 15 === stats.black && stats.white === 15; } if (!countChecker(before) || !countChecker(after)) return {error: '15'} let fromCount = 0; let toCount = 0; before.forEach( (column, i) => (column.count > after[i].count) && from.push(i) && (fromCount+=column.count - after[i].count)) before.forEach( (column, i) => column.count < after[i].count && to.push(i) && (toCount-=column.count - after[i].count)) console.log(fromCount, toCount, from, to) if (before[from[0]].color !== after[to[0]].color) return {error: 'colors wrong'} if (from.length === 2 && before[from[0]].color !== before[from[1]].color) return {error: 'colors wrong'} if (to.length === 2 && after[to[0]].color !== after[to[1]].color) return {error: 'colors wrong'} if (before[to[0]].color && before[to[0]].color !== after[to[0]].color) return {error: 'forbidden'} if (to[1] && before[to[1]].color && before[to[1]].color !== after[to[1]].color) return {error: 'forbidden'} if (fromCount === 2){ if (from.length === 1 && to.length === 1){ if (dice[0] !== dice[1] || moveCalc(from[0], dice[0]) !== to[0]) {return {error: 'error move two 1 to another 1'}} } if (from.length === 1 && to.length === 2){ if (dice[0] === dice[1] || moveCalc(from[0], dice[0]) !== to[0] || moveCalc(from[0], dice[1]) !== to[1]) return {error: 'error move two 1 to another 2'} } if (from.length === 2 && to.length === 1){ if (dice[0] === dice[1] || moveCalc(from[0], dice[1]) !== to[0] || moveCalc(from[1], dice[0]) !== to[0]) return {error: 'error move two 2 to another 1'} } if (from.length === 2 && to.length === 2){ if (moveCalc(from[0], dice[0]) === to[0] && moveCalc(from[1], dice[1]) === to[1]) return {ok: 'ok'} if (moveCalc(from[0], dice[1]) === to[1] && moveCalc(from[1], dice[0]) === to[0]) return {ok: 'ok'} return {error: 'hz'} } return {ok: 'ok'} } if (fromCount === 1){ if (moveCalc(from[0], dice[0] + dice[1]) !== to[0]) return {error: 'error dice sum'} let passThrough = [before[moveCalc(from[0], dice[0])], before[moveCalc(from[0], dice[1])]] if ((passThrough[0].color && passThrough[0].count && passThrough[0].color !== before[from[0]].color) || (passThrough[1].color && passThrough[1].count && passThrough[1].color !== before[from[0]].color)) return {error: 'forbidden passThrough'} return {ok: 'ok'} } return {error: 'count wrong'} //dice check } //console.log(turnValidate(startBoard(), [5,4], [ //{color: 'white', count: 14}, //{color: 'white', count: 0}, {color: 'white', count: 0}, { count: 0}, {color: 'black' ,count: 1}, {color: 'black', count: 1}, {color: 'white', count: 0}, { count: 0}, { count: 0}, {color:'white', count: 1}, { count: 0}, { count: 0}, //{color: 'black', count: 13}, //{ count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, { count: 0}, //])) io.on('connection', socket => { socket.emit('hi', {id: socket.id}) socket.on('disconnect', () => { gamers = gamers.filter(n => n.socket !== socket) emitGamers() }); socket.on('conn', token => { const decoded = verify(token, jwtSecret) if (decoded){ gamers.push({nick: decoded.sub.login, socket: socket, id: socket.id}) } else { socket.emit("error", 'jwt failed') } emitGamers() }) socket.on('newGame', msg => { let gamer = thisGamer(socket) gamer.newGame = msg.newGame emitGamers() }) socket.on('startGame', ({id}) => { let gamer = thisGamer(socket) let enemy = gamerById(id) //console.log(id, gamers) if (enemy && enemy.newGame){ gamer.inGameWith = enemy.id enemy.inGameWith = gamer.id gamer.turn = Math.random() > 0.5 enemy.turn = !gamer.turn } gamer.socket.emit('startGame', cleanSocket(gamer)) enemy.socket.emit('startGame', cleanSocket(enemy)) const whoTurn = gamer.turn ? gamer : enemy whoTurn.socket.emit('turn', {board: startBoard(), dice: [dice(), dice()]}) whoTurn.lastBoard = {board: startBoard(), dice: [dice(), dice()]} emitGamers() }) socket.on('turn', data => { let gamer = thisGamer(socket) let enemy = gamerById(gamer.inGameWith) if (gamer && enemy && gamer.inGameWith === enemy.id && enemy.inGameWith === gamer.id && gamer.turn){ gamer.turn = !gamer.turn enemy.turn = !enemy.turn enemy.lastBoard = data data = {...data, dice: [dice(), dice()]} gamer.socket.emit('dice', data.dice) enemy.socket.emit('turn', data) } }) socket.on('validate', data => { socket.emit('validate',{data, result: turnValidate(...data)}) }) }); http.listen(4000, function(){ console.log(`listening`); });