Evanyou Blog 彩带

小游戏:五子棋(带AI)

这个代码,是本蒟蒻写过几乎最长的代码了……

此程序可能会有非常多的bug,但是这个代码太长了(至少对于一个没见识过fib heap什么的人来说),而且写得比较乱,所以可能以后不会更新了。

此AI算法是我自己脑补的一个简单优先值算法,所以水平比较低,不要喷。

蒟蒻不易,转载请标明出处。

蒟蒻不易,转载请标明出处。

蒟蒻不易,转载请标明出处。

下载链接:https://pan.baidu.com/s/1HiaQHZMJcihs-29cpeZhBw

密码:2dij

代码(建议直接bdy下载):

#include<bits/stdc++.h>
#include<conio.h>
#include <Windows.h>
#define Line 17
#define Row 17
#define char char
#define Player1 'X'
#define Player2 'O'
using namespace std;
char Chess[Line+1][Row+1];
int DX[]={0,1,1,1};
int DY[]={1,1,0,-1};
int PlayWith;
class GobangAI{
	#define Human 'X'
	#define AI 'O'
	#define Empty ' '
	#define nextx x+DX[Direct]
	#define nexty y+DY[Direct]
	private:
		int Gobang[Line+1][Row+1],Score[Line+1][Row+1];
		int SetHumanScore[6]={0,10,100,1000,10000,100000},SetAIScore[6]={0,10,100,1000,10000,100000};
	public:
		void clear(){
			memset(Score,0,sizeof Score);
			memset(Gobang,Empty,sizeof Gobang);
		}
		void GetChessBoard(char Chess[Line+1][Row+1])
		{
			for(int i=1;i<=Line;i++)
			{
				for(int j=1;j<=Row;j++) Gobang[i][j]=Chess[i][j];
			}
		}
		bool IsAllow(int x,int y)
		{
			return (x>=1&&x<=Line&&y>=1&&y<=Row);
		}
		int JUSTDFS(int x,int y,int Direct,int Sum,char Player)
		{
			if(IsAllow(nextx,nexty)&&Gobang[nextx][nexty]==Player) return JUSTDFS(nextx,nexty,Direct,Sum+1,Player);
			else return Sum+1;
		}
		int DFS(int x,int y,int Direct,int Sum,char Player)
		{
			if(IsAllow(x,y)&&Gobang[x][y]==Player) return DFS(x+DX[Direct],y+DY[Direct],Direct,Sum+1,Player);
			else
			{
				int tx=nextx,ty=nexty;
				if(IsAllow(tx,ty)&&Gobang[tx][ty]==Player)
				{
					int d=JUSTDFS(tx,ty,Direct,0,Player);
					if(d+Sum>=4) Gobang[x][y]=10000000;
					else Gobang[x][y]=Player==Human?SetHumanScore[Sum+d]:SetAIScore[Sum+d];
					return Player==Human?SetHumanScore[Sum]:SetAIScore[Sum];
				}
				int d=0;
				if(Player==Human) d=SetHumanScore[Sum];
				else d=SetAIScore[Sum];
				if(!IsAllow(x,y)) return d;
				if(Gobang[x][y]==Empty) Score[x][y]+=d;
				else if(Gobang[x][y]!=Player) d/=10;
				return d;
			}
		}
		void GetHuman()
		{
			for(int i=1;i<=Line;i++)
			{
				for(int j=1;j<=Row;j++)
				{
					if(Gobang[i][j]==Human)
					{
						int d=0;
						d=DFS(i,j,0,0,Human);
						if(IsAllow(i-DX[0],j-DY[0])&&Gobang[i-DX[0]][j-DY[0]]==Empty) Score[i-DX[0]][j-DY[0]]+=d;
						d=DFS(i,j,1,0,Human);
						if(IsAllow(i-DX[1],j-DY[1])&&Gobang[i-DX[1]][j-DY[1]]==Empty) Score[i-DX[1]][j-DY[1]]+=d;
						d=DFS(i,j,2,0,Human);
						if(IsAllow(i-DX[2],j-DY[2])&&Gobang[i-DX[2]][j-DY[2]]==Empty) Score[i-DX[2]][j-DY[2]]+=d;
						d=DFS(i,j,3,0,Human);
						if(IsAllow(i-DX[3],j-DY[3])&&Gobang[i-DX[3]][j-DY[3]]==Empty) Score[i-DX[3]][j-DY[3]]+=d;
					}
				}
			}
		}
		void GetAI()
		{
			for(int i=1;i<=Line;i++)
			{
				for(int j=1;j<=Row;j++)
				{
					if(Gobang[i][j]==AI)
					{
						int d=0;
						d=DFS(i,j,0,0,AI);
						if(IsAllow(i-DX[0],j-DY[0])&&Gobang[i-DX[0]][j-DY[0]]==Empty) Score[i-DX[0]][j-DY[0]]+=d;
						d=DFS(i,j,1,0,AI);
						if(IsAllow(i-DX[1],j-DY[1])&&Gobang[i-DX[1]][j-DY[1]]==Empty) Score[i-DX[1]][j-DY[1]]+=d;
						d=DFS(i,j,2,0,AI);
						if(IsAllow(i-DX[2],j-DY[2])&&Gobang[i-DX[2]][j-DY[2]]==Empty) Score[i-DX[2]][j-DY[2]]+=d;
						d=DFS(i,j,3,0,AI);
						if(IsAllow(i-DX[3],j-DY[3])&&Gobang[i-DX[3]][j-DY[3]]==Empty) Score[i-DX[3]][j-DY[3]]+=d;
					}
				}
			}
		}
		pair<int,int> GetAIChoice()
		{
			int MaxValue=0,Index_I=Line/2,Index_J=Row/2,bj=0;
			for(int i=1;i<=Line;i++)
			{
				for(int j=1;j<=Row;j++)
				{
					if(Score[i][j]>MaxValue)
					{
						Index_I=i,Index_J=j,MaxValue=Score[i][j];
						bj=1;
					}
					else if(Score[i][j]==MaxValue)
					{
						srand(time(NULL));
						if(rand()&1) Index_I=i,Index_J=j;
					}
				}
			}
			return make_pair(Index_I,Index_J);
		}
		pair<int,int> OneKeyStart(char Chess[Line+1][Row+1])
		{
			clear();
			GetChessBoard(Chess);
			GetHuman();
			GetAI();
			return GetAIChoice();
		}
}AICHOICE;
int Chess_Num[2];
string Player_Name[2];
int x,y;
bool AlwaysControlPlayer,TheFirstPlayer;
bool pd()
{
	if(x>=1&&x<=Line&&y>=1&&y<=Row) return true;
	return false;
}
int Judge()
{
	int t=getch();
	if(t==13)
	{
		if(Chess[x][y]!=Empty) return 2;
		else return 1;
	}
	else if(t==224);
	else return 0;
	//else if(t==27) exit(0);
	int ch=getch();
	switch(ch)
	{
		case 75:
			{
				y--;if(!pd()) y++;
				break;
			}
		case 72:
			{
				x--;if(!pd()) x++;
				break;
			}
		case 77:
			{
				y++;if(!pd()) y--;
				break;
			}
		case 80:
			{
				x++;if(!pd()) x--;
				break;
			}
			{

			}
		default:
			return -1;
	}
	return 0;
}
void Print(char Chess[Line+1][Row+1],bool Player)
{
	system("cls");
	for(int i=1;i<=Line;i++)
	{
		for(int j=1;j<Row;j++)
		{
			if(j==1)
			{
				if(x!=i||y!=j) putchar(' ');
				else putchar('<');
			}
			printf("%c",Chess[i][j]);
			if((i==x&&j==y-1)) printf("<");
			else if(i==x&&j==y) printf(">");
			else printf(" ");
		}
		printf("%c",Chess[i][Row]);
		if(x==i&&y==Row) printf(">");
		if(i!=x||Row!=y) printf("  |");
		else printf(" |");
		if(i==Line/2-1) cout<<"  "<<"Now Choice:";
		else if(i==Line/2) cout<<"  "<<Player_Name[Player];
		else if(i==Line/2+2) cout<<"  "<<Player_Name[0]<<':'<<Chess_Num[0];
		else if(i==Line/2+3) cout<<"  "<<Player_Name[1]<<':'<<Chess_Num[1];
		else if(i==Line/2+5) cout<<"  Press the ARROW KEYs to move your CHESS.";
		else if(i==Line/2+6) cout<<"  Press the ENTER to put you CHESS.";
		puts("");
	}
	for(int i=1;i<=Row+1;i++) printf("__");
	printf("|");
}
void Move(bool Player)
{
	Print(Chess,Player);
	while(1)
	{
		int ok=Judge();
		if(ok==1) break;
		else if(ok==2) printf("There is already a chess here.\n"),Sleep(1000);
		Print(Chess,Player);
	}
}
int Choice(bool Player)
{
	Move(Player);
	if(!Player) Chess[x][y]=Player1;
	else Chess[x][y]=Player2;
	Print(Chess,Player);
}
bool Check_Winner(char ch,int cnt,int x,int y,int p)
{
	if(x>Line||y>Row) return 0;
	if(cnt==5) return 1;
	if(p!=0&&Chess[x][y]!=ch) return 0;
    if(p==1)
	  return Check_Winner(ch,cnt+1,x+1,y,1);
	if(p==2)
	  return Check_Winner(ch,cnt+1,x,y+1,2);
	if(p==3)
	  return Check_Winner(ch,cnt+1,x+1,y+1,3);
	if(p==4)
	  return Check_Winner(ch,cnt+1,x+1,y-1,4);
	for(int i=x;i<=Line;++i)
	{
		for(int j=(i==x?y:1);j<=Row;++j)
		{
			if(Chess[i][j]==ch)
			{
				if(Check_Winner(ch,cnt+1,i+1,j,1)) return 1;
				if(Check_Winner(ch,cnt+1,i,j+1,2)) return 1;
				if(Check_Winner(ch,cnt+1,i+1,j+1,3)) return 1;
				if(Check_Winner(ch,cnt+1,i+1,j-1,4)) return 1;
			}
		}
	}
	return 0;
}
int Print_Meun(string Meun)
{
	int time=100;
	for(int i=0;i<Meun.length();i++)
	{
		putchar(Meun[i]);
		Sleep(time);
	}
}
int Start_Game()
{

	bool Player=!TheFirstPlayer;
	while(1)
	{
	    if(!AlwaysControlPlayer) Player=!Player;
		if(Player==0) Choice(Player);
		else if(PlayWith==1)
		{
			pair<int,int> p=AICHOICE.OneKeyStart(Chess);
			Chess[p.first][p.second]=Player==Player1?Player1:Player2;
		}
		else Choice(Player);
		Chess_Num[Player]++;
		if(Check_Winner(Player==0?Player1:Player2,0,1,1,0))
		{
			system("cls");
			Print_Meun("Game Over!"+Player_Name[Player]+" is the Winner!\n\n");
			break;
		}
	}
	Sleep(1000);
	Print_Meun("Play Again? Press ENTER to continue, Press ESC to Back Your Table.");

}
void Input_Player_Name(bool Player)
{
	system("cls");
	re:;
	string t=" ";
	t[0]=Player+'0';
	Print_Meun("Input Player "+t+" name:\n");
	cin>>Player_Name[Player];
	if(Player_Name[Player].length()>16)
	{
		printf("\n\nYour Name is too long.\nInput again please.\n");
		Sleep(1500);
		system("cls");
		goto re;
	}
}
void Waiting()
{
	system("cls");
	Print_Meun("Please wait for a minute……");
	Sleep(1000);
	system("cls");
}
void DevelopSetting()
{
	ifstream fin("DevelopSetting.code");
	string Name;
	bool value;
	while(fin>>Name)
	{
		if(Name=="AlwaysControlPlayer;") AlwaysControlPlayer=1;
		else if(Name=="SetFirstPlayer=")
		{
			fin>>value;TheFirstPlayer=value;
			char tmp;
			fin>>tmp;
		}
		else if(Name=="SetName")
		{
			bool Player;
			fin>>Player;
			string PN;
			fin>>PN;
			Player_Name[Player]=PN;
		}
	}
	fin.close();
}
void ini()
{
	memset(Chess,Empty,sizeof Chess);
	memset(Chess_Num,0,sizeof Chess_Num);
	Player_Name[0].clear(),Player_Name[1].clear();
	Print_Meun("Welcome to the Gobang!\n");
	Sleep(1000);
	x=Line/2,y=Row/2;
	DevelopSetting();
}
void CLEAR_INI()
{
	DevelopSetting();
}
void print_Gamemode(int choice,int SUM)
{
	system("cls");
	cout<<"Please choice the GAMEMODE:\n\n";
	string a[]={"","""Play with People Player.","Play with AI Robot."};
	for(int i=1;i<=SUM;i++)
	{
		if(i==choice) cout<<"  ->\t";
		else cout<<"    \t";
		cout<<a[i]<<endl;
	}
}
void Choice_Gamemode()
{
	string a="Please choice the GAMEMODE:\n";
	Print_Meun(a);
	int choose=1;
	print_Gamemode(1,2);
	int First;
	while(First=getch()!=13)
	{
		int Second=getch();
		switch(Second)
		{
			case 72:choose--;if(choose<1) choose++;break;
			case 80:choose++;if(choose>2) choose--;break;
		}
		print_Gamemode(choose,2);
	}
	switch(choose)
	{
		case 1:break;
		case 2:PlayWith=1;break;
	}
	system("cls");
}
int main()
{
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};   
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);  
	//CLEAR_INI();
	ini();
	system("cls");
	Choice_Gamemode();
	Input_Player_Name(0);
	if(!PlayWith) Input_Player_Name(1);
	else Player_Name[1]="AI";
	Waiting();
	restart:
	{
		memset(Chess,Empty,sizeof Chess);
		system("cls");
		x=Line/2,y=Row/2;
		Chess_Num[0]=Chess_Num[1]=0;
	}
	Start_Game();
	char ch=getch();
	if(ch==27) exit(0);
	else if(ch==13) goto restart;
}
posted @ 2018-10-15 18:31  MaxDYF  阅读(309)  评论(0编辑  收藏  举报