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

Add chess for raspberry pi

上级 bc3d30b7
......@@ -10,4 +10,5 @@ release
*.pdb
build-*
*.user
*.exe
\ No newline at end of file
*.exe
.vscode
#ifndef CHESSPI_H
#define CHESSPI_H
#include <vector>
#include <string>
/**
* @brief The chess_node struct 棋盘状态节点
*/
struct chess_node{
/**
* @brief coords 棋盘坐标,
* 每个字节一个棋子,X(高4比特)Y(低4比特),X1-9,Y1-10
* 顺序:0=红方, 1=黑方
* 0 15 16 31
* 帅士士相相马马车车炮炮兵兵兵兵兵 將仕仕象象馬馬車車砲砲卒卒卒卒卒
*/
unsigned char coords[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};
/*!
* \brief alive 存活标记,每个1比特.顺序:0=红方, 1=黑方
* 0 15 16 31
* 帅士士相相马马车车炮炮兵兵兵兵兵 將仕仕象象馬馬車車砲砲卒卒卒卒卒
*/
unsigned int alive = 0;
size_t parent = 0;
size_t leaves = 0;
float jump_cost[2]{0,0};//跳转损失
char side = 0;
char depth = 0;
//遍历
float weight = 1;
};
//走位和显示
//-------------------------------------------
std::vector<chess_node> expand_node(const chess_node & root, 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 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);
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
//-------------------------------------------
unsigned int calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],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
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.cpp \
chesspi_rules.cpp \
chesspi_ai.cpp
HEADERS += \
chesspi.h
QMAKE_CXXFLAGS += -fopenmp
LIBS += -lgomp
#include <cstdio>
#include <memory.h>
#include <vector>
#include <string>
#include <cassert>
#include <algorithm>
#include <set>
#include <unordered_set>
#include <cmath>
#include <omp.h>
#include <atomic>
#include "chesspi.h"
unsigned int calc_cost(const int coordx[/*32*/], const int coordy[/*32*/],const int idx)
{
unsigned int cost[16] = {100000,150,150,150,150,100,100,100,100,500,500,10,100,1000,100,10};
assert(idx >= 16);
unsigned int rescost = cost[idx%16];
return rescost;
}
std::vector<chess_node> build_tree(const chess_node & root, const int side,const std::vector<chess_node> & history)
{
std::vector<chess_node> tree;
std::unordered_set <std::string> dict;
for (const chess_node & n: history)
dict.insert(node2hash(n.coords,n.alive));
tree.push_back(root);
tree[0].side = side % 2;
tree[0].depth = 0;
size_t curr_i = 0;
size_t max_nodes = 1024*1024*4;
while (tree.size()<=max_nodes && curr_i<tree.size())
{
const size_t ts = tree.size();
const int cores = omp_get_num_procs();
std::vector<std::vector<chess_node> > vec_appends;
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;
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);
const size_t sz = next_status.size();
for (size_t j=0;j<sz;++j)
{
std::string ha = node2hash(next_status[j].coords,next_status[j].alive);
bool needI = false;
#pragma omp critical
{
if (dict.find(ha)==dict.end())
{
needI = true;
dict.insert(ha);
}
}
if (needI)
{
next_status[j].parent = i;
next_status[j].side = curr_side;
next_status[j].depth = clock+1;
vec_appends[tid].push_back(next_status[j]);
++tree[i].leaves;
++new_appends;
}
}
}
}
for (int i=0;i<cores;++i)
{
if (vec_appends[i].size())
std::move(vec_appends[i].begin(),vec_appends[i].end(),std::back_inserter(tree));
}
curr_i += (ts - curr_i);
}
//printf ("\nDepth = %d\n",tree.rbegin()->depth);
return tree;
}
size_t judge_tree(std::vector<chess_node> & tree)
{
const size_t total_nodes = tree.size();
if (total_nodes<2)
return 0;
int side = tree[0].side;
size_t i = total_nodes - 1;
while (i > 0)
{
if (tree[i].side==0)
{
float ratio = sqrt((tree[i].jump_cost[1]+1) / (tree[i].jump_cost[0]+1)/ (tree[i].jump_cost[0]+1));
tree[i].weight = ratio;
}
else
{
float ratio = sqrt((tree[i].jump_cost[0]+1) / (tree[i].jump_cost[1]+1)/ (tree[i].jump_cost[1]+1));
tree[i].weight = ratio;
}
size_t parent = tree[i].parent;
tree[parent].jump_cost[0] += tree[i].jump_cost[0] * tree[i].weight/tree[i].depth/tree[i].depth;
tree[parent].jump_cost[1] += tree[i].jump_cost[1] * tree[i].weight/tree[i].depth/tree[i].depth;
--i;
}
size_t p = 1;
float max_v = 0;
int max_p = 1;
while (p<total_nodes)
{
if (tree[p].parent)
break;
//float v = (tree[p].jump_cost[1-side]+1)/(tree[p].jump_cost[side]);
float v = (tree[p].weight);
if (v > max_v)
{
max_v = v;
max_p = p;
}
++p;
}
return max_p;
}
#include <cstdio>
#include <memory.h>
#include <vector>
#include <string>
#include <cassert>
#include <algorithm>
#include <set>
#include <unordered_set>
#include "chesspi.h"
std::vector<chess_node> expand_node(const chess_node & r_root, const int side)
{
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_coords[16][8][2] = {
{{-1,0},{1,0},{0,-1},{0,1},{100,100},{100,100},{100,100},{100,100}},
{{-1,-1},{1,1},{1,-1},{-1,1},{100,100},{100,100},{100,100},{100,100}},
{{-1,-1},{1,1},{1,-1},{-1,1},{100,100},{100,100},{100,100},{100,100}},
{{-2,-2},{2,2},{2,-2},{-2,2},{100,100},{100,100},{100,100},{100,100}},
{{-2,-2},{2,2},{2,-2},{-2,2},{100,100},{100,100},{100,100},{100,100}},
{{-1,-2},{1,2},{1,-2},{-1,2},{-2,-1},{2,1},{2,-1},{-2,1}},
{{-1,-2},{1,2},{1,-2},{-1,2},{-2,-1},{2,1},{2,-1},{-2,1}},
{{-1,0},{1,0},{0,-1},{0,1},{100,100},{100,100},{100,100},{100,100}},
{{-1,0},{1,0},{0,-1},{0,1},{100,100},{100,100},{100,100},{100,100}},
{{-1,0},{1,0},{0,-1},{0,1},{100,100},{100,100},{100,100},{100,100}},
{{-1,0},{1,0},{0,-1},{0,1},{100,100},{100,100},{100,100},{100,100}},
{{0,1},{1,0},{-1,0},{100,100},{100,100},{100,100},{100,100},{100,100}},
{{0,1},{1,0},{-1,0},{100,100},{100,100},{100,100},{100,100},{100,100}},
{{0,1},{1,0},{-1,0},{100,100},{100,100},{100,100},{100,100},{100,100}},
{{0,1},{1,0},{-1,0},{100,100},{100,100},{100,100},{100,100},{100,100}},
{{0,1},{1,0},{-1,0},{100,100},{100,100},{100,100},{100,100},{100,100}}
};
std::vector<chess_node> res;
//如果是黑方,反转坐标
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};
if (side==0)
{
for (int i=0;i<32;++i)
{
coordx[i] = root->coords[i] >> 4;
coordy[i] = root->coords[i] & 0x0f;
alive[i] = (root->alive & (1<<i))?1:0;
}
}
else {
for (int i=0;i<32;++i)
{
const int od = i%16 + (1-i/16)*16;
const unsigned char x = root->coords[od] >> 4;
const unsigned char y = root->coords[od] & 0x0f;
coordx[i] = 10 - x;
coordy[i] = 11 - y;
alive[i] = (root->alive & (1<<od))?1:0;
}
}
//制作坐标站位表
int map_coords[11][10];
memset (map_coords,0,sizeof(map_coords));
for (int i=0;i<32;++i)
if (alive[i])
map_coords[coordy[i]][coordx[i]] = i+1;
for (int i=0;i<16;++i)
{
if (!alive[i])
continue;
switch (i)
{
case 0://将
for (int d = 0; d < valid_directs[i];++d)
{
const int new_x = coordx[i] + valid_coords[i][d][0];
const int new_y = coordy[i] + valid_coords[i][d][1];
if (new_x <4 || new_x >6 || new_y <1 || new_y >3 )
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
}
if (coordx[0]==coordx[16])
{
bool hit = true;
for (int cy = coordy[0]+1; cy < coordy[16] && hit;++cy)
if (map_coords[cy][coordx[0]])
hit = false;
if (hit)
{
chess_node node;
if (!build_node(coordx,coordy,alive,i,coordx[16],coordy[16],
side,map_coords,&node))
continue;
res.push_back(node);
}
}
break;
case 1://士
case 2://士
for (int d = 0; d < valid_directs[i];++d)
{
const int new_x = coordx[i] + valid_coords[i][d][0];
const int new_y = coordy[i] + valid_coords[i][d][1];
if (new_x <4 || new_x >6 || new_y <1 || new_y >3 )
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
}
break;
case 3://相
case 4://相
for (int d = 0; d < valid_directs[i];++d)
{
const int new_x = coordx[i] + valid_coords[i][d][0];
const int new_y = coordy[i] + valid_coords[i][d][1];
const int test_x = coordx[i] + valid_coords[i][d][0]/2;
const int test_y = coordy[i] + valid_coords[i][d][1]/2;
if (new_x <1 || new_x >9 || new_y <1 || new_y >5 )
continue;
if (map_coords[test_y][test_x])
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
}
break;
case 5://马
case 6://马
for (int d = 0; d < valid_directs[i];++d)
{
const int new_x = coordx[i] + valid_coords[i][d][0];
const int new_y = coordy[i] + valid_coords[i][d][1];
const int test_x = coordx[i] + valid_coords[i][d][0]/2;
const int test_y = coordy[i] + valid_coords[i][d][1]/2;
if (new_x <1 || new_x >9 || new_y <1 || new_y >10 )
continue;
if (map_coords[test_y][test_x])
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
}
break;
case 7://车
case 8://车
for (int d = 0; d < valid_directs[i];++d)
{
for (int a=1;a<10;++a)
{
const int new_x = coordx[i] + valid_coords[i][d][0]*a;
const int new_y = coordy[i] + valid_coords[i][d][1]*a;
if (new_x <1 || new_x >9 || new_y <1 || new_y >10 )
continue;
if (map_coords[new_y][new_x]>0 && map_coords[new_y][new_x]<=16)
break;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
if (map_coords[new_y][new_x])
break;
}
}
break;
case 9://炮
case 10://炮
for (int d = 0; d < valid_directs[i];++d)
{
int hitn = 0;
for (int a=1;a<10;++a)
{
const int new_x = coordx[i] + valid_coords[i][d][0]*a;
const int new_y = coordy[i] + valid_coords[i][d][1]*a;
if (new_x <1 || new_x >9 || new_y <1 || new_y >10 )
continue;
if (map_coords[new_y][new_x])
++hitn;
if (hitn==0 || hitn==2)
{
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
break;
res.push_back(node);
}
if (hitn==2)
break;
}
}
break;
case 11://卒
case 12://卒
case 13://卒
case 14://卒
case 15://卒
for (int d = 0; d < valid_directs[i];++d)
{
//小卒不过河只能前进
if (coordy[i]<6 && d)
break;
const int new_x = coordx[i] + valid_coords[i][d][0];
const int new_y = coordy[i] + valid_coords[i][d][1];
if (new_x <1 || new_x >9 || new_y <1 || new_y >10 )
continue;
chess_node node;
if (!build_node(coordx,coordy,alive,i,new_x,new_y,
side,map_coords,&node))
continue;
res.push_back(node);
}
break;
default:
assert(false);
break;
}
}
return res;
}
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)
{
//不能吃自己的棋子
if (map_coords[new_y][new_x]>=1 && map_coords[new_y][new_x]<=16)
return false;
assert(new_x>0 && new_x <10);
assert(new_y>0 && new_y <11);
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};
memcpy(coordx,old_coordx,sizeof(coordx));
memcpy(coordy,old_coordy,sizeof(coordy));
memcpy(alive,old_alive,sizeof(alive));
coordx[idx] = new_x;
coordy[idx] = new_y;
if (map_coords[new_y][new_x]>16)
{
assert(map_coords[new_y][new_x]);
alive[map_coords[new_y][new_x]-1] = 0;
//计算吃子代价
node->jump_cost[1-side] = calc_cost(coordx,coordy,map_coords[new_y][new_x]-1);
}
//反转
if (side==0)
{
for (int i=0;i<32;++i)
{
node->coords[i] &=0x0f;
node->coords[i] ^= (coordx[i] << 4);
node->coords[i] &=0xf0;
node->coords[i] ^= coordy[i];
node->alive |= (1<<i);
node->alive ^= (!alive[i])? (1<<i):0;
}
}
else {
for (int i=0;i<32;++i)
{
const int od = i%16 + (1-i/16)*16;
node->coords[i] &=0x0f;
node->coords[i] ^=((10-coordx[od]) << 4);
node->coords[i] &=0xf0;
node->coords[i] ^=11 - coordy[od];
node->alive |= (1<<i);
node->alive ^= (!alive[od])? (1<<i):0;
}
}
return true;
}
bool build_node(const int coordx[/*32*/], const int coordy[/*32*/],
const int alive[/*32*/],const int side,chess_node * node)
{
//反转
if (side==0)
{
for (int i=0;i<32;++i)
{
node->coords[i] &=0x0f;
node->coords[i] ^= (coordx[i] << 4);
node->coords[i] &=0xf0;
node->coords[i] ^= coordy[i];
node->alive |= (1<<i);
node->alive ^= (!alive[i])? (1<<i):0;
}
}
else {
for (int i=0;i<32;++i)
{
const int od = i%16 + (1-i/16)*16;
node->coords[i] &=0x0f;
node->coords[i] ^= (10 - coordx[od]) << 4;
node->coords[i] &=0xf0;
node->coords[i] ^= 11 - coordy[od];
node->alive |= (1<<i);
node->alive ^= (!alive[od])? (1<<i):0;
}
}
return true;
}
void print_node(const chess_node & node)
{
const int side = node.side;
printf ("side=%d\n",side);
static const char * pstr[] = {"帅","士","士","相","相","马","马","车","车","炮","炮","兵","兵","兵","兵","兵","將","仕","仕","象","象","馬","馬","車","車","砲","砲","卒","卒","卒","卒","卒"};
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};
std::string nhash = node2hash(node.coords,node.alive);
for (int i=0;i<32;++i)
{
coordx[i] = node.coords[i] >> 4;
coordy[i] = node.coords[i] & 0x0f;
alive[i] = (node.alive & (1<<i))?1:0;
printf ("%X",((unsigned char)(nhash[i]))>>4);
printf ("%X",((unsigned char)(nhash[i]))&0x0F);
}
printf ("\n");
//制作坐标站位表
int map_coords[11][10];
memset (map_coords,0,sizeof(map_coords));
for (int i=0;i<32;++i)
if (alive[i])
map_coords[coordy[i]][coordx[i]] = i+1;
if (side)
{
printf (" ");
for (int x = 1; x<=9; ++x)
printf("%2d",x-1);
printf ("\n");
for (int y = 1; y <=10 ;++y)
{
printf ("%2d ", y-1);
for (int x=1;x<=9;++x)
{
if (map_coords[y][x]>0 && map_coords[y][x]<=16)
printf("\33[1m\033[31m%s\033[0m",pstr[map_coords[y][x]-1]);
else if (map_coords[y][x]>16)
printf("\33[1m\033[36m%s\033[0m",pstr[map_coords[y][x]-1]);
else
printf (" ");
}
printf ("\n");
}
}
else
{
printf (" ");
for (int x = 1; x<=9; ++x)
printf("%2d",8-(x-1));
printf ("\n");
for (int y = 10; y >0 ;--y)
{
printf ("%2d ", y-1);
for (int x=9;x>0;--x)
{
if (map_coords[y][x]>0 && map_coords[y][x]<=16)
printf("\33[1m\033[31m%s\033[0m",pstr[map_coords[y][x]-1]);
else if (map_coords[y][x]>16)
printf("\33[1m\033[36m%s\033[0m",pstr[map_coords[y][x]-1]);
else
printf (" ");
}
printf ("\n");
}
}
printf ("----------------------------------------\n");
}
std::vector<std::string> node2hash(const std::vector<chess_node> & nodes)
{
std::vector<std::string> v;
const size_t sz = nodes.size();
for (size_t i=0;i<sz;++i)
v.push_back(node2hash(nodes[i].coords,nodes[i].alive));
return v;
}
std::string node2hash(const unsigned char coords[/*32*/], const unsigned int alive)
{
std::string res;
std::string str1;
for (int i=0;i<32;++i)
{
if(alive & (1<<i))
str1+=coords[i];
else
str1+=0xff;
}
//哈西需要考虑镜像
std::sort(str1.begin()+1,str1.begin()+3,std::less<unsigned char>());
std::sort(str1.begin()+3,str1.begin()+5,std::less<unsigned char>());
std::sort(str1.begin()+5,str1.begin()+7,std::less<unsigned char>());
std::sort(str1.begin()+7,str1.begin()+9,std::less<unsigned char>());
std::sort(str1.begin()+9,str1.begin()+11,std::less<unsigned char>());
std::sort(str1.begin()+11,str1.begin()+16,std::less<unsigned char>());
std::sort(str1.begin()+17,str1.begin()+19,std::less<unsigned char>());
std::sort(str1.begin()+19,str1.begin()+21,std::less<unsigned char>());
std::sort(str1.begin()+21,str1.begin()+23,std::less<unsigned char>());
std::sort(str1.begin()+23,str1.begin()+25,std::less<unsigned char>());
std::sort(str1.begin()+25,str1.begin()+27,std::less<unsigned char>());
std::sort(str1.begin()+27,str1.begin()+32,std::less<unsigned char>());
unsigned char codsm[32];
mirror_coordx(coords,codsm);
std::string str2;
for (int i=0;i<32;++i)
{
if(alive & (1<<i))
str2+=codsm[i];
else
str2+=0xff;
}
//哈西需要考虑镜像
std::sort(str2.begin()+1,str2.begin()+3,std::less<unsigned char>());
std::sort(str2.begin()+3,str2.begin()+5,std::less<unsigned char>());
std::sort(str2.begin()+5,str2.begin()+7,std::less<unsigned char>());
std::sort(str2.begin()+7,str2.begin()+9,std::less<unsigned char>());
std::sort(str2.begin()+9,str2.begin()+11,std::less<unsigned char>());
std::sort(str2.begin()+11,str2.begin()+16,std::less<unsigned char>());
std::sort(str2.begin()+17,str2.begin()+19,std::less<unsigned char>());
std::sort(str2.begin()+19,str2.begin()+21,std::less<unsigned char>());
std::sort(str2.begin()+21,str2.begin()+23,std::less<unsigned char>());
std::sort(str2.begin()+23,str2.begin()+25,std::less<unsigned char>());
std::sort(str2.begin()+25,str2.begin()+27,std::less<unsigned char>());
std::sort(str2.begin()+27,str2.begin()+32,std::less<unsigned char>());
if (str1 > str2)
res = str2 + str1;
else
res = str1 + str2;
return res;
}
void mirror_coordx(const unsigned char cod1[/*32*/],unsigned char cod2[/*32*/])
{
for (int i=0;i<32;++i)
{
const unsigned char x = 10-(cod1[i]>>4);
const unsigned char y = cod1[i] & 0x0f;
cod2[i] = (x<<4) ^ y;
}
}
bool move_node(const chess_node & root, chess_node * new_node, const int x1, const int y1,const int x2, const int y2,const int side)
{
std::vector <chess_node> vec = expand_node(root,side);
int idx = -1;
for (int i=0;i<32 && idx < 0;++i)
{
int rx = root.coords[i]>>4;
int ry = root.coords[i]& 0x0F;
if (rx==x1 && ry==y1 && (root.alive & (1<<i)))
idx = i;
}
if (idx<0)
return false;
if (side==0 && idx >=16)
return false;
if (side==1 && idx <16)
return false;
const size_t sz = vec.size();
for (size_t i=0;i<sz;++i)
{
const int newx = vec[i].coords[idx] >> 4;
const int newy = vec[i].coords[idx] & 0x0F;
if (newx == x2 && newy==y2)
{
*new_node = vec[i];
return true;
}
}
return false;
}
#include <cstdio>
#include <memory.h>
#include <vector>
#include <string>
#include <cstring>
#include <cassert>
#include <algorithm>
#include <set>
#include <unordered_set>
#include "chesspi.h"
int main()
{
//初始棋局
int coordx[32]{5,4,6,3,7,2,8,1,9,2,8,1,3,5,7,9,5,4,6,3,7,2,8,1,9,2,8,1,3,5,7,9};
int coordy[32]{1,1,1,1,1,1,1,1,1,3,3,4,4,4,4,4,10,10,10,10,10,10,10,10,10,8,8,7,7,7,7,7};
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};
chess_node root;
if (!build_node(coordx,coordy,alive,0,&root))
{
printf ("创建棋局失败!\n");
return 0;
}
//回合
size_t round = 0;
bool finished = false;
print_node(root);
std::vector<chess_node> history;
history.push_back(root);
while (!finished)
{
printf ("\nround %d:\n==========\n", round);
if (round % 2==0)
{
//找到棋子
bool ok = false;
chess_node new_node;
while (!ok)
{
printf ("请输入四个整数,分别是棋子X,Y,目的X,Y,逗号分割:\n");
int x1,y1,x2,y2;
scanf("%d,%d,%d,%d",&x1,&y1,&x2,&y2);
ok = move_node(root,&new_node,x1+1,y1+1,x2+1,y2+1,round % 2);
if (!ok)
{
printf ("没有选中棋子.\n");
getchar();
}
else {
root = new_node;
}
}
}
else {
std::vector<chess_node> tree =
build_tree(root,(0+round)%2,history);
size_t best = judge_tree(tree);
if (best <1 || best + 1 > tree.size())
break;
root = tree[best];
printf ("Best % d Cost: %f, %f, Weight %f\n",best
,root.jump_cost[0],root.jump_cost[1],root.weight
);
}
root.side = 0;
print_node(root);
history.push_back(root);
++round;
if (!((root.alive & 0x00010001)==0x00010001))
break;
}
printf ("FINISHED!\n");
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册