The original God is a blog written by Html5+js about the chess AI, which focuses on
The moves of chess pieces, the evaluation function of their own design and the simple Minmax theory, there is no specific search algorithm, this article is to the original study and analysis of the supplement
One, the chess pieces of the
Com.bylaw ={} First create an array to store the point at which the piece can go
(1) Car:
COM.BYLAW.C = function (x,y,map,my) {var d=[];//the left side of the search if there are pieces and different colors push past and end the loop, or step push <span style= "color: #ff0000;" > </span>for (var i=x-1; i>= 0; i--) {if (Map[y][i]) {if (com.mans[map[y][i]].my!=my) D.push ([i,y]); break} Else{d.push ([i,y])}}//to the right of the search for (var i=x+1; I <= 8; i++) {if (Map[y][i]) {if (com.mans[map[y][i]].my!=my) D.push ([i,y]); Break}else{d.push ([i,y])}}//search for (var i = y-1; I >= 0; i--) {if (Map[i][x]) {if (com.mans[map[i][x]].my!=my) D.push ([ X,i]); Break}else{d.push ([x,i])}}//search for (var i = y+1; i<= 9; i++) {if (Map[i][x]) {if (com.mans[map[i][x]].my!=my) D.P Ush ([x,i]); Break}else{d.push ([X,i])}}return D;}
Algorithm Analysis:
Search in four directions, up, down, left, and right, if a point is found and the color is different from the piece (hostile pawn), the point coordinates are recorded in the D array, and if there are no other pieces in one direction, all coordinates in that direction are recorded in the D array.
In simple terms, the coordinates on the cross centered on the vehicle are recorded in the D array .(You say so well, start talking so much)
Additional Prerequisites:
1, map in the code:
Com.initmap = [[' C0 ', ' M0 ', ' X0 ', ' S0 ', ' J0 ', ' S1 ', ' X1 ', ' M1 ', ' C1 '],[,,,,,,,, ],[ , ' P0 ',,,,,,, ' P1 ', ],[' Z0 ', , ' Z1 ', , ' Z2 ', , ' Z3 ' ,, ' Z4 '],[,,,,,,,, ],[ , ,,, ,,, , ],[' z0 ', , ' Z1 ', , ' Z2 ', , ' Z3 ', , ' Z4 '],[ , ' P0 ', , ,,,, ' P1 ',],[,,,,,,, , ],[' C0 ', ' M0 ', ' x0 ', ' s0 ', ' j0 ', ' s1 ', ' X1 ', ' M1 ', ' C1 '];
The string here represents the key value for each piece:
Com.keys = { //Set key value for each type of pawn "C0": "C", "C1": "C", "M0": "M", "M1": "M", "x0": "X", "x1": "X", "S0": "S", "S1": "S", "J0": "J", " P0 ":" P "," P1 ":" P "," z0 ":" Z "," Z1 ":" Z "," Z2 ":" Z "," Z3 ":" Z "," Z4 ":" Z "," Z5 ":" Z "," C0 ":" C "," C1 ":" C "," M0 ":" M "," M1 ":" M "," X0 ":" X "," X1 ":" X "," S0 ":" S "," S1 ":" "S", "J0": "J", "P0": "P", "P1": "P", "Z0": "Z", "Z1": "Z", "Z2": "Z", "Z3": "Z", "Z4": "Z", "Z5": "Z",}
2,my:
Tagged Value: 1 represents the red side (here refers to the person. The player always manipulates red);-1 for AI
3,map[y][i] and D.push ([I][y])
Search in the left direction, the Y coordinate is constant, the x-coordinate is traversed, and reflected in the map (up to the 1th), look closely will find: the first subscript represents the Y value, the second subscript represents the X-value, which is exactly the opposite of the coordinate value
Other directions and so on ...
(2) Horse
COM.BYLAW.M = function (x,y,map,my) {var d=[];//1 o ' clock no tripwire 1 points no checkers or 1 piece color different push if (y-2>= 0 && x+1<= 8 & amp;&!play.map[y-1][x] && (!com.mans[map[y-2][x+1] | | com.mans[map[y-2][x+1]].my!=my)) D.push ([x+1,y-2 ]);//2 points if (y-1>= 0 && x+2<= 8 &&!play.map[y][x+1] && (!com.mans[map[y-1][x+2]] | | com.mans [Map[y-1][x+2]].my!=my]) D.push ([x+2,y-1]);//4 points if (y+1<= 9 && x+2<= 8 &&!play.map[y][x+1] && amp; (!com.mans[map[y+1][x+2] | | com.mans[map[y+1][x+2]].my!=my) D.push ([x+2,y+1]);//5-point if (y+2<= 9 && x+1<= 8 &&!play.map[y+1][ X] && (!com.mans[map[y+2][x+1] | | com.mans[map[y+2][x+1]].my!=my)) D.push ([x+1,y+2]);//7 point if (y+2<= 9 & & x-1>= 0 &&!play.map[y+1][x] && (!com.mans[map[y+2][x-1] | | com.mans[map[y+2][x-1]].my!=my)) D.push ([x-1,y+2]);//8 points if (y+1<= 9 && x-2>= 0 &&!play.map[y][x-1] && (!com.mans[map[y+1][ X-2] | | Com.mans[map[y+1][x-2]].my!=my) D.push ([x-2,y+1]);//10 points if (y-1>= 0 && x-2>= 0 &&!play.map[y][x-1] & amp;& (!com.mans[map[y-1][x-2] | | com.mans[map[y-1][x-2]].my!=my)) D.push ([x-2,y-1]);//11-point if (y-2>= 0 & & x-1>= 0 &&!play.map[y-1][x] && (!com.mans[map[y-2][x-1] | | com.mans[map[y-2][x-1]].my!=my)) D.push ([x-1,y-2]); return D;}
Algorithm Analysis:
When a horse is at a point, you can walk up to 8 different directions, each of which is discussed in each direction: If you do not stumble, and there is no pawn or chess piece in that direction, the rational point is recorded.
Legend Analysis:
A little ugly, made out of paint, don't mind the details.
(iii) phase
com.bylaw.x = function (x,y,map,my) {var d=[];if (my===1) {//red color different, Y's range of values is different, and cannot cross the river//4:30 do not stumble like feet 4.5 position No child or pawn color different pushif ( y+2<= 9 && x+2<= 8 &&!play.map[y+1][x+1] && (!com.mans[map[y+2][x+2]] | | com.mans[map[y+2 ][x+2]].my!=my) D.push ([x+2,y+2]);//7:30 if (y+2<= 9 && x-2>= 0 &&!play.map[y+1][x-1] && ( !com.mans[map[y+2][x-2] | | com.mans[map[y+2][x-2]].my!=my) D.push ([x-2,y+2]);//1:30 if (y-2>= 5 && x+2<= 8 &&!play.map[y-1] [X+1] && (!com.mans[map[y-2][x+2] | | com.mans[map[y-2][x+2]].my!=my)) D.push ([x+2,y-2]);//10:30 if (y-2>= 5 && x-2>= 0 &&!play.map[y-1][x-1] && (!com.mans[map[y-2][x-2] | | com.mans[map[y-2][x-2]]. my!=my)) D.push ([x-2,y-2]);} ELSE{//4 Point Half if (y+2<= 4 && x+2<= 8 &&!play.map[y+1][x+1] && (!com.mans[map[y+2][x+2]] | | com . Mans[map[y+2][x+2]].my!=my)) D.push ([x+2,y+2]);//7:30 if (y+2<= 4 && x-2>= 0 &&!Play.map[y+1][x-1] && (!com.mans[map[y+2][x-2] | | com.mans[map[y+2][x-2]].my!=my)) D.push ([x-2,y+2]);// 1:30 if (y-2>= 0 && x+2<= 8 &&!play.map[y-1][x+1] && (!com.mans[map[y-2][x+2]] | | com.mans[m ap[y-2][x+2]].my!=my) D.push ([x+2,y-2]);//10:30 if (y-2>= 0 && x-2>= 0 &&!play.map[y-1][x-1] && (!com.mans[map[y-2][x-2] | | com.mans[map[y-2][x-2]].my!=my)) D.push ([x-2,y-2]);} return D;}
Algorithm Analysis:
Because we can not cross the river, so we have to discuss the color according to the situation (different colors, y coordinates are different)
Each color has four possible moves, similar to the horse: if you do not stumble like a foot, the point of no pieces or pieces of different colors, records
Legend Analysis:
(iv) Shi
COM.BYLAW.S = function (x,y,map,my) {var d=[];if (my===1) {//Red Square//4:30 if (y+1<= 9 && x+1<= 5 && (!com. Mans[map[y+1][x+1] | | com.mans[map[y+1][x+1]].my!=my) D.push ([x+1,y+1]);//7:30 if (y+1<= 9 && x-1>= 3 && (!com.mans[map [Y+1] [X-1]] || com.mans[map[y+1][x-1]].my!=my) D.push ([x-1,y+1]);//1:30 if (y-1>= 7 && x+1<= 5 && (!com.mans[map [Y-1] [X+1]] || com.mans[map[y-1][x+1]].my!=my) D.push ([x+1,y-1]);//10:30 if (y-1>= 7 && x-1>= 3 && (!com.mans[ Map[y-1][x-1] | | com.mans[map[y-1][x-1]].my!=my)) D.push ([x-1,y-1]);} ELSE{//4 Point Half if (y+1<= 2 && x+1<= 5 && (!com.mans[map[y+1][x+1]] | | com.mans[map[y+1][x+1]].my!=my)) D.push ([x+1,y+1]);//7:30 if (y+1<= 2 && x-1>= 3 && (!com.mans[map[y+1][x-1]] | | com.mans[map[y+1][ x-1]].my!=my) D.push ([x-1,y+1]);//1:30 if (y-1>= 0 && x+1<= 5 && (!com.mans[map[y-1][x+1]] | | com.m ans[map[y-1][x+1]].my!=my)) D.push ([x+1, y-1]);//10:30 if (y-1>= 0 && x-1>= 3 && (!com.mans[map[y-1][x-1]] | | com.mans[map[y-1][x-1]].my!= My) D.push ([x-1,y-1]);} return D;}
Algorithm Analysis:
Nine Gongge, the x, y values are limited. be discussed in terms of color. Each color has 4 possible moves: If the rational point does not have a pawn or a piece of different color, record
Legend Analysis:
This simple, do not draw ~ ~ ~ ~
(v) to
COM.BYLAW.J = function (x,y,map,my) {var D=[];var isnull= (function (y1,y2) {var y1=com.mans["j0"].Y; Red handsome yvar x1=com.mans["J0"].x; Black will the Xvar y2=com.mans["J0"].Y; Black will be yfor (var i=y1-1; i>y2; i--) {if (map[i][x1]) return false; will be with the non-null between, having the child}return true;}) () if (my===1) {//Red Square//down if (y+1<= 9 && (!com.mans[map[y+1][x)] | | com.mans[map[y+1][x]].my!=my)) D.push ([x,y+ 1]);//Upper if (y-1>= 7 && (!com.mans[map[y-1][x] | | com.mans[map[y-1][x]].my!=my)) D.push ([x,y-1]);// Veteran to Veteran's situation if (com.mans["j0"].x = = com.mans["J0"].x &&isnull) D.push ([com.mans["J0"].x,com.mans["J0"].y]); X is equal, and the middle is empty, push black coordinates}else{//under if (y+1<= 2 && (!com.mans[map[y+1][x] | | com.mans[map[y+1][x]].my!=my)) D.push ([x,y+1]);//Upper if (y-1>= 0 && (!com.mans[map[y-1][x]] | | com.mans[map[y-1][x]].my!=my)) D.push ([x,y-1] )///veteran of the situation if (com.mans["j0"].x = = com.mans["J0"].x &&isnull) D.push ([com.mans["J0"].x,com.mans["J0"].y]);Push red-handsome coordinates}//right if (x+1<= 5 && (!com.mans[map[y][x+1] | | com.mans[map[y][x+1]].my!=my)) D.push ([x+1,y]);// Left if (x-1>= 3 && (!com.mans[map[y][x-1] | | com.mans[map[y][x-1]].my!=my)) D.push ([x-1,y]); return D;}
Algorithm Analysis:
In addition to different colors cause the Y value is different, there is a special situation: that veteran meet. So start by writing a function to determine if there are other pieces between the handsome
The next two moves are discussed in terms of color differences: The emphasis is on the definition of Y-values. Take handsome for example: Handsome in the chess board, y coordinates can only take 7,8,9. If you go down, take 7, 8, so the Y value is a maximum of 8. And judge after the moves to determine whether the veteran met the special situation: If the two x-coordinate and no other pieces in the middle, flashed past the head ~ ~ ~ and then victory
(vi), cannon
COM.BYLAW.P = function (x,y,map,my) {var d=[];//to the left to retrieve Var n=0;for (var i=x-1; i>= 0; i--) {if (Map[y][i]) { //Touch Sub if (n= =0) { //If the first child, no tube, jump out of this cycle, Mark bit plus 1n++;continue;} else{ //If it is not the first child, judging the color if it is different, push past and end the loop if (com.mans[map[y][i]].my!=my) D.push ([i,y]); break}}else{ //If you can't touch the child, Move the child to the leftmost if (n==0) D.push ([i,y])}}//to the right to retrieve Var n=0;for (var i=x+1; I <= 8; i++) {if (Map[y][i]) {if (n==0) {n++;continue;} Else{if (Com.mans[map[y][i]].my!=my) D.push ([I,y]), Break}}else{if (n==0) D.push ([i,y])}}//retrieve Var n=0;for (var i = y-1; I >= 0; i--) {if (Map[i][x]) {if (n==0) {n++;continue;} Else{if (Com.mans[map[i][x]].my!=my) D.push ([X,i]), Break}}else{if (n==0) D.push ([x,i])}}//retrieve Var n=0;for (var i = y+1; I <= 9; i++) {if (Map[i][x]) {if (n==0) {n++;continue;} Else{if (Com.mans[map[i][x]].my!=my) D.push ([x,i]) break}}else{if (n==0) D.push ([x,i])}}return D;}
Algorithm Analysis:
Like a car, you need to search in 4 directions.
If there is no pawn in that direction, then all point coordinates are recorded in that direction.
If you walk to find a pawn, first calm down (jump out of this cycle), secretly see the next direction there are no enemy pieces, there, you can Gank tower. Then record the location of the enemy's death and leave it for remembrance ~ ~ ~
(vii) Stroke
Com.bylaw.z = function (x,y,map,my) {var d=[];if (my===1) {//Red side//up if (y-1>= 0 && (!com.mans[map[y-1][x]] | | com . Mans[map[y-1][x]].my!=my)) D.push ([x,y-1]);//Right if (x+1<= 8 && y<=4 && (!com.mans[map[y][x+ 1] | | com.mans[map[y][x+1]].my!=my)) D.push ([x+1,y]); Y<4, that is, after crossing the river, you can move around//left if (x-1>= 0 && y<=4 && (!com.mans[map[y][x-1] "| | com.mans[map[y][x-1]]. my!=my)) D.push ([X-1,y]);} else{//under if (y+1<= 9 && (!com.mans[map[y+1][x] | | com.mans[map[y+1][x]].my!=my)) D.push ([x,y+1]);// Right if (x+1<= 8 && y>=6 && (!com.mans[map[y][x+1] | | com.mans[map[y][x+1]].my!=my)) D.push ([x+ 1,y]);//Left if (x-1>= 0 && y>=6 && (!com.mans[map[y][x-1]] | | com.mans[map[y][x-1]].my!=my)) D.push ( [X-1,y]);} return D;}
Algorithm Analysis:
The same situation is discussed. And because the stroke can not retreat so only with the judgment, left, right three cases. and the stroke due to cross the river can move around, so the judgment of the left and right in addition to the definition of x and y value of the definition. It's the same as the car. If the rational point has no pawn or the piece has a different color, record the point
Second, use Alpha-beta to search for the best moves in all the moves.
Ai.getalphabeta = function (A, B, depth, map, my) {if (depth = = 0) {return {"value": ai.evaluate (Map, my)};//When the search depth is 0 is called situation evaluation function; } var moves = ai.getmoves (map, my); Generate all the way; <span style= "color: #ff0000;" >//here sorting will increase efficiency for (Var i=0; i < moves.length; i++) {</span>//go this way; var move= moves[i];var key = Move[4];var oldx= move[0];var oldy= move[1];var newx= move[2];var newy= move[3];var clearkey = map[NewY [NewX]| | ""; map[Newy] [newx] = key; Go, assign a new value, delete the old value delete map[OldY] [OLDX];p lay.mans[key].x = NEWX;PLAY.MANS[KEY].Y = Newy; <span style= "color: #ff0000;" >if (clearkey== "J0" | | clearkey== "J0") {//eaten veteran play.mans[key].x = Oldx;play.mans[key].y = oldy;map[OldY] [OLDX] = Key;delete map[newy [NEWX]; Not really go, so here to revoke if (Clearkey) {map[newy] [newx] = Clearkey;} return {"Key": Key, "X": Newx, "y": Newy, "value":8888};</span>}else {var val =-ai.getalphabeta (-B,-A, Depth-1, M AP,-my). Value; Above represents AI, here upside down,-my, representing the human//val = Val from the above: Val.value; <span style= "color: #ff0000;" > Undo this walk; play.mans[key].x = OLDX;PLAY.MANS[KEY].Y = oldy;map[OldY [OLDX] = Key;delete map[newy [newx];if (ClearKey) {map[n Ewy] [newx] = Clearkey; play.mans[Clearkey].isshow = true;} </span> if (val >= B) {//This walk is recorded in the history table;//ai.sethistorytable (txtmap,ai.treedepth-depth+1,b,my); return {"Key": Key, "X": Newx, "y": Newy, "value": B}; } <span style= "color: #ff0000;" >if (val > a) {a = Val;//Set Best go, if (ai.treedepth = = depth) var rootkey={"key": Key, "X": Newx, "y": Newy, "value": A };} </span>}} if (ai.treedepth = = depth) {//has been handed back to root if (!rootkey) {//ai does not have the best way to show that AI is going to die, return Falsereturn false;} else{//This is the best way to go; return rootkey;}} return {"Key": Key, "X": Newx, "y": Newy, "value": A}; }
Simplified pseudo-code (corresponds to code one by one above):
int Alphabeta (int vlalpha, int vlbeta, int ndepth) {if (ndepth = = 0) {return situation evaluation function;} generate all walk; <span style= "COLOR: #f f0000; " > Sort by History table all;</span> for (each generated walk) {Walk this way; <span style= "color: #ff0000;" >if (by General) {undo this walk; } else</span> {int vl =-alphabeta (-vlbeta,-vlalpha, nDepth-1); <span style= "color: #ff0000;" > Undo This Walk;</span> if (VL >= Vlbeta) {<span style= "color: #ff0000;" > Record this walk to the history table;</span> return Vlbeta; } if (VL > Vlalpha) {<span style= "color: #ff0000;" > Set the best way to go;</span> Vlalpha = VL; }}} if (without going through any way) { //ai is going to die return to kill the score,} to record the best way to the history table, if (root node) {The best way to go is the computer to go chess;} return vlalpha;}
In this way, simply apply the above-mentioned Alpha-beta algorithm, you can search for the relative best path to ~ ~ ~
Finally set the coordinates can realize AI automatic moves or eat son
Chess AI Algorithm (two)