Skip to content

Commit 39c8ff2

Browse files
committed
Merge branch 'refactor-graph'
2 parents b1be93a + a6401af commit 39c8ff2

File tree

18 files changed

+549
-358
lines changed

18 files changed

+549
-358
lines changed

src/IntelOrca.Biohazard.BioRand.Common/Routing/OneToManyDictionary.cs renamed to src/IntelOrca.Biohazard.BioRand.Common/Collections/ImmutableOneToManyDictionary.cs

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,12 @@
1-
using System.Collections.Generic;
2-
using System.Collections.Immutable;
1+
using System.Collections.Immutable;
32

4-
namespace IntelOrca.Biohazard.BioRand.Routing
3+
namespace IntelOrca.Biohazard.BioRand.Collections
54
{
6-
public class OneToManyDictionary<TOne, TMany>
7-
where TOne : notnull
8-
where TMany : notnull
9-
{
10-
private Dictionary<TOne, TMany> _keyToValue = new Dictionary<TOne, TMany>();
11-
private Dictionary<TMany, HashSet<TOne>> _valueToKeys = new Dictionary<TMany, HashSet<TOne>>();
12-
13-
public TMany this[TOne key] => _keyToValue[key];
14-
15-
public bool TryGetValue(TOne key, out TMany value) => _keyToValue.TryGetValue(key, out value);
16-
17-
public void Add(TOne key, TMany value)
18-
{
19-
_keyToValue.Add(key, value);
20-
var set = GetManyToOneList(value);
21-
set.Add(key);
22-
}
23-
24-
public ISet<TOne> GetKeysContainingValue(TMany value)
25-
{
26-
if (_valueToKeys.TryGetValue(value, out var keys))
27-
return keys;
28-
return ImmutableHashSet<TOne>.Empty;
29-
}
30-
31-
private HashSet<TOne> GetManyToOneList(TMany value)
32-
{
33-
if (!_valueToKeys.TryGetValue(value, out var set))
34-
{
35-
set = new HashSet<TOne>();
36-
_valueToKeys.Add(value, set);
37-
}
38-
return set;
39-
}
40-
41-
public ImmutableOneToManyDictionary<TOne, TMany> ToImmutable()
42-
{
43-
return new ImmutableOneToManyDictionary<TOne, TMany>(
44-
_keyToValue.ToImmutableDictionary(),
45-
_valueToKeys.ToImmutableDictionary(x => x.Key, x => x.Value.ToImmutableHashSet()));
46-
}
47-
}
48-
495
public sealed class ImmutableOneToManyDictionary<TOne, TMany>
506
where TOne : notnull
517
where TMany : notnull
528
{
53-
public static ImmutableOneToManyDictionary<Node, Node> Empty { get; } = new ImmutableOneToManyDictionary<Node, Node>();
9+
public static ImmutableOneToManyDictionary<TOne, TMany> Empty { get; } = new ImmutableOneToManyDictionary<TOne, TMany>();
5410

5511
private readonly ImmutableDictionary<TOne, TMany> _keyToValue;
5612
private readonly ImmutableDictionary<TMany, ImmutableHashSet<TOne>> _valueToKeys;

src/IntelOrca.Biohazard.BioRand.Common/Routing/MultiSet.cs renamed to src/IntelOrca.Biohazard.BioRand.Common/Collections/MultiSet.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using System.Collections.Generic;
44
using System.Collections.Immutable;
55

6-
namespace IntelOrca.Biohazard.BioRand.Routing
6+
namespace IntelOrca.Biohazard.BioRand.Collections
77
{
88
internal class MultiSet<T> : ICollection<T>, IEnumerable<T>
99
{
@@ -91,7 +91,7 @@ public IEnumerator<T> GetEnumerator()
9191

9292
internal class ImmutableMultiSet<T> : ICollection<T>, IEnumerable<T> where T : notnull
9393
{
94-
public static ImmutableMultiSet<Node> Empty { get; } = new ImmutableMultiSet<Node>();
94+
public static ImmutableMultiSet<T> Empty { get; } = new ImmutableMultiSet<T>();
9595

9696
private readonly ImmutableDictionary<T, int> _dict = ImmutableDictionary<T, int>.Empty;
9797

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Collections.Generic;
2+
using System.Collections.Immutable;
3+
4+
namespace IntelOrca.Biohazard.BioRand.Collections
5+
{
6+
public class OneToManyDictionary<TOne, TMany>
7+
where TOne : notnull
8+
where TMany : notnull
9+
{
10+
private Dictionary<TOne, TMany> _keyToValue = new Dictionary<TOne, TMany>();
11+
private Dictionary<TMany, HashSet<TOne>> _valueToKeys = new Dictionary<TMany, HashSet<TOne>>();
12+
13+
public TMany this[TOne key] => _keyToValue[key];
14+
15+
public bool TryGetValue(TOne key, out TMany value) => _keyToValue.TryGetValue(key, out value);
16+
17+
public void Add(TOne key, TMany value)
18+
{
19+
_keyToValue.Add(key, value);
20+
var set = GetManyToOneList(value);
21+
set.Add(key);
22+
}
23+
24+
public ISet<TOne> GetKeysContainingValue(TMany value)
25+
{
26+
if (_valueToKeys.TryGetValue(value, out var keys))
27+
return keys;
28+
return ImmutableHashSet<TOne>.Empty;
29+
}
30+
31+
private HashSet<TOne> GetManyToOneList(TMany value)
32+
{
33+
if (!_valueToKeys.TryGetValue(value, out var set))
34+
{
35+
set = new HashSet<TOne>();
36+
_valueToKeys.Add(value, set);
37+
}
38+
return set;
39+
}
40+
41+
public ImmutableOneToManyDictionary<TOne, TMany> ToImmutable()
42+
{
43+
return new ImmutableOneToManyDictionary<TOne, TMany>(
44+
_keyToValue.ToImmutableDictionary(),
45+
_valueToKeys.ToImmutableDictionary(x => x.Key, x => x.Value.ToImmutableHashSet()));
46+
}
47+
}
48+
}

src/IntelOrca.Biohazard.BioRand.Common/Routing/MermaidBuilder.cs renamed to src/IntelOrca.Biohazard.BioRand.Common/Graphing/MermaidBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using System;
22
using System.Text;
33

4-
namespace IntelOrca.Biohazard.BioRand.Routing
4+
namespace IntelOrca.Biohazard.BioRand.Graphing
55
{
6-
internal class MermaidBuilder
6+
public class MermaidBuilder
77
{
88
private readonly StringBuilder _sb = new StringBuilder();
99
private int _indent;
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using System.Collections.Generic;
2+
3+
namespace IntelOrca.Biohazard.BioRand.Routing
4+
{
5+
/// <summary>
6+
/// Builds a graph by passing in the requirements (dependencies)
7+
/// when creating each node.
8+
/// </summary>
9+
public class DependencyGraphBuilder
10+
{
11+
private readonly List<Key> _keys = [];
12+
private readonly List<Node> _nodes = [];
13+
private readonly List<Edge> _edges = [];
14+
private int _id;
15+
16+
private int GetNextId()
17+
{
18+
return ++_id;
19+
}
20+
21+
public Key ReusuableKey(int group, string? label)
22+
{
23+
var key = new Key(GetNextId(), group, KeyKind.Reusuable, label);
24+
_keys.Add(key);
25+
return key;
26+
}
27+
28+
public Key ConsumableKey(int group, string? label)
29+
{
30+
var key = new Key(GetNextId(), group, KeyKind.Consumable, label);
31+
_keys.Add(key);
32+
return key;
33+
}
34+
35+
public Key RemovableKey(int group, string? label)
36+
{
37+
var key = new Key(GetNextId(), group, KeyKind.Removable, label);
38+
_keys.Add(key);
39+
return key;
40+
}
41+
42+
public Node Item(int group, string? label, Node source, params Requirement[] requires)
43+
{
44+
var node = new Node(GetNextId(), group, NodeKind.Item, label);
45+
_nodes.Add(node);
46+
_edges.Add(new Edge(source, node, [.. requires], false));
47+
return node;
48+
}
49+
50+
public Node AndGate(string? label)
51+
{
52+
var node = new Node(GetNextId(), 0, NodeKind.Default, label);
53+
_nodes.Add(node);
54+
return node;
55+
}
56+
57+
public Node AndGate(string? label, Node source, params Requirement[] requires)
58+
{
59+
var node = new Node(GetNextId(), 0, NodeKind.Default, label);
60+
_nodes.Add(node);
61+
_edges.Add(new Edge(source, node, [.. requires], false));
62+
return node;
63+
}
64+
65+
public Node OrGate(string? label, params Node[] sources)
66+
{
67+
var node = new Node(GetNextId(), 0, NodeKind.Default, label);
68+
_nodes.Add(node);
69+
foreach (var r in sources)
70+
{
71+
_edges.Add(new Edge(r, node, [], false));
72+
_edges.Add(new Edge(r, node, [], false));
73+
}
74+
return node;
75+
}
76+
77+
public Node OneWay(string? label, Node source, params Requirement[] requires)
78+
{
79+
var node = new Node(GetNextId(), 0, NodeKind.Default, label);
80+
_nodes.Add(node);
81+
_edges.Add(new Edge(source, node, [.. requires], true));
82+
return node;
83+
}
84+
85+
public Graph Build()
86+
{
87+
return new Graph([.. _keys], [.. _nodes], [.. _edges]);
88+
}
89+
90+
public Route GenerateRoute(int? seed = null)
91+
{
92+
return new RouteFinder(seed).Find(Build());
93+
}
94+
}
95+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using System.Collections.Immutable;
3+
using System.Linq;
4+
5+
namespace IntelOrca.Biohazard.BioRand.Routing
6+
{
7+
public readonly struct Edge(Node source, Node destination, ImmutableArray<Requirement> requires, bool oneWay)
8+
{
9+
public Node Source => source;
10+
public Node Destination => destination;
11+
public ImmutableArray<Requirement> Requires => requires;
12+
public bool OneWay => oneWay;
13+
14+
public IEnumerable<Key> RequiredKeys => requires.Where(x => x.IsKey).Select(x => x.Key!.Value);
15+
public IEnumerable<Node> RequiredNodes => requires.Where(x => x.IsNode).Select(x => x.Node!.Value);
16+
17+
public override string ToString()
18+
{
19+
var requires = Requires.Length == 0 ? "" : $" [{string.Join(", ", Requires)}] ";
20+
return oneWay
21+
? $"{Source} =={requires}=> {Destination}"
22+
: $"{Source} <={requires}=> {Destination}";
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)