Browse Source

Added Game Machine Working. Missing Full four side Plus attack(will fail)!!

Nikatlas 6 years ago
parent
commit
cbe53d380f
4 changed files with 308 additions and 0 deletions
  1. 11 0
      game/machine/Card.js
  2. 223 0
      game/machine/GameMachine.js
  3. 36 0
      game/machine/GameMachine.test.js
  4. 38 0
      game/machine/GameMoves.js

+ 11 - 0
game/machine/Card.js

@@ -1,5 +1,16 @@
 class Card {
 	constructor() {
+		this.attack = [0,0,0,0];
+		this.portrait = "";
+		this.owner = "";
+	}
+
+	setAttack(attack) {
+		this.attack = attack;
+	}
+
+	setOwner(owner) {
+		this.owner = owner;
 	}
 
 }

+ 223 - 0
game/machine/GameMachine.js

@@ -0,0 +1,223 @@
+var Card = require('./Card.js');
+
+class GameMachine {
+	constructor() {
+		this.state = {
+			board: new Board(),
+			players: [],
+			hash: "0123456789"
+		};
+
+	}
+
+	setState(state) {
+		this.state = { ...this.state, ...state};
+	}
+
+	setBoard(board) {
+		this.state = { ...this.state, board};
+	}
+
+	setPlayers(players) {
+		this.state = { ...this.state, players};
+	}
+
+	runMove(move) {
+		move.performMove(this.state.board);
+	}
+}
+
+class Board {
+	constructor() {
+		this.data = [];
+		this.owners = [];
+
+		// These 2 to be updated after every move
+		this.triggerPaths = []; // like attackVectors
+		this.plusPaths = []; // like attackVectors
+		for (var i=0; i < 9; i += 1) {
+			this.triggerPaths[i] = [];
+			this.plusPaths[i] = {
+				winner: -1,
+				sums: []
+			}
+		}
+	}
+
+	debug() {
+		console.log('BOARD');
+		console.log('---------------------------');
+		console.log('Cards :');
+		let s = '';
+		for(var i=0,j=0;i<this.data.length;i+=1) {
+			s += this.owners[i] + ':' + this.data[i] + '\t';
+			j += 1;
+			if(j%3===0)s += '\n';
+		}
+		console.log(s);
+		console.log('---------------------------');
+		console.log('Triggers');
+		console.log('---------------------------');
+		s = '';
+		for(var i=0,j=0;i<this.triggerPaths.length;i+=1) {
+			s += '[' + this.triggerPaths[i] + ']' + '\t\t';
+			j += 1;
+			if(j%3===0)s += '\n';
+		}
+		console.log(s);
+		console.log('---------------------------');
+		console.log('Pluspaths');
+		console.log('---------------------------');
+		s = '';
+		for(var i=0,j=0;i<this.plusPaths.length;i+=1) {
+			s += '[' + (this.plusPaths[i].winner) + ']' + '\t\t';
+			j += 1;
+			if(j%3===0)s += '\n';
+		}
+		console.log(s);
+		console.log('---------------------------');
+
+	}
+
+	putCard(card, position, player) { // position = 0-9
+		this.data[ position ] = card;
+		this.owners[position] = player;
+
+		this._calculatePlusAndTriggers(position);
+		this._analyze(position);
+	}
+
+	_calculatePlusAndTriggers(position) {
+		const attacker 		= this.data[position];
+		for (let j = 0; j < 4; j += 1) {
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;
+			
+			const dx = this._getDisplacement(j);
+			const attackedCard  = this.data[position + dx];
+			const defendJ = ( j + 2 ) % 4;
+
+			if (attackedCard) {
+				const sum = attacker.attack[j] + attackedCard.attack[defendJ];
+				this.plusPaths[	 	 position  ].sums[j] = sum;
+				this.plusPaths[   position + dx].sums[defendJ] = sum;
+				this.triggerPaths[	 position  ][j] =   attacker.attack[j] - attackedCard.attack[defendJ];
+				this.triggerPaths[position + dx][defendJ] =   -this	.triggerPaths[position][j]; // opposite to the above
+			}
+		}
+	}
+
+	_getDisplacement(j) {
+		switch(j) {
+			case 0: return 1;//return {x: 1, y:0};
+			case 1: return -3;//return {x: 0, y:1};
+			case 2: return -1;//return {x: -1, y:0};
+			case 3: return 3;//return {x: 0, y:-1};
+			default: throw Error("Cannot _getDisplacement of this value: " + j);
+		}
+	}
+
+	_flipCard(position, combo, owner) {
+		// change owner!
+
+		this.owners[position] = owner;
+		if(combo) this._analyze(position, combo);
+	}
+
+	_analyze(position, combo) {
+		// check rules!
+		if(			this._checkSameRule(position) && !combo ) {
+			// Apply Same Rule
+			this._applySameRule(position);
+		} else if ( this._checkPlusRule(position) && !combo ) {
+			// Apply Plus Rule
+			this._applyPlusRule(position);
+		} else {
+			this._applyAttackRule(position);
+		}
+	}
+
+	_applyAttackRule(position) { //seems ok
+		if ( !this.triggerPaths[position] ) return;
+		for (let j = 0; j < 4; j += 1) {
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;
+			const dx = this._getDisplacement(j);
+			if ( this.triggerPaths[position][j] > 0 ) {
+				this._flipCard(position + dx, false, this.owners[position]);
+			}
+		}
+	}
+
+	_applySameRule(position) {
+		for (let j = 0; j < 4; j += 1) {
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;
+			const dx = this._getDisplacement(j);
+			if ( this.triggerPaths[position][j] === 0 ) {
+				this._flipCard(position + dx, true, this.owners[position]);
+			}
+		}	
+	}
+
+	_applyPlusRule(position) {
+		for (let j = 0; j < 4; j += 1) { // this for loop can be fixed seems obsolete & slow
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;
+			const dx = this._getDisplacement(j);
+			if ( this.plusPaths[position].sums[j] === this.plusPaths[position].winner ) {
+				this._flipCard(position + dx, true, this.owners[position]);
+			}
+		}
+	}
+
+	_checkSameRule(position) {
+		const card = this.data[position];
+		let  sames = 0;
+		for (let j = 0; j < 4; j += 1) {
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;			
+			if (this.triggerPaths[position] && 
+				this.triggerPaths[position][j] === 0) {
+				sames += 1;
+			}
+		}	
+		return sames > 1;
+	}
+
+	_checkPlusRule(position) { // refactor plz // need fix (problem double plus a.k.a. four side attack)
+		const card = this.data[position];
+		let pluses = {};
+		let sum = -1;
+		for (let j = 0; j < 4; j += 1) {
+			if ( Board.ATTACK_VECTORS[position][j] === 0 ) continue;
+			if(sum = this.plusPaths[position].sums[j])
+				pluses[sum] = (pluses[sum] || 0) + 1;
+		}
+		for (var i in pluses) {
+			if (pluses[i] > 1) {
+				this.plusPaths[position].winner = parseInt(i);
+				console.log(i);
+				return true;
+			}
+		}
+		this.plusPaths[position].winner = -1;
+		return false;
+	}
+
+	isEmpty(position) {
+		return !!this.data[position];
+	}
+}
+// START From top left goin row row  
+Board.ATTACK_VECTORS = [
+//  [R, U, L, D] // right up left down
+	[1, 0, 0, 1],
+	[1, 0, 1, 1],
+	[0, 0, 1, 1],
+	[1, 1, 0, 1],
+	[1, 1, 1, 1],
+	[0, 1, 1, 1],
+	[1, 1, 0, 0],
+	[1, 1, 1, 0],
+	[0, 1, 1, 0]
+];
+
+module.exports = {
+	GameMachine
+};

+ 36 - 0
game/machine/GameMachine.test.js

@@ -0,0 +1,36 @@
+let GameMachine = require('./GameMachine').GameMachine;
+let Moves = require('./GameMoves');
+let Card = require('./Card');
+
+var mac = new GameMachine();
+
+
+let card = new Card();
+card.setAttack([4,2,3,1]);
+card.setOwner(666);
+
+
+let ncard = new Card();
+ncard.setAttack([4,3,3,10]);
+ncard.setOwner(666);
+
+let nncard = new Card();
+nncard.setAttack([8,5,6,9]);
+nncard.setOwner(665);
+
+let move = new Moves.PlaceMove(card, 4, 666);
+mac.runMove(move);
+
+let nmove = new Moves.PlaceMove(card, 3, 665);
+mac.runMove(nmove);
+
+let nnmove = new Moves.PlaceMove(ncard, 1, 666);
+mac.runMove(nnmove);
+
+
+let nnnmove = new Moves.PlaceMove(nncard, 0, 665);
+mac.runMove(nnnmove);
+
+
+mac.state.board.debug();
+

+ 38 - 0
game/machine/GameMoves.js

@@ -0,0 +1,38 @@
+class GameMove {	
+	constructor(type, data) {
+		this.type = type;
+		this.data = data;
+	}
+	verify() {}
+	performMove() {}
+};
+GameMove.TYPES = {
+	PLACE: 1,
+	PLACE_AND_REVEAL: 2,
+	SELECT_CARDS: 0
+};
+
+
+class PlaceMove extends GameMove {
+	constructor(card, position, player) {
+		super(GameMove.TYPES.PLACE, {});
+		this.position = position;
+		this.card = card;
+		this.player = player;
+	}
+	verify(state) {
+		if (state.board.isEmpty(this.position)) {
+			throw Error('Not a valid move, there is already a card there!');
+		}
+
+		return true;
+	}
+
+	performMove(board) {
+		board.putCard(this.card, this.position, this.player);
+	}
+}
+
+module.exports = {
+	PlaceMove
+};