-
-
Notifications
You must be signed in to change notification settings - Fork 318
/
Node.cs
110 lines (95 loc) · 3.25 KB
/
Node.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (C) 2022 Maxim Gumin, The MIT License (MIT)
using System;
using System.Linq;
using System.Xml.Linq;
abstract class Node
{
abstract protected bool Load(XElement xelem, bool[] symmetry, Grid grid);
abstract public void Reset();
abstract public bool Go();
protected Interpreter ip;
public Grid grid;
public static Node Factory(XElement xelem, bool[] symmetry, Interpreter ip, Grid grid)
{
if (!nodenames.Contains(xelem.Name.LocalName))
{
Interpreter.WriteLine($"unknown node type \"{xelem.Name}\" at line {xelem.LineNumber()}");
return null;
}
Node result = xelem.Name.LocalName switch
{
"one" => new OneNode(),
"all" => new AllNode(),
"prl" => new ParallelNode(),
"markov" => new MarkovNode(),
"sequence" => new SequenceNode(),
"path" => new PathNode(),
"map" => new MapNode(),
"convolution" => new ConvolutionNode(),
"convchain" => new ConvChainNode(),
"wfc" when xelem.Get<string>("sample", null) != null => new OverlapNode(),
"wfc" when xelem.Get<string>("tileset", null) != null => new TileNode(),
_ => null
};
result.ip = ip;
result.grid = grid;
bool success = result.Load(xelem, symmetry, grid);
if (!success) return null;
return result;
}
protected static string[] nodenames = new string[] { "one", "all", "prl", "markov", "sequence", "path", "map", "convolution", "convchain", "wfc" };
}
abstract class Branch : Node
{
public Branch parent;
public Node[] nodes;
public int n;
override protected bool Load(XElement xelem, bool[] parentSymmetry, Grid grid)
{
string symmetryString = xelem.Get<string>("symmetry", null);
bool[] symmetry = SymmetryHelper.GetSymmetry(ip.grid.MZ == 1, symmetryString, parentSymmetry);
if (symmetry == null)
{
Interpreter.WriteLine($"unknown symmetry {symmetryString} at line {xelem.LineNumber()}");
return false;
}
XElement[] xchildren = xelem.Elements(nodenames).ToArray();
nodes = new Node[xchildren.Length];
for (int c = 0; c < xchildren.Length; c++)
{
var child = Factory(xchildren[c], symmetry, ip, grid);
if (child == null) return false;
if (child is Branch branch) branch.parent = branch is MapNode || branch is WFCNode ? null : this;
nodes[c] = child;
}
return true;
}
override public bool Go()
{
for (; n < nodes.Length; n++)
{
Node node = nodes[n];
if (node is Branch branch) ip.current = branch;
if (node.Go()) return true;
}
ip.current = ip.current.parent;
Reset();
return false;
}
override public void Reset()
{
foreach (var node in nodes) node.Reset();
n = 0;
}
}
class SequenceNode : Branch { }
class MarkovNode : Branch
{
public MarkovNode() { }
public MarkovNode(Node child, Interpreter ip) { nodes = new Node[] { child }; this.ip = ip; grid = ip.grid; }
public override bool Go()
{
n = 0;
return base.Go();
}
}