import Evaluator from '../Evaluator' ; import Point from '../../common/Point' ; import Board from '../../common/Board' ; import Rule from '../../common/Rule' ; import { PLAYER , PIECE , SIZE , pos2idx } from '../../common/define' ; export default class SimpleEvaluator extends Evaluator { private static baseValue = function ( piece ) : number { switch ( piece ) { case PIECE . Pawn : return 100 ; case PIECE . Guard : return 200 ; case PIECE . Bishop : return 200 ; case PIECE . Rook : return 900 ; case PIECE . Knight : return 400 ; case PIECE . Cannon : return 450 ; case PIECE . King : return 10000 ; } } ; private static flexibility = function ( piece ) : number { switch ( piece ) { case PIECE . Pawn : return 15 ; case PIECE . Guard : return 1 ; case PIECE . Bishop : return 1 ; case PIECE . Rook : return 6 ; case PIECE . Knight : return 12 ; case PIECE . Cannon : return 6 ; case PIECE . King : return 0 ; } } ; private static extraPawnValue = function ( board , owner , pos ) : number { let value = [ [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] , [ 70 , 70 , 70 , 70 , 70 , 70 , 70 , 70 , 70 ] , [ 70 , 90 , 110 , 110 , 110 , 110 , 110 , 90 , 70 ] , [ 90 , 90 , 110 , 120 , 120 , 120 , 110 , 90 , 90 ] , [ 90 , 90 , 110 , 120 , 120 , 120 , 110 , 90 , 90 ] , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ] ; if ( owner === board . upSidePlayer ) return value [ pos . x ] [ pos . y ] ; else return value [ pos . x ] [ SIZE . ranks - pos . y ] ; } ; constructor ( ) { super ( ) ; this . threshold = 19900 ; this . maxSearchDepth = 100 ; } ; evaluate ( board ) { let attack = Array . apply ( null , Array ( SIZE . files * SIZE . ranks ) ) . map ( ( ) => 0 ) ; let guard = Array . apply ( null , Array ( SIZE . files * SIZE . ranks ) ) . map ( ( ) => 0 ) ; let flexibility = Array . apply ( null , Array ( SIZE . files * SIZE . ranks ) ) . map ( ( ) => 0 ) ; let possible = Rule . getPossibleMoves ( board , false ) ; for ( let move of possible ) { let from = pos2idx ( move . from . x , move . from . y ) ; let to = pos2idx ( move . to . x , move . to . y ) ; if ( move . protege != null ) { guard [ to ] += 1 ; } else if ( move . target !== null ) { let attacker = board . at ( move . from ) ; let attackee = board . at ( move . to ) ; if ( attacker == null || attackee == null ) throw Error ( "Piece Not Found!" ) ; attack [ to ] += 3 + Math . floor ( 0.01 * ( SimpleEvaluator . baseValue ( attackee . type ) - SimpleEvaluator . baseValue ( attacker . type ) ) ) ; if ( attackee . type === PIECE . King ) { if ( board . currentMover !== attackee . owner ) { return this . WIN ; } } } } let self = 0 ; let opponent = 0 ; for ( let x = 0 ; x < SIZE . files ; ++ x ) { for ( let y = 0 ; y < SIZE . ranks ; ++ y ) { let piece = board . at ( new Point ( x , y ) ) ; if ( piece == null ) continue ; let pos = pos2idx ( x , y ) ; let pieceValue = 0 ; pieceValue += SimpleEvaluator . baseValue ( piece . type ) ; pieceValue += SimpleEvaluator . flexibility ( piece . type ) * flexibility [ pos ] ; if ( piece . type === PIECE . Pawn ) { pieceValue += SimpleEvaluator . extraPawnValue ( board , piece . owner , new Point ( x , y ) ) ; } let unit = Math . floor ( SimpleEvaluator . baseValue ( piece . type ) / 16 ) ; if ( attack [ pos ] > 0 ) { if ( board . currentMover === piece . owner ) { if ( piece . type === PIECE . King ) { pieceValue -= 20 ; } else { pieceValue -= 2 * unit ; if ( guard [ pos ] > 0 ) pieceValue += unit ; } } else { if ( piece . type === PIECE . King ) { return this . WIN ; } pieceValue -= 10 * unit ; if ( guard [ pos ] > 0 ) pieceValue += 9 * unit ; } pieceValue -= attack [ pos ] ; } else { if ( guard [ pos ] > 0 ) pieceValue += 5 ; } if ( piece . isOwnedBy ( board . currentMover ) ) { self += pieceValue ; } else { opponent += pieceValue ; } } } return self - opponent ; } }