shogun/web/js/game.js
2020-04-01 11:12:19 +02:00

432 lines
17 KiB
JavaScript

class Figure {
constructor(x,y) {
this.x = x;
this.y = y;
}
setX(x) {
this.x = x;
}
setY(y) {
this.y = y;
}
getX() {
return parseInt(this.x);
}
getY() {
return parseInt(this.y);
}
getPosition() {
return new Array(parseInt(this.x), parseInt(this.y));
}
reset() {
this.x = 0;
this.y = 0;
}
}
class Field {
constructor(x,y) {
this.x = x;
this.y = y;
}
}
class Game {
constructor() {
this.whitePlayer = new Player('white');
this.blackPlayer = new Player('black');
this.chosenFigure = new Figure(0,0);
this.fields = [];
this.currentPlayer = 'white';
this.otherPlayer = (this.currentPlayer == 'white') ? 'black' : 'white';
}
drawGamePanel(x,y, widthAndHeight) {
var boxes = new Array();
for(var i=0; i<y; i++) {
this.fields[(i+1)] = [];
for(var j=0; j<x; j++) {
this.fields[(i+1)][(j+1)] = new Field((i+1),(j+1));
boxes.push(new Array(i+1,j+1))
}
}
var rows = new Array();
var row = new Array();
var that = this;
boxes.forEach(function(item, index) {
var domElement = document.createElement('div');
domElement.setAttribute('data-x', item[1]);
domElement.setAttribute('data-y', item[0]);
domElement.setAttribute('id', 'field-'+(index+1))
var backgroudColor = '';
domElement.setAttribute(
'style',
'width:'+widthAndHeight+'px; height:'+widthAndHeight+'px;'
)
if(row.length<8) {
row.push(domElement);
}
if(row.length == 8 ) {
rows.push(row)
row = new Array();
}
})
rows.forEach(function(item, indexRow) {
var wrap = document.createElement('div');
wrap.setAttribute('id', 'row-'+(indexRow+1));
document.getElementById('gamePanel').append(wrap)
item.forEach(function(field, indexField) {
if(((indexRow+1)+(indexField+1))%2 == 0) {
field.setAttribute('class', 'even field')
} else {
field.setAttribute('class', 'odd field')
}
wrap.append(field);
field.addEventListener(
"click",
function() {
that.handleClick(this)
},
{
passive: true
}
)
})
})
}
handleClick(item) {
if(!item.classList.contains(this.currentPlayer) && !item.classList.contains('possibleMove')) {
alert(this.otherPlayer + ' ist nicht dran');
return;
}
if(item.classList.contains('shogun') || item.classList.contains('farmer')) {
this.chosenFigure.setX(item.getAttribute('data-x'));
this.chosenFigure.setY(item.getAttribute('data-y'));
this.pickUpFigure(item);
}
else if(item.classList.contains('possibleMove')) {
this.releaseFigure(item, this.chosenFigure)
} else {
this.removeIndicator();
}
}
setPlayingFigures() {
var whiteStartRow = document.getElementById('row-1');
var whiteFields = document.querySelectorAll('#row-1 .field')
var blackStartRow = document.getElementById('row-8');
var blackFields = document.querySelectorAll('#row-8 .field')
whiteFields.forEach(function(item, index) {
if(index==3) {
item.classList.add('white');
item.classList.add('shogun');
item.setAttribute('data-figure', 'sh');
} else {
item.classList.add('white');
item.classList.add('farmer');
item.setAttribute('data-figure', index<3 ? 'b'+(index+1) : 'b'+index );
}
})
blackFields.forEach(function(item, index) {
if(index==4) {
item.classList.add('black');
item.classList.add('shogun');
item.setAttribute('data-figure', 'sh');
} else {
item.classList.add('black');
item.classList.add('farmer');
item.setAttribute('data-figure', index<4 ? 'b'+(index+1) : 'b'+index );
}
})
}
calculateMovesForPlayers() {
this.whitePlayer.calculateMoves();
this.blackPlayer.calculateMoves();
}
showPossibleMoves() {
//console.log('show possible moves')
var whitePlayer = this.whitePlayer;
var blackPlayer = this.blackPlayer;
var busyFields = document.querySelectorAll('.farmer, .shogun');
busyFields.forEach(item => this.addBobbles(item));
}
addBobbles(item) {
var that = this;
if(item.classList.contains('white')) {
var possibleMoves = this.whitePlayer.figures[item.getAttribute('data-figure')][(parseInt(item.getAttribute('id').replace('field-',''))-1)];
item.setAttribute('data-moves', possibleMoves)
if(!item.childNodes[0]) {
var bobble = document.createElement('div');
var bobbleText = document.createTextNode(possibleMoves)
bobble.setAttribute('class', 'bobble');
bobble.appendChild(bobbleText);
item.append(bobble);
}
}
if(item.classList.contains('black')) {
var possibleMoves = this.blackPlayer.figures[item.getAttribute('data-figure')][(parseInt(item.getAttribute('id').replace('field-',''))-1)];
item.setAttribute('data-moves', possibleMoves)
if(!item.childNodes[0]) {
var bobble = document.createElement('div');
var bobbleText = document.createTextNode(possibleMoves);
bobble.setAttribute('class', 'bobble');
bobble.appendChild(bobbleText);
item.append(bobble);
}
}
}
pickUpFigure(item) {
if(!item.classList.contains('farmer') && !(item.classList.contains('shogun'))) {
return;
}
var possibleMoves = parseInt(item.getAttribute('data-moves'));
var possibleTargets = new Set();
var x = parseInt(item.getAttribute('data-x'));
var y = parseInt(item.getAttribute('data-y'));
const isInField = function(target) {
const [x,y] = target;
if(x < 1 || x > 8 || y < 1 || y > 8) {
return false;
}
return true;
}
switch(possibleMoves) {
case 1:
possibleTargets.add([x+possibleMoves, y]);
possibleTargets.add(new Array(x, y+possibleMoves));
possibleTargets.add(new Array(x-possibleMoves, y));
possibleTargets.add(new Array(x, y-1));
break;
case 2:
possibleTargets.add(new Array(x+possibleMoves, y));
possibleTargets.add(new Array(x, y+possibleMoves));
possibleTargets.add(new Array(x-possibleMoves, y));
possibleTargets.add(new Array(x, y-possibleMoves));
possibleTargets.add(new Array(x+1, y+1));
possibleTargets.add(new Array(x-1,y-1));
possibleTargets.add(new Array(x+1,y-1));
possibleTargets.add(new Array(x-1, y+1));
break;
case 3:
possibleTargets.add(new Array(x+possibleMoves, y));
possibleTargets.add(new Array(x, y+possibleMoves));
possibleTargets.add(new Array(x-possibleMoves, y));
possibleTargets.add(new Array(x, y-possibleMoves));
possibleTargets.add(new Array(x-1, y-2));
possibleTargets.add(new Array(x+1, y-2));
possibleTargets.add(new Array(x+1, y+2));
possibleTargets.add(new Array(x-1, y+2));
possibleTargets.add(new Array(x-2, y+1));
possibleTargets.add(new Array(x-2, y-1));
possibleTargets.add(new Array(x+2, y-1));
possibleTargets.add(new Array(x+2, y+1));
break;
case 4:
possibleTargets.add(new Array(x-possibleMoves, y));
possibleTargets.add(new Array(x+possibleMoves, y));
possibleTargets.add(new Array(x, y+possibleMoves));
possibleTargets.add(new Array(x, y-possibleMoves));
possibleTargets.add(new Array(x+1, y-3));
possibleTargets.add(new Array(x-1, y-3));
possibleTargets.add(new Array(x+3, y+1));
possibleTargets.add(new Array(x+3, y-1));
possibleTargets.add(new Array(x+1, y+3));
possibleTargets.add(new Array(x-1, y+3));
possibleTargets.add(new Array(x-3, y-1));
possibleTargets.add(new Array(x-3, y+1));
possibleTargets.add(new Array(x+2, y-2));
possibleTargets.add(new Array(x+2, y+2));
possibleTargets.add(new Array(x-2, y+2));
possibleTargets.add(new Array(x-2, y-2));
break;
}
// remove out of bounds
for(var possibleTarget of possibleTargets) {
if(!isInField(possibleTarget)) {
possibleTargets.delete(possibleTarget)
}
}
// get possible ways
var that = this;
for(var possibleTarget of possibleTargets) {
possibleTarget["ways"] = this.getPossibleWays(possibleTarget);
}
for(var possibleTarget of possibleTargets) {
for(var way of possibleTarget["ways"]) {
for(var field of way) {
var chosenField = document.querySelector('[data-x="'+that.chosenFigure.getX()+'"][data-y="'+that.chosenFigure.getY()+'"]');
var currentField = document.querySelector('[data-x="'+field.x+'"][data-y="'+field.y+'"]');
var oppositeColor = chosenField.classList.contains('white') ? 'black' : 'white';
var sameColor = chosenField.classList.contains('white') ? 'white' : 'black';
var targetField = document.querySelector('[data-x="'+possibleTarget[0]+'"][data-y="'+possibleTarget[1]+'"]');
var targetX = parseInt(targetField.getAttribute('data-x'));
var targetY = parseInt(targetField.getAttribute('data-y'));
//Startfeld überspringen
if( (( field.x === that.chosenFigure.getX() ) && (field.y === that.chosenFigure.getY() ))) {
continue;
}
// Zielfeld prüfen
if( (( field.x === targetX ) && (field.y === targetY ))) {
if(currentField.classList.contains(sameColor)) {
const ways = possibleTarget["ways"].filter(w => w !== way);
possibleTarget["ways"] = ways;
if(possibleTarget["ways"].length == 0) {
possibleTargets.delete(possibleTarget);
}
}
} else {
if(currentField.classList.contains('shogun') || currentField.classList.contains('farmer')) {
const ways = possibleTarget["ways"].filter(w => w !== way);
possibleTarget["ways"] = ways;
if(possibleTarget["ways"].length == 0) {
possibleTargets.delete(possibleTarget);
}
}
}
}
}
}
for(var possibleTarget of possibleTargets) {
document.querySelector('[data-x="'+possibleTarget[0]+'"][data-y="'+possibleTarget[1]+'"]').classList.add('possibleMove');
}
}
getPossibleWays(to) {
const x1 = this.chosenFigure.getX();
const y1 = this.chosenFigure.getY();
const [x2,y2] = to;
const directionX = x1 < x2 ? 1 : -1;
const directionY = y1 < y2 ? 1 : -1;
const way1 = new Set();
for (let x = x1; directionX == 1 ? x <= x2 : x >= x2; x = x + directionX) {
way1.add(this.getField(x, y1));
}
for (let y = y1; directionY == 1 ? y <= y2 : y >= y2; y = y + directionY) {
way1.add(this.getField(x2, y));
}
const way2 = new Set();
for (let y = y1; directionY == 1 ? y <= y2 : y >= y2; y = y + directionY) {
way2.add(this.getField(x1, y));
}
for (let x = x1; directionX == 1 ? x <= x2 : x >= x2; x = x + directionX) {
way2.add(this.getField(x, y2));
}
const setsEqual = (a,b) => a.size === b.size && [...a].every(value => b.has(value));
if(setsEqual(way1, way2)) {
return [way1];
}
return [way1, way2];
}
getField(x,y) {
return this.fields[x][y];
}
isFree(field) {
if(field.classList.contains('farmer') || field.classList.contains('shogun')) {
return false;
}
return true;
}
releaseFigure(targetField) {
var source = document.querySelector('[data-x="'+this.chosenFigure.getX()+'"][data-y="'+this.chosenFigure.getY()+'"]');
var colorClass = source.classList.contains('white') ? 'white' : 'black';
var oppositeColorClass = source.classList.contains('white') ? 'black' : 'white';
var figureClass = source.classList.contains('farmer') ? 'farmer' : 'shogun';
var figureData = source.getAttribute('data-figure');
source.removeChild(source.childNodes[0]);
source.classList.remove('shogun','farmer', 'black', 'white');
source.setAttribute('data-figure', '');
source.setAttribute('data-moves', '');
targetField.classList.add(figureClass, colorClass);
targetField.setAttribute('data-figure', figureData);
this.removeIndicator();
this.showPossibleMoves();
this.chosenFigure.reset();
game.updateLists();
this.switchPlayers();
}
switchPlayers() {
var currentPlayer = this.currentPlayer;
this.currentPlayer = this.otherPlayer;
this.otherPlayer = currentPlayer;
}
removeIndicator() {
var greenFields = document.querySelectorAll('.possibleMove');
greenFields.forEach(item => {
item.classList.remove('possibleMove')
})
}
updateLists() {
var whiteList = document.querySelector('.whitePlayer');
var blackList = document.querySelector('.blackPlayer');
}
}
class Player {
constructor(color) {
this.figures = {
positions: new Array(),
b1: new Array(),
b2: new Array(),
b3: new Array(),
b4: new Array(),
b5: new Array(),
b6: new Array(),
b7: new Array(),
sh: new Array(),
}
if(color == 'white') {
this.figures.positions["b1"] = new Array(1,1);
this.figures.positions["b2"] = new Array(2,1);
this.figures.positions["b3"] = new Array(3,1);
this.figures.positions["b4"] = new Array(5,1);
this.figures.positions["b5"] = new Array(6,1);
this.figures.positions["b6"] = new Array(7,1);
this.figures.positions["b7"] = new Array(8,1);
this.figures.positions["sh"] = new Array(4,1);
}
if(color == 'black') {
this.figures.positions["b1"] = new Array(1,8);
this.figures.positions["b2"] = new Array(2,8);
this.figures.positions["b3"] = new Array(3,8);
this.figures.positions["b4"] = new Array(4,8);
this.figures.positions["b5"] = new Array(6,8);
this.figures.positions["b6"] = new Array(7,8);
this.figures.positions["b7"] = new Array(8,8);
this.figures.positions["sh"] = new Array(5,8);
}
}
calculateMoves() {
for(var figure in this.figures) {
if(figure != 'positions') {
if(figure != 'sh') {
for(var i=1; i<65; i++) {
this.figures[figure].push(Math.floor(Math.random() * (5 - 1)) + 1);
}
} else {
for(var i=1; i<65; i++) {
this.figures[figure].push(Math.floor(Math.random() * (3 - 1)) + 1);
}
}
}
}
}
}