Skip to content

Commit

Permalink
feat: migrate computer to async
Browse files Browse the repository at this point in the history
  • Loading branch information
loks0n committed Apr 2, 2023
1 parent 4c1ca50 commit 1f2c9c8
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 29 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ const strongComputer = ComputerFactory.alphaBeta({
while (draughts.status === DraughtsStatus.PLAYING) {
console.log(`${draughts.asciiBoard()}`);
console.log(`to_move = ${draughts.player}`);
const move =
draughts.player === DraughtsPlayer.LIGHT
? weakComputer(draughts)
: strongComputer(draughts);

const computerPlayer =
draughts.player === DraughtsPlayer.LIGHT ? weakComputer : strongComputer;

const move = await computerPlayer(draughts);
if (move) draughts.move(move);
}

Expand Down
8 changes: 4 additions & 4 deletions examples/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const strongComputer = ComputerFactory.alphaBeta({
while (draughts.status === DraughtsStatus.PLAYING) {
console.log(`${draughts.asciiBoard()}`);
console.log(`to_move = ${draughts.player}`);
const move =
draughts.player === DraughtsPlayer.LIGHT
? weakComputer(draughts)
: strongComputer(draughts);

const computerPlayer =
draughts.player === DraughtsPlayer.LIGHT ? weakComputer : strongComputer;

const move = await computerPlayer(draughts);
if (move) draughts.move(move);
}

Expand Down
29 changes: 14 additions & 15 deletions src/computer/alpha-beta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,28 @@ export type AlphaBetaOptions<T extends Bitboard, E> = {
quiescence?: boolean;
};

export function alphaBeta<T extends Bitboard, E>({
export async function alphaBeta<T extends Bitboard, E>({
options: { maxDepth, evaluationFunction, quiescence = true },
engine,
}: DraughtsComputerStrategyArgs<
T,
E,
AlphaBetaOptions<T, E>
>): DraughtsEngineMove<T> {
}: DraughtsComputerStrategyArgs<T, E, AlphaBetaOptions<T, E>>): Promise<
DraughtsEngineMove<T>
> {
let recordEvaluation = Number.NEGATIVE_INFINITY;
let recordMove: DraughtsEngineMove<T> | undefined;

for (const move of engine.moves) {
const next = engine.clone();
next.move(move);

const evaluation = -alphaBetaSearch({
const evaluation = -(await alphaBetaSearch({
data: {
engine: next,
alpha: Number.NEGATIVE_INFINITY,
beta: Number.POSITIVE_INFINITY,
depth: maxDepth - 1,
},
options: { evaluationFunction, quiescence: quiescence },
});
options: { evaluationFunction, quiescence },
}));
if (evaluation >= recordEvaluation) {
recordEvaluation = evaluation;
recordMove = move;
Expand Down Expand Up @@ -65,7 +63,7 @@ type AlphaBetaSearchArguments<T extends Bitboard, E> = {
options: Omit<AlphaBetaOptions<T, E>, 'maxDepth'>;
};

function alphaBetaSearch<T extends Bitboard, E>({
async function alphaBetaSearch<T extends Bitboard, E>({
data: { engine, alpha, beta, depth },
options: { evaluationFunction, quiescence },
}: AlphaBetaSearchArguments<T, E>) {
Expand All @@ -81,15 +79,15 @@ function alphaBetaSearch<T extends Bitboard, E>({
const next = engine.clone();
next.move(move);

const evaluation = -alphaBetaSearch({
const evaluation = -(await alphaBetaSearch({
data: {
engine: next,
alpha: -beta,
beta: -alpha,
depth: depth - 1,
},
options: { evaluationFunction, quiescence: quiescence },
});
}));
if (evaluation >= beta) return beta;
alpha = Math.max(evaluation, alpha);
}
Expand All @@ -108,7 +106,7 @@ interface QuiescenceSearchArguments<T extends Bitboard, E> {
};
}

function quiescenceSearch<T extends Bitboard, E>({
async function quiescenceSearch<T extends Bitboard, E>({
data: { engine, alpha, beta },
options: { evaluationFunction },
}: QuiescenceSearchArguments<T, E>) {
Expand All @@ -121,10 +119,11 @@ function quiescenceSearch<T extends Bitboard, E>({
const next = engine.clone();
next.move(move);

const nextEvaluation = -quiescenceSearch({
const nextEvaluation = -(await quiescenceSearch({
data: { engine: next, alpha: -beta, beta: -alpha },
options: { evaluationFunction },
});
}));

if (nextEvaluation >= beta) return beta;
alpha = Math.max(nextEvaluation, alpha);
}
Expand Down
8 changes: 4 additions & 4 deletions src/computer/computer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ export type DraughtsComputerStrategyArgs<T extends Bitboard, E, O> = {

export type DraughtsComputerStrategy<T extends Bitboard, E, O> = (
args: DraughtsComputerStrategyArgs<T, E, O>
) => DraughtsEngineMove<T>;
) => Promise<DraughtsEngineMove<T>>;

export type DraughtsComputer<T extends Bitboard, E> = (
game: DraughtsGame1D<T, E>
) => DraughtsMove1D;
) => Promise<DraughtsMove1D>;

export type DraughtsComputerArguments<T extends Bitboard, E, O> = {
adapter: DraughtsAdapter1D<T>;
Expand All @@ -34,8 +34,8 @@ export const DraughtsComputerFactory = {
strategy,
options,
}: DraughtsComputerArguments<T, E, O>): DraughtsComputer<T, E> {
return (game) => {
const engineMove = strategy({
return async (game) => {
const engineMove = await strategy({
options,
engine: game.engine,
});
Expand Down
6 changes: 4 additions & 2 deletions src/computer/random.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Bitboard, DraughtsEngineMove } from '../core/engine';
import { DraughtsComputerStrategyArgs } from './computer';

export function random<T extends Bitboard, E>({
export async function random<T extends Bitboard, E>({
engine,
}: DraughtsComputerStrategyArgs<T, E, undefined>): DraughtsEngineMove<T> {
}: DraughtsComputerStrategyArgs<T, E, undefined>): Promise<
DraughtsEngineMove<T>
> {
if (engine.moves.length === 0) throw new Error('no valid moves');

const randomIndex = Math.floor(Math.random() * engine.moves.length);
Expand Down

0 comments on commit 1f2c9c8

Please # to comment.