五子棋人机对决(C++)

#include<bits/stdc++.h>
#include<unistd.h>
using namespace std;


string str, tmp;
int a[30][30] = {0}, z, n, maxX = 0, maxY = 0;  // 棋盘 
const int d[8][2] = {{-1, -1}, {1, 1}, {-1, 0}, {1, 0}, {0, 1}, {0, -1}, {-1, 1}, {1, -1}};  // 向量 
const int width_a = 15;
const int weightLen = 7;
const int black[weightLen] = {1, 10, 12, 100, 102, 1000, 10000};
const int white[weightLen] = {2, 11, 13, 101, 103, 1001, 1000000};

void initialize(){  // 初始化
	for(int i = 4; i < 4 + width_a + 2; i++){
		a[4][i] = -3;
		a[4 + width_a + 1][i] = -3;
	}
	for(int i = 4; i < 4 + width_a + 2; i++){
		a[i][4] = -3;
		a[i][4 + width_a + 1] = -3;
	}
} 

bool winOrLose(){  // 判断胜负
	for(int i = 0; i < 15; i++){  // 在棋盘上填空(胜负) 
		for(int j = 0; j < 15; j++){
			int num = 0; 
			for(int v = 0; v < 8; v++){  // 遍历向量 
				for(int len = 1; len <= 5; len++){  // 遍历长度 
					if(a[i + 5 + d[v][0] * len][j + 5 + d[v][1] * len] == -2){  // 判断是不是白子 
						num++;
					}
					else{
						break;
					}
				}
				if(num >= 5){
					char p[] = "AI 获胜!";
					printf("\033[0m\033[1;5m%s\033[0m", p); 
					cin >> str;
					return true;
				}
				num = 0;
			}
			for(int v = 0; v < 8; v++){  // 遍历向量 
				for(int len = 1; len <= 5; len++){  // 遍历长度 
					if(a[i + 5 + d[v][0] * len][j + 5 + d[v][1] * len] == -1){  // 判断是不是黑子 
						num++;
					}
					else{
						break;
					}
				}
				if(num >= 5){
					cout << str << " 获胜!"; 
					cin >> str;
					return true;
				}
				num = 0;
			}
		} 
	}
	return false;
}

void print(){  // 输出棋盘
	cout << "  ";
	for(int i = 0; i < 15; i++){
		cout << char(i + 'A');
	}
	cout << endl;
	for(int i = 0; i < 15; i++){
		cout << char(i + 'A') << ' ';
		for(int j = 0; j < 15; j++){
			z++;
			if(a[i + 5][j + 5] == -1){
				char pc[] = "○";
				printf(pc);  // 黑方(玩家) 
			}
			else if(a[i + 5][j + 5] == -2){
				char pc[] = "●";
				if(i == maxX - 5 && j == maxY - 5){
					printf("\033[0m\033[1;34m%s\033[0m", pc);  // 白方(AI)
				}
				else{
					printf(pc);  // 白方(AI) 
				} 
			}
			else{
				char pc[] = "┼";
				if(z % 3 == 0){
					printf("\033[0m\033[1;41m%s\033[0m", pc);  // 空
				} 
				else if(z % 3 == 1){
					printf("\033[0m\033[1;46m%s\033[0m", pc);  // 空
				}
				else{
					printf("\033[0m\033[1;43m%s\033[0m", pc);  // 空
				}
			}
		} 
		cout << endl;
		z = 0;
	} 
}

int countValue(int x, int y, int invade, int vec){  // 填(x, y)的invade颜色棋子的权值,方向为vec
	int numB = 0, numW = 0, w = 0, len;
	if(invade == -2){  // 白子 
		for(len = 1; a[x + len * d[vec][0]][y + len * d[vec][1]] == -2; len++) ;  // 遍历长度 
		numW = len - 1;
		if(a[x + len * d[vec][0]][y + len * d[vec][1]] == -1 || a[x + len * d[vec][0]][y + len * d[vec][1]] == -3){
			numB++;
		}
		
		for(len = 1; a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -2; len++) ;  // 遍历长度 
		numW += len - 1;
		if(a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -1 || a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -3){
			numB++;
		}
		if(numW == 4){
			return white[weightLen - 1]; 
		}
		else if(numW - numB >= 0){
			return white[numW * 2 - numB - 1];
		}
		else{
			return 0;
		}
	}
	else{  // 黑子 
		for(len = 1; a[x + len * d[vec][0]][y + len * d[vec][1]] == -1; len++) ;
		numB = len - 1;
		if(a[x + len * d[vec][0]][y + len * d[vec][1]] == -2 || a[x + len * d[vec][0]][y + len * d[vec][1]] == -3){
			numW++;
		}
		
		for(len = 1; a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -1; len++) ;
		numB += len - 1;
		if(a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -2 || a[x + len * d[vec + 1][0]][y + len * d[vec + 1][1]] == -3){
			numW++;
		}
		if(numB == 4){
			return black[weightLen - 1];
		}
		else if(numB - numW >= 0){
			return black[numB * 2 - numW - 1];
		}
		else{
			return 0;
		}
	}
}

void countAllValue(){  // 填所有权值
	for(int i = 0; i < 15; i++){  // 在棋盘上填空(权值) 
		for(int j = 0; j < 15; j++){
			if(a[i + 5][j + 5] >= 0){
				int w = 0;
				for(int k = 0; k < 8; k += 2){  // 遍历向量 
					w += countValue(i + 5, j + 5, -1, k) + countValue(i + 5, j + 5, -2, k);
				}
				a[i + 5][j + 5] = w;
			}
		} 
	} 	
}

void findMax(){  // 找最大权值
	int maxn = -2;  // 最大 
	for(int i = 0; i < 15; i++){  // 寻找最优解 
		for(int j = 0; j < 15; j++){
			if(a[i + 5][j + 5] == -1){
				continue;
			}
			if(a[i + 5][j + 5] > maxn){
				maxn = a[i + 5][j + 5];  // 重新定义 
				maxX = i + 5;
				maxY = j + 5;
			}
		}
	}
	a[maxX][maxY] = -2;
	n = 1;
}

bool FallChessman(){  // 玩家下子
	char x, y;  // 定义玩家坐标 
	cin >> y >> x;  // 输入玩家xy坐标
	else if(x >= 'a'){
		x -= 'a';
		y -= 'a';
	}
	else{
		x -= 'A';
		y -= 'A';
	}
	if(a[x + 5][y + 5] != -2 && x < 15 && y < 15 && x >= 0 && y >= 0){
		a[x + 5][y + 5] = -1;
	} 
	else if(a[x + 5][y + 5] != -2){
		cout << "AI:我吃柠檬!" << endl;  // 下子失败 
		cout << "按a+Enter继续";
		cin >> tmp;
		return true;
	}
	else{
		cout << "桌子:我吃柠檬!" << endl;  // 下子失败 
		cout << "按a+Enter继续";
		cin >> tmp;
		return true;
	} 
	return false;
}

int main(){  // 主函数
	char p[] = "你的名字是:";
	cout << "新手指南 \n1、棋盘中空心圆为你的棋子,实心圆为对方的,蓝色的是对方刚下的 \n2、每轮你都得下一枚棋子,输入坐标就行(先左右,再前后),如:“AA” \n3、下到对方的棋子上或出界会提醒你并让你再来,但下到自己上的不会 \n4、不能反悔 \n5、名字还不能带空格 \n按a+Enter继续 \n";
	cin >> tmp; 
	system("cls"); 
	printf("\033[0m\033[1;5m%s\033[0m", p);
	cin >> str; 
	cheat();
	initialize();
	while(true){  // 主循环
		system("cls"); 
		print();
		if(n){
			cout << "AI: " << (char)(maxY - 5 + 'A') << ' ' << (char)(maxX - 5 + 'A') << endl;
		}
		if(winOrLose()){
			return 0;
		}
		if(FallChessman()){
			continue;
		}
		countAllValue();
		findMax();
	}
	return 0;
} 

#由于代码是十岁时写的,所以代码不规范,注释很少,并且没有前端。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值