-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharena.js
More file actions
120 lines (119 loc) · 3.27 KB
/
arena.js
File metadata and controls
120 lines (119 loc) · 3.27 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
'use strict'
function isGameFinished(gameboard) {
let ai_1 = 0
let ai_2 = 0
let length = gameboard.length
let lengthHalf = (length / 2) - 1
length--
for (let i = 0; i < length; i++) {
if (i === lengthHalf) {
i++
}
let score = gameboard[i]
if (i < lengthHalf) {
ai_1 += score
} else {
ai_2 += score
}
}
return ai_1 === 0 || ai_2 === 0
}
function doMove(gameboard, move, rules) {
let size = gameboard.length
let steps = gameboard[move]
let ownStore = (size / 2) - 1
gameboard[move] = 0
while (0 < steps) {
move++
move %= size
if (move < size - 1) { // If on last, do not add. Is opposite goal.
steps--
gameboard[move] += 1
}
}
if (rules.empty_capture) {
if (move < ownStore && 1 === gameboard[move]) {
let score = gameboard[move]
gameboard[move] = 0
let oppositeSide = size - move - 2
score += gameboard[oppositeSide]
gameboard[oppositeSide] = 0
gameboard[ownStore] += score
}
}
return { moveAgain: move === ownStore, gameboard, gameboard }
}
function sumBoard(gameboard) {
let data = [0, 0]
for (let i = 0; i < gameboard.length; i++) {
data[i < gameboard.length / 2 ? 0 : 1] += gameboard[i]
}
return data
}
function sumScore(score, gameboardLength, startValue, participants) {
let boardValue = gameboardLength * startValue
let errorFound = boardValue != score[0] + score[1]
if (errorFound) {
return null
}
participants.forEach((participant) => {
participant.addScore(score[participant.team])
})
}
function callParticipant(match, aiIndex) {
let participant = match.participants.get(aiIndex % 2, 0)
participant.postMessage(match.gameboard).then((response) => {
let selectedMove = 0
if (response.message) {
if (0 <= response.message.data && response.message.data < match.gameboard.length / 2 && 0 < match.gameboard[response.message.data]) { // Check if legal move.
selectedMove = response.message.data
}
}
while (match.gameboard[selectedMove] === 0) { // Validate
selectedMove++
}
let moveData = doMove(match.gameboard, selectedMove, match.settings.rules)
match.gameboard = moveData.gameboard
ArenaHelper.log('tick', { mover: participant.name, gameboard: match.gameboard.slice() })
// Switch AI
if (!moveData.moveAgain) {
aiIndex++
for (let i = 0; i < match.gameboard.length / 2; i++) {
match.gameboard.push(match.gameboard.shift())
}
}
if (isGameFinished(match.gameboard)) {
if (aiIndex % 2) {
for (let i = 0; i < match.gameboard.length / 2; i++) {
match.gameboard.push(match.gameboard.shift())
}
}
match.participants.terminateAllWorkers()
let score = sumScore(sumBoard(match.gameboard), match.gameboard.length - 2, match.settings.gameboard.startValue, match.participants)
if (score === null) {
ArenaHelper.postAbort(participant, 'General error - Illegal final score.')
} else {
ArenaHelper.postDone()
}
} else {
callParticipant(match, aiIndex)
}
})
}
ArenaHelper.init = (participants, settings) => {
let gameboard = []
for (let i = 0; i < 2; i++) {
for (let n = 0; n < settings.gameboard.boardLength; n++) {
gameboard.push(settings.gameboard.startValue)
}
gameboard.push(0)
}
let match = {
participants: null,
score: undefined,
gameboard: gameboard,
settings: settings,
}
match.participants = participants
callParticipant(match, 0)
}