diff --git a/game.js b/game.js index d8bc8fc..6a60f62 100644 --- a/game.js +++ b/game.js @@ -71,7 +71,7 @@ function getPrey(region, area) function suburbPrey(area) { - return fill_area(area, {"Person": 0.5, "House": 0.5, "Car": 0.2, "Tram": 0.1, "Bus": 0.1}); + return fill_area2(area, {"Person": 0.5, "House": 0.5, "Car": 0.2, "Tram": 0.1, "Bus": 0.1}); } function updateVictims(type,prey) diff --git a/recursive-macro.js b/recursive-macro.js index bd998cb..86a492d 100644 --- a/recursive-macro.js +++ b/recursive-macro.js @@ -18,7 +18,7 @@ var things = var areas = { "Container": 0, - "Person": 3, + "Person": 1, "Car": 4, "Bus": 12, "Tram": 20, @@ -30,6 +30,59 @@ var areas = "Overpass": 10000, }; +// general logic: each step fills in a fraction of the remaining space + +function fill_area2(area, weights = {"Person": 0.1, "Car": 0.05, "House": 0.1}) +{ + result = []; + candidates = []; + for (var key in weights) { + if (weights.hasOwnProperty(key)) { + candidates.push({"name": key, "area": areas[key], "weight": weights[key]}); + } + } + + candidates = candidates.sort(function (x,y) { + return x.area > y.area + }); + + while(candidates.length > 0) { + var candidate = candidates.pop(); + + if (candidate.area > area) + continue; + + var max = Math.floor(area / candidate.area); + var limit = Math.min(max, 100); + + var count = 0; + + // for small amounts, actually do the randomness + while (limit > 0) { + count += Math.random() < candidate.weight ? 1 : 0; + --limit; + } + + if (limit < max) { + count += Math.round((max-limit) * candidate.weight); + } + + area -= count * candidate.area; + + if (count > 0) + result.push(new things[candidate.name](count)); + } + + if (result.length > 1) { + return new Container(result); + } else if (result.length == 1) { + return result[0]; + } else { + return new Person(1); + } + +} + function fill_area(area, weights = {"Person": 0.1}) { var testRadius = Math.sqrt(area / Math.PI); @@ -296,7 +349,7 @@ function Container(contents = []) { } } - this.describe = function() { + this.describe = function(verbose = true) { return describe_all(this.contents) } @@ -313,22 +366,27 @@ function Person(count = 1) { this.describeOne = function (verbose=true) { - sex = random_desc(["male", "female"], (verbose ? 1 : 0)); body = random_desc(["skinny","fat","tall","short","stocky","spindly"], (verbose ? 0.6 : 0)); + sex = random_desc(["male", "female"], (verbose ? 1 : 0)); species = random_desc(["wolf","cat","dog","squirrel","horse","hyena","fox","jackal","crux","sergal"]); - return "a " + merge_desc([sex,body,species]); + return "a " + merge_desc([body,sex,species]); } - this.describe = function() { - if (count <= 3) { - list = []; - for (var i = 0; i < count; i++) { - list.push(this.describeOne(this.count <= 2)); + this.describe = function(verbose=true) { + if (verbose) { + if (count <= 3) { + list = []; + for (var i = 0; i < count; i++) { + list.push(this.describeOne(this.count <= 2)); + } + return merge_things(list); + } else { + return this.count + " people" } - return merge_things(list); } else { - return this.count + " people" + return this.count + " " + (this.count > 1 ? "people" : "person"); } + } return this; } @@ -343,23 +401,28 @@ function EmptyCar(count = 1) { - this.describeOne = function() { + this.describeOne = function(verbose=true) { color = random_desc(["black","black","gray","gray","blue","red","tan","white","white"]); adjective = random_desc(["rusty","brand-new"],0.3); type = random_desc(["SUV","coupe","sedan","truck","van","convertible"]); return "a parked " + merge_desc([adjective,color,type]); } - this.describe = function() { - if (this.count <= 3) { - list = []; - for (var i = 0; i < this.count; i++) { - list.push(this.describeOne()); + this.describe = function(verbose = true) { + if (verbose) { + if (this.count <= 3) { + list = []; + for (var i = 0; i < this.count; i++) { + list.push(this.describeOne()); + } + return merge_things(list); + } else { + return this.count + " parked cars"; } - return merge_things(list); } else { - return this.count + " parked cars"; + return this.count + " parked " + (this.count > 1 ? "cars" : "car"); } + } } @@ -380,16 +443,21 @@ function Car(count = 1) { return "a " + merge_desc([adjective,color,type]); } - this.describe = function() { - if (this.count <= 3) { - list = []; - for (var i = 0; i < this.count; i++) { - list.push(this.describeOne(this.count < 2)); + this.describe = function(verbose = true) { + if (verbose) { + if (this.count <= 3) { + list = []; + for (var i = 0; i < this.count; i++) { + list.push(this.describeOne(this.count < 2)); + } + return merge_things(list) + " with " + this.contents.person.describe(false) + " inside"; + } else { + return this.count + " cars with " + this.contents.person.describe(false) + " inside"; } - return merge_things(list) + " with " + this.contents.person.describe() + " inside"; } else { - return this.count + " cars with " + this.contents.person.describe() + " inside"; + return this.count + " " + (this.count > 1 ? "cars" : "car"); } + } } @@ -410,7 +478,7 @@ function Bus(count = 1) { return "a " + merge_desc([adjective,color,type]); } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) { @@ -440,7 +508,7 @@ function Tram(count = 1) { return "a " + merge_desc([adjective,color,type]); } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) { @@ -493,7 +561,7 @@ function Train(count = 1) { return "a " + merge_desc([adjective,color,type]); } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) { @@ -528,7 +596,7 @@ function TrainCar(count = 1) { return "a " + merge_desc([adjective,color,type]); } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) { @@ -562,7 +630,7 @@ function House(count = 1) { return "a " + merge_desc([size,color,name]); } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) { @@ -595,7 +663,7 @@ function ParkingGarage(count = 1) { return "a parking garage"; } - this.describe = function() { + this.describe = function(verbose = true) { if (this.count <= 3) { list = []; for (var i = 0; i < this.count; i++) {