Skip to content

Commit 066cf47

Browse files
committed
wip count
1 parent f0799bb commit 066cf47

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

src/main/client/src/model/count.js

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
import {
2+
PointQueue,
3+
} from "./PointQueue.js"
4+
import {
5+
PointList,
6+
} from "./PointList.js"
7+
import {
8+
PointSet,
9+
} from "./PointSet.js"
10+
import {
11+
hasStone,
12+
BLACK,
13+
WHITE,
14+
COLORS,
15+
TERRITORY_B,
16+
TERRITORY_W,
17+
TERRITORY,
18+
REMOVED_B,
19+
REMOVED_W,
20+
} from "../util.js"
21+
22+
function findStone(board, xx, yy) {
23+
if (hasStone(board[yy][xx])) {
24+
return board[yy][xx]
25+
}
26+
let dim = board.length
27+
let pointsChecked = new PointSet(dim)
28+
pointsChecked.add(xx, yy)
29+
let pointsToCheck = new PointQueue(dim)
30+
pointsToCheck.offer(xx, yy)
31+
while (!pointsToCheck.isEmpty()) {
32+
let ptId = pointsToCheck.poll()
33+
let y = Math.trunc(ptId / dim)
34+
let x = ptId % dim
35+
if (hasStone(board[y][x])) {
36+
return board[y][x]
37+
}
38+
if (y > 0 && !pointsChecked.has(x, y - 1)) {
39+
pointsChecked.add(x, y - 1)
40+
pointsToCheck.offer(x, y - 1)
41+
}
42+
if (y < dim - 1 && !pointsChecked.has(x, y + 1)) {
43+
pointsChecked.add(x, y + 1)
44+
pointsToCheck.offer(x, y + 1)
45+
}
46+
if (x > 0 && !pointsChecked.has(x - 1, y)) {
47+
pointsChecked.add(x - 1, y)
48+
pointsToCheck.offer(x - 1, y)
49+
}
50+
if (x < dim - 1 && !pointsChecked.has(x + 1, y)) {
51+
pointsChecked.add(x + 1, y)
52+
pointsToCheck.offer(x + 1, y)
53+
}
54+
}
55+
return 0
56+
}
57+
58+
function colorEmptyTerritory(board, acc, xx, yy) {
59+
if (hasStone(board[yy][xx])) {
60+
acc[yy][xx] = board[yy][xx]
61+
return
62+
}
63+
let found = findStone(board, xx, yy)
64+
if (found === 0) { // empty board
65+
for (let row of acc) {
66+
row.fill(0)
67+
}
68+
return
69+
}
70+
let disputed = false
71+
let opponentColor = found ^ COLORS
72+
let dim = board.length
73+
let territory = new PointList(dim)
74+
let pointsToCheck = new PointQueue(dim)
75+
acc[yy][xx] = getTerritoryMarker(found, board[yy][xx])
76+
pointsToCheck.offer(xx, yy)
77+
while (!pointsToCheck.isEmpty()) {
78+
let ptId = pointsToCheck.poll()
79+
let y = Math.trunc(ptId / dim)
80+
let x = ptId % dim
81+
territory.add(x, y)
82+
if (y > 0) {
83+
let c = board[y - 1][x]
84+
disputed |= c === opponentColor
85+
if (isEmpty(c) && acc[y - 1][x] === -1) {
86+
acc[y - 1][x] = getTerritoryMarker(found, c)
87+
pointsToCheck.offer(x, y - 1)
88+
}
89+
}
90+
if (y < dim - 1) {
91+
let c = board[y + 1][x]
92+
disputed |= c === opponentColor
93+
if (isEmpty(c) && acc[y + 1][x] === -1) {
94+
acc[y + 1][x] = getTerritoryMarker(found, c)
95+
pointsToCheck.offer(x, y + 1)
96+
}
97+
}
98+
if (x > 0) {
99+
let c = board[y][x - 1]
100+
disputed |= c === opponentColor
101+
if (isEmpty(c) && acc[y][x - 1] === -1) {
102+
acc[y][x - 1] = getTerritoryMarker(found, c)
103+
pointsToCheck.offer(x - 1, y)
104+
}
105+
}
106+
if (x < dim - 1) {
107+
let c = board[y][x + 1]
108+
disputed |= c === opponentColor
109+
if (isEmpty(c) && acc[y][x + 1] === -1) {
110+
acc[y][x + 1] = getTerritoryMarker(found, c)
111+
pointsToCheck.offer(x + 1, y)
112+
}
113+
}
114+
}
115+
if (disputed) {
116+
territory.forEach((x, y) => acc[y][x] = board[y][x] & ~TERRITORY)
117+
}
118+
}
119+
120+
export function count(board) {
121+
let acc = createAcc(board.length)
122+
for (let y = 0; y < board.length; y++) {
123+
let row = board[y]
124+
for (let x = 0; x < row.length; x++) {
125+
if (acc[y][x] === -1) {
126+
colorEmptyTerritory(board, acc, x, y)
127+
}
128+
}
129+
}
130+
return acc
131+
}
132+
133+
function getTerritoryMarker(found, empty) {
134+
if ((empty & asRemoved(found)) !== 0) {
135+
return found // resurrect
136+
}
137+
return asTerritory(found) | (empty & ~TERRITORY)
138+
}
139+
140+
function asTerritory(color) {
141+
if (color === BLACK) {
142+
return TERRITORY_B
143+
}
144+
if (color === WHITE) {
145+
return TERRITORY_W
146+
}
147+
return color
148+
}
149+
150+
function asRemoved(color) {
151+
if (color === BLACK) {
152+
return REMOVED_B
153+
}
154+
if (color === WHITE) {
155+
return REMOVED_W
156+
}
157+
return color
158+
}
159+
160+
function createAcc(dim) {
161+
let result = Array(dim)
162+
for (let y = 0; y < dim; y++) {
163+
result[y] = new Int32Array(dim).fill(-1)
164+
}
165+
return result
166+
}
167+
168+
function isEmpty(color) {
169+
return (color & COLORS) === 0
170+
}

0 commit comments

Comments
 (0)