|
|
|
|
|
|
|
|
|
|
|
|
|
import Board from './ai/board'; |
|
import { minmax } from './ai/minmax'; |
|
import { board_size } from './config'; |
|
|
|
|
|
onmessage = async function (event) { |
|
const { action, payload } = event.data; |
|
let res = null; |
|
switch (action) { |
|
case 'start': |
|
res = await start(payload.board_size, payload.aiFirst, payload.depth); |
|
break; |
|
case 'move': |
|
res = move(payload.position, payload.depth); |
|
break; |
|
case 'undo': |
|
res = undo(); |
|
break; |
|
case 'end': |
|
res = end(); |
|
break; |
|
default: |
|
break; |
|
} |
|
postMessage({ |
|
action, |
|
payload: res, |
|
}); |
|
}; |
|
|
|
|
|
let board = new Board(board_size); |
|
let score = 0, bestPath = [], currentDepth = 0; |
|
|
|
|
|
const getBoardData = () => { |
|
return { |
|
board: JSON.parse(JSON.stringify(board.board)), |
|
winner: board.getWinner(), |
|
current_player: board.role, |
|
history: JSON.parse(JSON.stringify(board.history)), |
|
size: board.size, |
|
score, |
|
bestPath, |
|
currentDepth, |
|
} |
|
} |
|
|
|
|
|
export const start = async (board_size, aiFirst = true, depth = 4) => { |
|
console.log('start', board_size, aiFirst, depth); |
|
board = new Board(board_size); |
|
try { |
|
if (aiFirst) { |
|
let score, move, bestPath, currentDepth; |
|
if (depth <= 0) { |
|
|
|
|
|
|
|
const response = await fetch('https://zjowowen-gomoku.hf.space/gomoku_server_ui/', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json' |
|
}, |
|
body: JSON.stringify({ |
|
command: 'reset', |
|
argument: depth, |
|
uid: ':1' |
|
})}); |
|
|
|
if (!response.ok) { |
|
throw new Error('Network response was not ok'); |
|
} |
|
const data = await response.json(); |
|
|
|
const agentAction = data.result.action; |
|
move = [agentAction.i, agentAction.j]; |
|
console.log('env reset agent action:', move); |
|
} else { |
|
|
|
const res = minmax(board, board.role, depth); |
|
[score, move, bestPath, currentDepth] = res; |
|
} |
|
|
|
board.put(move[0], move[1]); |
|
} |
|
|
|
} catch (e) { |
|
console.log(e); |
|
|
|
postMessage({ |
|
action: 'error', |
|
payload: { message: e.message } |
|
}); |
|
} |
|
return getBoardData(); |
|
}; |
|
|
|
|
|
export const move = (position, depth) => { |
|
console.log('move now', 'board_size:', board_size, 'depth:', depth); |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!board.isGameOver()) { |
|
let score, move, bestPath, currentDepth; |
|
if (depth <= 0) { |
|
|
|
try { |
|
board.put(position[0], position[1]); |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
|
|
move = [position[2], position[3]]; |
|
} else { |
|
try { |
|
board.put(position[0], position[1]); |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
|
|
const res = minmax(board, board.role, depth); |
|
[score, move, bestPath, currentDepth] = res; |
|
} |
|
|
|
board.put(move[0], move[1]); |
|
} |
|
|
|
return getBoardData(); |
|
}; |
|
|
|
|
|
export const end = () => { |
|
|
|
return getBoardData(); |
|
}; |
|
|
|
|
|
export const undo = () => { |
|
board.undo(); |
|
board.undo(); |
|
return getBoardData(); |
|
} |