From a8b67bf7e4c4f84a2b2e449d4a66b69a5e02bae3 Mon Sep 17 00:00:00 2001 From: cncplyr Date: Thu, 17 Apr 2014 00:40:22 +0100 Subject: [PATCH] Extracted map and game. Extracted map functions to map.js (really just 2d grid functions). Extracted game functions to game.js. Started objectifying game functions. Started refactor of game functions. Temporary map now uses a 2d json object instead of an array of json objects. --- animals-base.js | 2 + animals-wolves.js | 26 +++-- game.js | 211 ++++++++++++++++++++++++++++++++++++ index.html | 271 ++++------------------------------------------ map.js | 40 +++++++ 5 files changed, 286 insertions(+), 264 deletions(-) create mode 100644 game.js create mode 100644 map.js diff --git a/animals-base.js b/animals-base.js index 4afbeb8..9fc2a22 100644 --- a/animals-base.js +++ b/animals-base.js @@ -1,3 +1,5 @@ +// This file contains the Animal interface and base animal implementations + var animalsBase = [Stone, Lion, Bear]; var animalsBaseCount = { diff --git a/animals-wolves.js b/animals-wolves.js index ae4aac5..a6ebeb5 100644 --- a/animals-wolves.js +++ b/animals-wolves.js @@ -1,3 +1,5 @@ +var animalsWolves = [LazyWolf, EmoWolf, SheepWolf]; + // Animal: LazyWolf function LazyWolf() { Animal.call(this); @@ -79,32 +81,32 @@ SheepWolf.prototype.move = function(surroundings) { var yWeight = 0; // Northwest - xWeight += this.animalWeights.get(surroundings[0][0]); - yWeight += this.animalWeights.get(surroundings[0][0]); + xWeight += this.animalWeights[surroundings[0][0]]; + yWeight += this.animalWeights[surroundings[0][0]]; // North - yWeight += this.animalWeights.get(surroundings[0][1]); + yWeight += this.animalWeights[surroundings[0][1]]; // Northeast - xWeight += this.animalWeights.get(surroundings[0][2]); - yWeight += this.animalWeights.get(surroundings[0][2]); + xWeight += this.animalWeights[surroundings[0][2]]; + yWeight += this.animalWeights[surroundings[0][2]]; // West - xWeight += this.animalWeights.get(surroundings[1][0]); + xWeight += this.animalWeights[surroundings[1][0]]; // East - xWeight += this.animalWeights.get(surroundings[1][2]); + xWeight += this.animalWeights[surroundings[1][2]]; // Southwest - xWeight += this.animalWeights.get(surroundings[2][0]); - yWeight += this.animalWeights.get(surroundings[2][0]); + xWeight += this.animalWeights[surroundings[2][0]]; + yWeight += this.animalWeights[surroundings[2][0]]; // South - yWeight += this.animalWeights.get(surroundings[2][1]); + yWeight += this.animalWeights[surroundings[2][1]]; // South - xWeight += this.animalWeights.get(surroundings[2][2]); - yWeight += this.animalWeights.get(surroundings[2][2]); + xWeight += this.animalWeights[surroundings[2][2]]; + yWeight += this.animalWeights[surroundings[2][2]]; if (Math.abs(xWeight) < Math.abs(yWeight)) { if (yWeight > 0) { diff --git a/game.js b/game.js new file mode 100644 index 0000000..7d458c9 --- /dev/null +++ b/game.js @@ -0,0 +1,211 @@ +// Game object +function SurvivalGame(blockSize, mapSize) { + this.blockSize = blockSize; + this.mapSize = mapSize; + this.map = makeSquareArray(this.mapSize); + + this.currentTurn = 0; // Default value + this.maxTurn = 500; // Default value +} +SurvivalGame.prototype.newGame = function() { + this.currentTurn = 0; + this.map = makeSquareArray(this.mapSize); + // TODO: This should be elsewhere? + $.each(animalsBaseCount, function(k, v){ + animalsBaseCount[k] = 0; + }); +} +SurvivalGame.prototype.populate = function(activeAnimalList, count) { + // TODO: array?! What?! where does this come from? + $.each(activeAnimalList, function(k, animalType){ + for(var animalCount = 0; animalCount < count; animalCount++){ + var x = Math.floor(Math.random() * array.length); + var y = Math.floor(Math.random() * array.length); + array[x][y] = new animalType; + /* + var x = Math.floor(Math.random() * this.mapSize); + var y = Math.floor(Math.random() * this.mapSize); + var foo = new animalType; + console.log(this.map); + this.map[x][y] = foo; // TODO: this.map is undefined... + */ + } + + // TODO: I don't think we should be making a new animal just to get it's name... + // TODO: Can't access properties from method? + var a = new animalType; + animalsBaseCount[a.name()] += count; + }); +} +SurvivalGame.prototype.next = function() { + // Clear the temp map used to find fights + // TODO: Should this be moved to function SurvivalGame? + var halfStepMap = {}; + + // Go through all the animals + for (var x = 0; x < this.mapSize; x++) { + for (var y = 0; y < this.mapSize; y++) { + if (this.map[x][y] != null) { + // Get the animal's surroundings and ask for it's move + var surroundings = getSurroundings(x,y); + var animal = this.map[x][y]; + var move = animal.move(surroundings); + + // Move the animal + switch (move) { + case 'h': + moveAnimal(halfStepMap, x, y, animal); + break; + case 'l': + moveAnimal(halfStepMap, getSafeCoordinate(x-1), y, animal); + break; + case 'u': + moveAnimal(halfStepMap, x, getSafeCoordinate(y-1), animal); + break; + case 'r': + moveAnimal(halfStepMap, getSafeCoordinate(x+1), y, animal); + break; + case 'd': + moveAnimal(halfStepMap, x, getSafeCoordinate(y+1), animal); + break; + } + + // Remove the animal from the old position + // Animals that don't move shouldn't be removed + if (move != 'h'){ + this.map[x][y] = null; + } + } + } + } + + // Resolve any fights that occur + resolveAllFights(halfStepMap, this.map); + + this.currentTurn++; + + function moveAnimal(temporaryMap, x, y, animal) { + if (temporaryMap[x] != undefined) { + if (temporaryMap[x][y] != undefined) { + // Animal already there! + temporaryMap[x][y].push(animal); + } else { + // No animal in this grid square + temporaryMap[x][y] = [animal]; + } + } else { + // No animal in this row! + temporaryMap[x] = {}; + temporaryMap[x][y] = [animal] + } + } + + // Resolve fights on the map + function resolveAllFights(temporaryMap, finalMap) { + $.each(temporaryMap, function(x, columns){ + $.each(columns, function(y, animals){ + if (animals.length > 1) { + // fight the animals! + finalMap[x][y] = resolveFight(animals); + } else { + // only one animal + finalMap[x][y] = animals[0] + } + }); + }); + } + + // Takes an array of animals, pseudo-randomly fights pairs of animals + // until only one remains + function resolveFight(animals) { + while(animals.length > 1){ + // Shuffle list of animals + shuffle(animals); + // Make the first two animals fight! + var move0 = animals[0].fight(animals[1].name()); + var move1 = animals[1].fight(animals[0].name()); + var winner = playRockPaperScissorsSuicide(move0, move1); + if (winner === -1) { + // Both animals died, remove both from the list + animals.splice(0, 2) + } else { + // Remove the loser + animalsBaseCount[animals[winner].name()]--; + animals.splice(winner, 1); + } + } + return animals[0]; + } + + // Returns 0 if first move won, 1 if second move won. -1 for double suicide + function playRockPaperScissorsSuicide(move0, move1){ + var winner = -1; // No winners! + + if (move0 === move1) { + // A draw! + if (move0 === 'x') { + // Double Suicide! Return -1 + } else { + // Return a random winner + return Math.floor(Math.random()*2); + } + } else { + // Suicides + if (move0 === 'x') { return 1; } + if (move1 === 'x') { return 0; } + + switch (move0 + move1) { + case 'rp': + winner = 1; + break; + case 'rs': + winner = 0; + break; + case 'pr': + winner = 0; + break; + case 'ps': + winner = 1; + break; + case 'sr': + winner = 1; + break; + case 'sp': + winner = 0; + break; + } + } + + return winner; + } + + + // http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array + function shuffle(array) { + var currentIndex = array.length + , temporaryValue + , randomIndex + ; + + // While there remain elements to shuffle... + while (0 !== currentIndex) { + // Pick a remaining element... + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // And swap it with the current element. + temporaryValue = array[currentIndex]; + array[currentIndex] = array[randomIndex]; + array[randomIndex] = temporaryValue; + } + + return array; + } +} +SurvivalGame.prototype.isFinished = function() { + return this.currentTurn >= this.maxTurn; +} +SurvivalGame.prototype.getProgress = function() { + // Returns the percentage of the game that has completed as an int + return Number((100 * (this.currentTurn / this.maxTurn)).toFixed()); +} diff --git a/index.html b/index.html index 5b5dfe8..7335a14 100644 --- a/index.html +++ b/index.html @@ -6,6 +6,8 @@ + + @@ -56,257 +58,21 @@

Rules

\ No newline at end of file diff --git a/map.js b/map.js new file mode 100644 index 0000000..f8ae35f --- /dev/null +++ b/map.js @@ -0,0 +1,40 @@ +// This file has methods to make a 2d-array for the game + +var mapSize; + +// make an m-by-n 2d array +function makeArray(cols, rows) { + array = []; + for(var i = 0; i < rows; i++){ + array[i] = []; + array[i][rows-1] = null; + } + return array; +} + +function makeSquareArray(size) { + return makeArray(size, size); +} + +function getSurroundings(x, y) { + var surroundings = [[],[],[]]; + for (var i = 0; i < 3; i++) { + for (var j = 0; j < 3; j++) { + var posX = getSafeCoordinate(x + i - 1); + var posY = getSafeCoordinate(y + j - 1); + var location = surroundings[i][j] = game.map[posX][posY]; + if (location == null) { + surroundings[i][j] == ' '; + } else { + surroundings[i][j] = location.name(); + } + } + } + return surroundings; +} + +function getSafeCoordinate(coord) { + if (coord < 0) return game.mapSize - 1; + if (coord >= game.mapSize) return 0; + return coord; +}