diff --git a/Assets/Driver.cs b/Assets/Driver.cs
index 41f7ecc..76c3285 100644
--- a/Assets/Driver.cs
+++ b/Assets/Driver.cs
@@ -2,6 +2,7 @@
using Prolog;
using UnityEngine;
+// ReSharper disable once CheckNamespace
public class Driver : MonoBehaviour
{
public GUIStyle CharacterNameStyle;
@@ -30,41 +31,65 @@ public class Driver : MonoBehaviour
private readonly object[] playerRelationships = new object[MaxPlayers];
private readonly bool[] playerRelationshipPin = new bool[MaxPlayers];
+ int currentPlaysetNumber;
+ Playset currentPlayset;
+
+ internal void Start()
+ {
+ SetPlayset(0);
+ }
+
+ void SetPlayset(int playsetNumber)
+ {
+ currentPlaysetNumber = playsetNumber;
+ currentPlayset = Playset.Playsets[playsetNumber];
+ Array.Clear(playerDetailPin, 0, playerDetailPin.Length);
+ Array.Clear(playerRelationshipPin, 0, playerRelationshipPin.Length);
+ }
+
internal void OnGUI()
{
var nameHeight = CharacterNameStyle.lineHeight;
GUI.Label(new Rect(30, 30, 0, 0), "Fiascomatic", CharacterNameStyle);
- GUI.Label(new Rect(30, 60, 100, 30), "Players:");
- countSelection = GUI.Toolbar(new Rect(80, 60, 100, 20), countSelection, playerCountStrings);
+
+ GUI.Label(new Rect(30, 60, 100, 30), "Playset:");
+ var playsetSelection = GUI.Toolbar(new Rect(0, 0, Screen.width, 20), currentPlaysetNumber, Playset.PlaysetNames);
+ if (playsetSelection != currentPlaysetNumber)
+ {
+ SetPlayset(playsetSelection);
+ }
+
+ GUI.Label(new Rect(30, 90, 100, 30), "Players:");
+ countSelection = GUI.Toolbar(new Rect(80, 90, 100, 20), countSelection, playerCountStrings);
playerCount = countSelection + 3;
- GUI.Label(new Rect(30, 175, 150, 300), "Click on a character name to edit it");
+ GUI.Label(new Rect(30, 205, 150, 300), "Click on a character name to edit it");
- if (GUI.Button(new Rect(30, 100, 200, 60), "Let the suffering begin!"))
+ if (GUI.Button(new Rect(30, 130, 200, 60), "Let the suffering begin!"))
{
- this.Setup();
+ Setup();
}
for (int i = 0; i < playerCount; i++)
{
- var textposition = this.PlayerScreenPosition(i);
+ var textposition = PlayerScreenPosition(i);
playerNames[i] = GUI.TextField(
new Rect(textposition.x, textposition.y, 100, nameHeight),
playerNames[i],
- this.CharacterNameStyle);
- var detailposition = this.DetailScreenPosition(i);
+ CharacterNameStyle);
+ var detailposition = DetailScreenPosition(i);
GUI.Label(
new Rect(detailposition.x, detailposition.y, 160, 300),
playerDetailStrings[i],
- this.DetailStyle);
+ DetailStyle);
if (playerDetails[i] != null)
playerDetailPin[i] = GUI.Toggle(new Rect(detailposition.x - 25, detailposition.y, 20, 20), playerDetailPin[i], "");
- var relationshipposition = this.RelationshipScreenPosition(i);
+ var relationshipposition = RelationshipScreenPosition(i);
GUI.Label(
new Rect(relationshipposition.x, relationshipposition.y, 160, 300),
playerRelationshipStrings[i],
- this.RelationshipStyle);
+ RelationshipStyle);
if (playerRelationships[i] != null)
playerRelationshipPin[i] = GUI.Toggle(new Rect(relationshipposition.x - 25, relationshipposition.y, 20, 20), playerRelationshipPin[i], "");
}
@@ -73,43 +98,43 @@ internal void OnGUI()
private void Setup()
{
PrologContext.DefaultStepLimit = 1000000;
- switch (this.playerCount)
+ switch (playerCount)
{
case 3:
- this.SolveSetup(new[]
+ SolveSetup(new[]
{
- this.RelationshipTuple(0, 1), this.RelationshipTuple(1, 2), this.RelationshipTuple(2, 0),
- this.DetailTuple(0), this.DetailTuple(1), this.DetailTuple(2)
+ RelationshipTuple(0, 1), RelationshipTuple(1, 2), RelationshipTuple(2, 0),
+ DetailTuple(0), DetailTuple(1), DetailTuple(2)
});
break;
case 4:
- this.SolveSetup(new[]
+ SolveSetup(new[]
{
- this.RelationshipTuple(0, 1), this.RelationshipTuple(1, 2), this.RelationshipTuple(2, 3),
- this.RelationshipTuple(3, 0),
- this.DetailTuple(0), this.DetailTuple(1), this.DetailTuple(2),
- this.DetailTuple(3)
+ RelationshipTuple(0, 1), RelationshipTuple(1, 2), RelationshipTuple(2, 3),
+ RelationshipTuple(3, 0),
+ DetailTuple(0), DetailTuple(1), DetailTuple(2),
+ DetailTuple(3)
});
break;
case 5:
- this.SolveSetup(new[]
+ SolveSetup(new[]
{
- this.RelationshipTuple(0, 1), this.RelationshipTuple(1, 2), this.RelationshipTuple(2, 3),
- this.RelationshipTuple(3, 4), this.RelationshipTuple(4, 0),
- this.DetailTuple(0), this.DetailTuple(1), this.DetailTuple(2),
- this.DetailTuple(3), this.DetailTuple(4)
+ RelationshipTuple(0, 1), RelationshipTuple(1, 2), RelationshipTuple(2, 3),
+ RelationshipTuple(3, 4), RelationshipTuple(4, 0),
+ DetailTuple(0), DetailTuple(1), DetailTuple(2),
+ DetailTuple(3), DetailTuple(4)
});
break;
case 6:
- this.SolveSetup(new[]
+ SolveSetup(new[]
{
- this.RelationshipTuple(0, 1), this.RelationshipTuple(1, 2), this.RelationshipTuple(2, 3),
- this.RelationshipTuple(3, 4), this.RelationshipTuple(4, 5), this.RelationshipTuple(5, 0),
- this.DetailTuple(0), this.DetailTuple(1), this.DetailTuple(2),
- this.DetailTuple(3), this.DetailTuple(4), this.DetailTuple(5)
+ RelationshipTuple(0, 1), RelationshipTuple(1, 2), RelationshipTuple(2, 3),
+ RelationshipTuple(3, 4), RelationshipTuple(4, 5), RelationshipTuple(5, 0),
+ DetailTuple(0), DetailTuple(1), DetailTuple(2),
+ DetailTuple(3), DetailTuple(4), DetailTuple(5)
});
break;
}
@@ -117,26 +142,26 @@ private void Setup()
private void SolveSetup(object[] setup)
{
- using (var prologContext = PrologContext.Allocate(KnowledgeBase.Global, null))
+ using (var prologContext = PrologContext.Allocate(currentPlayset.KnowledgeBase, null))
{
if (!prologContext.IsTrue("make_setup", Prolog.Prolog.IListToPrologList(setup)))
Debug.Log("Failed to make setup!");
else
{
- for (int i = 0; i < this.playerCount; i++)
+ for (int i = 0; i < playerCount; i++)
{
- this.playerRelationships[i] = Term.CopyInstantiation(setup[i]);
- this.playerRelationshipStrings[i] =
+ playerRelationships[i] = Term.CopyInstantiation(setup[i]);
+ playerRelationshipStrings[i] =
string.Format("{0}",
((Structure)(setup[i])).Argument(1).ToString().Replace("/", " / ")).Replace("_", " ");
}
- for (int i = 0; i < this.playerCount; i++)
+ for (int i = 0; i < playerCount; i++)
{
- this.playerDetails[i] = Term.CopyInstantiation(setup[this.playerCount + i]);
- this.playerDetailStrings[i] = string.Format(
+ playerDetails[i] = Term.CopyInstantiation(setup[playerCount + i]);
+ playerDetailStrings[i] = string.Format(
"{0}:\n{1}",
- ((Structure)(setup[this.playerCount + i])).Argument(1),
- ((Structure)(setup[this.playerCount + i])).Argument(2)).Replace("_", " ");
+ ((Structure)(setup[playerCount + i])).Argument(1),
+ ((Structure)(setup[playerCount + i])).Argument(2)).Replace("_", " ");
}
}
}
@@ -167,7 +192,7 @@ object DetailTuple(int player)
private Vector2 PlayerScreenPosition(int i)
{
var center = new Vector2(Screen.width / 2f , Screen.height / 2f - 50);
- var angle = i * Math.PI * 2 / this.playerCount;
+ var angle = i * Math.PI * 2 / playerCount;
var radius = (Math.Min(Screen.width, Screen.height) * 0.5f) - 70;
var textposition = center + radius * new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
return textposition;
@@ -176,7 +201,7 @@ private Vector2 PlayerScreenPosition(int i)
private Vector2 RelationshipScreenPosition(int i)
{
var center = new Vector2(Screen.width / 2f , Screen.height / 2f - 50);
- var angle = (i+0.5f) * Math.PI * 2 / this.playerCount;
+ var angle = (i+0.5f) * Math.PI * 2 / playerCount;
var radius = (Math.Min(Screen.width, Screen.height) * 0.5f) - 70;
var textposition = center + radius * new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
return textposition;
@@ -184,6 +209,6 @@ private Vector2 RelationshipScreenPosition(int i)
private Vector2 DetailScreenPosition(int i)
{
- return this.PlayerScreenPosition(i) + new Vector2(0f, CharacterNameStyle.lineHeight);
+ return PlayerScreenPosition(i) + new Vector2(0f, CharacterNameStyle.lineHeight);
}
}
diff --git a/Assets/MainScene.unity b/Assets/MainScene.unity
index 4061d38..b873c27 100644
Binary files a/Assets/MainScene.unity and b/Assets/MainScene.unity differ
diff --git a/Assets/Playset.cs b/Assets/Playset.cs
new file mode 100644
index 0000000..cf3fa90
--- /dev/null
+++ b/Assets/Playset.cs
@@ -0,0 +1,43 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using UnityEngine;
+using Prolog;
+
+public class Playset
+{
+ const string PlaysetsDirectory = "Playsets";
+
+ public static readonly List Playsets = new List();
+ public static readonly string[] PlaysetNames;
+ static Playset()
+ {
+ string playsetsPath = Path.Combine(Application.dataPath, PlaysetsDirectory);
+ string[] playsetsDirectory = Directory.GetFiles(playsetsPath);
+ var names = new List();
+ foreach (var playset in playsetsDirectory)
+ {
+ if (Path.GetExtension(playset) == ".prolog")
+ {
+ var playsetName = Path.GetFileNameWithoutExtension(playset);
+ if (playsetName != null)
+ {
+ Playsets.Add(new Playset(playset));
+ names.Add(playsetName);
+ }
+ }
+ }
+ PlaysetNames = names.ToArray();
+ }
+
+
+ private Playset(string path)
+ {
+ KnowledgeBase = new KnowledgeBase(Path.GetFileNameWithoutExtension(path), null);
+ KnowledgeBase.Consult(Path.Combine(Application.dataPath, "Solver.prolog"));
+ KnowledgeBase.Consult(path);
+ }
+
+ public readonly KnowledgeBase KnowledgeBase;
+}
+
diff --git a/Assets/Playset.cs.meta b/Assets/Playset.cs.meta
new file mode 100644
index 0000000..0aff48f
--- /dev/null
+++ b/Assets/Playset.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 907c06800e181d747b2ac004c7230679
+timeCreated: 1446932902
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Playsets/Ethan play set.prolog b/Assets/Playsets/Ethan play set.prolog
new file mode 100644
index 0000000..0d0b528
--- /dev/null
+++ b/Assets/Playsets/Ethan play set.prolog
@@ -0,0 +1,316 @@
+% Ethan Robison
+% Kevin Ye
+% Daniel Thirman
+% Alexander Martin
+
+%
+% relationships
+%
+
+roles_relation(father/son).
+ % son cannot be father of father
+contradiction(relationship(X, father, Y), relationship(Y, father, X)).
+
+symmetric(brothers).
+contradiction(relationship(X, brothers, Y), relationship(X, father, Y)).
+contradiction(relationship(X, brothers, Y), relationship(X, cousins, Y)).
+
+symmetric(cousins).
+ % son cannot be cousin of father
+contradiction(roles_relation(X, father ,Y), roles_relation(X, cousin, Y)).
+
+symmetric(family).
+transitive(family).
+
+symmetric(friends).
+symmetric(at_odds).
+symmetric(old_schoolmates).
+symmetric(old_school_enemies).
+symmetric(amicable_neighbors).
+symmetric(belligerent_neighbors).
+symmetric(cohorts).
+
+generalizes(cousins, family).
+generalizes(brothers, family).
+generalizes(father, family).
+generalizes(son, family).
+
+
+generalizes(old_schoolmates, friends).
+generalizes(amicable_neighbors, friends).
+generalizes(old_school_enemies, at_odds).
+generalizes(belligerent_neighbors, at_odds).
+
+ % no need to make so many conflicting roles...
+contradiction(relationship(X, friends, Y), relationship(X, at_odds, Y)).
+
+
+
+symmetric(sexual_partners).
+ % incest is out
+contradiction(relationship(X, sexual_partners, Y), relationship(X, family, Y)).
+
+
+roles_relation(pastor_of(X)/churchgoer_of(X)):-
+ religion(X).
+implies(role(C, pastor_of(_)), has(C, dogearred_NIV)).
+implies(role(C, pastor_of(_)), has(C, jesus_figurine)).
+ % one pastor_of(_) per town
+contradiction(role(C, pastor_of(_)), role(D, pastor_of(_))) :-
+ C \= D.
+
+roles_relation(sheriff/criminal).
+implies(role(C, sheriff), has(C, stetson_hat)).
+implies(role(C, sheriff), has(C, handgun_45_caliber)).
+% one sheriff per town
+contradiction(role(C, sheriff), role(D, sheriff)):-
+ C \= D.
+
+roles_relation(drug_dealer/druggee).
+implies(role(C, drug_dealer), role(C, criminal)).
+implies(role(C, druggee), role(C, criminal)).
+implies(relationship(X, drug_dealer, Y), relationship(X, cohorts, Y)).
+
+roles_relation(bartender/bar_patron).
+roles_relation(gas_station_clerk/gas_station_patron).
+roles_relation(car_salesman/dealership_patron).
+roles_relation(mechanic/bodyshop_patron).
+
+roles_relation(scientist/subject).
+implies(role(C, scientist), has(C, walkie_talkie)).
+implies(role(C, scientist), has(C, secret_facility_id_card)).
+
+roles_relation(secret_agent/person_of_interest).
+implies(role(C, secret_agent), has(C, handgun_45_caliber)).
+implies(role(C, secret_agent), has(C, walkie_talkie)).
+implies(role(C, secret_agent), has(C, secret_facility_id_card)).
+implies(role(C, secret_agent), has(C, unmarked_sedan)).
+
+
+conflicting_roles(scientist, secret_agent).
+conflicting_roles(scientist, subject).
+conflicting_roles(scientist, person_of_interest).
+conflicting_roles(scientist, bartender).
+conflicting_roles(scientist, car_salesman).
+conflicting_roles(scientist, gas_station_clerk).
+conflicting_roles(scientist, mechanic).
+conflicting_roles(scientist, pastor_of(_)).
+conflicting_roles(scientist, sheriff).
+conflicting_roles(sheriff, criminal).
+conflicting_roles(sheriff, bartender).
+conflicting_roles(sheriff, car_salesman).
+conflicting_roles(sheriff, gas_station_clerk).
+conflicting_roles(sheriff, mechanic).
+conflicting_roles(sheriff, pastor_of(_)).
+conflicting_roles(pastor_of(_), churchgoer_of(_)).
+conflicting_roles(pastor_of(_), bar_patron).
+conflicting_roles(pastor_of(_), criminal).
+conflicting_roles(pastor_of(_), bartender).
+conflicting_roles(pastor_of(_), car_salesman).
+conflicting_roles(pastor_of(_), gas_station_clerk).
+conflicting_roles(pastor_of(_), mechanic).
+conflicting_roles(bartender, bar_patron).
+conflicting_roles(bartender, car_salesman).
+conflicting_roles(bartender, gas_station_clerk).
+conflicting_roles(bartender, mechanic).
+conflicting_roles(gas_station_clerk, car_salesman).
+conflicting_roles(gas_station_clerk, gas_station_patron).
+conflicting_roles(gas_station_patron, mechanic).
+conflicting_roles(car_salesman, dealership_patron).
+conflicting_roles(car_salesman, mechanic).
+conflicting_roles(mechanic, bodyshop_patron).
+
+
+%
+% locations
+%
+
+location(gas_station).
+location(brew_thru).
+location(strip_club).
+location(bar).
+location(winn_dixie).
+location(church).
+location(school).
+location(house).
+
+
+location(inside_car(X)):-
+ car(X).
+ % anyone who starts out in the boat needs to be on the river
+implies(at(X, inside_car(leaky_rowboat)), at(X, river)).
+
+location(car_dealership).
+
+
+location(bog).
+location(tree_grove).
+location(farm).
+location(country_road).
+location(cemetary).
+location(river).
+
+
+location(inside_spaceship).
+location(mysterious_facility).
+location(inside_abondoned_facility).
+location(inside_active_facility).
+
+implies(at(C, inside_active_facility), role(C, secret_agent)).
+implies(at(C, inside_abondoned_facility), role(C, secret_agent)).
+
+%
+% objects
+%
+
+object(X) :-
+ car(X).
+car(red_volvo).
+car(stolen_hot_rod).
+car(leaky_rowboat). % laughs, this was deliberate
+car(old_pickup).
+car(new_pickup).
+car(unmarked_sedan).
+
+
+object(metal_detector).
+object(electric_generator).
+object(barrel_of_motor_oil).
+object(suitcase_of_gold_bullion).
+
+
+object(dogearred_NIV).
+object(jesus_figurine).
+
+
+object(tattered_confederate_flag).
+object(collectors_shotgun).
+
+
+object(handgun_45_caliber).
+object(stetson_hat).
+
+
+object(alien_corpse).
+object(human_corpse).
+contradiction(has(C, alien_corpse), has(D, alien_corpse)) :-
+ C \= D.
+contradiction(has(C, human_corpse), has(D, human_corpse)) :-
+ C \= D.
+
+
+object(walkie_talkie).
+object(secret_facility_id_card).
+object(vial_of_experimental_phlebotinum).
+
+ % these sorts of things are a bit shady...
+object(backpack_full_of_dynamite).
+object(bloody_revolver).
+implies(has(C, backpack_full_of_dynamite, role(C, criminal))).
+implies(has(C, bloody_revolver), role(C, criminal)).
+
+
+object(tesla_coil).
+ % tesla coils are not a common possession...
+implies(has(C, tesla_coil), role(C, scientist)).
+
+object(truth_serum).
+ % truth serum is for secret agents only
+implies(has(C, truth_serum), role(C, secret_agent)).
+
+
+%
+% needs
+%
+
+need(peer_approval).
+need(make_parents_proud).
+need(ten_grand_by_tomorrow).
+need(get_out_of_this_town).
+
+need(find_a_job).
+ % why would such a person even need a job?
+contradiction(needs(C, find_a_job), has(C, suitcase_of_gold_bullion)).
+
+need(satisfy_curiosity).
+need(build_a_flying_machine).
+
+need(sexual_satisfaction).
+ % sexual_satisfaction means that one probably is not getting any
+contradiction(needs(C, sexual_satisfaction), relationship(C, sexual_partners, _)).
+
+need(clean_up_this_town).
+implies(needs(C, clean_up_this_town), role(C, sheriff)).
+
+need(confirm_research_hypothesis).
+ % have to have a hypothesis to confirm it
+implies(needs(C, confirm_research_hypothesis), role(C, scientist)).
+
+need(hide_facility).
+need(guard_facility_secret).
+ % have to know about the faacility to hide/guard it
+implies(needs(C, hide_facility), access_to_secrets(C)).
+implies(needs(C, guard_facility_secret), access_to_secrets(C)).
+
+
+need(keep_parole).
+ % have to have committed a crime to have parole
+implies(needs(C, keep_parole), role(C, criminal)).
+
+need(pay_bar_tab).
+ % have to have a tab to need to pay it
+implies(needs(C, pay_bar_tab), role(C, bar_patron)).
+need(drink_to_forget).
+ % bars are a good start...
+implies(needs(C, drink_to_forget), role(C, bar_patron)).
+
+
+religion(accepting_sort_of_christianity).
+religion(bigoted_sort_of_christianity).
+religion(eldritch).
+religion(paganism).
+
+sacrificing_sort_of_religion(eldritch).
+sacrificing_sort_of_religion(paganism).
+
+need(evangelize_religion(X)) :-
+ religion(X).
+need(follow_religion(X)) :-
+ religion(X).
+
+ % to evangelize a religion one must follow that religion
+implies(needs(C, evangelize_religion(X)), follows_religion(C, X)).
+
+need(encounter_human_for_sacrificial_religion(X)) :-
+ sacrificing_sort_of_religion(X).
+
+ % to need to find a human sacrifice, one must follow that sort of religion
+implies(needs(C, encounter_human_for_sacrificial_religion(X)), follows_religion(C, X)).
+
+ % sons follow their religions of their fathers
+implies((relationship(X, son, Y), follows_religion(Y, R)), follows_religion(X, R)).
+ % people who are trying to sacrifice a person are, knowingly or unknowingly, cohorts
+implies((needs(C, encounter_human_for_sacrificial_religion(R)), needs(D, encounter_human_for_sacrificial_religion(R))), relationship(C, cohorts, D)).
+
+contradiction(follows_religion(C, R1), follows_religion(C, R2)) :-
+ R1 \= R2.
+
+need(drug_addiction(X)) :-
+ drug(X).
+
+need(hide_drug_addiction_to(X)) :-
+ drug(X).
+
+implies(needs(C, hide_drug_addiction_to(X)), needs(C, drug_addiction(X))).
+implies(needs(C, drug_addiction(_)), role(C, druggee)).
+
+drug(meth).
+drug(crack).
+drug(bath_salts).
+drug(human_blood).
+drug(phlebotinum).
+
+need(buy_new_tires_for_car(X)):-
+ car(X).
+ % have to have a car to need tires for it
+implies(needs(C, buy_new_tires_for_car(X)), has(C, X)).
diff --git a/Assets/Playsets/Ethan play set.prolog.meta b/Assets/Playsets/Ethan play set.prolog.meta
new file mode 100644
index 0000000..fe232b8
--- /dev/null
+++ b/Assets/Playsets/Ethan play set.prolog.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 731ba742d1af8be48b88c34f44ecb50e
+timeCreated: 1446935109
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset
index c2c607a..22ea8ba 100644
Binary files a/ProjectSettings/ProjectSettings.asset and b/ProjectSettings/ProjectSettings.asset differ
diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt
index e040c5c..b11ab9b 100644
--- a/ProjectSettings/ProjectVersion.txt
+++ b/ProjectSettings/ProjectVersion.txt
@@ -1,2 +1,2 @@
-m_EditorVersion: 5.2.0f3
+m_EditorVersion: 5.2.2f1
m_StandardAssetsVersion: 0