* @constructor | * @constructor | ||||
*/ | */ | ||||
var Board = function() { | var Board = function() { | ||||
this.cells = []; | |||||
this.cups = []; | |||||
this.players = []; | this.players = []; | ||||
this.currentTurn = 0; | this.currentTurn = 0; | ||||
this.ready = false; | this.ready = false; | ||||
Board.events = { | Board.events = { | ||||
PLAYER_CONNECTED: 'playerConnected', | PLAYER_CONNECTED: 'playerConnected', | ||||
GAME_READY: 'gameReady', | GAME_READY: 'gameReady', | ||||
CELL_MARKED: 'cellMarked', | |||||
CUP_MARKED: 'cupMarked', | |||||
CHANGE_TURN: 'changeTurn', | CHANGE_TURN: 'changeTurn', | ||||
WINNER: 'winner', | WINNER: 'winner', | ||||
DRAW: 'draw' | DRAW: 'draw' | ||||
*/ | */ | ||||
Board.prototype.init = function() { | Board.prototype.init = function() { | ||||
for (var i = 0; i < 9; i++) { | for (var i = 0; i < 9; i++) { | ||||
this.cells.push({}); | |||||
this.cups.push({}); | |||||
} | } | ||||
}; | }; | ||||
Board.prototype.disableAll = function() { | Board.prototype.disableAll = function() { | ||||
this.cells.forEach(function(cell) { | |||||
cell.active = false; | |||||
this.cups.forEach(function(cup) { | |||||
cup.active = false; | |||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.enableAll = function() { | Board.prototype.enableAll = function() { | ||||
this.cells.forEach(function(cell) { | |||||
cell.active = true; | |||||
this.cups.forEach(function(cup) { | |||||
cup.active = true; | |||||
}); | }); | ||||
}; | }; | ||||
/** | /** | ||||
* | * | ||||
* @param cellId | |||||
* @param cupId | |||||
*/ | */ | ||||
Board.prototype.mark = function(cellId) { | |||||
var cell = this.cells[cellId]; | |||||
Board.prototype.mark = function(cupId) { | |||||
var cup = this.cups[cupId]; | |||||
if (!cell) { | |||||
if (!cup) { | |||||
return false; | return false; | ||||
} | } | ||||
if (this.ready && cell.active) { | |||||
if (this.ready && cup.active) { | |||||
var player = this.players[this.currentTurn]; | var player = this.players[this.currentTurn]; | ||||
cell.value = player.label; | |||||
cell.active = false; | |||||
cup.value = player.label; | |||||
cup.active = false; | |||||
this.emit(Board.events.CELL_MARKED, {cellId: cellId, player: player}); | |||||
this.emit(Board.events.CUP_MARKED, {cupId: cupId, player: player}); | |||||
var res = this.checkWinner(); | var res = this.checkWinner(); | ||||
if (res.win) { | if (res.win) { | ||||
var pos = []; | var pos = []; | ||||
var win = winPosition.some(function(win) { | var win = winPosition.some(function(win) { | ||||
if (this.cells[win[0]].value === player.label) { | |||||
var res = this.cells[win[0]].value === this.cells[win[1]].value && this.cells[win[1]].value === this.cells[win[2]].value; | |||||
if (this.cups[win[0]].value === player.label) { | |||||
var res = this.cups[win[0]].value === this.cups[win[1]].value && this.cups[win[1]].value === this.cups[win[2]].value; | |||||
if (res) { | if (res) { | ||||
pos = win; | pos = win; | ||||
* @returns {boolean} | * @returns {boolean} | ||||
*/ | */ | ||||
Board.prototype.checkDraw = function() { | Board.prototype.checkDraw = function() { | ||||
return this.cells.every(function(cell) { | |||||
return cell.value === this.players[0].label || cell.value === this.players[1].label; | |||||
return this.cups.every(function(cup) { | |||||
return cup.value === this.players[0].label || cup.value === this.players[1].label; | |||||
}, this); | }, this); | ||||
}; | }; | ||||
} | } | ||||
}; | }; | ||||
module.exports = Board; | |||||
module.exports = Board; |
0%{top: var(--top)} | 0%{top: var(--top)} | ||||
100%{top: var(--top325)} | 100%{top: var(--top325)} | ||||
} | } | ||||
::selection { | |||||
background: transparent; | |||||
} | |||||
.bgWhite { | |||||
background: #F5F2F5; | |||||
} | |||||
.colorWhite { | |||||
color: #F5F2F5 !important; | |||||
} | |||||
.bgDark { | |||||
background: #516D66; | |||||
} | |||||
.colorDark { | |||||
color: #516D66; | |||||
} | |||||
.bgRed { | |||||
background: #F286A0; | |||||
} | |||||
.colorRed { | |||||
color: #F286A0 !important; | |||||
} | |||||
.gameBoard, .scoreBoard { | |||||
font-weight: 400; | |||||
} | |||||
.gameBoard { | |||||
width: 100%; | |||||
} | |||||
.gameBoard td { | |||||
text-align: center; | |||||
color: #516D66; | |||||
font-size: 8em; | |||||
cursor: pointer; | |||||
transition: all 0.5s; | |||||
} | |||||
.gameCell { | |||||
width: 181px; | |||||
height: 181px; | |||||
} | |||||
.gameCell:not(.marked):hover { | |||||
box-shadow: 0 0 42px #555; | |||||
} | |||||
.gameBoard td.gameCell.notActive:hover, .gameBoard td.gameCell.notActive:active { | |||||
box-shadow: none !important; | |||||
cursor: default; | |||||
} | |||||
.scoreBoard { | |||||
color: #516D66; | |||||
height: 100px; | |||||
} | |||||
.boardCol { | |||||
width: 5px; | |||||
cursor: default !important; | |||||
} | |||||
.boardRow { | |||||
height: 5px; | |||||
cursor: default !important; | |||||
} | |||||
.scoreBoard span.active { | |||||
border-bottom: 4px solid #F286A0; | |||||
} |
* @constructor | * @constructor | ||||
*/ | */ | ||||
var Board = function(scoreBoard) { | var Board = function(scoreBoard) { | ||||
this.cells = []; | |||||
this.cups = []; | |||||
this.dom = document.createElement('table'); | this.dom = document.createElement('table'); | ||||
this.dom.addEventListener('click', this.mark.bind(this)); | this.dom.addEventListener('click', this.mark.bind(this)); | ||||
this.players = []; | this.players = []; | ||||
this.init(); | this.init(); | ||||
}; | }; | ||||
Board.prototype.onMark = function(cellId){}; | |||||
Board.prototype.onMark = function(cupId){}; | |||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
Board.prototype.init = function() { | Board.prototype.init = function() { | ||||
var row = document.createElement('tr'); | |||||
/* var row = document.createElement('tr'); | |||||
var rowCol = document.createElement('td'); | var rowCol = document.createElement('td'); | ||||
var col = document.createElement('td'); | var col = document.createElement('td'); | ||||
var cell = document.createElement('td'); | |||||
var cup = document.createElement('td'); | |||||
rowCol.classList.add('boardRow'); | rowCol.classList.add('boardRow'); | ||||
rowCol.classList.add('bgWhite'); | rowCol.classList.add('bgWhite'); | ||||
col.classList.add('boardCol'); | col.classList.add('boardCol'); | ||||
col.classList.add('bgWhite'); | col.classList.add('bgWhite'); | ||||
cell.classList.add('gameCell'); | |||||
cell.classList.add('notActive'); | |||||
cell.setAttribute('marked', 'false'); | |||||
cell.setAttribute('data-intent', 'gameCell'); | |||||
cup.classList.add('gamecup'); | |||||
cup.classList.add('notActive'); | |||||
cup.setAttribute('marked', 'false'); | |||||
cup.setAttribute('data-intent', 'gamecup'); | |||||
this.dom.classList.add('gameBoard'); | this.dom.classList.add('gameBoard'); | ||||
for (var i = 0; i < 9; i++) { | for (var i = 0; i < 9; i++) { | ||||
this.cells.push(cell.cloneNode(true)); | |||||
this.cups.push(cup.cloneNode(true)); | |||||
} | } | ||||
for (var r, i = 0; i < 9; i += 3) { | for (var r, i = 0; i < 9; i += 3) { | ||||
r = row.cloneNode(false); | r = row.cloneNode(false); | ||||
r.appendChild(this.cells[i]); | |||||
r.appendChild(this.cups[i]); | |||||
r.appendChild(col.cloneNode(false)); | r.appendChild(col.cloneNode(false)); | ||||
r.appendChild(this.cells[i + 1]); | |||||
r.appendChild(this.cups[i + 1]); | |||||
r.appendChild(col.cloneNode(false)); | r.appendChild(col.cloneNode(false)); | ||||
r.appendChild(this.cells[i + 2]); | |||||
r.appendChild(this.cups[i + 2]); | |||||
this.dom.appendChild(r); | this.dom.appendChild(r); | ||||
if (i < 6) { | if (i < 6) { | ||||
this.dom.appendChild(row.cloneNode(true)); | this.dom.appendChild(row.cloneNode(true)); | ||||
} | } | ||||
} | |||||
}*/ | |||||
}; | }; | ||||
/** | /** | ||||
}; | }; | ||||
Board.prototype.disableAll = function() { | Board.prototype.disableAll = function() { | ||||
this.cells.forEach(function(cell) { | |||||
cell.classList.add('notActive'); | |||||
this.cups.forEach(function(cup) { | |||||
//cup.classList.add('notActive'); | |||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.enableAll = function() { | Board.prototype.enableAll = function() { | ||||
this.cells.forEach(function(cell) { | |||||
cell.classList.remove('notActive'); | |||||
cell.setAttribute('marked', 'false'); | |||||
this.cups.forEach(function(cup) { | |||||
//cup.classList.remove('notActive'); | |||||
cup.setAttribute('marked', 'false'); | |||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.enableTurn = function() { | Board.prototype.enableTurn = function() { | ||||
this.cells.forEach(function(cell) { | |||||
if (cell.getAttribute('marked') === 'false') { | |||||
cell.classList.remove('notActive'); | |||||
cell.setAttribute('active', 'true'); | |||||
this.cups.forEach(function(cup) { | |||||
if (cup.getAttribute('marked') === 'false') { | |||||
//cup.classList.remove('notActive'); | |||||
cup.setAttribute('active', 'true'); | |||||
} | } | ||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.highlightCells = function(pos) { | |||||
var cells = this.cells; | |||||
Board.prototype.highlightcups = function(pos) { | |||||
var cups = this.cups; | |||||
pos.forEach(function(i) { | pos.forEach(function(i) { | ||||
cells[i].classList.add('colorRed'); | |||||
// cups[i].classList.add('colorRed'); | |||||
}); | }); | ||||
cells.forEach(function(cell) { | |||||
cell.setAttribute('marked', 'true'); | |||||
cups.forEach(function(cup) { | |||||
cup.setAttribute('marked', 'true'); | |||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.lowlightCells = function() { | |||||
var cells = this.cells; | |||||
cells.forEach(function(cell) { | |||||
cell.classList.add('colorWhite'); | |||||
Board.prototype.lowlightcups = function() { | |||||
alert('lowlightcups'); | |||||
var cups = this.cups; | |||||
cups.forEach(function(cup) { | |||||
//cup.classList.add('colorWhite'); | |||||
}); | }); | ||||
}; | }; | ||||
Board.prototype.mark = function(event) { | Board.prototype.mark = function(event) { | ||||
var target = event.target; | var target = event.target; | ||||
if (this.ready && target.getAttribute('data-intent') === 'gameCell' && target.getAttribute('active') === 'true') { | |||||
this.onMark(this.cells.indexOf(target)); | |||||
if (this.ready && target.getAttribute('data-intent') === 'gamecup' && target.getAttribute('active') === 'true') { | |||||
this.onMark(this.cups.indexOf(target)); | |||||
this.disableAll(); | this.disableAll(); | ||||
} | } | ||||
}; | }; | ||||
/** | /** | ||||
* | * | ||||
* @param cellId | |||||
* @param cupId | |||||
* @param label | * @param label | ||||
*/ | */ | ||||
Board.prototype.doMark = function(cellId, label) { | |||||
var cell = this.cells[cellId]; | |||||
cell.textContent = label; | |||||
cell.classList.add('notActive'); | |||||
cell.setAttribute('marked', 'true'); | |||||
Board.prototype.doMark = function(cupId, label) { | |||||
var cup = this.cups[cupId]; | |||||
cup.textContent = label; | |||||
//cup.classList.add('notActive'); | |||||
// removeCup | |||||
cup.setAttribute('marked', 'true'); | |||||
}; | }; | ||||
/** | /** | ||||
*/ | */ | ||||
Board.prototype.doWinner = function(pos) { | Board.prototype.doWinner = function(pos) { | ||||
this.disableAll(); | this.disableAll(); | ||||
this.highlightCells(pos); | |||||
this.highlightcups(pos); | |||||
}; | }; | ||||
/** | /** | ||||
* | * | ||||
*/ | */ | ||||
Board.prototype.doDraw = function() { | Board.prototype.doDraw = function() { | ||||
this.lowlightCells(); | |||||
this.lowlightcups(); | |||||
}; | }; | ||||
/** | /** | ||||
*/ | */ | ||||
Board.prototype.highlightScoreboard = function(playerId) { | Board.prototype.highlightScoreboard = function(playerId) { | ||||
this.scoreBoard.forEach(function(score) { | this.scoreBoard.forEach(function(score) { | ||||
score.classList.remove('active'); | |||||
// score.classList.remove('active'); | |||||
}); | }); | ||||
this.scoreBoard.forEach(function(board){ | this.scoreBoard.forEach(function(board){ | ||||
if (board.getAttribute('playerId') == playerId) { | if (board.getAttribute('playerId') == playerId) { | ||||
board.classList.add('active'); | |||||
// board.classList.add('active'); | |||||
} | } | ||||
}); | }); | ||||
}; | }; | ||||
var pos = []; | var pos = []; | ||||
var win = winPosition.some(function(win) { | var win = winPosition.some(function(win) { | ||||
if (this.cells[win[0]].textContent === player.label) { | |||||
var res = this.cells[win[0]].textContent === this.cells[win[1]].textContent && this.cells[win[1]].textContent === this.cells[win[2]].textContent; | |||||
if (this.cups[win[0]].textContent === player.label) { | |||||
var res = this.cups[win[0]].textContent === this.cups[win[1]].textContent && this.cups[win[1]].textContent === this.cups[win[2]].textContent; | |||||
if (res) { | if (res) { | ||||
pos = win; | pos = win; | ||||
* @returns {boolean} | * @returns {boolean} | ||||
*/ | */ | ||||
Board.prototype.checkDraw = function() { | Board.prototype.checkDraw = function() { | ||||
return this.cells.every(function(cell) { | |||||
return cell.textContent === this.players[0].label || cell.textContent === this.players[1].label; | |||||
return this.cups.every(function(cup) { | |||||
return cup.textContent === this.players[0].label || cup.textContent === this.players[1].label; | |||||
}, this); | }, this); | ||||
}; | }; | ||||
var socket = new WebSocket('ws://192.168.188.23:2667'); | |||||
var socket = new WebSocket('ws://192.168.2.131:2667'); | |||||
var events = { | var events = { | ||||
outgoing: { | outgoing: { | ||||
JOIN_GAME: 'csJoinGame', | JOIN_GAME: 'csJoinGame', | ||||
QUIT: 'scQuit' | QUIT: 'scQuit' | ||||
} | } | ||||
}; | }; | ||||
// container creates the startBtn | |||||
var container = document.querySelector('#gameBoard'); | var container = document.querySelector('#gameBoard'); | ||||
var startBtn = document.querySelector('#startBtn'); | var startBtn = document.querySelector('#startBtn'); | ||||
var nameInput = document.querySelector('#nickname'); | var nameInput = document.querySelector('#nickname'); | ||||
var hero = {}; | var hero = {}; | ||||
var board = new Board(scoreBoard); | var board = new Board(scoreBoard); | ||||
// disable startBtn and nameInput before website finished loading | |||||
startBtn.setAttribute('disabled', true); | startBtn.setAttribute('disabled', true); | ||||
nameInput.setAttribute('disabled', true); | nameInput.setAttribute('disabled', true); | ||||
nameInput.setAttribute('placeholder', 'Loading...'); | nameInput.setAttribute('placeholder', 'Loading...'); | ||||
/** | /** | ||||
* | * | ||||
* @param cellId | |||||
* @param cupId | |||||
*/ | */ | ||||
board.onMark = function(cellId){ | |||||
socket.send(makeMessage(events.outgoing.MARK, {playerId: hero.id, cellId: cellId})); | |||||
board.onMark = function(cupId){ | |||||
socket.send(makeMessage(events.outgoing.MARK, {playerId: hero.id, cupId: cupId})); | |||||
}; | }; | ||||
/** | /** | ||||
board.bindTo(container); | board.bindTo(container); | ||||
} | } | ||||
// if startBtn is pressed | |||||
startBtn.addEventListener('click', function(event) { | startBtn.addEventListener('click', function(event) { | ||||
var name = nameInput.value.trim(); | var name = nameInput.value.trim(); | ||||
break; | break; | ||||
case events.incoming.SET_TURN: | case events.incoming.SET_TURN: | ||||
// change Scoreboard | |||||
board.highlightScoreboard(msg.data.id); | board.highlightScoreboard(msg.data.id); | ||||
board.ready = true; | board.ready = true; | ||||
if (msg.data.id === hero.id) { | if (msg.data.id === hero.id) { | ||||
// remove opponent cups | |||||
board.enableTurn(); | board.enableTurn(); | ||||
} | } | ||||
break; | break; | ||||
case events.incoming.MARK: | case events.incoming.MARK: | ||||
board.doMark(msg.data.cellId, msg.data.player.label); | |||||
board.doMark(msg.data.cupId, msg.data.player.label); | |||||
break; | break; | ||||
break; | break; | ||||
case events.incoming.QUIT: | case events.incoming.QUIT: | ||||
// close | |||||
socket.close(); | socket.close(); | ||||
break; | break; | ||||
} | } | ||||
}; | }; | ||||
// if socket is open, show startBtn and nameInput | |||||
socket.onopen = function(event) { | socket.onopen = function(event) { | ||||
startBtn.removeAttribute('disabled'); | startBtn.removeAttribute('disabled'); | ||||
nameInput.removeAttribute('disabled'); | nameInput.removeAttribute('disabled'); |
}); | }); | ||||
}); | }); | ||||
board.on(Board.events.CELL_MARKED, function(event) { | |||||
board.on(Board.events.CUP_MARKED, function(event) { | |||||
wss.clients.forEach(function(client) { | wss.clients.forEach(function(client) { | ||||
client.send(makeMessage(events.outgoing.MARK, event)); | client.send(makeMessage(events.outgoing.MARK, event)); | ||||
}); | }); |
extends layout | |||||
block content | |||||
h1= message | |||||
h2= error.status | |||||
pre #{error.stack} |
extends layout | |||||
extends layout | |||||
block content | block content | ||||
.cups | |||||
.tisch | |||||
img(src='bierbankgarnitur_ausg.png') | |||||
.row.row1 | |||||
img#cup1.cup.cup1(src='cup.png' alt='') | |||||
img#cup2.cup.cup2(src='cup.png' alt='') | |||||
img#cup3.cup.cup3(src='cup.png' alt='') | |||||
img#cup4.cup.cup4(src='cup.png' alt='') | |||||
.row.row2 | |||||
img#cup5.cup.cup5(src='cup.png' alt='') | |||||
img#cup6.cup.cup6(src='cup.png' alt='') | |||||
img#cup7.cup.cup7(src='cup.png' alt='') | |||||
.row.row3 | |||||
img#cup8.cup.cup8(src='cup.png' alt='') | |||||
img#cup9.cup.cup9(src='cup.png' alt='') | |||||
.row.row4 | |||||
img#cup10.cup.cup10(src='cup.png' alt='') | |||||
#shooter.shooter | |||||
svg#ball.ball | |||||
ellipse(cx='25' cy='25' rx='24' ry='24') | |||||
.container | |||||
.cups | |||||
.tisch | |||||
img(src='bierbankgarnitur_ausg.png') | |||||
.row1 | |||||
img#cup1.cup.cup1(src='cup.png' alt='') | |||||
img#cup2.cup.cup2(src='cup.png' alt='') | |||||
img#cup3.cup.cup3(src='cup.png' alt='') | |||||
img#cup4.cup.cup4(src='cup.png' alt='') | |||||
.row2 | |||||
img#cup5.cup.cup5(src='cup.png' alt='') | |||||
img#cup6.cup.cup6(src='cup.png' alt='') | |||||
img#cup7.cup.cup7(src='cup.png' alt='') | |||||
.row3 | |||||
img#cup8.cup.cup8(src='cup.png' alt='') | |||||
img#cup9.cup.cup9(src='cup.png' alt='') | |||||
.row4 | |||||
img#cup10.cup.cup10(src='cup.png' alt='') | |||||
#shooter.shooter | |||||
svg#ball.ball | |||||
ellipse(cx='25' cy='25' rx='24' ry='24') | |||||
.row | |||||
.col-sm-3.col-sm-offset-3.scoreBoard | |||||
h1 | |||||
span#p1Score | |||||
.col-sm-3.scoreBoard | |||||
h1.text-right | |||||
span#p2Score | |||||
.row | |||||
.col-sm-6.col-sm-offset-3#gameBoard | |||||
h1.text-center.colorDark Enter your name | |||||
.panel.panel-danger | |||||
.panel-body | |||||
.input-group | |||||
input#nickname.form-control.input-lg( autofocus ) | |||||
span.input-group-btn | |||||
button#startBtn.btn.btn-lg.btn-danger PLAY! |
meta( http-equiv='X-UA-Compatible', content='IE=edge' ) | meta( http-equiv='X-UA-Compatible', content='IE=edge' ) | ||||
meta(name='viewport' content='width=device-width, initial-scale=1.0') | meta(name='viewport' content='width=device-width, initial-scale=1.0') | ||||
title= title | title= title | ||||
link(rel='stylesheet', href='/css/bootstrap.min.css') | |||||
link(rel='stylesheet' href='/css/style.css') | link(rel='stylesheet' href='/css/style.css') | ||||
link(rel='icon' href='cup.png') | link(rel='icon' href='cup.png') | ||||
body | body | ||||
block content | block content | ||||
script(src='/js/index.js') | |||||
script(src='/js/script.js') | |||||
script(src='/js/Board.js') | |||||
script(src='/js/app.js') | |||||