1 public import std
.random
: uniform
;
2 import std
.exception
: Exception
;
3 import std
.functional
: memoize
;
4 import std
.string
: format
;
11 // provides dynamic function dispatch with objects, not classes
12 mixin template funcwrapper(alias func
) {
13 import std
.traits
: ReturnType
;
14 mixin(ReturnType
!func
.stringof
~ " "
15 ~ __traits(identifier
, func
)[1 .. $] // [1:$] to get rid of the leading _
16 ~ "(T...)(T args) {" // (Parameters!func).stringof
17 ~ (ReturnType
!func
.stringof
== "void" ?
"" : "return ")
18 ~ __traits(identifier
, func
) ~ "(this, args);"
21 /*mixin template funcwrappers(funcs...) {
22 static foreach (func; funcs) {
23 mixin funcwrapper!func;
32 void delegate(ref Bla self) _func;
34 mixin funcwrapper!_func;
36 writeln(ReturnType!doshit.stringof);
43 bla._func = (ref Bla self) {
44 writefln("I have %s", self.n);
53 public alias rnd
= uniform
;
55 class DException
: Exception
{
56 pragma(inline
, true) pure this(T
...)(T args
) {
61 class InternalError
: DException
{
62 pragma(inline
, true) pure this(T
...)(T args
) {
67 void exit(ubyte code
) {
68 import core
.runtime
: Runtime
;
69 static import core
.stdc
.stdlib
;
71 core
.stdc
.stdlib
.exit(code
);
74 pure string
fillstr(size_t length
, char ch
=' ') {
76 while (length
--> 0) {
83 // a/b chance of returning true
84 bool chances(uint a
, uint b
) {
85 //if (a > b) return chances(b, a);
86 // mod 100 -- 123% = 23%
87 // e.g., 8/5 = 3/5 + 5/5 = 3/5 + 100%. -100%. = 3/5
88 //if (a > b) return chances(a%b, b);
89 //if (a > b) throw new InternalError("HELP ME I DON'T KNOW HOW TO ADD SHIT
90 //if (a >= b) return true; // boring as it is, this is probably the sane choice
91 if (a
> b
) return *(cast(bool*)null); // actually fuck sanity let's SEGFAULT
93 return (a
/b
)*uint.max
> uniform
!uint();
98 // Taken directly from http://stackoverflow.com/a/41978310
99 /* It's supposed to be incredibly performant...but honestly I used it because
100 * I could copy-paste it easily.
102 alias get256colour
= memoize
!((RGBColour colour
) {
103 enum ubyte[6] i2cv
= [0, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
104 pragma(inline
, true) {
105 auto v2ci
= (int v
) => v
< 48 ?
0 : v
< 115 ?
1 : (v
- 35) / 40;
106 auto colour_index
= (int r
, int g
, int b
) => 36*r
+ 6*g
+ b
;
107 auto distance
= (int r1
, int g1
, int b1
, int r2
, int g2
, int b2
) => (r1
-r2
)*(r1
-r2
) + (g1
-g2
)*(g1
-g2
) + (b1
-b2
)*(b1
-b2
);
110 int ir
= v2ci(colour
.r
), ig
= v2ci(colour
.g
), ib
= v2ci(colour
.b
);
111 int average
= (colour
.r
+ colour
.g
+ colour
.b
) / 3;
112 int igray
= average
> 238 ?
23 : (average
-3) / 10;
113 int cr
= i2cv
[ir
], cg
= i2cv
[ig
], cb
= i2cv
[ib
];
114 int gv
= 8 + 10 * igray
;
116 int colour_err
= distance(cr
, cg
, cb
, colour
.r
, colour
.g
, colour
.b
);
117 int gray_err
= distance(gv
, gv
, gv
, colour
.r
, colour
.g
, colour
.b
);
119 return cast(ubyte)(colour_err
<= gray_err ?
16 + colour_index(ir
, ig
, ib
) : 232 + igray
);
124 pragma(inline
, true) ubyte get256colour(ubyte r
, ubyte g
, ubyte b
) { return get256colour(RGBColour(r
, g
, b
)); }
125 pragma(inline
, true) ubyte get256colour(string colour
) { return get256colour(RGBColour(colour
)); }
128 auto newmap
= (ushort height
= map_y
+2, ushort width
= map_x
+2) => new Tile
[][](width
, height
);