import Board from '../common/Board' ; import Move from '../common/Move' ; import Evaluator from './Evaluator' ; import MoveGenerator from './MoveGenerator' ; import Rule from '../common/Rule' ; import { STATUS } from '../common/define' ; export default abstract class SearchEngine { protected currentBoard ! : Board ; protected evaluator ! : Evaluator ; protected generator ! : MoveGenerator ; protected maxDepth : number = 3 ; protected bestMove : Move | null = null ; protected status : STATUS = STATUS . NotEnded ; protected resignStep : number = 1 ; protected winStep : number = 0 ; protected searchNodes : number = 0 ; constructor ( ) { } public abstract searchAGoodMove ( board , timeLimit ? ) ; public get STATUS ( ) : STATUS { return this . status ; } setSearchDepth ( depth ) { this . maxDepth = depth ; } setEvaluator ( evaluator ) { this . evaluator = evaluator ; } setMoveGenerator ( generator ) { this . generator = generator ; } protected doMove ( move ) { this . currentBoard . doMove ( move ) ; } protected undoMove ( ) { this . currentBoard . undoMove ( ) ; } protected quickEvaluate ( depth ) { let status = this . currentBoard . quickTestStatus ( ) ; switch ( status ) { case STATUS . Win : return this . evaluator . win ( depth ) ; case STATUS . Lost : return this . evaluator . lost ( depth ) ; case STATUS . FlyCheck : return this . evaluator . win ( depth ) ; case STATUS . Impossbile : throw new Error ( "Impossible!" ) ; } return 0 ; } protected stalemate ( step ) { return this . evaluator . lost ( step ) ; } protected setStatus ( score ) { if ( this . evaluator . isWin ( score , this . winStep ) ) this . status = STATUS . Win ; else if ( this . evaluator . isLost ( score , this . resignStep ) ) this . status = STATUS . Lost ; else this . status = STATUS . NotEnded ; } }