Chinese chess software-engine Implementation (4) Search Algorithms

Source: Internet
Author: User

 

The search algorithms of chess and board software have developed mature alpha-Beta Search Algorithms and other auxiliary enhancement algorithms. Therefore, Xiaosheng directly draws on the Alpha-Beta Search Algorithm in his own program and is inspired by history. Wang xiaochun's PC game programming (man-machine game) and elephantboard's home page http://www.elephantbase.net/are all very detailed introductions. Here I will simply introduce the main idea of the solution:

First, there is a "game Tree" for chess games-each node of the tree represents a situation on the board, for every situation (node) different steps lead to different situations (new nodes), so that there is no choice to go through the process ).

Now, assuming that the game is played by both parties, the win-win situation is a maximum value (a positive number), then the win-win situation is a minimum value (a negative value of the maximum value ), the game is zero or close to zero. In this way, when it is the turn of a to play the game, he will choose the path with the largest value of the generated node, on the contrary, when it is the turn of B to play the game, he will choose the path with the smallest value of the generated node (of course, search will deduce multiple steps down and select a score that is advantageous to the current chess player ). This is the basic idea of "maximum-minimum. In this way, the search function can find the best method by searching the entire tree with the current situation as the root node and a limited number of layers. Unfortunately, the game tree is quite large (it will grow exponentially), So searching for the entire tree is quite time-consuming.

However, playing chess is a process in which you alternate and compete with each other, because each party tries its best to direct the situation to itself and to the other party. Therefore, some "temporary" situations seem very good because they may have a bad situation and thus have no value to consider. So when you see a situation that may lead to a very bad situation (specifically, the "bad" is compared with the previous situation ), you should immediately stop analyzing the remaining child nodes-Don't fantasizing about it any more. If you choose it, you will surely get that bad situation, or even worse ...... This greatly reduces the search workload and improves the search efficiency. This is called "Tree Pruning ". To make it easier for everyone to understand, I will refer to the elephantboard home page called mongomoreland (brucemo@seanet.com ).
Example of a pocket:

For example, you have a lot of pockets in front of your dead enemy, And he bet you lose, so he must give you something, but the selection rules are very strange:
There are several items in each pocket. You can pick one of them. You pick the pocket where this item is located, and he picks the items in this pocket. You need to pick out your pockets and leave, because you don't want to keep turning your pockets there and let your dead enemy stare at you.
Suppose you can only find one pocket at a time, and you can only find one thing from it at a time.
Apparently, when you pick out your pockets, your enemies will give you the worst items in your pockets, therefore, your goal is to pick out the pocket "The Best of the many worst items.
You can easily apply the minimum-Maximum Principle to this problem. You are the biggest player, and you will pick out the best pockets. While your enemy is the smallest player, he will pick out the best item in his pocket as far as possible. With the minimum-Maximum Principle, you need to pick a pocket with the "best and worst" item.
If you can estimate the exact value of each item in your pocket, the minimum-Maximum Principle will allow you to make the right choice. In our discussion, accurate evaluation is not important because it is irrelevant to the minimum-maximum or alpha-beta operating principle. Now let's assume that you can correctly evaluate an item.
Min-the principle of maximum is discussed just now. The problem with it is that the efficiency is too low. You have to view every item in every pocket, which takes a lot of time.
So how can we make it more efficient than minimum-maximum?
We start from the first pocket, look at each item, and evaluate the pocket. For example, there is a peanut butter sandwich in the pocket and the key to a new car. You know the sandwich is worse, so if you pick this pocket, you will get the sandwich. In fact, as long as we assume that our opponent will review items correctly, the car keys in our pockets are irrelevant.
Now you start to flip the second pocket. This time, your solution is different from the minimum-maximum solution. Each time you read an item and compare it with the best one you can get (sandwich. As long as the item is better than the sandwich, you can follow the minimum-maximum solution-find the worst, maybe the worst, is better than the sandwich, then you can pick this pocket, it is better than the pocket containing the sandwich.
For example, the first item in this pocket is a $20 bill, which is better than a sandwich. If nothing else in the bag is worse than this, then if you choose this pocket, it is the item that the opponent must give you, and this pocket is your choice.
The next item in this pocket is a six-pack pop album. You think it is better than sandwich, but it is worse than $20, so this pocket can still be selected. Another item is a rotten fish, which is worse than a sandwich. Then you say "No thanks" and put your pocket back without considering it.
No matter what is in your pocket or the key of another car, it's useless because you will get the rotten fish. There may be something worse than rotten fish (so you can do it ). No matter how bad the fish is, you know that it would be better to pick a pocket with a sandwich.

The "maximum-minimum" concept, coupled with "Tree Pruning", is the core of the alpha-Beta Search Algorithm.
The following is the code implementation of cchesssearch. h. The specific implementation of "historical Inspiration" and "method-based sorting" will be provided in the next article.

// Cchesssearch. h # include "historyheuristic. H "# include" sortmove. H "# include" cchessevaluate. H "// Data define ///////////////// /// // int nmaxsearchdepth; // maximum search depth cchessmove cmbestmove; // optimal storage method ////////////// //// // use alphabeta search + historical inspiration to search for the best method and execute cchessmove searchagoodmove (); // alphabeta search + history Inspired, ndepth indicates the search depth, // Alpha indicates the minimum initial value, and beta indicates the maximum value int alphabeta_hh (INT ndepth, int Alpha, int beta). // determines whether the game is over, if it ends, the system returns the corresponding extreme value based on the current player. Otherwise, the system returns 0 // The maximum value for the current player. If the current player fails, the system returns the minimum value (the player pursues the maximum value) int isgameover (INT fwhoseturn); // execute the method to return the condition of the pawns at the ptto position. That is, if a child is eaten and the child is not eaten, 0 byte domove (cchessmove * move) is returned. // The execution method is revoked to restore the pawns in the original position. Void undomove (cchessmove * move, byte ncchessid ); //// // programmer-Defined Function ////////////////// /////////// cchessmove searchagoodmove () {resethistorytable (); int I; I = alphabeta_hh (nmaxsearchdepth,-maxvalue, maxvalue); domove (& cmbestmove); Return cmbestmove;} int alphabeta_hh (INT ndepth, int Alpha, int beta) {int nscore; int ncount; byte ncches Sid; int I; I = isgameover (nmaxsearchdepth-ndepth) % 2); if (I! = 0) // return I after the game ends; If (ndepth = 0) // The leaf node return eveluate (nmaxsearchdepth-ndepth) % 2 ); ncount = generatemove (nmaxsearchdepth-ndepth) % 2, ndepth); for (I = 0; I <ncount; I ++) // obtain the score of the History Table {movelist [ndepth] [I]. nscore = gethistoryscore (& movelist [ndepth] [I]);} mergesort (movelist [ndepth], ncount); // sort int ibestmove =-1 in descending order; for (I = 0; I <ncount; I ++) {ncchessid = Domove (& movelist [ndepth] [I]); // execute the method (generate a new node) nscore =-alphabeta_hh (ndepth-1,-Beta,-alpha ); // call alphabeta_hh undomove recursively (& movelist [ndepth] [I], ncchessid); // cancel execution (delete node) if (nscore> alpha) {alpha = nscore; // retain the maximum value if (ndepth = nmaxsearchdepth) cmbestmove = movelist [ndepth] [I]; ibestmove = I; // Save the sequence number of the best walk method} If (alpha> = beta) {ibestmove = I; // Save the optimal sequential number break;} If (ibestmov E! =-1) enterhistoryscore (& movelist [ndepth] [ibestmove], ndepth); // records the historical score return Alpha;} int isgameover (INT fwhoseturn) {int X, Y; if (fwhoseturn = red) // It is the red party's turn to play the game. It is only possible that the red handsome guy has been eaten. {// Red Square Palace for (x = 3; x <= 5; X ++) for (y = 0; y <= 2; y ++) {If (cchessboard [x] [Y] = red_k) {return 0; // red handsome was not eaten, it indicates that the game is not over yet} return-maxvalue; // return the Extreme Value of failure (verified as-maxvalue)} else // it is the turn of the black player to play the game, it is only possible that black will have been eaten {// black square jiugong for (x = 3; x <= 5; X ++) for (y = 9; y> = 7; Y --) {If (cchessboard [x] [Y] = black_k) {return 0; // if Black is not eaten, the game is not over yet.} return-maxvalue; // return the Extreme Value of failure (-maxvalue verified)} byte domove (cchessmove * move) {byte ncchessid; // retain the position of the pawns in the target position. ncchessid = cchessboard [move-> ptto. x] [move-> ptto. y]; // move the child to the target location cchessboard [move-> ptto. x] [move-> ptto. y] = cchessboard [move-> ptfrom. x] [move-> ptfrom. y]; cchessboard [move-> ptfrom. x] [move-> ptfrom. y] = 0; return ncchessid;} void undomove (cchessmove * move, byte ncchessid) {// move the child back to the original cchessboard [move-> ptfrom. x] [move-> ptfrom. y] = cchessboard [move-> ptto. x] [move-> ptto. y]; // restore the child cchessboard [move-> ptto. x] [move-> ptto. y] = ncchessid;} // end of cchesssearch. h
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.