diff options
author | Holden Rohrer <hr@hrhr.dev> | 2021-08-31 18:36:27 -0400 |
---|---|---|
committer | Holden Rohrer <hr@hrhr.dev> | 2021-08-31 18:36:27 -0400 |
commit | 9b80e6eef31b0c852c772ba6552e419856fe0aa9 (patch) | |
tree | 2f3e077a8b6c6f8351bcd0d7f18e2f04a9da7af0 /source/spots.d | |
parent | ec9ce614d87a47137cfbbb0f6d13aa30e4a1239c (diff) |
finished in-world portal features
Diffstat (limited to 'source/spots.d')
-rw-r--r-- | source/spots.d | 119 |
1 files changed, 53 insertions, 66 deletions
diff --git a/source/spots.d b/source/spots.d index 49b9c85..a0f549e 100644 --- a/source/spots.d +++ b/source/spots.d @@ -6,94 +6,96 @@ import std.stdio; import lru : LRUCache; import std.traits : isSomeString; -private BigInt positive(BigInt n) -{ +private BigInt positive(BigInt n) { if (n >= 0) return n * 2; else return -n * 2 - 1; } -private BigInt pair(BigInt n, BigInt m) -{ +private BigInt pair(BigInt n, BigInt m) { // https://stackoverflow.com/a/919661 return (positive(n) + positive(m)) * (positive(n) + positive(m) + 1) / 2 + positive(m); } -struct Spot -{ +struct Spot { private char _contents; - this(char c) - { + private int _id; + this(char c) { _contents = c; } + this(char c, int id) { + this(c); + _id = id; + } + import std.format : format, formattedRead; - string toString() - { + string toString() { - return format!`'%c'`(_contents); + return format!`'%c' %d`(_contents, _id); } - void fromString(Range)(auto ref Range s) - { - s.formattedRead!`'%c'`(_contents); + void fromString(Range)(auto ref Range s) { + s.formattedRead!`'%c' %d`(_contents, _id); } - @property contents() - { + @property contents() { return _contents; } - bool opEqual(const Spot s) - { + @property id() { + return _id; + } + + bool opEqual(const Spot s) { return s._contents == _contents; } - bool isRock() - { + bool isSpace() { + return _contents == ' '; + } + + bool isRock() { return _contents == '*'; } + + bool isPortal() { + return _contents == '/'; + } } -interface SpotSource -{ +interface SpotSource { Spot opIndex(BigInt y, BigInt x); void save(File); void load(File); } -class RandomSource : SpotSource -{ +class RandomSource : SpotSource { uint seed; double density = .0025; private LRUCache!(BigInt[2], Spot) cache; - this() - { + this() { seed = unpredictableSeed; cache = new LRUCache!(BigInt[2], Spot)(50000); } - this(uint seed) - { + this(uint seed) { this.seed = seed; } - this(uint seed, double density) - { + this(uint seed, double density) { this.density = density; this(seed); } - private uint hash(BigInt n) - { + private uint hash(BigInt n) { CRC32 crc; crc.start(); crc.put((cast(ubyte*)&seed)[0 .. seed.sizeof]); - foreach (i; iota(n.ulongLength)) - { + foreach (i; iota(n.ulongLength)) { auto digit = n.getDigit(i); crc.put((cast(ubyte*)&digit)[0 .. digit.sizeof]); } @@ -102,8 +104,7 @@ class RandomSource : SpotSource return hash; } - public Spot opIndex(BigInt y, BigInt x) - { + public Spot opIndex(BigInt y, BigInt x) { if ([y, x] in cache) return cache[[y, x]]; auto roll = cast(double) hash(pair(y, x)) / uint.max; @@ -116,44 +117,35 @@ class RandomSource : SpotSource return ret; } - public void save(File f) - { + public void save(File f) { f.writefln!"%d %f"(seed, density); } - public void load(File f) - { + public void load(File f) { f.readf!"%d %f\n"(seed, density); cache = new LRUCache!(BigInt[2], Spot)(50000); } } -class OverlaySource : SpotSource -{ +class OverlaySource : SpotSource { private SpotSource _base; private Spot[BigInt[2]] _overlay; immutable private string terminator = "END OVERLAY\n"; - this(SpotSource base) - { + this(SpotSource base) { _base = base; } - void opIndexAssign(Spot spot, BigInt y, BigInt x) - { + void opIndexAssign(Spot spot, BigInt y, BigInt x) { Spot* p = [y, x] in _overlay; - if (p !is null && spot == _base[y, x]) - { + if (p !is null && spot == _base[y, x]) { _overlay.remove([y, x]); - } - else - { + } else { _overlay[[y, x]] = spot; } } - Spot opIndex(BigInt y, BigInt x) - { + Spot opIndex(BigInt y, BigInt x) { Spot* p = [y, x] in _overlay; if (p !is null) return *p; @@ -161,25 +153,21 @@ class OverlaySource : SpotSource return _base[y, x]; } - void save(File f) - { + void save(File f) { _base.save(f); - foreach (coord; _overlay.keys()) - { + foreach (coord; _overlay.keys()) { f.writefln!"%s %s: %s"(coord[0], coord[1], _overlay[coord]); } f.write(terminator); } - void load(File f) - { + void load(File f) { import std.conv : to; import std.algorithm; //_overlay = _overlay.init; _base.load(f); - foreach (char[] line; f.lines) - { + foreach (char[] line; f.lines) { if (line == terminator) break; @@ -189,14 +177,13 @@ class OverlaySource : SpotSource ints.popFront; coord[1] = ints.front; - auto s = new Spot(); - (*s).fromString(line.find(':').find('\'')); - _overlay[coord] = *s; + auto s = Spot(); + s.fromString(line.find(':').find('\'')); + _overlay[coord] = s; } } - unittest - { + unittest { auto base = new RandomSource(0, 0.0); auto src = new OverlaySource(base); src[BigInt(0), BigInt(0)] = Spot('*'); |