Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
杨家三木
qtcpp_demo
提交
d4863242
qtcpp_demo
项目概览
杨家三木
/
qtcpp_demo
与 Fork 源项目一致
Fork自
colorEagleStdio / qtcpp_demo
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
qtcpp_demo
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
d4863242
编写于
6月 05, 2021
作者:
D
dev@dev.com
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
加入策略
上级
0102c2a1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
74 addition
and
44 deletion
+74
-44
chesspi/chesspi.h
chesspi/chesspi.h
+10
-13
chesspi/chesspi_ai.cpp
chesspi/chesspi_ai.cpp
+36
-10
chesspi/chesspi_rules.cpp
chesspi/chesspi_rules.cpp
+20
-17
chesspi/main.cpp
chesspi/main.cpp
+8
-4
未找到文件。
chesspi/chesspi.h
浏览文件 @
d4863242
...
...
@@ -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
chesspi/chesspi_ai.cpp
浏览文件 @
d4863242
...
...
@@ -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
(
"
\n
Depth = %d
\n
"
,
tree
.
rbegin
()
->
depth
);
return
tree
;
}
...
...
chesspi/chesspi_rules.cpp
浏览文件 @
d4863242
...
...
@@ -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
)
...
...
chesspi/main.cpp
浏览文件 @
d4863242
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录