提交 d4863242 编写于 作者: D dev@dev.com

加入策略

上级 0102c2a1
...@@ -33,30 +33,27 @@ struct chess_node{ ...@@ -33,30 +33,27 @@ struct chess_node{
//走位和显示 //走位和显示
//------------------------------------------- //-------------------------------------------
std::vector<chess_node> expand_node(const chess_node & root, const int side); std::vector<chess_node> expand_node(const chess_node & root, const int side,bool onlykill=false);
//移动棋子
bool move_node(const chess_node & root, chess_node * new_node,const int oldx, const int oldy,const int newx, const int newy,const int side); bool move_node(const chess_node & root, chess_node * new_node,const int oldx, const int oldy,const int newx, const int newy,const int side);
//转换松散坐标为棋子的压缩格式坐标
bool build_node(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int idx, const int newx, const int newy,const int side,int map_coords[/*11*/][10],chess_node * node,bool onlykill=false);
bool build_node(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int idx, const int newx, const int newy,const int side,int map_coords[/*11*/][10],chess_node * node);
bool build_node(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int side,chess_node * node); bool build_node(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int side,chess_node * node);
//打印棋盘
void print_node(const chess_node & node,const chess_node & old_node); void print_node(const chess_node & node,const chess_node & old_node);
//X镜像反转坐标
void mirror_coordx(const unsigned char cod1[/*32*/],unsigned char cod2[/*32*/]); void mirror_coordx(const unsigned char cod1[/*32*/],unsigned char cod2[/*32*/]);
//计算棋盘哈希
std::vector<std::string> node2hash(const std::vector<chess_node> & nodes); std::vector<std::string> node2hash(const std::vector<chess_node> & nodes);
std::string node2hash(const unsigned char cod[/*32*/], const unsigned int alive); std::string node2hash(const unsigned char cod[/*32*/], const unsigned int alive);
//AI //AI
//------------------------------------------- //-------------------------------------------
//计算走位代价
float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int killed,const int idx); float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int killed,const int idx);
//建立决策树
std::vector<chess_node> build_tree(const chess_node & root, const int side,const std::vector<chess_node> & history); std::vector<chess_node> build_tree(const chess_node & root, const int side,const std::vector<chess_node> & history);
//评估并返回走位
size_t judge_tree(std::vector<chess_node> & tree); size_t judge_tree(std::vector<chess_node> & tree);
#endif // CHESSPI_H #endif // CHESSPI_H
...@@ -11,7 +11,18 @@ ...@@ -11,7 +11,18 @@
#include <atomic> #include <atomic>
#include "chesspi.h" #include "chesspi.h"
int max_depth = 5;
//棋子代价
static const unsigned int table_cost[16] = {100000,150,150,150,150,150,150,500,500,150,150,100,100,100,100,100}; static const unsigned int table_cost[16] = {100000,150,150,150,150,150,150,500,500,150,150,100,100,100,100,100};
/*!
* \brief calc_cost 计算走位后,idx棋子被击杀的代价,并返回
* \param coordx 当前各个棋子的X坐标
* \param coordy 当前各个棋子的Y坐标
* \param alive 当前各个棋子的存活标记
* \param killed 总击杀数
* \param idx 被击杀的棋子
* \return 击杀代价
*/
float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int killed,const int idx) float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int alive[/*32*/],const int killed,const int idx)
{ {
...@@ -30,7 +41,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali ...@@ -30,7 +41,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali
if (alive[(idx-1)/2*2+1] || alive [(idx-1)/2*2+2]) if (alive[(idx-1)/2*2+1] || alive [(idx-1)/2*2+2])
rescost *= 2; rescost *= 2;
break; break;
//马战线挺进,以及后期击杀价值高 //马战线挺进,以及后期击杀价值高
case 5: case 5:
case 6: case 6:
if (idx<16 ) if (idx<16 )
...@@ -39,7 +50,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali ...@@ -39,7 +50,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali
rescost *= 1+((11-coordy[idx])/3.0); rescost *= 1+((11-coordy[idx])/3.0);
rescost *= 1 + killed / 4.0; rescost *= 1 + killed / 4.0;
break; break;
//车战线击杀高 //车战线击杀高
case 7: case 7:
case 8: case 8:
if (idx<16 ) if (idx<16 )
...@@ -47,7 +58,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali ...@@ -47,7 +58,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali
else else
rescost *= 1+((11-coordy[idx])/3.0); rescost *= 1+((11-coordy[idx])/3.0);
break; break;
//炮前期击杀高 //炮前期击杀高
case 9: case 9:
case 10: case 10:
if (idx<16 ) if (idx<16 )
...@@ -56,7 +67,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali ...@@ -56,7 +67,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali
rescost *= 1+((11-coordy[idx])/3.0); rescost *= 1+((11-coordy[idx])/3.0);
rescost *= 1 + (32 - killed) / 4.0; rescost *= 1 + (32 - killed) / 4.0;
break; break;
//卒过河击杀高 //卒过河击杀高
case 11: case 11:
case 12: case 12:
case 13: case 13:
...@@ -88,9 +99,12 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const ...@@ -88,9 +99,12 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
tree.push_back(root); tree.push_back(root);
tree[0].side = side % 2; tree[0].side = side % 2;
tree[0].depth = 0; tree[0].depth = 0;
int max_nodes = 1000*1000*32;
size_t curr_i = 0; size_t curr_i = 0;
size_t max_nodes = 1024*1024*16;
//要停留在敌走的偶数步
const int stop_depth = (max_depth+1)/2 * 2;
while (tree.size()<=max_nodes && curr_i<tree.size()) while (tree.size()<=max_nodes && curr_i<tree.size())
{ {
const size_t ts = tree.size(); const size_t ts = tree.size();
...@@ -99,18 +113,22 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const ...@@ -99,18 +113,22 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
for (int i=0;i<cores;++i) for (int i=0;i<cores;++i)
vec_appends.push_back(std::vector<chess_node>()); vec_appends.push_back(std::vector<chess_node>());
std::atomic<int> new_appends (0); std::atomic<int> new_appends (0);
#pragma omp parallel for #pragma omp parallel for
for (int i=curr_i;i<ts;++i) for (int i=curr_i;i<ts;++i)
{ {
if (new_appends + ts >=max_nodes) if (new_appends + ts >=max_nodes)
continue; continue;
const unsigned char clock = tree[i].depth; const unsigned char clock = tree[i].depth;
if (clock >= stop_depth)
continue;
bool onlykill = clock >=max_depth;
const int tid = omp_get_thread_num(); const int tid = omp_get_thread_num();
if ((tree[i].alive & 0x00010001)==0x00010001) if ((tree[i].alive & 0x00010001)==0x00010001)
{ {
const int curr_side = (side + clock) % 2; const int curr_side = (side + clock) % 2;
std::vector<chess_node> next_status = std::vector<chess_node> next_status =
expand_node(tree[i],curr_side); expand_node(tree[i],curr_side,onlykill);
const size_t sz = next_status.size(); const size_t sz = next_status.size();
for (size_t j=0;j<sz;++j) for (size_t j=0;j<sz;++j)
...@@ -119,11 +137,19 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const ...@@ -119,11 +137,19 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
bool needI = false; bool needI = false;
#pragma omp critical #pragma omp critical
{ {
if (dict.find(ha)==dict.end()) if (dict.find(ha)==dict.end() && clock+1 <= max_depth)
{ {
needI = true; needI = true;
dict.insert(ha); dict.insert(ha);
} }
else if (dict.find(ha)==dict.end() && clock + 1 <= stop_depth)
{
if (next_status[j].jump_cost[0]+next_status[j].jump_cost[1]>0)
{
needI = true;
dict.insert(ha);
}
}
} }
if (needI) if (needI)
{ {
...@@ -135,7 +161,7 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const ...@@ -135,7 +161,7 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
++new_appends; ++new_appends;
if (new_appends%1000==0) if (new_appends%1000==0)
{ {
printf ("Thinking.%d... \r",int(new_appends+ts)); printf ("Thinking.%d:%d... \r",i,int(new_appends+ts));
} }
} }
} }
...@@ -149,7 +175,7 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const ...@@ -149,7 +175,7 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
curr_i += (ts - curr_i); curr_i += (ts - curr_i);
} }
printf ("Depth = %d \n",tree.rbegin()->depth); printf ("\nDepth = %d \n",tree.rbegin()->depth);
return tree; return tree;
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "chesspi.h" #include "chesspi.h"
std::vector<chess_node> expand_node(const chess_node & r_root, const int side) std::vector<chess_node> expand_node(const chess_node & r_root, const int side,bool onlykill)
{ {
const chess_node * root = &r_root; const chess_node * root = &r_root;
static const int valid_directs[16] = {4,4,4,4,4,8,8,4,4,4,4,3,3,3,3,3}; static const int valid_directs[16] = {4,4,4,4,4,8,8,4,4,4,4,3,3,3,3,3};
...@@ -36,7 +36,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -36,7 +36,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
int coordx[32]{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}; int coordx[32]{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};
int coordy[32]{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}; int coordy[32]{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};
int alive[32]{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}; int alive[32]{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};
int alive_total = 0;
if (side==0) if (side==0)
{ {
for (int i=0;i<32;++i) for (int i=0;i<32;++i)
...@@ -44,6 +44,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -44,6 +44,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
coordx[i] = root->coords[i] >> 4; coordx[i] = root->coords[i] >> 4;
coordy[i] = root->coords[i] & 0x0f; coordy[i] = root->coords[i] & 0x0f;
alive[i] = (root->alive & (1<<i))?1:0; alive[i] = (root->alive & (1<<i))?1:0;
alive_total += alive[i];
} }
} }
else { else {
...@@ -55,6 +56,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -55,6 +56,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
coordx[i] = 10 - x; coordx[i] = 10 - x;
coordy[i] = 11 - y; coordy[i] = 11 - y;
alive[i] = (root->alive & (1<<od))?1:0; alive[i] = (root->alive & (1<<od))?1:0;
alive_total += alive[i];
} }
} }
//制作坐标站位表 //制作坐标站位表
...@@ -67,14 +69,13 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -67,14 +69,13 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
//有限层级优先顺序 //有限层级优先顺序
// * 帅士士相相马马车车炮炮兵兵兵兵兵 將仕仕象象馬馬車車砲砲卒卒卒卒卒 // * 帅士士相相马马车车炮炮兵兵兵兵兵 將仕仕象象馬馬車車砲砲卒卒卒卒卒
const int order[5][16] = { const int order[4][16] = {
{7,8,9,10,5,6,11,12,14,15,1,2,3,4,13,0},
{7,8,9,10,5,6,11,12,1,2,3,4,14,15,13,0},
{7,8,9,10,5,6,1,2,3,4,11,12,14,15,13,0},
{7,8,9,10,5,6,11,12,14,15,1,2,3,4,13,0}, {7,8,9,10,5,6,11,12,14,15,1,2,3,4,13,0},
{9,10,7,8,5,6,11,12,14,15,1,2,3,4,13,0},
{5,6,9,10,7,8,11,12,14,15,1,2,3,4,13,0},
{9,6,5,7,10,8,1,2,3,4,11,12,14,15,13,0},
{10,8,5,7,9,6,1,2,3,4,11,12,14,15,13,0}
}; };
int curr_od = rand() % 5; int curr_od = (32 - alive_total)/8;
for (int oi=0;oi<16;++oi) for (int oi=0;oi<16;++oi)
{ {
const int i = order[curr_od][oi]; const int i = order[curr_od][oi];
...@@ -91,7 +92,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -91,7 +92,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue; continue;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -105,7 +106,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -105,7 +106,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
{ {
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,coordx[16],coordy[16], if (!build_node(coordx,coordy,alive,i,coordx[16],coordy[16],
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -122,7 +123,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -122,7 +123,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue; continue;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -141,7 +142,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -141,7 +142,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue; continue;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -160,7 +161,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -160,7 +161,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue; continue;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -179,7 +180,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -179,7 +180,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
break; break;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
if (map_coords[new_y][new_x]) if (map_coords[new_y][new_x])
...@@ -205,7 +206,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -205,7 +206,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
{ {
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
break; break;
res.push_back(node); res.push_back(node);
} }
...@@ -231,7 +232,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side) ...@@ -231,7 +232,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue; continue;
chess_node node; chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y, if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node)) side,map_coords,&node,onlykill))
continue; continue;
res.push_back(node); res.push_back(node);
} }
...@@ -249,7 +250,7 @@ bool build_node(const int old_coordx[/*32*/], const int old_coordy[/*32*/], ...@@ -249,7 +250,7 @@ bool build_node(const int old_coordx[/*32*/], const int old_coordy[/*32*/],
const int old_alive[/*32*/], const int old_alive[/*32*/],
const int idx, const int new_x, const int new_y,const int side, const int idx, const int new_x, const int new_y,const int side,
int map_coords[/*11*/][10], int map_coords[/*11*/][10],
chess_node * node) chess_node * node,bool onlykill)
{ {
//不能吃自己的棋子 //不能吃自己的棋子
if (map_coords[new_y][new_x]>=1 && map_coords[new_y][new_x]<=16) if (map_coords[new_y][new_x]>=1 && map_coords[new_y][new_x]<=16)
...@@ -270,6 +271,8 @@ chess_node * node) ...@@ -270,6 +271,8 @@ chess_node * node)
assert(map_coords[new_y][new_x]); assert(map_coords[new_y][new_x]);
alive[map_coords[new_y][new_x]-1] = 0; alive[map_coords[new_y][new_x]-1] = 0;
} }
else if (onlykill)
return false;
//反转 //反转
if (side==0) if (side==0)
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <ctime> #include <ctime>
#include <unordered_set> #include <unordered_set>
#include "chesspi.h" #include "chesspi.h"
extern int max_depth;
int main() int main()
{ {
//初始棋局 //初始棋局
...@@ -18,7 +18,6 @@ int main() ...@@ -18,7 +18,6 @@ int main()
int alive[32]{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; int alive[32]{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
srand(time(0)); srand(time(0));
printf ("Side(0=RED,1=BLACK):");
chess_node root; chess_node root;
if (!build_node(coordx,coordy,alive,0,&root)) if (!build_node(coordx,coordy,alive,0,&root))
...@@ -26,10 +25,15 @@ int main() ...@@ -26,10 +25,15 @@ int main()
printf ("创建棋局失败!\n"); printf ("创建棋局失败!\n");
return 0; return 0;
} }
//回合
int side = 0; int side = 0;
int nodesInM = 0;
printf ("Side(0=RED,1=BLACK):");
scanf("%d",&side); scanf("%d",&side);
printf ("Max Depth(default 5):");
scanf("%d",&nodesInM);
if (nodesInM>=4 && nodesInM<10)
max_depth = nodesInM;
//回合
side %=2; side %=2;
if (side <0) if (side <0)
side = 1; side = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册