1 /// Acornsoft Elite space trading video game planet name generator 2 module namegen.elite; 3 4 pure: 5 6 const 7 { 8 ubyte galaxiesNum = 8; 9 ubyte galaxiesMask = 0x07; 10 ushort systemsPerGalaxy = 256; 11 12 ushort[3] seed = [0x5A4A, 0x0248, 0xB753]; 13 14 string otherDigrams = 15 "ABOUSEITILETSTONLONUTHNO"; 16 17 // Dots should be nullprint characters 18 string planetDigrams = 19 "..LEXEGEZACEBISO"~ 20 "USESARMAINDIREA."~ 21 "ERATENBERALAVETI"~ 22 "EDORQUANTEISRION"; 23 24 string[] governments = 25 [ 26 "Anarchy", 27 "Feudal", 28 "Multi-gov", 29 "Dictatorship", 30 "Communist", 31 "Confederacy", 32 "Democracy", 33 "Corporate State", 34 ]; 35 36 string[] economies = 37 [ 38 "Rich Industrial", 39 "Average Industrial", 40 "Poor Industrial", 41 "Mainly Industrial", 42 "Mainly Agricultural", 43 "Rich Agricultural", 44 "Average Agricultural", 45 "Poor Agricultural", 46 ]; 47 } 48 49 struct GalaxySeed 50 { 51 ushort[3] w; 52 alias w this; 53 54 void tweakSeed() pure 55 { 56 ushort t = w[0]; 57 t += w[1]; 58 t += w[2]; 59 60 w[0] = w[1]; 61 w[1] = w[2]; 62 w[2] = t; 63 } 64 } 65 66 GalaxySeed createGalaxySeed(ubyte galaxyNum) 67 { 68 assert(galaxyNum < 8); 69 70 auto g = GalaxySeed(seed); 71 72 while(galaxyNum > 0) 73 { 74 g[0].twist; 75 g[1].twist; 76 g[2].twist; 77 78 galaxyNum--; 79 } 80 81 return g; 82 } 83 84 string makeName(ref GalaxySeed currSeed) 85 { 86 string name; 87 88 const longName = currSeed.isLongName; 89 90 foreach(_; 0 .. 3) 91 { 92 name ~= getPair(currSeed); 93 currSeed.tweakSeed; 94 } 95 96 if(longName) 97 name ~= getPair(currSeed); 98 99 currSeed.tweakSeed; 100 101 return name; 102 } 103 104 unittest 105 { 106 for(ubyte gal = 0; gal < galaxiesNum; gal++) 107 { 108 auto currSeed = createGalaxySeed(gal); 109 110 foreach(i; 0 .. systemsPerGalaxy) 111 { 112 string name = makeName(currSeed); 113 114 if(gal == 0) 115 { 116 assert(i != 0 || name == "TIBEDIED", name); 117 assert(i != 7 || name == "LAVE", name); 118 } 119 120 if(gal == 1) 121 { 122 assert(i != 2 || name == "BEEDBEON", name); 123 } 124 } 125 } 126 } 127 128 private: 129 130 void twist(ref ushort x) 131 { 132 x = rotatel((x >> 8) & 0xFF) * 256 + rotatel(x & 255); 133 } 134 135 ubyte rotatel(ubyte b) /// rotate 8 bit number leftwards 136 { 137 b &= 0xFF; 138 139 return (b & 127) << 1 | b >> 7; 140 } 141 142 bool isLongName(in GalaxySeed seed) 143 { 144 return (seed.w[0] & 64) != 0; 145 } 146 147 auto wrapSeedValueToDigramsIndex(ushort w) 148 { 149 return ((w >> 8) & 31) << 1; 150 } 151 152 string getPair(in GalaxySeed seed) 153 { 154 size_t idx = seed.w[2].wrapSeedValueToDigramsIndex; 155 auto dg = planetDigrams[idx .. idx + 2]; 156 157 import std.string: replace; 158 159 return dg.replace(".", ""); 160 }