Skip to content

Instantly share code, notes, and snippets.

@SharpCoder
Created August 4, 2014 21:47
Show Gist options
  • Save SharpCoder/81eb55d59cca9a258d83 to your computer and use it in GitHub Desktop.
Save SharpCoder/81eb55d59cca9a258d83 to your computer and use it in GitHub Desktop.
This is the entry point for my political simulation game. Well, the game is actually about cause and effect. This is the core foundation that simulates the domino effect one mishap may have. In my engine, everything ultimately leads to murder...
// Created by SharpCoder (@debugglesoft)
// 08-03-2014
//
// politics.js is the event creation engine for
// the world. It simulates the interaction between
// people in power and everyone else.
Human = (function() {
function Human() {
this.Name = Helper.GetName();
this.Role = 'Union Member';
this.Rep = 0;
this.Insanity = 0;
this.Alive = true;
this.Arrested = false;
this.Groups = new Array();
this.Branch = new Array(); // Political branches that this person has contributed to.
this.HateBranch = new Array();
this.Crime = new Array();
this.Project = new Array();
this.Donated = new Array();
this.Disposition = new Array();
this.Paintings = new Array();
this.Inventions = new Array();
this.Investigated = false;
}
Human.prototype.Hate = function( target ) {
if ( target == null ) return;
// Change disposition if we can find them.
var found = false;
if ( this.Disposition.length > 0 ) {
for ( var i = 0; i < this.Disposition.length; i++ ) {
if ( this.Disposition[i].Name === target ) {
this.Disposition[i].Value++;
found = true;
}
}
}
// If we haven't found the entry, create a new one.
if ( !found ) {
this.Disposition.push({
Name: target,
Value: 1
});
}
// If the target has formed any political branches, target
// it for dissolution.
for ( var i = 0; i < target.Branch.length; i++ ) {
this.HateBranch.push( target.Branch[i] );
}
}
Human.prototype.GetDisposition = function( target ) {
for ( var i = 0; i < this.Disposition.length; i++ )
if ( this.Disposition[i].Name === target )
return this.Disposition[i].Value;
return 0;
}
Human.prototype.GetTarget = function() {
if ( this.Disposition.length > 0 ) {
var target = Helper.RandomizeList( this.Disposition );
return target[0].Name;
}
}
Human.prototype.IsHateful = function() {
return this.Disposition.length > 0;
}
Human.prototype.StartProject = function(title) {
this.Project.push(title);
}
Human.prototype.FinishProject = function() {
this.Project.pop();
}
Human.prototype.Reprimand = function(title) {
this.Crime.push(title);
}
Human.prototype.HasBranch = function( branch ) {
for ( var i = 0; i < this.Branch.length; i++ )
if ( this.Branch[i] === branch )
return true;
return false;
}
Human.prototype.RemoveCrime = function() {
if ( this.Crime.length > 0 )
this.Crime.pop();
}
Human.prototype.RemoveGroup = function(group) {
this.Groups = Helper.RemoveFromList( this.Groups, group );
}
Human.prototype.RemoveBranch = function( branch ) {
this.Branch = Helper.RemoveFromList( this.Branch, branch );
}
return Human;
})();
World = (function() {
// Seed the random number generator.
Math.random = RNG.prototype.uniform.bind(new RNG('Guppy'));
function IsHateAbound() {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].Alive && this.People[i].IsHateful() )
return true;
}
return false;
}
// This method will return true if
// someone in the world has committed a crime and
// not yet been caught.
function IsCrimeAbound() {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].Alive && this.People[i].Arrested === false && this.People[i].Crime.length > 0 )
return true;
}
return false;
}
function IsPrisonersAbound() {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].Alive && this.People[i].Arrested || this.People[i].Crime.length > 0 )
return true;
}
return false;
}
function GetAngryPolitician() {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].Alive && this.People[i].IsHateful() )
if ( this.People[i].Role === "President" || this.People[i].Role === "Vice President" || this.People[i].Role === "Congressman")
return this.People[i];
}
return null;
}
function GetAngryPerson() {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].Alive && this.People[i].Arrested === false && this.People[i].IsHateful() )
return this.People[i];
}
return null;
}
// Create the Event Tree.
var Events = {
"Vendetta": {
// This category is intended to make sure people can resolve
// their problems such that /some/ paths do not lead to murder.
"Make Amends": {
"Chance": 30,
"Requisite": IsHateAbound
},
// This category is intended for those who are marginally
// miffed at someone.
"Libel": {
"Chance": 40,
"Requisite": IsHateAbound,
"Question Morality": {
GetText: function() {
var bases = ["{name} has published an article questioning the morale character of {target}.",
"{name} has released a public statement doubting the morale character of {target}."];
return Helper.RandomizeList( bases )[0];
},
Who: function() {
var source = GetAngryPerson();
var target = source.GetTarget();
// This will only happen if the target is in the early stages of hate.
if ( target.Value > 2 ) return null;
if ( source === undefined || target === undefined || source === null || target === null ) return null;
return {
Source: source,
Target: target
};
},
Action: function( source, target ) {
target.Hate( source );
target.Insanity++;
source.Insanity++;
target.Rep -= 2;
source.Reprimand( "Slander" );
}
},
"Question Sanity": {
GetText: function() {
var bases = ["{name} has published an article questioning the sanity of {target}.",
"{name} tried to institutionalize {target} for alleged insanity."];
return Helper.RandomizeList( bases )[0];
},
Who: function() {
var source = GetAngryPerson();
var target = source.GetTarget();
// This will only happen if the target is in the early stages of hate.
if ( target.Value > 2 ) return null;
if ( source === undefined || target === undefined || source === null || target === null ) return null;
return {
Source: source,
Target: target
};
},
Action: function( source, target ) {
target.Hate( source );
target.Insanity++;
source.Insanity++;
target.Rep -= 2;
source.Reprimand( "Slander" );
target.Reprimand( "Insanity" );
}
}
},
// This category is intended for causing defamation of character
// and should be used by anyone with a high-enough disposition.
"Accuse": {
"Chance": 30,
"Requisite": IsHateAbound,
"Crime": {
}
},
// This category is intended for causing irrepreable financial
// ruin on the part of the target.
"Property Damage": {
"Chance": 20,
"Requisite": IsHateAbound
},
// This category is intended for those who wish to dissolve political
// groups and, eventually, destroy products, albums, paintings, etc.
"Dissolve": {
"Chance": 30,
"Requisite": IsHateAbound,
"Dissolve Political Branch": {
GetText: function( who ) {
// Get the political branch this person is related to.
if ( who.HateBranch.length <= 0 )
return null;
var branch = Helper.RandomizeList( who.HateBranch );
this.ex = branch[0];
var bases = ["{name} has forced the dissolution of the '" + this.ex + "'!",
"{name} has use political clout to shut down the '" + this.ex + "'!",
"{name} has dissolved the '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Get an angry person.
var person = GetAngryPolitician();
if ( person === null || person === undefined || person.HateBranch.length <= 0 ) return null;
// Get the target.
var target_branch = Helper.RandomizeList( person.HateBranch )[0];
this.ex = target_branch;
// Return the information
return {
Source: person
};
},
Action: function( source ) {
for ( var i = 0; i < this.People.length; i++ ) {
if ( this.People[i].HasBranch( this.ex )) {
this.People[i].Hate( source );
this.People[i].RemoveBranch( this.ex );
}
}
}
}
},
// This category is intended for those who have reached their limit with
// peers in the world.
"Murder": {
"Chance": 10,
"Requisite": IsHateAbound
}
},
"Political": {
"Power Change": {
"Chance": 5,
"President Assassinated": {
},
"Vice President Assassinated": {
},
"President Impeached": {
},
"Accidental Death": {
},
"Resignation": {
}
},
"Scandal": {
"Chance": 95,
"Crime": {
},
"Execution": {
},
"Pardon": {
}
},
"Political Climate": {
"Chance": 25,
"Create new Branch": {
GetText: function() {
this.ex = Helper.GetPoliticalBranch();
var bases = ["{name} has established the '" + this.ex + "'!",
"{name} has created the '" + this.ex + "'!",
"{name} has founded the '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// If there are too many branches, return null to prevent
// this action from happening.
if ( this.Branch.length >= 5 ) return null;
// Return the information
return {
Source: this.GetPerson(["President","Vice President","Congressman"])
};
},
Action: function( source ) {
source.Rep += 2;
source.Branch.push( this.ex );
this.Branch.push( this.ex );
}
},
"Fund Branch": {
GetText: function( who ) {
this.ex = Helper.RandomizeList( this.Branch )[0];
var bases = ["{name} has generously donated to the '" + this.ex + "'.",
"{name} has contributed to the '" + this.ex + "'.",
"{name} has donated to the '" + this.ex + "'."];
return Helper.RandomizeList( bases )[0];
},
Who: function() {
if ( this.Branch.length <= 0 ) return null;
return {
Source: this.GetPerson(["President", "Vice President", "Congressman"])
};
},
Action: function( source ) {
source.Rep += 2;
source.Branch.push( this.ex );
}
}
}
},
"Justice": {
"Investigative": {
"Chance": 40,
"Requisite": IsCrimeAbound,
"Investigate Criminal": {
},
"Pardon Criminal": {
},
"Sue Criminal": {
},
"Commit Purjery": {
// NOTE: This is for someone who is under investigation.
},
"Obstruct Investigation": {
// NOTE: This is for someone who is under investigation.
}
},
"Prison": {
"Chance": 20,
"Requisite": IsPrisonersAbound,
"Prison Escape": {
},
"Arrest": {
}
},
// This is the entry point for causing a cascading effect
// in society.
"Pranks": {
"Chance": 40,
"Requisite": function() { return true; },
"Pissing someone off": {
GetText: function() {
var bases = ["{name} is suspected of falsifying an email about {target}!",
"{name} is suspected of accessing confidential information about {target}!",
"{name} is suspected of publicly humiliating {target}!",
"{name} is suspected of threatening {target}!",
"{name} is suspected of harassing {target}!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Return null to prevent this
// action from being taken.
var origin = null, target = null;
do {
origin = this.GetPerson();
target = this.GetPerson();
} while ( origin !== null && target !== null && origin !== target );
// Return the information
return {
Source: origin,
Target: target
};
},
Action: function( source, target ) {
// Cause some contention between the two parties.
target.Hate( source );
// Reprimand the source.
source.Reprimand( "Harassment in the First Degree" );
}
}
}
},
"Culture": {
"Discovery": {
"Chance": 40,
"Requisite": function() { return true; },
"Discover Science": {
GetText: function() {
this.ex = Helper.GetScienceTitle();
var bases = ["{name} has invented the '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Return the information
return {
Source: this.GetPersonInRole("Inventor")
};
},
Action: function( source ) {
source.Rep += 2;
source.Inventions.push( this.ex );
this.Inventions.push( this.ex );
}
}
},
// These are ways to improve your standing in society.
"Creation": {
"Chance": 40,
"Requisite": function() { return true; },
"Form a Group": {
GetText: function() {
this.ex = Helper.GetTitle();
var bases = ["{name} has formed the group '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Return the information
return {
Source: this.GetPerson()
};
},
Action: function( source ) {
source.Rep += 2;
this.Groups.push( this.ex );
}
},
"Unveil a Painting": {
GetText: function() {
this.ex = Helper.GetTitle();
var bases = ["{name} has finished painting '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Return the information
return {
Source: this.GetPerson()
};
},
Action: function( source ) {
source.Rep += 2;
source.Paintings.push( this.ex );
this.Paintings.push( this.ex );
}
},
"Record an Album": {
GetText: function() {
this.ex = Helper.GetTitle();
var bases = ["{name} has finished recording their new album '" + this.ex + "'!"];
return Helper.RandomizeList(bases)[0];
},
Who: function() {
// Return the information
return {
Source: this.GetPerson()
};
},
Action: function( source ) {
source.Rep += 2;
this.Albums.push( this.ex );
}
}
},
"Charity": {
"Chance": 20,
"Requisite": function() { return true; },
"Donate to Invention": {
GetText: function() {
this.ex = Helper.RandomizeList( this.Inventions )[0];
var bases = ["The '" + this.ex + "' has received a large, anonymous donation."];
return Helper.RandomizeList( bases) [0];
},
Who: function() {
return {
Source: this.GetPerson()
};
},
Action: function( source ) {
source.Rep += 1;
source.Inventions.push( this.ex );
}
}
}
}
};
// Constructor
function World() {
this.Population = 150;
this.People = new Array();
this.Roles = {
President: 1,
"Vice President": 1,
Congressman: 5,
Artisan: 5,
Inventor: 5,
Musician: 5
};
// Variables that can be kept track of.
this.Inventions = new Array();
this.Paintings = new Array();
this.Albums = new Array();
this.Groups = new Array();
this.Branch = new Array();
// Populate the world.
this.FillRoles();
}
World.prototype.GetEvent = function() {
// This method is designed to return a random event
// from the event tree. The idea is that the event will
// be guarenteed to work. So the "Requisite" method
// should be called to verify.
var categories = new Array(), evt = null, max = 0, target = 0, current = 0;
for ( var prop in Events ) {
if ( Events.hasOwnProperty( prop ))
categories.push( prop );
}
// Randomly choose a category.
var category = Helper.RandomizeList( categories )[0];
// Add up the chances.
for ( var prop in Events[category] ) {
if ( Events[category].hasOwnProperty( prop ))
if ( Events[category][prop].Chance !== undefined )
max += Events[category][prop].Chance;
}
// Set a target.
target = max * Math.random();
// Iterate again.
for ( var prop in Events[category] ) {
if ( Events[category].hasOwnProperty( prop )) {
if ( Events[category][prop].Chance !== undefined ) {
current += Events[category][prop].Chance;
// Check for a match.
if ( current >= target ) {
evt = Events[category][prop];
}
}
}
}
// Randomly choose something from the bucket.
if ( evt !== null ) {
for ( var prop in evt ) {
if ( evt.hasOwnProperty(prop) && prop !== "Chance" && prop !== "Requisite" ) {
// Check the pre-requisite.
if ( evt[prop].Requisite === undefined || evt[prop].Requisite.call( this )) {
return evt[prop];
}
}
}
}
// If we haven't found anything, recurse.
return this.GetEvent();
}
World.prototype.Iterate = function() {
// This is where the magic happens.
}
World.prototype.FillRoles = function() {
var roles = this.Roles;
for ( var i = 0; i < this.People.length; i++ ) {
// Decrement the role, if we have it.
var person = this.People[i];
if ( roles[person.Role] !== undefined ) {
roles[person.Role]--;
}
}
// Iterate over the remaining roles and populate the world.
for ( var prop in roles ) {
if ( roles.hasOwnProperty(prop) ) {
if ( roles[prop] > 0 ) {
for ( var r = 0; r < roles[prop]; r++ ) {
var person = new Human();
person.Role = prop;
this.People.push( person );
}
}
}
}
// Add any missing people.
for ( var i = this.People.length; i < this.Population; i++ ) {
this.People.push( new Human() );
}
}
World.prototype.GetRoles = function() {
var list = new Array();
for ( var prop in this.Roles )
if ( this.Roles.hasOwnProperty(prop) )
list.push( prop );
return list;
}
World.prototype.GetPerson = function( roles ) {
if ( roles === undefined )
roles = this.GetRoles();
var role = Helper.RandomizeList( roles )[0];
return this.GetPersonInRole( role );
}
World.prototype.GetPersonInRole = function( role, comparator ) {
for ( var i = 0; i < this.People.length; i++ ) {
if ( !this.People[i].Alive ) continue;
// Check if the person matches the role.
if ( this.People[i].Role === role ) {
// Run the comparator, if applicable.
if ( comparator === undefined || comparator.call(this, this.People[i]) ) {
return this.People[i];
}
}
}
return null;
}
return World;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment