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

加入策略

上级 0102c2a1
......@@ -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 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 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 side,chess_node * 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*/]);
//计算棋盘哈希
std::vector<std::string> node2hash(const std::vector<chess_node> & nodes);
std::string node2hash(const unsigned char cod[/*32*/], const unsigned int alive);
//AI
//-------------------------------------------
//计算走位代价
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);
//评估并返回走位
size_t judge_tree(std::vector<chess_node> & tree);
#endif // CHESSPI_H
......@@ -11,7 +11,18 @@
#include <atomic>
#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};
/*!
* \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)
{
......@@ -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])
rescost *= 2;
break;
//马战线挺进,以及后期击杀价值高
//马战线挺进,以及后期击杀价值高
case 5:
case 6:
if (idx<16 )
......@@ -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 + killed / 4.0;
break;
//车战线击杀高
//车战线击杀高
case 7:
case 8:
if (idx<16 )
......@@ -47,7 +58,7 @@ float calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int ali
else
rescost *= 1+((11-coordy[idx])/3.0);
break;
//炮前期击杀高
//炮前期击杀高
case 9:
case 10:
if (idx<16 )
......@@ -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 + (32 - killed) / 4.0;
break;
//卒过河击杀高
//卒过河击杀高
case 11:
case 12:
case 13:
......@@ -88,9 +99,12 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
tree.push_back(root);
tree[0].side = side % 2;
tree[0].depth = 0;
int max_nodes = 1000*1000*32;
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())
{
const size_t ts = tree.size();
......@@ -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)
vec_appends.push_back(std::vector<chess_node>());
std::atomic<int> new_appends (0);
#pragma omp parallel for
for (int i=curr_i;i<ts;++i)
{
if (new_appends + ts >=max_nodes)
continue;
const unsigned char clock = tree[i].depth;
if (clock >= stop_depth)
continue;
bool onlykill = clock >=max_depth;
const int tid = omp_get_thread_num();
if ((tree[i].alive & 0x00010001)==0x00010001)
{
const int curr_side = (side + clock) % 2;
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();
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
bool needI = false;
#pragma omp critical
{
if (dict.find(ha)==dict.end())
if (dict.find(ha)==dict.end() && clock+1 <= max_depth)
{
needI = true;
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)
{
......@@ -135,7 +161,7 @@ std::vector<chess_node> build_tree(const chess_node & root, const int side,const
++new_appends;
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
curr_i += (ts - curr_i);
}
printf ("Depth = %d \n",tree.rbegin()->depth);
printf ("\nDepth = %d \n",tree.rbegin()->depth);
return tree;
}
......
......@@ -9,7 +9,7 @@
#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;
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)
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 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)
{
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)
coordx[i] = root->coords[i] >> 4;
coordy[i] = root->coords[i] & 0x0f;
alive[i] = (root->alive & (1<<i))?1:0;
alive_total += alive[i];
}
}
else {
......@@ -55,6 +56,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
coordx[i] = 10 - x;
coordy[i] = 11 - y;
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)
//有限层级优先顺序
// * 帅士士相相马马车车炮炮兵兵兵兵兵 將仕仕象象馬馬車車砲砲卒卒卒卒卒
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},
{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)
{
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)
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -105,7 +106,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
{
chess_node node;
if (!build_node(coordx,coordy,alive,i,coordx[16],coordy[16],
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -122,7 +123,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -141,7 +142,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -160,7 +161,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -179,7 +180,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
break;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
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)
{
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
break;
res.push_back(node);
}
......@@ -231,7 +232,7 @@ std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
side,map_coords,&node,onlykill))
continue;
res.push_back(node);
}
......@@ -249,7 +250,7 @@ bool build_node(const int old_coordx[/*32*/], const int old_coordy[/*32*/],
const int old_alive[/*32*/],
const int idx, const int new_x, const int new_y,const int side,
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)
......@@ -270,6 +271,8 @@ chess_node * node)
assert(map_coords[new_y][new_x]);
alive[map_coords[new_y][new_x]-1] = 0;
}
else if (onlykill)
return false;
//反转
if (side==0)
......
......@@ -9,7 +9,7 @@
#include <ctime>
#include <unordered_set>
#include "chesspi.h"
extern int max_depth;
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};
srand(time(0));
printf ("Side(0=RED,1=BLACK):");
chess_node root;
if (!build_node(coordx,coordy,alive,0,&root))
......@@ -26,10 +25,15 @@ int main()
printf ("创建棋局失败!\n");
return 0;
}
//回合
int side = 0;
int nodesInM = 0;
printf ("Side(0=RED,1=BLACK):");
scanf("%d",&side);
printf ("Max Depth(default 5):");
scanf("%d",&nodesInM);
if (nodesInM>=4 && nodesInM<10)
max_depth = nodesInM;
//回合
side %=2;
if (side <0)
side = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册