summaryrefslogtreecommitdiff
path: root/board.h
diff options
context:
space:
mode:
Diffstat (limited to 'board.h')
-rw-r--r--board.h85
1 files changed, 85 insertions, 0 deletions
diff --git a/board.h b/board.h
new file mode 100644
index 0000000..a144ed7
--- /dev/null
+++ b/board.h
@@ -0,0 +1,85 @@
+#pragma once
+
+#include <iostream>
+#include <vector>
+#include <bitset>
+#include <functional>
+#include <cstdint>
+#include "params.h"
+
+using namespace std;
+
+
+class Bag {
+public:
+ static Bag uninitialised();
+ static Bag makeFull();
+
+ int numLeft(uint8_t clr) const;
+ int totalLeft() const;
+ uint8_t drawRandom();
+ uint8_t peekRandom() const; // picks random colour but doesn't draw
+ void drawColour(uint8_t clr);
+ void replace(uint8_t clr);
+
+private:
+ // Number of stones left of the given colours. Index with clr-1.
+ int num[NC];
+
+ // Sum of num[0 .. NC-1].
+ int sum;
+
+ Bag() = default;
+};
+
+struct Bounds {
+ int left = BSZ, right = -1, top = BSZ, bottom = -1;
+};
+
+class Board {
+public:
+ // Up to the user to keep this in sync with the board. (It is initialised
+ // in makeEmpty().)
+ Bag bag = Bag::uninitialised();
+
+ static Board makeEmpty();
+
+ inline const uint8_t& operator[](int idx) const { return bd[idx]; }
+
+ void put(int idx, uint8_t clr);
+ void undo(int idx);
+
+ uint8_t putCW(int idx, uint8_t clr);
+
+ // The callback may modify the board, but must leave it as it was after returning.
+ void forEachMove(const function<void(int idx)> &f);
+
+ void write(ostream &os) const;
+
+ Bounds computeBounds() const;
+
+private:
+ // 0 = empty, 1...NC = coloured stones
+ uint8_t bd[BSZ * BSZ];
+
+ // Candidates for edge cells; all cells that can take a stone must be
+ // elements of this list, but there may be more.
+ vector<int> edgeCands;
+
+ // Whether a particular cell is in edgeCands.
+ bitset<BSZ * BSZ> inEdgeCands;
+
+ Board() = default;
+
+ int countStones(uint8_t clr, int idx, int delta) const;
+ void newEdgeCand(int idx);
+ bool checkEdge(int idx) const;
+};
+
+struct Stone {
+ uint8_t clr;
+ inline Stone(uint8_t clr) : clr(clr) {}
+};
+
+ostream& operator<<(ostream &os, Stone stone);
+ostream& operator<<(ostream &os, const Board &bd);