Преглед на файлове

commiting base game machine to web

Nikatlas преди 6 години
родител
ревизия
9a60831c98

+ 0 - 1
src/Game/app.js

@@ -17,7 +17,6 @@ class App {
 		this._router = new Router(this.app.stage);
 		this._router.addRoute('Login', new Menu(this.app, 'LoginMenuConfig.js'));
 		this._router.addRoute('Test', new Menu(this.app, 'TestMenuConfig.js'));
-
 	}
 	destroy() {
 		this.app.view.style.display = 'none';

+ 9 - 0
src/Game/game/index.js

@@ -0,0 +1,9 @@
+const GameMachine = require('./machine/GameMachine');
+const GameMoves = require('./machine/GameMoves');
+const Card = require('./machine/Card');
+
+module.exports = {
+	Card,
+	GameMachine,
+	GameMoves
+}

+ 23 - 0
src/Game/game/machine/Booster.js

@@ -0,0 +1,23 @@
+var CryptoJS = require('crypto-js');
+
+const SHA = CryptoJS.SHA256;
+
+// var salt = CryptoJS.lib.WordArray.random(128 / 8).toString();
+
+class Booster {
+	constructor(user) {
+		if(!user) throw Error("Booster must be owned by a user!");
+		this.id = this.randomID();
+		this.treasure = this.randomTreasure();
+		this.user = user;
+	}
+
+	randomID() {
+		return CryptoJS.lib.WordArray.random(128 / 8).toString();
+	}
+
+	randomTreasure() {
+		return CryptoJS.lib.WordArray.random(256 / 8).toString();
+	}
+}
+module.exports = Booster;

+ 23 - 0
src/Game/game/machine/BoosterService.js

@@ -0,0 +1,23 @@
+let BoostersRepository = require('../../database').Repositories.Boosters;
+var Booster = require('./Booster');
+
+class BoosterService {
+	constructor() {
+	}
+
+	getUserBoosters(user) {
+		return BoostersRepository.getBoostersByUser(user);
+	}
+
+	givePack(user) {
+		let {id, ...boosterdata} = new Booster(user);
+		return BoostersRepository.insert(id, boosterdata);
+	}
+}
+
+
+let service = null; 
+function getSingleton() { 
+	return service = (service === null ? new BoosterService() : service);
+}
+module.exports = getSingleton();

+ 17 - 0
src/Game/game/machine/Card.js

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

+ 223 - 0
src/Game/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
src/Game/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
src/Game/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
+};

+ 38 - 0
src/Game/services/Net.js

@@ -0,0 +1,38 @@
+function checkIt(resp) {
+    if ( Math.parseInt(resp.status / 100, 10) === 2) {
+	    return resp;
+	} else {
+  		throw resp;
+	}
+}
+
+function catchIt(err) {
+	if ( Math.parseInt(err.status / 500, 10) === 5 ){
+		return err;
+	} else {
+		throw err;
+	}
+}
+
+class Net {
+	constructor(baseURL) {
+		this.baseURL = baseURL;
+	}
+
+	get(url) {
+		url = this.baseURL + url;
+		return fetch(url, {method: 'GET'}).then(checkIt).catch(catchIt);
+	}
+
+	post(url, body) {
+		url = this.baseURL + url;
+		return fetch(url, {
+			method: 'GET',
+			headers: {
+				'Content-Type':'application/json' 
+			}
+		})
+	}
+}
+
+module.exports = new Net();

+ 19 - 0
src/Game/services/UserService.js

@@ -0,0 +1,19 @@
+var Net = require('./net.js');
+
+
+class UserService {
+
+	constructor() {
+	
+	}
+
+	login(username, password) {
+
+
+
+	}
+
+
+}
+
+export default UserService;

+ 1 - 1
src/Game/views/Menu.js

@@ -5,7 +5,7 @@ class Menu extends PIXI.Container{
 	constructor(app, config){
 		super();
 		this.stage = app.stage;
-		this.buttons = require('./'+config).default || [];
+		this.buttons = require('./menuConfigs/'+config).default || [];
 		this.calculatePositions();
 		this.buttons.forEach((e,i) => this.addChild(e));
 

+ 4 - 4
src/Game/views/LoginMenuConfig.js → src/Game/views/menuConfigs/LoginMenuConfig.js

@@ -1,7 +1,7 @@
-import Button from '../misc/Button.js'
-import TextInput from '../misc/TextInput.js'
-import Text from '../misc/Text.js'
-import App from '../app.js'
+import Button from '../../misc/Button.js'
+import TextInput from '../../misc/TextInput.js'
+import Text from '../../misc/Text.js'
+import App from '../../app.js'
 
 
 const buttons = [];

+ 3 - 3
src/Game/views/TestMenuConfig.js → src/Game/views/menuConfigs/TestMenuConfig.js

@@ -1,6 +1,6 @@
-import Button from '../misc/Button.js'
-import TextInput from '../misc/TextInput.js'
-import Text from '../misc/Text.js'
+import Button from '../../misc/Button.js'
+import TextInput from '../../misc/TextInput.js'
+import Text from '../../misc/Text.js'
 
 const buttons = [];
 buttons.push(new TextInput("Test input"));