diff options
Diffstat (limited to 'board.h')
-rw-r--r-- | board.h | 85 |
1 files changed, 85 insertions, 0 deletions
@@ -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); |