#include "Rule.h"
#include <vector>
Position Rule::getPosition(const int state[15][15], int color) {//计算下一步棋子的位置
//旗手和棋子的标志 + 1 = 棋盘的标志
int mycolor = color + 1;//棋盘标志
int rivalcolor;
int userscore[15][15] = { 0 };//我的分数
int rivalscore[15][15] = { 0 };//对手的分数
int tempstate[15][15] = { 0 };//临时标志
//判断是否第一次下棋
int judge = 0;
int k = 0, h = 0;
for (k = 0; k < 15; k++) {
for (h = 0; h < 15; h++) {
if (state[k][h]>0) {
judge = 1;
break;
}
}
if (judge)
break;
}
if (k == 15 && h == 15) {//第一次下棋
Position position = { 7,7 };//默认最中间
return position;
}
//把最后一步标志还原
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (state[i][j]>2)
tempstate[i][j] = state[i][j] - 2;
else
tempstate[i][j] = state[i][j];
}
}
//打分
for (int i = 0; i < 15; i++)
for (int j = 0; j < 15; j++) {
Position position;
int score;
position.x = i;
position.y = j;
//我的分数
score = situation(tempstate, position, mycolor);//返回当前形势分数
userscore[i][j] = score;
if (mycolor == BQ)
rivalcolor = WQ;
else
rivalcolor = BQ;
//对手分数
score = situation(tempstate, position, rivalcolor);//返回当前形势分数
rivalscore[i][j] = score;
}
//根据分数,给出位置
return maxScore(userscore, rivalscore);
}
int Rule::situation(const int state[15][15], Position position, int color) {
Situation situation = { 0 };//记录当前形势变量
if (state[position.x][position.y])
return Level15;//有子不能下,返回0分
for (int direction = 0; direction < 4; direction++) {//四个方向,0横,1竖,2左上右下,3右上左下
int type;
type = getType(state, position, color, direction);//取得类型(死四,活四等)
switch (type) {//根据类型对situation设置
case FIVELINK:
situation.fivelink++;
break;
case H4:
situation.h4++;
break;
case S4:
situation.s4++;
break;
case SS4:
situation.ss4++;
break;
case H3:
situation.h3++;
break;
case K3:
situation.k3++;
break;
case S3:
situation.s3++;
break;
case H2:
situation.h2++;
break;
case HH2:
situation.hh2++;
break;
case S2:
situation.s2++;
break;
case SAFE:
situation.safe++;
break;
default:
//差错控制
break;
}
}
return giveScore(situation);//根据形势得出分数
}
int Rule::giveScore(Situation situation) {
int s4 = situation.s4 + situation.ss4;
int h3 = situation.h3 + situation.k3;
int h2 = situation.h2 + situation.hh2;
if (situation.fivelink >= 1)
return Level1;//赢
if (situation.h4 >= 1 || s4 >= 2 || (s4 >= 1 && h3 >= 1))
return Level2;//活四或者双死四或死四活三的情况都有
if (h3 >= 2)
return Level3;//双活3
if (situation.s3 >= 1 && situation.h3 >= 1)
return Level4;//死三活三化为一类
if (situation.s4 >= 1)
return Level5;//一边被堵的四连
if (situation.ss4 >= 1)
return Level6;//两边都堵的四连
if (situation.h3 >= 1)
return Level7;//一边堵住的三连
if (situation.k3 >= 1)
return Level8;//中间空一格的活三
if (situation.h2 >= 2)
return Level9;//双活2
if (situation.h2 >= 1)
return Level10;//活2
if (situation.hh2 >= 1)
return Level11;//不全开的活2
if (situation.s3 >= 1)
return Level12;//被堵住的三连
if (situation.s2 >= 1)
return Level13;//被堵的二连
return Level14;//安全
}
int Rule::getType(const int state[15][15], Position position, int color, int direction) {
//判断已经下的棋子类型
int type;
int chess[9] = { 0 };//初始化为0
//从最新下的棋开始判断,设为第四个,往右数四个,往左数四个或往下,往左上右下,右上左下数
getChess(chess, state, position, color, direction);
type = judgeType(chess);
return type;
}
void Rule::getChess(int chess[9], const int state[15][15], Position position, int color, int direction) {
int rivalcolor;//如果边界出界了,用对方棋颜色赋值
if (color == BQ)
rivalcolor = WQ;
else
rivalcolor = BQ;
chess[4] = color;//以该棋为中心
switch (direction) {//四个方向的连线情况都要判
case 0://一行的走棋情况
for (int i = position.x, j = 1; j <= 4; j++) {//往左走四个
int col = position.y - j;
if (col < 0) {
for (j; j <= 4; j++)
chess[4 - j] = rivalcolor;//出界设置成对手颜色
break;
}
chess[4 - j] = state[i][col];//没出界,直接用state数组
}
for (int i = position.x, j = 1; j <= 4; j++) {//往右走四个
int col = position.y + j;
if (col > 14) {
for (; j <= 4; j++)
chess[4 + j] = rivalcolor;//出界设置成对手颜色
break;
}
chess[4 + j] = state[i][col];
}
break;
case 1://一列的走棋情况
for (int j = position.y, i = 1; i <= 4; i++) {//往上看四个
int row = position.x - i;
if (row < 0) {
for (; i <= 4; i++)
chess[4 - i] = rivalcolor;//出界设置对手颜色
break;
}
chess[4 - i] = state[row][j];
}
for (int i = 1, j = position.y; i <= 4; i++) {//往下看四个
int row = position.x + i;
if (row > 14) {
for (; i <= 4; i++)
chess[4 + i] = rivalcolor;
break;
}
chess[4 + i] = state[row][j];
}
break;
case 2://左上右下
for (int i = 1, j = 1; i <= 4; i++, j++) {//往左上看四个
int row = position.x - i;
int col = position.y - j;
if (row < 0 || col <0) {//其中一个出界即可,以先出界的为标准
for (; i <= 4; i++)
chess[4 - i] = rivalcolor;//出界设置对手颜色
break;
}
chess[4 - i] = state[row][col];
}
for (int i = 1, j = 1; i <= 4; i++, j++) {//往右下看四个
int row = position.x + i;
int col = position.y + j;
if (row > 14 || col > 14) {
for (; i <= 4; i++)
chess[4 + i] = rivalcolor;
break;
}
chess[4 + i] = state[row][col];
}
break;
case 3://左下右上
for (int i = 1, j = 1; i <= 4; i++, j++) {//往左下看四个
int row = position.x + i;
int col = position.y - j;
if (row > 14 || col <0) {
for (; i <= 4; i++)
chess[4 - i] = rivalcolor;
break;
}
chess[4 - i] = state[row][col];
}
for (int i = 1, j = 1; i <= 4; i++, j++) {//往右看四个
int row = position.x - i;
int col = position.y + j;
if (row < 0 || col > 14) {
for (; i <= 4; i++)
chess[4 + i] = rivalcolor;
break;
}
chess[4 + i] = state[row][col];
}
break;
default:
//差错控制
break;
}
}
int Rule::judgeType(const int chess[9]) {
int mycolor = chess[4];
int rivalcolor;
int left, right;//开始和中心线断开的位置
int colorL, colorR;//开始和中心线断开的颜色
int count = 1;//中心线有多少个,初始化
if (mycolor == BQ)
rivalcolor = WQ;
else
rivalcolor = BQ;
for (int i = 1; i <= 4; i++) {
if (chess[4 - i] == mycolor)
count++;//同色
else {
left = 4 - i;//保存断开位置
colorL = chess[4 - i];//保存断开颜色
break;
}
}
for (int i = 1; i <= 4; i++) {
if (chess[4 + i] == mycolor)
count++;//同色
else {
right = 4 + i;//保存断开位置
colorR = chess[4 + i];//保存断开颜色
break;
}
}
if (count >= 5)//中心线5连
return FIVELINK;//5连
if (count == 4)//中心线4连
{
if (colorL == NQ && colorR == NQ)//两边断开位置均空
return H4;//活四
else if (colorL == rivalcolor && colorR == rivalcolor)//两边断开位置均非空
return SAFE;//没有威胁
else if (colorL == NQ || colorR == NQ)//两边断开位置只有一个空
return S4;//死四
}
if (count == 3) {//中心线3连
int colorL1 = chess[left - 1];
int colorR1 = chess[right + 1];
if (colorL == NQ && colorR == NQ)//两边断开位置均空
{
if (colorL1 == rivalcolor && colorR1 == rivalcolor)//均为对手棋子
return S3;
else if (colorL1 == mycolor || colorR1 == mycolor)//只要一个为自己的棋子
return SS4;
else if (colorL1 == NQ || colorR1 == NQ)//只要有一个空
return H3;
}
else if (colorL == rivalcolor && colorR == rivalcolo