1 module gameboard; 2 3 enum boardWidth = 6; 4 enum boardHeight = 9; 5 enum numRounds = 9; 6 7 struct Hex 8 { 9 size_t playerId; 10 uint numShips; 11 uint systemLevel; 12 } 13 14 enum triPrimeX = 2; 15 enum triPrimeY = 3; 16 17 bool isTriPrime(size_t x, size_t y) 18 { 19 return 20 (y == 3 && x == 2) || 21 (y == 4 && (x == 2 || x == 3)) || 22 (y == 5 && x == 2); 23 } 24 25 struct HexCoords 26 { 27 ubyte x; 28 ubyte y; 29 } 30 31 uint sectorNumber(HexCoords hexCoords) 32 { 33 return hexCoords.x / 2 + (hexCoords.y / 3) * 3; // [0..9) 34 } 35 36 HexCoords hexCoordsFromIndex(ubyte index) // [0..54) 37 { 38 return HexCoords(index % boardWidth, index / boardWidth); 39 } 40 41 // 6 x 9 42 struct GameBoard 43 { 44 Hex[54] data; 45 46 ref Hex triPrime() @property 47 { 48 return data[triPrimeX + triPrimeY * boardWidth]; 49 } 50 51 ref Hex triPrime(Hex newData) @property 52 { 53 return data[triPrimeX + triPrimeY * boardWidth] = newData; 54 } 55 56 ref Hex opIndex(size_t x, size_t y) 57 { 58 // x < 6 on even row, x < 5 on odd row. 59 if (x >= boardWidth - (y % 2) || y >= boardHeight) 60 return data[11]; // unused hex 61 62 if (isTriPrime(x, y)) 63 return triPrime; 64 65 return data[x + y * boardWidth]; 66 } 67 68 ref Hex opIndexAssign(Hex newData, size_t x, size_t y) 69 { 70 // x < 6 on even row, x < 5 on odd row. 71 if (x >= boardWidth - (y % 2) || y >= boardHeight) 72 return data[11]; // unused hex 73 74 if (isTriPrime(x, y)) 75 return triPrime = newData; 76 77 return data[x + y * boardWidth] = newData; 78 } 79 80 auto sectorHexes(ubyte sectorId) // 0-8 81 { 82 HexCoords[] sectors; 83 foreach(ubyte index, hex; data) 84 { 85 HexCoords coords = hexCoordsFromIndex(index); 86 if (sectorNumber(coords) == sectorId) 87 sectors ~= coords; 88 } 89 return sectors; 90 } 91 }