blob: 03f096c623f0787728aaf05c697fc5407837bcc1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#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;
bool checkEdge(int idx) 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);
};
struct Stone {
uint8_t clr;
inline Stone(uint8_t clr) : clr(clr) {}
};
#define EDGE_STR "\x1B[36m+\x1B[0m"
#define OPEN_STR "ยท"
ostream& operator<<(ostream &os, Stone stone);
ostream& operator<<(ostream &os, const Board &bd);
|