//返回一个你的落子决定
std::pair<int, int> othello_ai::get(){
	adjust_valuemap();
	//获得所有可落子的位置,按先行后列的顺序
	std::vector< std::pair<int, int> > ans = o.allmove(o.mycolor);

	std::cerr<<std::endl<<"starting running ..."<<std::endl;

	next = seize_peak(ans);
	if ( next.first >= 0 && next.second >= 0 ) {
		std::cerr<<std::endl<<"-->> player "<<o.mycolor<<" move ("<<next.first<<", "<<next.second<<")"<<std::endl;
		return next;
	}

	turn(o, o.mycolor, MAXVALUE, DEPTH);
	//while (!steps.empty()) { 
	//	next = steps.top();
	//	steps.pop();
	//}
	if (next.first >= 0 && next.second >= 0) {
		if (next.first == ans[0].first && next.second == ans[1].second)
			std::cerr<<std::endl<<"turn choose first"<<std::endl;
		std::cerr<<std::endl<<"-->> player "<<o.mycolor<<" move ("<<next.first<<", "<<next.second<<")"<<std::endl;
		return next;
	} else {
		std::cerr<<std::endl<<"have to choose first"<<std::endl;
		return ans[0];
	}
}
void othello_ai::adjust_valuemap() {
	if ( o.is(o.mycolor, 0, 0) ) {
		valuemap[0][1] *= (valuemap[0][1] < 0) ? -1 : 1;
		valuemap[1][0] *= (valuemap[1][0] < 0) ? -1 : 1;
		valuemap[1][1] *= (valuemap[1][1] < 0) ? -1 : 1;
	}
	if ( o.is(o.mycolor, 0, MAXEDGE - 1) ) {
		valuemap[0][MAXEDGE - 2] *= (valuemap[0][MAXEDGE - 2] < 0) ? -1 : 1;
		valuemap[1][MAXEDGE - 1] *= (valuemap[1][MAXEDGE - 1] < 0) ? -1 : 1;
		valuemap[1][MAXEDGE - 2] *= (valuemap[1][MAXEDGE - 2] < 0) ? -1 : 1;
	}
	if ( o.is(o.mycolor, MAXEDGE - 1, 0) ) {
		valuemap[MAXEDGE - 2][1] *= (valuemap[MAXEDGE - 2][1] < 0) ? -1 : 1;
		valuemap[MAXEDGE - 1][0] *= (valuemap[MAXEDGE - 1][0] < 0) ? -1 : 1;
		valuemap[MAXEDGE - 2][1] *= (valuemap[MAXEDGE - 2][1] < 0) ? -1 : 1;
	}
	if ( o.is(o.mycolor, MAXEDGE - 1, MAXEDGE - 1) ) {
		valuemap[MAXEDGE - 1][MAXEDGE - 2] *= (valuemap[MAXEDGE - 1][MAXEDGE - 2] < 0) ? -1 : 1;
		valuemap[MAXEDGE - 2][MAXEDGE - 1] *= (valuemap[MAXEDGE - 2][MAXEDGE - 1] < 0) ? -1 : 1;
		valuemap[MAXEDGE - 2][MAXEDGE - 2] *= (valuemap[MAXEDGE - 2][MAXEDGE - 2] < 0) ? -1 : 1;
	}
}
int othello_ai::evaluation(othello16 o_t, int player) {
	int total_black = o_t.count(BLACK);
	int total_white = o_t.count(WHITE);
	std::string map = o_t.tostring();
	int value = 0, i, j, num = 0, liberty_value = 0;
	
	if (total_black + total_white <= 48 ) {

		// 前期
		for (i = 0; i < MAXEDGE; i ++) {
			for (j = 0; j < MAXEDGE; j ++) {
				num = i * MAXEDGE + j;
				if (map[num] == BLANK + '0') {
					continue; 
				}
				value += ( ( o_t.mycolor == map[num] - '0' ) ? 1 : -1 ) * valuemap[i][j];
			}
		}
		return value;
	} else if (total_black + total_white <= 192 ) {

		// 中期
		for (i = 0; i < MAXEDGE; i ++) {
			for (j = 0; j < MAXEDGE; j ++) {
				num = i * MAXEDGE + j;
				if (map[num] == BLANK + '0') {
					continue; 
				}
				value += ( ( o_t.mycolor == map[num] - '0' ) ? 1 : -1 ) * valuemap[i][j];
			}
		}
		liberty_value += 4 * o_t.canmove(player) * ((player == o_t.mycolor) ? 1 : -1);
		return value + liberty_value;

	}
}
Beispiel #4
0
void othello_ai::init(int color, string s){
	o.init(color, s);//让sdk初始化局面
	cost[0][0] = 9;
	cost[0][15] = 9;
	cost[15][0] = 9;
	cost[15][15] = 9;
	int i;
	int j;
	for(i = 2 ;i < 14 ; i ++)
	{
		cost[0][i] = 4;
		cost[i][0] = 4;
		cost[15][i] = 4;
		cost[i][15] = 4;
	}
	for(i = 0; i < 16; i ++)
	{
		cost[1][i] = -2;
		cost[14][i] = -2;
		cost[i][1] = -2;
		cost[i][14] = -2;
	}
	cost[1][1] = -20;
	cost[1][0] = -20;
	cost[0][1] = -20;

	cost[0][14] = -20;
	cost[1][14] = -20;
	cost[1][15] = -20;

	cost[14][0] = -20;
	cost[14][1] = -20;
	cost[15][1] = -20;

	cost[14][15] = -20;
	cost[14][14] = -20;
	cost[15][14] = -20;
	for(i = 2 ; i < 14; i ++)
		for(j = 2 ; j < 14 ; j ++)
			cost[i][j] = 1;

}
Beispiel #5
0
int othello_ai::result(othello16 a)
{
	int n1, n2, n3, n4;
	int num = 0;//棋子个数差
	int canput;//可下子差(行动力)
	int bothputnum;
	int pos = 0;//布局差
	int evaluation = 0;
	int potential_canput = 0;
	vector<pair<int, int> > t1 = o.allmove(o.mycolor);
	vector<pair<int, int> > t2 = o.allmove(3 - o.mycolor);

	canput = t1.size() - t2.size();
	bothputnum = t1.size() + t2.size();
	int total;
	string borad = a.tostring();
	
	num = a.count(a.mycolor) - a.count(3 - a.mycolor);//棋子个数差
	total = a.count(a.mycolor) + a.count(3 - a.mycolor);
	if(bothputnum == 0)
	{
		if(num > 0)
			return 99999;
		else if(num < 0)
			return -99999;
		else
			return	0;
	}
	int i,j,z;
	for(i = 0 ; i < 16 ; i ++)
	{
		for(j = 0 ; j < 16 ; j ++)
		{
			char t =  borad.at(i * 16 + j);
			if(t == '0' + a.mycolor)
			{
				pos = pos + cost[i][j];
			}
			else if(t == '0' + 3 - a.mycolor)
			{
				pos = pos - cost[i][j];
			}
		}
	}
	int x[9];
	for(i = 0 ; i < 16 ; i ++)
	{
		for(j = 0 ; j < 16 ; j ++)
		{
			for(z = 0 ; z < 9 ; z ++)
			{
				x[z] = i * 16 + j + (z/3 - 1) * 16 + (z%3 - 1);
				if(x[z] >= 0 && x[z] <= 255)
				{
					char t = borad.at(i * 16 + j);
					char t1 = borad.at(x[z]);
					if(t1 == '0')
					{
						if(t == '0' + a.mycolor)
						{
							potential_canput = potential_canput - 1;
						}
						else if(t == '0' + 3 - a.mycolor)
						{
							potential_canput = potential_canput + 1;
						}
					}
				}
			}
		}
	}
	if(total < 210)
	{
		n1 = 1;
		n2 = 4;
		n3 = 3;
		n4 = 4;

	}
	else
	{
		n1 = 4;
		n2 = 2;
		n3 = 1;
		n4 = 2;
	}
	evaluation =n1 * num + n2 * canput + n3 * pos + n4 * potential_canput;
	return evaluation;
}
Beispiel #6
0
void othello_ai::move(int color, int x, int y){
	o.play(color, x, y);//告诉sdk落子情况,改变局面

}
Beispiel #7
0
pair<int, int> othello_ai::get(){
	vector<pair<int, int> > ans = o.allmove(o.mycolor);
	//获得所有可落子的位置,按先行后列的顺序
	if(o.tostring().at(0) == '0' + o.mycolor)
	{
		cost[0][1] = 5;
		cost[1][0] = 5;
	}
	if(o.tostring().at(15) == '0' + o.mycolor)
	{
		cost[0][14] = 5;
		cost[1][15] = 5;
	}
	if(o.tostring().at(16*15) == '0' + o.mycolor)
	{
		cost[14][0] = 5;
		cost[15][1] = 5;
	}
	if(o.tostring().at(16*16 - 1) == '0' + o.mycolor)
	{
		cost[14][15] = 5;
		cost[15][14] = 5;
	}
	int len = ans.size();
	int i;
	int max = 0;
	int pos = 0;
	int position = 0;

	for(i = 0 ; i < len ; i ++)
	{
		int n = cost[ans[i].first][ans[i].second];
		if(max < n)
		{
			max = n;
			pos = i;
		}
	}
	if(max > 0)
	{
		std::cerr<<"----------------------------------------------------"<<"\n";
		std::cerr<<"time : "<<get_time()<<"   choose:"<<pos<<"\n";
		return ans[pos];
	}
	if(len == 1)
	{
		std::cerr<<"====================================================="<<"\n";
		std::cerr<<"time : "<<get_time()<<"   choose: 0"<<"\n";
		return ans[0];
	}
	max = 0;
	pos = 0;
	for(i = 0 ; i < len ; i ++)
	{
		temp = o;
		temp.play(temp.mycolor,ans[i].first,ans[i].second);
		int t = f(temp, 1, position, max);
	//	std::cerr<<t<<"  "<<"line: 1"<<"\n";
		if(i == 0)
			max = t;
		position = 1;
		if(max < t)
		{
			max = t;
			pos = i;
		}
	}
	std::cerr<<">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<<"\n";
	std::cerr<<"time : "<<get_time()<<"   choose:"<<pos<<"\n";
	
	return ans[pos];//返回落子位置为第一个可下的点
}
Beispiel #8
0
int othello_ai::f(othello16 a, int line, int position, int var)
{
	if(line == 4)
	{
		int x;
		x = result(a);
		return x;
	}
	else
	{
		int number = line % 2;
		int color;
		if(number == 1)
			color = 3 - a.mycolor;
		else
			color = a.mycolor;
		vector<pair<int, int> > t = a.allmove(color);
		
		int len = t.size();
		int i = 0;
		int max = var;
		int pos = 0;
		if(position == 1)
			pos = 1;
		if(line == 2)
			pos = 0;
		for( ; i < len ; i ++)
		{
			temp = a;
			temp.play(color,t[i].first,t[i].second);
			int t = f(temp,line + 1, pos ,max);
	//		std::cerr<<t<<" "<<"    var: "<<var<<"   "<<"line: "<<line + 1<<"\n";
			if(i == 0)
			{
				max = t;
			}
			pos = 1;
			if(number == 1)
			{
				if(max > t)
				{
					max = t;
				}
				if(t <= var && position > 0)
				{
	//				std::cerr<<"------"<<"\n";
					return t;
				}
			}
			else
			{
				if(t >= var && position > 0)
				{
	//				std::cerr<<"------"<<"\n";
					return t;
				}
				if(max < t)
				{
					max = t;
				}
			}
		}
	//	std::cerr<<"\n";
		return max;
	}
}
//初始化阶段,告知你所执子的颜色,和当前棋盘落子情况s
void othello_ai::init(int color, std::string s){
	o.init(color, s);
	init_valuemap();
	std::cerr<<"My color is "<<o.mycolor<<std::endl;
}
int othello_ai::turn(othello16 o_upper, int player, int backpoint, int depth) {
	// 检查超时
	int runtime = get_time();
	if (runtime > 1800) {
		std::cerr<<"time "<<runtime<<" overflow"<<std::endl;
		return (player == o.mycolor) ? MAXVALUE : -MAXVALUE;
	}
	-- depth;

	// std::cerr<<"player "<<player<<" my color "<<o.mycolor<<std::endl;
	othello16 o_t;
	int value_t, value_mark;
	std::pair<int, int> step_mark (-1, -1);
	// 初始化value_mark
	if (player == o.mycolor) {
		value_mark = -MAXVALUE;
	} else {
		value_mark = MAXVALUE;
	}

	std::vector< std::pair<int, int> > nextlist = o_upper.allmove(player);
	std::string map = o_upper.tostring();

	if ( nextlist.size() == 0 ) {
		// 无可下点
		std::cerr<<"nowhere to move ";
		return (player == o.mycolor) ? -MAXVALUE : MAXVALUE;
	} else if (depth <= 0) {

		// 到达最深层,计算估价函数值
		// std::cerr<<"tree hight "<<depth<<std::endl;
		std::vector< std::pair<int, int> >::iterator it;
		for (it = nextlist.begin() ; it != nextlist.end(); ++ it) {
			// 初始化当前棋盘
			o_t.init(o.mycolor, map);
			// 落子
			o_t.play(player, (*it).first, (*it).second);
			// string2map(o_t.tostring());
			value_t = evaluation(o_t, player);
			std::cerr<<std::endl<<"depth "<<DEPTH - depth<<":";
			for (int k = 0; k < DEPTH - depth; k ++) 
				std::cerr<<"    ";
			std::cerr<<"leaf ("<<(*it).first<<", "<<(*it).second<<") value "<<value_t<<", ";
			if ( (player == o.mycolor && value_t >= value_mark)
				|| (player != o.mycolor && value_t <= value_mark) ) {
					value_mark = value_t;
			}
			// 剪枝
			if (player == o.mycolor && value_mark >= backpoint) {
				std::cerr<<"cut beta parent value "<<backpoint<<" current value "<<value_mark<<std::endl;
				return value_mark;
			} else if (player != o.mycolor && value_mark <= backpoint) {
				std::cerr<<"cut alpha parent value "<<backpoint<<" current value "<<value_mark<<std::endl;
				return value_mark;
			}
		}
		return value_mark;
	} else {

		// 普通情况
		std::vector< std::pair<int, int> >::iterator it;
		for (it = nextlist.begin() ; it != nextlist.end(); ++ it) {
			// 初始化当前棋盘
			o_t.init(o.mycolor, map);
			// 落子
			o_t.play(player, (*it).first, (*it).second);
			// string2map(o_t.tostring());
			value_t = turn(o_t, 3 - player, value_mark, depth);
			if (value_t == MAXVALUE || value_t == -MAXVALUE) {
				// 子问题超时
				break;
			}
			std::cerr<<std::endl<<"depth "<<DEPTH - depth<<":";
			for (int k = 0; k < DEPTH - depth; k ++) 
				std::cerr<<"    ";
			std::cerr<<"node ("<<(*it).first<<", "<<(*it).second<<") value "<<value_t<<", ";
			if ( (player == o.mycolor && value_t >= value_mark)// 己方落子
				|| (player != o.mycolor && value_t <= value_mark) ) {//对方落子
					value_mark = value_t;
					step_mark.first = (*it).first;
					step_mark.second = (*it).second;
			}
			// 剪枝
			if (player == o.mycolor && value_mark >= backpoint) {
				std::cerr<<"cut beta parent value "<<backpoint<<" current value "<<value_mark<<std::endl;
				break;
			} else if (player != o.mycolor && value_mark <= backpoint) {
				std::cerr<<"cut alpha parent value "<<backpoint<<" current value "<<value_mark<<std::endl;
				break;
			}
		}
		if (depth = DEPTH - 1) {
			next.first = step_mark.first;
			next.second = step_mark.second;
		}
		return value_mark;
	}
}
//告知所有下子情况(包括你自己的落子情况)
void othello_ai::move(int color, int x, int y){
	o.play(color, x, y);
}