2023-04-01 23:11:32 -04:00
|
|
|
import{Chess,Ox88,DEFAULT_POSITION,SQUARES,rank,file,WHITE,BLACK,KING}from"./chess.min.js";function with_move(board,move){let new_board=new Chess(board.fen());new_board.move(move);return new_board}function shuffle(array){let currentIndex=array.length,randomIndex;while(currentIndex!=0){randomIndex=Math.floor(Math.random()*currentIndex);currentIndex--;[array[currentIndex],array[randomIndex]]=[array[randomIndex],array[currentIndex]]}return array}function min_move_by(board,score){let best_score=Infinity;let best_move="";let moves=board.moves();shuffle(moves);for(const move of moves){try{let new_board=with_move(board,move);let new_score=score(new_board);if(new_score<best_score){console.log("New best (or equal): ",new_score,move);best_score=new_score;best_move=move}}catch(e){console.error(e);continue}}return best_move}const random_move=board=>{const moves=board.moves();const move=moves[Math.floor(Math.random()*moves.length)];return move};function make_lexo(m){let{rank:src_row,file:src_col}=rank_and_file(m.from);let{rank:dst_row,file:dst_col}=rank_and_file(m.to);let promote_to=m.promotion;return[src_row,src_col,dst_row,dst_col,promote_to]}function lexo_sort_moves(a,b){let al=make_lexo(a);let bl=make_lexo(a);for(const i in al){if(al[i]<bl[i]){return-1}else if(al[i]>bl[i]){return 1}}return 0}const first_move=board=>{const moves=board.moves({verbose:true}).sort(lexo_sort_moves);return moves[0].san};const alphabetical=board=>{const moves=board.moves();moves.sort();return moves[0]};const equalizer_state_default={piece_moves:{p:0,b:0,n:0,r:0,q:0,k:0},square_visits:{a8:0,b8:0,c8:0,d8:0,e8:0,f8:0,g8:0,h8:0,a7:0,b7:0,c7:0,d7:0,e7:0,f7:0,g7:0,h7:0,a6:0,b6:0,c6:0,d6:0,e6:0,f6:0,g6:0,h6:0,a5:0,b5:0,c5:0,d5:0,e5:0,f5:0,g5:0,h5:0,a4:0,b4:0,c4:0,d4:0,e4:0,f4:0,g4:0,h4:0,a3:0,b3:0,c3:0,d3:0,e3:0,f3:0,g3:0,h3:0,a2:0,b2:0,c2:0,d2:0,e2:0,f2:0,g2:0,h2:0,a1:0,b1:0,c1:0,d1:0,e1:0,f1:0,g1:0,h1:0}};var equalizer_state=equalizer_state_default;const equalizer=board=>{let best_move;let least_moved_found=Infinity;let least_visited_found=Infinity;let piece_moving="k";let square_visiting="a1";for(const move of board.moves({verbose:true})){if(equalizer_state.piece_moves[move.piece]<least_moved_found||equalizer_state.piece_moves[move.piece]==least_moved_found&&equalizer_state.square_visits[move.to]<least_visited_found){best_move=move;least_moved_found=equalizer_state.piece_moves[move.piece];least_visited_found=equalizer_state.square_visits[move.to];piece_moving=move.piece;square_visiting=move.to}}equalizer_state.piece_moves[piece_moving]+=1;equalizer_state.square_visits[square_visiting]+=1;return best_move.san};const min_oppt_move=board=>{let num_moves=b=>b.moves().length;return min_move_by(board,num_moves)};function num_pieces_on_own_color(b){let count=0;for(const square of SQUARES){let piece=b.get(square);if(typeof piece=="boolean"){continue}if(piece.color==b.squareColor(square)){count+=1}}return count}const same_color=board=>{return min_move_by(board,b=>64-num_pieces_on_own_color(b))};const opposite_color=board=>{return min_move_by(board,num_pieces_on_own_color)};function rank_and_file(s){return{rank:rank(Ox88[s]),file:file(Ox88[s])}}function chebyshev_distance(a,b){let{rank:r1,file:f1}=rank_and_file(a);let{rank:r2,file:f2}=rank_and_file(b);return Math.max(Math.abs(r2-r1),Math.abs(f2-f1))}const START_BOARD=new Chess(DEFAULT_POSITION);function move_distance(piece){let rank=rank_and_file(piece.square).rank;let file=rank_and_file(piece.square).file;switch(piece.type){case"k":return chebyshev_distance(piece.square,find({color:HUMAN_COLOR,type:"k"},START_BOARD));case"p":return Math.abs(rank-6);case"r":return Math.abs(rank-7)+Math.min(Math.abs(file-7),Math.abs(file-0));case"n":return pieces_of_color(START_BOARD,HUMAN_COLOR).filter(p=>p.type=="k").map(p=>chebyshev_distance(piece.square,p.square)).reduce((a,b)=>Math.max(a,b));case"b":let is_black=START_BOARD.squareColor(piece.square)=="b";let dest_col=is_black?2:5;let dr=Math.abs(rank-7);let dc=Math.abs(file-dest_col);return Math.max(dr,dc);case"q":return Math.max(Math.abs(rank-7),Math.abs(file-3))}}function mini
|