Monte Carlo situation evaluation + uct game tree search is the mainstream of modern computer go. This methodAlgorithmThe efficiency is very high, so it is necessary to save the information of the chess string (a set of parallel color chess pieces connected in a straight line) in the mone carlo simulation process, to improve the efficiency of the sub.
Chess strings must meet the following requirements:
- Frequently queries the chess string where a piece is located ".
- Frequent creation of chess strings.
- Frequently query the "Gas" of a chess string ".
- Merge two chess strings frequently.
- Remove the chess string and enumerate the pawns.
Therefore, using a linked list to implement and query a set is a suitable data structure:
Struct node {pointindex next _, list_head _;}; struct list {pointindex tail _, Len _; airset air_set _ ;}; node nodes _ [foo_square (board_len)]; list lists _ [foo_square (board_len)];
Create a chess string with only one chess piece:
Template <boardlen board_len> voidchainset <board_len>: createlist (pointindex node_ I, const chainset <board_len>: airset & air_set) {nodes _ [node_ I]. list_head _ = node_ I; Lists _ [node_ I]. tail _ = node_ I; Lists _ [node_ I]. len _ = 1; Lists _ [node_ I]. air_set _ = air_set ;}
Query the chess string of a chess piece:
Pointindex getlisthead (pointindex node_ I)Const{ReturnNodes _ [node_ I]. list_head _;}
Merge two chess strings:
Template <boardlen board_len> Pointindex chainset <Board_len> : Mergelists (pointindex list_a, pointindex list_ B) {foo_assert (list_a ! = List_ B ); If (Lists _ [list_a]. Len _> Lists _ [list_ B]. Len _) Swap (list_a, list_ B ); For ( Int I = list_a; I =Nodes _ [I]. Next _) {nodes _ [I]. list_head _ = List_ B; If (I = lists _ [list_a]. Tail _) Break ;} Nodes _ [lists _ [list_ B]. Tail _]. Next _ = List_a; Lists _ [list_ B]. Tail _ = Lists _ [list_a]. Tail _; Lists _ [list_ B]. Len _ + = Lists _ [list_a]. Len _; Lists _ [list_ B]. air_set _ | = Lists _ [list_a]. air_set _; Return List_ B ;}
Remove a chess string:
Template <boardlen board_len>VoidChainset <board_len>: Removelist (pointindex head ){For(IntI = head; I =Nodes _ [I]. Next _) {nodes _ [I]. list_head _= Chainset <board_len>: None_list;If(I = lists _ [head]. Tail _)Break;}}
Enumeration pawns:
Template <boardlen board_len> Pntindxvector chainset <Board_len>: getpiecesofachain (pointindex list_ I) Const { Const List * PL = lists _ + List_ I; pntindxvector V (pl -> Len _); Int Vi = 0 ; For ( Int I = list_ I; I = Nodes _ [I]. Next _) {v [vi ++] = I; If (I = pl-> tail _) Break ;} Return V ;}
The "gas" of the chess string can be stored by bit, which saves both memory and increases efficiency. For example, the number of "Qi" is the number of 1 in the binary system. When merging two chess strings, you also need to merge their "Qi" for bit or operation. This data structure does not have to be implemented by yourself:
Typedef STD: bitset <foo_square (board_len)> airset;
Of course, you also need to write some high-level interfaces for sub-function calls.
Paste the test case of the sub-function:
Code: Https://github.com/chncwang/FooGo