+ getComputerMove() {
+ let moves = this.getAllValidMoves();
+ if (moves.length == 0) return null;
+ // "Search" at depth 1 for now
+ const maxeval = V.INFINITY;
+ const color = this.turn;
+ const emptyMove = {
+ start: { x: -1, y: -1 },
+ end: { x: -1, y: -1 },
+ appear: [],
+ vanish: []
+ };
+ moves.forEach(m => {
+ this.play(m);
+ m.eval = (color == "w" ? -1 : 1) * maxeval;
+ const moves2 = this.getAllValidMoves().concat([emptyMove]);
+ m.next = moves2[0];
+ moves2.forEach(m2 => {
+ this.play(m2);
+ const score = this.getCurrentScore();
+ let mvEval = 0;
+ if (score != "1/2") {
+ if (score != "*") mvEval = (score == "1-0" ? 1 : -1) * maxeval;
+ else mvEval = this.evalPosition();
+ }
+ if (
+ (color == 'w' && mvEval > m.eval) ||
+ (color == 'b' && mvEval < m.eval)
+ ) {
+ m.eval = mvEval;
+ m.next = m2;
+ }
+ this.undo(m2);
+ });
+ this.undo(m);
+ });
+ moves.sort((a, b) => {
+ return (color == "w" ? 1 : -1) * (b.eval - a.eval);
+ });
+ let candidates = [0];
+ for (let i = 1; i < moves.length && moves[i].eval == moves[0].eval; i++)
+ candidates.push(i);
+ const mIdx = candidates[randInt(candidates.length)];
+ const move2 = moves[mIdx].next;
+ delete moves[mIdx]["next"];
+ return [moves[mIdx], move2];
+ }
+