加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ai.cpp 12.44 KB
一键复制 编辑 原始数据 按行查看 历史
#include "func.h"
#include "image.h"
#include <math.h>
struct A {
int x, y, data;
};
class ai {
private:
A dp[225]; // 记录每个点的分数
int me, human; //记录player
// 方向从左上开始,顺时针一直到左边
int navigator[8][2] = {{-1,-1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}};
public:
ai(int pl) {
me = pl;
human = me == 1 ? 2 : 1;
srand(time(0));
}
// 为每个x, y 点打分的函数(太过于混乱,已经丢弃)
int check(const char bd[17][17], int x, int y) {
int r1 = 27, r2 = 7, r3 = 177;
int res[8][3] = {0}, i, r, ans = 0;
i = 1;
if (y + 1 <= 15) {
if (bd[x][y + 1] == me)
r = r1, res[0][2] = me;
else if (bd[x][y + 1])
r = r2, res[0][2] = human;
else
r = 0;
if (r)
while (y + i <= 15) {
if (bd[x][y + i] == bd[x][y + 1])
i++;
else
break;
}
// if(y+i <= 15 && bd[x][y+i] == 0) {
// if(y+1+i <= 15 && bd[x][y+i+1] == 0) r0[0] = 0;
// else if(y+1+i <= 15 && bd[x][y+i+1] == chess) r0[0] = 1;
// else if(y+1+i <= 15 && bd[x][y+i+1] != chess) r0[0] = -3;
// }
}
if (i - 1 )
res[0][0] = i - 1, res[0][1] = r;
if (i > 2) {
if (y + 1 + i <= 15 && bd[x][y + i + 1] != 0)
res[0][1] -= r3 ;
}
i = 1;
if (y + 1 <= 15 && x + 1 <= 15) {
if (bd[x + 1][y + 1] == me)
r = r1, res[1][2] = me;
else if (bd[x + 1][y + 1])
r = r2, res[1][2] = human;
else
r = 0;
if (r)
while (y + i <= 15 && x + i <= 15) {
if (bd[x + i][y + i] == bd[x + 1][y + 1])
i++;
else
break;
}
// if(y+i <= 15 && x+i <= 15 && bd[x+i][y+i] == 0){
// if(y+1+i <= 15 && x+1+i <= 15 && bd[x+i+1][y+i+1] == 0) r0[1] = 0;
// else if(y+1+i <= 15 && x+1+i <= 15 && bd[x+i+1][y+i+1] == chess) r0[1] = 1;
// else if(y+1+i <= 15 && x+1+i <= 15 && bd[x+i+1][y+i+1] != chess) r0[1] = -3;
// }
}
res[1][0] = i - 1, res[1][1] = r;
if (i > 2) {
if (y + 1 + i <= 15 && x + 1 + i <= 15 && bd[x + i + 1][y + i + 1] != 0)
res[1][1] -= r3 ;
}
i = 1;
if (x + 1 <= 15) {
if (bd[x + 1][y] == me)
r = r1, res[2][2] = me;
else if (bd[x + 1][y])
r = r2, res[2][2] = human;
else
r = 0;
if (r)
while (x + i <= 15) {
if (bd[x + i][y] == bd[x + 1][y])
i++;
else
break;
}
// if(x+i <= 15 && bd[x+i][y] == 0){
// if(bd[x+i+1][y] == 0 && x+1+i <= 15) r0[2] = 0;
// else if(x+1+i <= 15 && bd[x+i+1][y] == chess) r0[2] = 1;
// else if(x+1+i <= 15 && bd[x+i+1][y+i+1] != chess) r0[2] = -3;
// }
}
res[2][0] = i - 1, res[2][1] = r;
if (i > 2) {
if (bd[x + i + 1][y] != 0 && x + 1 + i <= 15)
res[2][1] -= r3;
}
i = 1;
if (x + 1 <= 15 && y - 1 >= 1) {
if (bd[x + 1][y - 1] == me)
r = r1, res[3][2] = me;
else if (bd[x + 1][y - 1])
r = r2, res[3][2] = human;
else
r = 0;
if (r)
while (x + 1 <= 15 && y - 1 >= 1) {
if (bd[x + i][y - i] == bd[x + 1][y - 1])
i++;
else
break;
}
// if(x+i <= 15 && y-i >= 1 && bd[x+i][y-i] == 0)
// if(bd[x+i+1][y-i-1] == 0 && x+1+i <= 15 && y-1-i >= 1) r0[3] = 0;
// else if(bd[x+i+1][y-i-1] == chess && x+1+i <= 15 && y-1-i >= 1) r0[3] = 1;
// else if(bd[x+i+1][y-i-1] != chess && x+1+i <= 15 && y-1-i >= 1) r0[3] = -3;
}
res[3][0] = i - 1, res[3][1] = r;
if (i > 2) {
if (bd[x + i + 1][y - i - 1] != 0 && x + 1 + i <= 15 && y - 1 - i >= 1)
res[3][1] -= r3 ;
}
i = 1;
if (y - 1 >= 1) {
if (bd[x][y - 1] == me)
r = r1, res[4][2] = me;
else if (bd[x][y - 1])
r = r2, res[4][2] = human;
else
r = 0;
if (r)
while (y - 1 >= 1) {
if (bd[x][y - i] == bd[x][y - 1])
i++;
else
break;
}
// if(y-i >= 1 && bd[x][y-i] == 0)
// if(bd[x][y-i-1] == 0 && y-1-i >= 1) r0[4] = 0;
// else if(bd[x][y-i-1] == chess && y-1-i >= 1) r0[4] = 1;
// else if(bd[x][y-i-1] != chess && y-1-i >= 1) r0[4] = -3;
}
res[4][0] = i - 1, res[4][1] = r;
if (i > 2) {
if (bd[x][y - i - 1] != 0 && y - 1 - i >= 1)
res[4][1] -= r3 ;
}
i = 1;
if (x - 1 >= 1 && y - 1 >= 1) {
if (bd[x - 1][y - 1] == me)
r = r1, res[5][2] = me;
else if (bd[x - 1][y - 1])
r = r2, res[5][2] = human;
else
r = 0;
if (r)
while (x - 1 >= 1) {
if (bd[x - i][y - i] == bd[x - 1][y - 1])
i++;
else
break;
}
if (i > 2) {
if (bd[x - i - 1][y - i - 1] != 0 && x - 1 - i >= 1 && y - 1 - i >= 1)
res[5][1] -= r3 ;
}
// if(y-i >= 1 && x-i >= 1 && bd[x-i][y-i] == 0)
// if(bd[x-i-1][y-i-1] == 0 && x-1-i >= 1 && y-1-i >= 1) r0[5] = 0;
// else if(bd[x-i-1][y-i-1] == chess && x-1-i >= 1 && y-1-i >= 1) r0[5] = 1;
// else if(bd[x-i-1][y-i-1] != chess && x-1-i >= 1 && y-1-i >= 1) r0[5] = -3;
}
res[5][0] = i - 1, res[5][1] += r;
i = 1;
if (x - 1 >= 1) {
if (bd[x - 1][y] == me)
r = r1, res[6][2] = me;
else if (bd[x - 1][y])
r = r2, res[6][2] = human;
else
r = 0;
if (r)
while (x - 1 >= 1) {
if (bd[x - i][y] == bd[x - 1][y])
i++;
else
break;
}
if (i > 2) {
if (bd[x - i - 1][y] != 0 && x - 1 - i >= 1)
res[6][1] -= r3 ;
}
// if(x-i >= 1 && bd[x-i][y] == 0)
// if(bd[x-i-1][y] == 0 && x-1-i >= 1) r0[6] = 0;
// else if(bd[x-i-1][y] == chess && x-1-i >= 1) r0[6] = 1;
// else if(bd[x-i-1][y] != chess && x-1-i >= 1) r0[6] = -3;
}
res[6][0] = i - 1, res[6][1] += r;
i = 1;
if (x - 1 >= 1 && y + 1 <= 15) {
if (bd[x - 1][y + 1] == me)
r = r1, res[7][2] = me;
else if (bd[x - 1][y + 1])
r = r2, res[7][2] = human;
else
r = 0;
if (r)
while (x - 1 >= 1 && y + 1 <= 15) {
if (bd[x - i][y + i] == bd[x - 1][y + 1])
i++;
else
break;
}
if (i > 2) {
if (bd[x - i - 1][y + i + 1] != 0 && x - 1 - i >= 1 && y + 1 + i <= 15)
res[7][1] -= r3;
}
// if(x-i >= 1 && y+i <= 15 && bd[x-i][y+i] == 0)
// if(bd[x-i-1][y+i+1] == 0 && x-1-i >= 1 && y+1+i <= 15) r0[7] = 0;
// else if(bd[x-i-1][y+i+1] == chess && x-1-i >= 1 && y+1+i <= 15) r0[7] = 1;
// else if(bd[x-i-1][y+i+1] != chess && x-1-i >= 1 && y+1+i <= 15) r0[7] = -3;
}
res[7][0] = i - 1, res[7][1] += r;
for (i = 0; i < 4; i++) {
if (res[i][2] == res[i + 4][2] && res[i][2]) {
res[i][0] += res[i + 4][0];
res[i + 4][0] = 0;
}
}
for (i = 0; i < 8; i++) {
if (res[i][0] == 3 && res[i][2] == me && res[(i + 4) % 8][2] != human)
res[i][1] += 35;
if (res[i][0] == 3 && res[i][2] == me && res[(i + 4) % 8][2] == human)
res[i][1] -= 10;
if (res[i][0] == 3 && res[i][2] == human && res[(i + 4) % 8][2] == human)
res[i][1] += 100;
if (res[i][0] == 3 && res[i][2] == human && res[(i + 4) % 8][2] != human)
res[i][1] += 20;
if (res[i][0] == 4 && res[i][2] == me)
res[i][1] += 1000;
if (res[i][0] == 4)
res[i][1] += 800;
}
for (i = 0; i < 8; i++) {
res[i][1] *= res[i][0];
}
for (i = 0; i < 8; i++)
ans += res[i][1];
return ans;
}
// 获取得分最高的点
A getMax(A q[]) {
A m = q[0];
for (int i = 1; i < 225; i++){
if (q[i].data > m.data) m = q[i];
else if (q[i].data == m.data && q[i].data != 0){
if (rand()%100 < 25) m = q[i];
}
}
return m;
}
// 下棋函数
void aidraw(char board[17][17]) {
// 初始化每个点的分数
for (int i = 0; i < 225; i++)
dp[i].data = 0;
// 通过check打分函数得出每个点得分数
for (int i = 1; i <= 15; i++) {
for (int j = 1; j <= 15; j++) {
if (!board[i][j]){
dp[(i - 1) * 15 + j - 1].data = check_v2(board, i, j);
dp[(i - 1) * 15 + j - 1].x = i;
dp[(i - 1) * 15 + j - 1].y = j;
}
}
}
// 获取最佳点并修改棋盘
A ans = getMax(dp);
int x = ans.x, y = ans.y;
board[x][y] = me;
prx = x, pry = y;
}
// 新的打分函数
int check_v2(const char bd[17][17], int x, int y) {
// 每个点可以有八个方向, 由 0 - 7 表示
// direct[i][0] 表示方向i的相同棋子个数,
// direct[i][1] 表示方向i的相同棋子类型
// direct[i][2] 表示方向i的棋子末端情况,方向i没有棋子:0,有棋子且末端为空:1,有棋子末端不空或者是边界:2
int direct[8][3] = {0};
// 计算八个方向的情况
check_line(bd, x, y, direct, 0);
check_line(bd, x, y, direct, 1);
check_line(bd, x, y, direct, 2);
check_line(bd, x, y, direct, 3);
check_line(bd, x, y, direct, 4);
check_line(bd, x, y, direct, 5);
check_line(bd, x, y, direct, 6);
check_line(bd, x, y, direct, 7);
// 为空的情况赋值0
for (int i = 0; i < 8; i++) if(!direct[i][1]) direct[i][0] = 0, direct[i][2] = 0;
// 总分和三个不同的权重
int sum = 0;
int w1 = 66, w2 = 22, w3 = 7;
// 前4个方向打分
for (int i = 0; i < 4; i++){
if (direct[i][1] == 0) continue; // 为空则继续
else if (direct[i][1] == direct[i+4][1]) direct[i+4][0] += direct[i][0]; // 相对的方向有相同棋子则留给相对方向计算
else {
// 此时相对方向没有棋子或者棋子不相同
// 有四个相同棋子的情况
if (direct[i][0] == 4 && direct[i][1] == me){
sum += 99999999;
}else if (direct[i][0] == 4 && direct[i][1] == human){
sum += 11111111;
}
// 相对方向没有棋子且本方向末端为空
else if (direct[i][2] == 1 && direct[i+4][2] == 0){
// 此时有三个相同棋子的情况,此时 sum += pow(w1, direct[i][0]) 不影响结果
if (direct[i][0] == 3 && direct[i][1] == me) sum += 5555555;
else if(direct[i][0] == 3 && direct[i][1] == human) sum += 1111111;
// 没有三个相同棋子时
sum += pow(w1, direct[i][0]);
}
// 相对方向没有棋子且本方向末端有棋子,或者相对方向有棋子且本方向末端没有棋子的情况
else if ((direct[i][2] == 2 && direct[i+4][2] == 0) ||
(direct[i][2] == 1 && direct[i+4][2] != 0)){
sum += pow(w2, direct[i][0]);
}else{
// 两边都有棋子
sum += pow(w3, direct[i][0]);
}
}
}
for (int i = 4; i < 8; i++){
if (direct[i][1] == 0) continue;
else if (direct[i][1] == direct[i-4][1]){ // 相对方向有棋子
// 四个棋子情况
if (direct[i][0] == 4 && direct[i][1] == me){
sum += 99999999;
}else if (direct[i][0] == 4 && direct[i][1] == human){
sum += 11111111;
}
// 两边末端都为空的情况
else if (direct[i][2] == 1 && direct[i-4][2] == 1){
if (direct[i][0] == 3 && direct[i][1] == me) sum += 5555555;
else if(direct[i][0] == 3 && direct[i][1] == human) sum += 1111111;
sum += pow(w1, direct[i][0]);
}
// 有一边末端不为空的情况
else if (direct[i][2] == 1 || direct[i-4][2] == 1){
sum += pow(w2, direct[i][0]);
}else {
// 两边末端都不为空
sum += pow(w3, direct[i][0]);
}
}else {
// 同 330 行
if (direct[i][0] == 4 && direct[i][1] == me){
sum += 99999999;
}else if (direct[i][0] == 4 && direct[i][1] == human){
sum += 11111111;
}else if (direct[i][2] == 1 && direct[i-4][2] == 0){
if (direct[i][0] == 3 && direct[i][1] == me) sum += 5555555;
else if(direct[i][0] == 3 && direct[i][1] == human) sum += 1111111;
sum += pow(w1, direct[i][0]);
}else if ((direct[i][2] == 2 && direct[i-4][2] == 0) ||
(direct[i][2] == 1 && direct[i+4][2] != 0)){
sum += pow(w2, direct[i][0]);
}else{
sum += pow(w3, direct[i][0]);
}
}
}
return sum;
}
// 检测 0 - 7 方向的棋子个数以及末端情况
void check_line(const char bd[17][17], int x, int y, int direct[][3], int idx){
int x1 = x+navigator[idx][0] , y1 = y+navigator[idx][1];
int px1 = x1, py1 = y1;
for(int i=1; x1 <= 15 && x1 >= 1 && y1 <= 15 && y1 >= 1; i++){
if (!bd[x1][y1]){
direct[idx][0] = i-1;
direct[idx][1] = bd[px1][py1];
direct[idx][2] = 1;
break;
}else if (i > 1 && bd[x1][y1] != bd[px1][py1]) {
direct[idx][0] = i-1;
direct[idx][1] = bd[px1][py1];
direct[idx][2] = 2;
break;
}
x1 = x1+navigator[idx][0] , y1 = y1+navigator[idx][1];
}
if (x1 > 15 || x1 < 1 || y1 > 15 || y1 < 1) direct[idx][2] = 2;
}
};
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化