aboutsummaryrefslogtreecommitdiff
path: root/source/spots.d
diff options
context:
space:
mode:
Diffstat (limited to 'source/spots.d')
-rw-r--r--source/spots.d119
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('*');