diff --git a/client/index.html b/client/index.html index 460ad6c..6a97c80 100644 --- a/client/index.html +++ b/client/index.html @@ -36,18 +36,18 @@

Připojit se

- +

Chyba!

- +

Soukromá Hra

-

Zvací kód: A5G3D

-

Hráč bílý: Test

+

Zvací kód: -

+

Hráč bílý: -

Hráč černý: -

diff --git a/client/javascript/menu.js b/client/javascript/menu.js index e007f3c..3a57043 100644 --- a/client/javascript/menu.js +++ b/client/javascript/menu.js @@ -8,6 +8,14 @@ function hide(id){ document.getElementById(id).style.display = "none"; } +function message(text){ + alert(text); +} + +function getValue(id){ + return document.getElementById(id).value; +} + function getUserName(){ if (userName == "") { userName = document.getElementById("nickname").value; @@ -45,6 +53,8 @@ function createGame(){ if(response.status == "success"){ hide("loader"); show("lobby"); + setText("whitePlayer", userName); + setText("inviteCode", response.inviteCode); }else{ alert("fck"); } @@ -60,11 +70,61 @@ function joinWithCode(){ show("code-entry"); } +function confirmJoinWithCode(){ + inviteCode = getValue("code"); + + if(inviteCode == ""){ + message("zadej musíš zadat kód hry"); + return; + } + + + setText("loaderText", "Hledám Hru"); + resetMenu(); + show("loader"); + + socket.emit("joinWithCodeRequest", {userName, inviteCode}, (response) =>{ + switch(response.status){ + case "error": + resetMenu(); + setText("errorMessage", response.message); + show("alert"); + break; + case "success": + resetMenu(); + show("lobby"); + + const whitePlayerName = (response.playerSwap) ? response.player2_name : response.player1_name; + const blackPlayerName = (response.playerSwap) ? response.player1_name : response.player2_name; + + setText("whitePlayer", whitePlayerName); + setText("blackPlayer", blackPlayerName); + setText("inviteCode", response.inviteCode); + show("lobby"); + } + + }) + + +} + function backToMainMenu(){ resetMenu(); show("main-menu"); } +socket.on('playerJoinGame', ({player1_name, layer1_name, player2_name, playerSwap}) => { + + const whitePlayerName = (playerSwap) ? player2_name : player1_name; + const blackPlayerName = (playerSwap) ? player1_name : player2_name; + + setText("whitePlayer", whitePlayerName); + setText("blackPlayer", blackPlayerName); + + +}) + + show("main-menu"); hide("game"); diff --git a/server/communication.js b/server/communication.js index 4e75e40..1acb3e1 100644 --- a/server/communication.js +++ b/server/communication.js @@ -12,6 +12,8 @@ const io = require('socket.io')(server, { }); const Game = require("./schemas/game-schema"); +const GameLogic = require('./game-logic.js'); + const databaseUrl = "mongodb://dama:dama@localhost:27017/dama"; const chance = new Chance(); @@ -23,7 +25,55 @@ io.on('connection', (socket) => { socket.on('disconnect', async () => { console.log('user disconnected'); - await Game.deleteMany({owner}); + await Game.deleteMany({owner:socket.id}); + }) + + socket.on('leaveGame', async () => { + await Game.deleteMany({owner:socket.id}); + }) + + socket.on('joinWithCodeRequest', async ({userName, inviteCode}, callback) => { + const game = await Game.findOne({"inviteCode":inviteCode}); + + if(!game){ + callback({status:"error", message:"Nebyly nalezeny žádné hry"}); + return; + } + + if(game.player1 != null && game.player2 != null){ + callback({status:"error", message:"Místnost je plná"}) + } + + other_player = null; + + if(game.player1 == null){ + game.player1 = socket.id; + game.player1_name = userName; + + other_player = game.player2; + }else{ + game.player2 = socket.id; + game.player2_name = userName; + + other_player = game.player1; + } + + await game.save(); + + + const player1 = game.player1; + const player1_name = game.player1_name; + const player2 = game.player2_name; + const player2_name = game.player2_name; + const playerSwap = game.playerSwap; + + callback({status:"success", player1:player1, player1_name:player1_name, player2:player2, player2_name:player2_name, playerSwap:playerSwap}) + io.sockets.sockets.get(other_player).emit('playerJoinGame', {player1, player1_name, player2, player2_name, playerSwap}); + socket.join(game.roomId); + + + + }) socket.on('createGameRequest', ({userName}, callback) => { @@ -31,6 +81,10 @@ io.on('connection', (socket) => { const roomId = chance.guid(); const inviteCode = chance.string({ length: 5, casing: 'upper', alpha: true, numeric: true, symbols: false }); + const gameLogic = new GameLogic(); + gameLogic.generateDefaultPositions(); + const pieceList = gameLogic.pieceList; + socket.join(roomId); newGame = new Game({ owner: socket.id, @@ -39,22 +93,13 @@ io.on('connection', (socket) => { player2: null, player2_name: null, channel: roomId, - white: 1, - black: 2, + playerSwap: false, public: false, started: false, inviteCode: inviteCode, currentPlayer: null, - missedOportunities: [String], - pieces: [ - { - id: Integer, - x: Integer, - y: Integer, - player: String, - type: String - } - ] + missedOportunities: [], + pieces: pieceList }); newGame.save(); diff --git a/server/game-logic.js b/server/game-logic.js index 2927f6e..519d204 100644 --- a/server/game-logic.js +++ b/server/game-logic.js @@ -1,306 +1,311 @@ - - -const pieceList = new Array(); -missedOportunities = new Array(); -currentPlayer = "white"; - -function isMissedOportunity(pieceRecord) { - const id = pieceRecord.id; - return missedOportunities.includes(id); -} - -function generateDefaultPositions(){ +class GameLogic{ - var id = 0; - - for (let i = 0; i < 8; i++) { - for (let j = 0; j < 3; j++) { - if((i+j) % 2 == 0){ - pieceRecord = {id:id, x:i, y:j, player:"white", type:"basic"}; - pieceList.push(pieceRecord); - id++; + constructor(pieceList = [], missedOportunities = [], currentPlayer = "white") { + this.pieceList = pieceList; + this.missedOportunities = missedOportunities; + this.currentPlayer = currentPlayer; + } + + isMissedOportunity(pieceRecord) { + const id = pieceRecord.id; + return this.missedOportunities.includes(id); + } + + generateDefaultPositions(){ + + var id = 0; + + for (let i = 0; i < 8; i++) { + for (let j = 0; j < 3; j++) { + if((i+j) % 2 == 0){ + const pieceRecord = {id:id, x:i, y:j, player:"white", type:"basic"}; + this.pieceList.push(pieceRecord); + id++; + } + } - } - } - for (let i = 0; i < 8; i++) { - for (let j = 5; j < 8; j++) { - if((i+j) % 2 == 0){ - pieceRecord = {id:id, x:i, y:j, player:"black", type:"basic"}; - pieceList.push(pieceRecord); - id++; + for (let i = 0; i < 8; i++) { + for (let j = 5; j < 8; j++) { + if((i+j) % 2 == 0){ + const pieceRecord = {id:id, x:i, y:j, player:"black", type:"basic"}; + this.pieceList.push(pieceRecord); + id++; + } + } - } } -} -function getPieceRecord(x,y){ - if (x > 7 || x < 0 || y > 7 || y < 0) { - return false; + getPieceRecord(x,y){ + if (x > 7 || x < 0 || y > 7 || y < 0) { + return false; + } + return this.pieceList.find(pieceRecord => pieceRecord.x == x && pieceRecord.y == y); } - return pieceList.find(pieceRecord => pieceRecord.x == x && pieceRecord.y == y); -} -function nukePieceRecord(pieceRecord) { - const index = pieceList.findIndex(record => record.id == pieceRecord.id); - pieceList.splice(index, 1); -} + nukePieceRecord(pieceRecord) { + const index = this.pieceList.findIndex(record => record.id == pieceRecord.id); + this.pieceList.splice(index, 1); + } -function updatePieceRecord(pieceRecord) { - const index = pieceList.findIndex(record => record.id == pieceRecord.id); - pieceList[index] = pieceRecord; -} + updatePieceRecord(pieceRecord) { + const index = this.pieceList.findIndex(record => record.id == pieceRecord.id); + this.pieceList[index] = pieceRecord; + } -function updatePieceRecordPosition(pieceRecord, x, y) { - pieceRecord.x = x; - pieceRecord.y = y; - updatePieceRecord(pieceRecord); - return pieceRecord; -} + updatePieceRecordPosition(pieceRecord, x, y) { + pieceRecord.x = x; + pieceRecord.y = y; + this.updatePieceRecord(pieceRecord); + return pieceRecord; + } -function getCasualties(oldX, oldY, newX, newY) { - const directionX = (newX > oldX) ? 1 : -1; - const directionY = (newY > oldY) ? 1 : -1; + getCasualties(oldX, oldY, newX, newY) { + const directionX = (newX > oldX) ? 1 : -1; + const directionY = (newY > oldY) ? 1 : -1; - const casualties = new Array(); + const casualties = new Array(); - for (let i = 1; i < (Math.abs(newY - oldY) + 1); i++) { - const x = oldX + (i*directionX); - const y = oldY + (i*directionY); - - pieceRecord = getPieceRecord(x,y); + for (let i = 1; i < (Math.abs(newY - oldY) + 1); i++) { + const x = oldX + (i*directionX); + const y = oldY + (i*directionY); + + pieceRecord = this.getPieceRecord(x,y); - if (pieceRecord) { - casualties.push(pieceRecord); + if (pieceRecord) { + casualties.push(pieceRecord); + + } } - + return casualties; } - return casualties; -} -function getLoser() { - if (!pieceList.find(pieceRecord => pieceRecord.player == "white")) { - return "white"; - } - if (!pieceList.find(pieceRecord => pieceRecord.player == "black")) { - return "black"; + getLoser() { + if (!this.pieceList.find(pieceRecord => pieceRecord.player == "white")) { + return "white"; + } + if (!this.pieceList.find(pieceRecord => pieceRecord.player == "black")) { + return "black"; + } + return null; } - return null; -} -function continuableInDirectionForQueen(directionX, directionY, pieceRecord) { - - const pieceX = pieceRecord.x; - const pieceY = pieceRecord.y; - const player = pieceRecord.player; + continuableInDirectionForQueen(directionX, directionY, pieceRecord) { - for (let i = 1; i < 8; i++) { - const x = pieceX + (i*directionX); - const y = pieceY + (i*directionY); - - if(x > 7 || x < 0 || y > 7 || y < 0 || (x+directionX) > 7 || (x+directionX) < 0 || (y+directionY) > 7 || (y+directionY) < 0 ){ - - return false; - } - - const record = getPieceRecord(x, y); + const pieceX = pieceRecord.x; + const pieceY = pieceRecord.y; + const player = pieceRecord.player; + + for (let i = 1; i < 8; i++) { + const x = pieceX + (i*directionX); + const y = pieceY + (i*directionY); - if (record) { - if (record.player == player) { + if(x > 7 || x < 0 || y > 7 || y < 0 || (x+directionX) > 7 || (x+directionX) < 0 || (y+directionY) > 7 || (y+directionY) < 0 ){ return false; } - const firstBlockRecord = getPieceRecord(x+directionX,y+directionY); - const secondBlockRecord = getPieceRecord(x-directionX,y-directionY); - + const record = this.getPieceRecord(x, y); - return ((!firstBlockRecord || firstBlockRecord.id == pieceRecord.id) && (!secondBlockRecord || secondBlockRecord.id == pieceRecord.id)); - + if (record) { + if (record.player == player) { + + return false; + } + + const firstBlockRecord = this.getPieceRecord(x+directionX,y+directionY); + const secondBlockRecord = this.getPieceRecord(x-directionX,y-directionY); + + + return ((!firstBlockRecord || firstBlockRecord.id == pieceRecord.id) && (!secondBlockRecord || secondBlockRecord.id == pieceRecord.id)); + + + } } - - } - return false; -} -function continuable(pieceRecord){ - const x = pieceRecord.x; - const y = pieceRecord.y; - const player = pieceRecord.player; - const type = pieceRecord.type; - - if(player == "white" && ((getPieceRecord(x+1, y+1) && getPieceRecord(x+1, y+1).player != player && !getPieceRecord(x+2, y+2) && (y+2) < 8 && (x+2) < 8) || ((getPieceRecord(x-1, y+1) && getPieceRecord(x-1, y+1).player != player && !getPieceRecord(x-2, y+2) && (y+2) < 8 && (x-2) > 0)))){ - - return true; + return false; } + continuable(pieceRecord){ + const x = pieceRecord.x; + const y = pieceRecord.y; + const player = pieceRecord.player; + const type = pieceRecord.type; - if( player == "black" && ((getPieceRecord(x+1, y-1) && getPieceRecord(x+1, y-1).player != player && !getPieceRecord(x+2, y-2) && (y-2) > 0 && (x+2) < 8) || ((getPieceRecord(x-1, y-1) && getPieceRecord(x-1, y-1).player != player && !getPieceRecord(x-2, y-2) && (y-2) > 0 && (x-2) > 0)))){ + if(player == "white" && ((this.getPieceRecord(x+1, y+1) && this.getPieceRecord(x+1, y+1).player != player && !this.getPieceRecord(x+2, y+2) && (y+2) < 8 && (x+2) < 8) || ((this.getPieceRecord(x-1, y+1) && this.getPieceRecord(x-1, y+1).player != player && !this.getPieceRecord(x-2, y+2) && (y+2) < 8 && (x-2) > 0)))){ - return true; - } - - if(type == "queen"){ + return true; + } + + if( player == "black" && ((this.getPieceRecord(x+1, y-1) && this.getPieceRecord(x+1, y-1).player != player && !this.getPieceRecord(x+2, y-2) && (y-2) > 0 && (x+2) < 8) || ((this.getPieceRecord(x-1, y-1) && this.getPieceRecord(x-1, y-1).player != player && !this.getPieceRecord(x-2, y-2) && (y-2) > 0 && (x-2) > 0)))){ + + return true; + } - return (continuableInDirectionForQueen(1,1,pieceRecord) || continuableInDirectionForQueen(-1,-1,pieceRecord) || continuableInDirectionForQueen(-1,1,pieceRecord) || continuableInDirectionForQueen(1,-1,pieceRecord)); + if(type == "queen"){ + + return (this.continuableInDirectionForQueen(1,1,pieceRecord) || this.continuableInDirectionForQueen(-1,-1,pieceRecord) || this.continuableInDirectionForQueen(-1,1,pieceRecord) || this.continuableInDirectionForQueen(1,-1,pieceRecord)); + } + + return false; } - return false; -} + getOportunities(pieceRecord){ + const player = pieceRecord.player; + const opportunities = new Array(); + + this.pieceList.forEach(record => { + if (record.player == player && record != pieceRecord && this.continuable(record)) { + + opportunities.push(record.id); + } + }); -function getOportunities(pieceRecord){ - const player = pieceRecord.player; - const opportunities = new Array(); + return opportunities; + } - pieceList.forEach(record => { - if (record.player == player && record != pieceRecord && continuable(record)) { - - opportunities.push(record.id); - } - }); + getOportunitiesIncludingSelf(pieceRecord){ + const player = pieceRecord.player; + const opportunities = new Array(); - return opportunities; -} + this.pieceList.forEach(record => { + if (record.player == player && this.continuable(record)) { + + opportunities.push(record.id); + } + }); -function getOportunitiesIncludingSelf(pieceRecord){ - const player = pieceRecord.player; - const opportunities = new Array(); + return opportunities; + } - pieceList.forEach(record => { - if (record.player == player && continuable(record)) { - - opportunities.push(record.id); + isMoveValid(pieceRecord, x, y){ + + + if(0 > y > 7 || 0 > x > 7){ + return false; } - }); - return opportunities; -} + if (this.getPieceRecord(x,y)) { + return false; + } -function isMoveValid(pieceRecord, x, y){ - - - if(0 > y > 7 || 0 > x > 7){ - return false; - } + const currentX = pieceRecord.x; + const currentY = pieceRecord.y; - if (getPieceRecord(x,y)) { - return false; - } + if (Math.abs(y - currentY) != Math.abs(x - currentX)) { + return false; + } - const currentX = pieceRecord.x; - const currentY = pieceRecord.y; + const player = pieceRecord.player; + const type = pieceRecord.type; - if (Math.abs(y - currentY) != Math.abs(x - currentX)) { - return false; - } + //Check correct Y direction if piece is basic + if (currentY > y && player == "white" && type == "basic") { + return false; + } - const player = pieceRecord.player; - const type = pieceRecord.type; - //Check correct Y direction if piece is basic - if (currentY > y && player == "white" && type == "basic") { - return false; - } + const directionY = (y > currentY) ? 1 : -1; + const directionX = (x > currentX) ? 1 : -1; + space = 0; + piecesInWay = 0; - const directionY = (y > currentY) ? 1 : -1; - const directionX = (x > currentX) ? 1 : -1; + for (let i = 1; i < (Math.abs(y-currentY)+1); i++) { + + const nowX = currentX + (i*directionX); + const nowY = currentY + (i*directionY); - space = 0; - piecesInWay = 0; + if (inWayPieceRecord = this.getPieceRecord(nowX, nowY)) { - for (let i = 1; i < (Math.abs(y-currentY)+1); i++) { - - const nowX = currentX + (i*directionX); - const nowY = currentY + (i*directionY); + if(inWayPieceRecord.player == player){ + return false; + } - if (inWayPieceRecord = getPieceRecord(nowX, nowY)) { + space = 0; + piecesInWay++; + }else{ + space++; + piecesInWay = 0; + } - if(inWayPieceRecord.player == player){ + if(piecesInWay > 1){ return false; } - space = 0; - piecesInWay++; - }else{ - space++; - piecesInWay = 0; + if (space > 1 && type == "basic") { + return false; + } + } - if(piecesInWay > 1){ - return false; - } + return true; + + } + swapPlayers() { + this.currentPlayer = (this.currentPlayer == "white") ? "black" : "white"; + } - if (space > 1 && type == "basic") { - return false; + makeMove(pieceRecord, x, y){ + const player = pieceRecord.player; + + if (!isMoveValid(pieceRecord, x, y)) { + return 0; } - } + const oldX = pieceRecord.x; + const oldY = pieceRecord.y; - return true; - -} -function swapPlayers() { - currentPlayer = (currentPlayer == "white") ? "black" : "white"; -} + const casualties = this.getCasualties(oldX, oldY, x, y); -function makeMove(pieceRecord, x, y){ - const player = pieceRecord.player; - - if (!isMoveValid(pieceRecord, x, y)) { - return 0; - } - - const oldX = pieceRecord.x; - const oldY = pieceRecord.y; + + casualties.forEach(casualty => { + this.nukePieceRecord(casualty); + }); - const casualties = getCasualties(oldX, oldY, x, y); + this.missedOportunities = new Array(); + oportunities = this.getOportunitiesIncludingSelf(pieceRecord); - - casualties.forEach(casualty => { - nukePieceRecord(casualty); - }); + if(casualties.length == 0 && oportunities.length != 0) { + this.missedOportunities = oportunities; + + } - missedOportunities = new Array(); - oportunities = getOportunitiesIncludingSelf(pieceRecord); + const original_type = pieceRecord.type; - if(casualties.length == 0 && oportunities.length != 0) { - missedOportunities = oportunities; + if ((player == "white" && y == 7) || (player == "black" && y == 0) && pieceRecord.type == "basic") { - } - - const original_type = pieceRecord.type; + pieceRecord.type = "queen"; + + } - if ((player == "white" && y == 7) || (player == "black" && y == 0) && pieceRecord.type == "basic") { + const updatedPieceRecord = updatePieceRecordPosition(pieceRecord, x, y); - pieceRecord.type = "queen"; + if (this.continuable(updatedPieceRecord) && casualties.length > 0 && pieceRecord.type == original_type) { + return 2; + } + + return 1; } - const updatedPieceRecord = updatePieceRecordPosition(pieceRecord, x, y); - - if (continuable(updatedPieceRecord) && casualties.length > 0 && pieceRecord.type == original_type) { - return 2; + nukePieceRecordThatMissedOportunity(pieceRecord) { + if (this.missedOportunities.includes(pieceRecord.id)) { + this.missedOportunities = new Array(); + this.nukePieceRecord(pieceRecord); + return true; + } + return false; } - - return 1; -} -function nukePieceRecordThatMissedOportunity(pieceRecord) { - if (missedOportunities.includes(pieceRecord.id)) { - missedOportunities = new Array(); - nukePieceRecord(pieceRecord); - return true; - } - return false; -} +} -generateDefaultPositions(); \ No newline at end of file +module.exports = GameLogic; \ No newline at end of file diff --git a/server/schemas/game-schema.js b/server/schemas/game-schema.js index ceef186..7297089 100644 --- a/server/schemas/game-schema.js +++ b/server/schemas/game-schema.js @@ -1,32 +1,30 @@ const mongoose = require("mongoose"); +const pieceSchema = new mongoose.Schema({ + id: Number, + x: Number, + y: Number, + player: String, + type: String + }); const gameSchema = new mongoose.Schema({ - owner: String, - player1: String, - player1_name: String, - player2: String, - player2_name: String, - channel: String, - white: String, - black: String, - public: Boolean, - started: Boolean, - inviteCode: String, - currentPlayer: String, - missedOportunities: [String], - pieces: [ - { - id: Number, - x: Number, - y: Number, - player: String, - type: String - } - ] + owner: { type: String, required:true, unique:true }, + player1: { type: String, default: null, unique:true }, + player1_name: { type: String, default: null }, + player2: { type: String, default: null, unique:true}, + player2_name: { type: String, default: null }, + channel: { type: String, required:true, unique:true}, + playerSwap: { type: Boolean, default: false }, + public: { type: Boolean, default: false }, + started: { type: Boolean, default: false }, + inviteCode: { type: String, default: null }, + currentPlayer: { type: Number, default: null }, + missedOportunities: {type: [String], default:[]}, + pieces: [pieceSchema] }); - + const Game = mongoose.model("Game", gameSchema, "games"); // Explicitly using "products" collection module.exports = Game;