Skip to content

Instantly share code, notes, and snippets.

@jonbro
Created November 8, 2013 15:18
Show Gist options
  • Save jonbro/7372471 to your computer and use it in GitHub Desktop.
Save jonbro/7372471 to your computer and use it in GitHub Desktop.
nanogenmo code version 2
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class MChain {
public class Node {
public string content;
public List<Node> followers; // just duplicate for each follower, make the random pick easier
public Node(string c){
content = c;
followers = new List<Node>();
}
}
public Dictionary<string, Node> allNodes;
public MChain(){
allNodes = new Dictionary<string, Node>();
}
public void BuildChain(string inputText){
// split the string based on whatever
Node lastNode = null;
foreach (string currentNode in inputText.Split(' ')) {
if (lastNode == null) {
allNodes.Add(currentNode, new Node(currentNode));
} else {
if (allNodes.ContainsKey(currentNode)) {
lastNode.followers.Add(allNodes[currentNode]);
} else {
Node thisNode = new Node(currentNode);
allNodes.Add(currentNode, thisNode);
lastNode.followers.Add(thisNode);
}
}
lastNode = allNodes[currentNode];
}
}
}
public class Structure {
// a description, allowed portals, and an allow structural bit
public enum SturctureType {
WALL,
FLOOR,
COLUMN,
CEILING,
CONNECTOR
};
public string description;
public Structure.SturctureType[] allowedTypes;
public static Structure[] structures = new []{
new Structure{
description = "wooden",
allowedTypes = new []{SturctureType.WALL, SturctureType.FLOOR, SturctureType.CEILING}
},
new Structure{
description = "glass block",
allowedTypes = new []{SturctureType.WALL}
},
new Structure{
description = "Linoleum",
allowedTypes = new []{SturctureType.WALL, SturctureType.FLOOR}
},
new Structure{
description = "acoustic tile",
allowedTypes = new []{SturctureType.CEILING}
},
new Structure{
description = "metal pole",
allowedTypes = new []{SturctureType.COLUMN}
},
new Structure{
description = "concrete pillar",
allowedTypes = new []{SturctureType.COLUMN}
},
new Structure{
description = "wood panel",
allowedTypes = new []{SturctureType.WALL}
}
};
public static List<Structure> GetStructuresForType(Structure.SturctureType t){
List<Structure> rList = new List<Structure> ();
foreach (Structure s in structures) {
foreach (Structure.SturctureType st in s.allowedTypes) {
if (st == t) {
rList.Add (s);
break;
}
}
}
return rList;
}
}
public class Location {
/*
// locations are made up of:
// base description
// structural elements (walls, floors) ... allow certain types of portals to be contained within
// objects contained within
// portals (connect to other locations)
*/
List<Structure> walls = new List<Structure>();
Structure floor;
Structure ceiling;
Structure columns;
public Location(){
// build the location out of four walls, a floor and a ceiling
// pick a wall type, bias towards existing wall types
int nWalls = Random.Range (3, 6);
List<Structure> allWallTypes = Structure.GetStructuresForType (Structure.SturctureType.WALL);
for (int i=0; i<nWalls; i++) {
walls.Add(allWallTypes[Random.Range(0, allWallTypes.Count)]);
}
}
public string GetDescription(){
// pick a random wall and return the description for it
// pick a specific wall
return "a room with a " + walls [Random.Range (0, walls.Count)].description + " wall";
}
}
public class Character {
public string name;
public Character(){
BuildName ();
}
// generate a name based on inputs from a text file
string nameStart = "den\n" +
"s\n" +
"bint\n" +
"rum\n" +
"qen\n" +
"par\n" +
"net\n" +
"frow\n" +
"telu";
string nameMid = "den\n" +
"tu\n" +
"un\n" +
"my\n" +
"d\n" +
"rat\n" +
"h\n" +
"en\n" +
"dal\n" +
"dus";
string nameEnd = "son\n" +
"san\n" +
"und\n" +
"dar\n" +
"il\n" +
"tun\n" +
"at\n" +
"t\n" +
"lus\n" +
"ul";
void BuildName(){
string[] first = nameStart.Split('\n');
string[] mid = nameMid.Split('\n');
string[] end = nameEnd.Split('\n');
name = first[Random.Range(0, first.Length)].Trim();
int nameMidCount = Random.Range(0, 2);
for (int i=0; i<nameMidCount; i++) {
name += mid[Random.Range (0, mid.Length)].Trim();
}
name += end [Random.Range (0, end.Length)];
}
}
public class RoomDescription : MonoBehaviour {
public TextAsset corpus;
// current plan, take corpus, build markov chain, output
// corpus of apartment blogs and travel blogs
// further plans: extract parts of speech and intelligently include them in the output words
// Use this for initialization
MChain chain = new MChain();
Character mainChar;
Location mainRoom;
bool built;
void Start () {
mainChar = new Character ();
mainRoom = new Location ();
}
void Update() {
if (!built) {
Debug.Log(mainChar.name + " is in " + mainRoom.GetDescription() +".");
built = true;
}
}
void BuildChain(){
chain.BuildChain(corpus.text);
// build a random output
List<string> keyList = new List<string>(chain.allNodes.Keys);
string randomKey = keyList[Random.Range(0, keyList.Count)];
string output = "";
MChain.Node startNode = chain.allNodes[randomKey];
output += startNode.content + " ";
for (int i=0; i<2000; i++) {
// pick a random node from the followers in the current node
startNode = startNode.followers[Random.Range(0, startNode.followers.Count)];
output += startNode.content + " ";
}
Debug.Log(output);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment