-
Notifications
You must be signed in to change notification settings - Fork 0
/
logic.jsx
101 lines (85 loc) · 2.22 KB
/
logic.jsx
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
89
90
91
92
93
94
95
96
97
98
99
100
101
// @flow
import { BOARD_SIZE, BOARD_SIZE_2 } from "./constants"
export const BLACK: boolean = false
export const WHITE: boolean = true
// Debug board view to console
export const boardPrint = (board: boolean[]) => {
console.log(board.map(t => {
switch (t) {
case BLACK:
return '0'
case WHITE:
return 'O'
default:
return '-'
}
}).reduce((s, v, i) => (
s + v + ((i + 1) % BOARD_SIZE === 0 ? '\n' : ' ')
), ''))
}
// Returns the boolean representation of player;
// false == 'black' or true == 'white'
export const playerType = (turn: number): boolean => (
!!(turn % 2)
)
// Creates an array of neighbouring positions
export const neighbours = (position: number): number[] => {
let nbs: number[] = []
if (position >= BOARD_SIZE) {
nbs.push(position - BOARD_SIZE)
}
if ((position % BOARD_SIZE) !== 0) {
nbs.push(position - 1)
}
if (((position + 1) % BOARD_SIZE) !== 0) {
nbs.push(position + 1)
}
if (position < (BOARD_SIZE * (BOARD_SIZE - 1))) {
nbs.push(position + BOARD_SIZE)
}
return nbs
}
type Group = {positions: number[], alive: boolean};
// Finds the board group belonging to a given piece
export const findGroup = (board: boolean[], position: number): Group => {
let group: Group = {
positions: [],
alive: false
}
let type = board[position]
if (type === null) {
return group
}
// Mutating search
let search: number[] = [position]
for (let i: number = 0; search[i] !== undefined; i++) {
let p = search[i]
let t = board[p]
if (t === type) {
group.positions.push(p)
search.push(
...neighbours(p).filter(x => !search.includes(x))
)
} else if (t === null) {
group.alive = true
}
}
group.positions.sort()
return group
}
// Finds the oppenents groups around a friendly position
export const findThreatenedGroups = (board: boolean[], position: number): Group[] => {
let type: boolean = !board[position] // opponents type
let positions: number[] = neighbours(position).filter(i => board[i] === type)
let groups: Group[] = []
for (let i = positions.length - 1; i >= 0; i--) {
let p = positions[i]
if (groups.reduce((s, g) => (
s || g.positions.includes(p)
), false)) {
continue // skip duplicate groups
}
groups.push(findGroup(board, p))
}
return groups
}