MWS_2021/unity_artifitial_world-st/Assets/Scripts/LSystem/Program.cs
2021-03-26 21:33:33 +01:00

354 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleLSystem {
public class LSystemNodeLiteral {
public string name { get; }
public int values_number { get; }
public float[] values { get; set; }
public LSystemNodeLiteral(string name, int values_number) {
this.name = name;
this.values_number = values_number;
//in case it would be 0
values = new float[values_number];
}
public LSystemNodeLiteral(LSystemNodeLiteral other) {
this.name = other.name;
this.values_number = other.values_number;
//in case it would be 0
values = new float[this.values_number];
other.values.CopyTo(values, 0);
}
public static bool operator ==(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) {
return thisLiteral.name == other.name && thisLiteral.values_number == other.values_number;
}
public static bool operator !=(LSystemNodeLiteral thisLiteral, LSystemNodeLiteral other) {
return !(thisLiteral.name == other.name && thisLiteral.values_number == other.values_number);
}
public override string ToString() {
if (values_number == 0) {
return name;
}
else {
StringBuilder sb = new StringBuilder(name, name.Length + values_number * 7 + 4);
sb.Append("(");
for (int i = 0; i < values_number; i++) {
var v = values[i];
sb.AppendFormat("{0:0.##}", v);
if (i < values_number - 1) {
sb.Append(",");
}
}
sb.Append(")");
return sb.ToString();
}
}
}
public class LSystemNode {
public LSystemNodeLiteral literal { get; set; }
public List<LSystemNode> children { get; set; }
public LSystemNode mainChild { get; set; }
private LSystemNode _parent;
public LSystemNode parent {
get { if (_parent is null) { return new LSystemNode(new LSystemNodeLiteral(" _ ", 0)); }
else { return _parent; } }
set { _parent = value; } }
public LSystemNode(LSystemNodeLiteral nodeLiteral) {
literal = nodeLiteral;
children = new List<LSystemNode>();
mainChild = null;
}
public LSystemNode(LSystemNodeLiteral nodeLiteral, List<LSystemNode> children, LSystemNode mainChild) {
literal = nodeLiteral;
this.children = children;
this.mainChild = mainChild;
}
public LSystemNode(LSystemNodeLiteral nodeLiteral, List<LSystemNode> children) {
literal = nodeLiteral;
this.children = children;
this.mainChild = null;
}
public List<LSystemNode> getAllChildren() {
var result = new List<LSystemNode>(children);
if (mainChild != null){
result.Add(mainChild);
}
return result;
}
public LSystemNode deep_copy() {
if (children.Count() == 0 && mainChild == null) {
return new LSystemNode(new LSystemNodeLiteral(literal));
}
else if (mainChild != null) {
var result = new LSystemNode(new LSystemNodeLiteral(literal));
result.mainChild = mainChild.deep_copy();
return result;
}
else {
var new_children = new List<LSystemNode>();
foreach (var x in children) {
new_children.Add(x.deep_copy());
}
return new LSystemNode(literal, new_children, this.mainChild.deep_copy());
}
}
private static LSystemNode deepestNode(LSystemNode node) {
while (node.mainChild != null) {
node = node.mainChild;
}
return node;
}
public LSystemNode newParent() {
return deepestNode(this);
}
public override string ToString() {
StringBuilder sb = new StringBuilder(literal.ToString());
var node = this;
while (true) {
foreach (var child in node.children) {
sb.Append("[");
sb.Append(child.ToString());
sb.Append("]");
}
if (node.mainChild != null) {
sb.Append(node.mainChild.literal.ToString());
node = node.mainChild;
}
else {
return sb.ToString();
}
}
}
}
public class LSystemEvaluator {
public LSystemNode lSystemString { get; set; }
public List<LSystemRule> lSystemRules { get; set; }
public String[] ignored { get; set; }
public LSystemEvaluator(LSystemNode startingString, List<LSystemRule> rules) {
lSystemString = startingString;
lSystemRules = rules;
ignored = new String[0];
}
public LSystemEvaluator(LSystemNode startingString, List<LSystemRule> rules, String[] ignored) {
lSystemString = startingString;
lSystemRules = rules;
this.ignored = ignored;
}
private LSystemNode _rewrite(LSystemNode node) {
foreach (var rule in lSystemRules) {
if (rule.is_aplicable(node, ignored)) {
return rule.rewrite(node, ignored);
}
}
return new LSystemNode(node.literal);
}
//private void _rewrite_recursive(LSystemNode node, LSystemNode parent) {
// var new_node = _rewrite(node);
// parent.children.Add(new_node);
// new_node.parent = parent;
// var new_parent = new_node.newParent();
// foreach (var child in node.children) {
// _rewrite_recursive(child, new_parent);
// }
//}
private void _rewrite_recursive(LSystemNode node, LSystemNode parent) {
var new_node = _rewrite(node);
parent.children.Add(new_node);
new_node.parent = parent;
var new_parent = new_node.newParent();
foreach (var child in node.children) {
_rewrite_recursive(child, new_parent);
}
while (node.mainChild != null) {
new_node = _rewrite(node.mainChild);
new_node.parent = new_parent;
new_parent.mainChild = new_node;
new_parent = new_node.newParent();
foreach (var child in node.mainChild.children) {
_rewrite_recursive(child, new_parent);
}
node = node.mainChild;
}
}
public void rewrite() {
var new_root = _rewrite(lSystemString);
var new_parent = new_root.newParent();
foreach (var child in lSystemString.children) {
_rewrite_recursive(child, new_parent);
}
var node = lSystemString;
while (node.mainChild != null) {
var new_node = _rewrite(node.mainChild);
new_node.parent = new_parent;
new_parent.mainChild = new_node;
new_parent = new_node.newParent();
foreach (var child in node.mainChild.children) {
_rewrite_recursive(child, new_parent);
}
node = node.mainChild;
}
lSystemString = new_root;
}
//private void rewrite(ref LSystemNode currentNode)
}
//abstract class LSystemWordParser { }
//abstract class LSystemRulesParser { }
class A {
public int B { get; set; }
public A[] AA { get; set; }
}
class Program {
static void runParametric() {
Dictionary<string, int> variableIndex = new Dictionary<string, int> {
{"a", 0},
{"b", 1},
};
var predecesor1 = LSystemFileParser.parsePredecesor("B(a,b)");
var predecesor2 = LSystemFileParser.parsePredecesor("A(a)");
var condition1 = MathExpressionComparasionParser.parse(variableIndex, "a>b");
var condition2 = MathExpressionComparasionParser.parse(variableIndex, "a>5");
var builder = new LSystemWordGeneratorBuilder(variableIndex);
var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,b)[A(a/2)]A(a/2)", builder);
var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a+3.5,b+1)", builder);
var consequent3 = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(0,a)", builder);
var consequent4 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder);
var rule1 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { condition1 }, consequent1 );
var rule2 = new LSystemRuleParametric(predecesor1, new MathExpressionComparison[] { }, consequent2 );
var rule3 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { condition2 }, consequent3 );
var rule4 = new LSystemRuleParametric(predecesor2, new MathExpressionComparison[] { }, consequent4);
var axiom = LSystemFileParser.parseWord("A(6)", new LSystemWordBuilder());
var rules = new List<LSystemRule> { rule1, rule2, rule3, rule4 };
var evaluator = new LSystemEvaluator(axiom, rules);
Console.WriteLine(evaluator.lSystemString.ToString());
for (int i = 0; i < 20; i++) {
evaluator.rewrite();
Console.WriteLine(evaluator.lSystemString.ToString());
}
}
static void runContext() {
var axiom = LSystemFileParser.parseWord("A(1)A(1)A(1)A(1)A(1)A(1)B(2)", new LSystemWordBuilder());
var predecesor = LSystemFileParser.parsePredecesor("A(a)");
var predecesor1 = LSystemFileParser.parsePredecesor("B(b)");
var contex = new LSystemContext();
contex.setOnlySucceeding(new LSystemNodeLiteral("B", 1));
var contex1 = new LSystemContext();
contex1.setOnlyPreceding(new LSystemNodeLiteral("A", 1));
Dictionary<string, int> variableIndex = new Dictionary<string, int> {
{ "a", 0 },
{ "b", 1 },
};
var builder = new LSystemWordGeneratorBuilder(variableIndex);
var consequent = (LSystemNodeGenerator)LSystemFileParser.parseWord("B(a)", builder);
var consequent1 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(1)", builder);
var consequent2 = (LSystemNodeGenerator)LSystemFileParser.parseWord("A(a+1)", builder);
MathExpressionComparison comparison = MathExpressionComparasionParser.parse(variableIndex, "a>b");
MathExpressionComparison comparison1 = MathExpressionComparasionParser.parse(variableIndex, "a<=b");
var rule = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { comparison }, consequent, contex);
var rule1 = new LSystemRuleParametricStochasticContext(predecesor, new MathExpressionComparison[] { }, consequent2, contex);
var rule2 = new LSystemRuleParametricStochasticContext(predecesor1, new MathExpressionComparison[] { comparison }, consequent1, contex1);
var rules = new List<LSystemRule> { rule, rule1, rule2 };
var evaluator = new LSystemEvaluator(axiom, rules);
Console.WriteLine(evaluator.lSystemString.ToString());
for (int i = 0; i < 20; i++) {
evaluator.rewrite();
Console.WriteLine(evaluator.lSystemString.ToString());
}
}
static void runFile() {
Console.WriteLine("Enter filepath:");
string filepath = Console.ReadLine();
var evaluator = LSystemFileParser.parseLSystem(new StreamReader(filepath));
Console.WriteLine(evaluator.lSystemString.ToString());
while (true) {
Console.ReadLine();
evaluator.rewrite();
Console.WriteLine(evaluator.lSystemString.ToString());
}
}
static void Main(string[] args) {
runFile();
//runContext();
//var Al = new LSystemNodeLiteral("Al", 0);
//var Ar = new LSystemNodeLiteral("Ar", 0);
//var Bl = new LSystemNodeLiteral("Bl", 0);
//var Br = new LSystemNodeLiteral("Br", 0);
//var root = new LSystemNode(Ar);
//var rule_list = new List<LSystemRule>();
//var result = new LSystemNode(Al);
//result.children.Add(new LSystemNode(Br));
//rule_list.Add(new LSystemRuleBasic(Ar, result));
//result = new LSystemNode(Bl);
//result.children.Add(new LSystemNode(Ar));
//rule_list.Add(new LSystemRuleBasic(Al, result));
//result = new LSystemNode(Ar);
//rule_list.Add(new LSystemRuleBasic(Br, result));
//result = new LSystemNode(Al);
//rule_list.Add(new LSystemRuleBasic(Bl, result));
//var evaluator = new LSystemEvaluator(root, rule_list);
//for (int i=0; i < 5; i++) {
// Console.WriteLine(evaluator.lSystemString.ToString());
// evaluator.rewrite();
//}
//Console.WriteLine(evaluator.lSystemString.ToString());
//var node = LSystemFileParser.parseWord("A[AA][A]AB(1,2)[A(1)]C", new LSystemWordBuilder());
//Console.WriteLine(node.ToString());
}
}
}