⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moves.cpp

📁 一个人工智能的国际象棋游戏
💻 CPP
字号:
/****************************************************
Author: S. Senthil kumar
File: Global.cpp
Purpose:    Implementation of Move Generator

******************************************************/

#include "Global.h"
#include "OneMove.h"
#include "Moves.h"
#include "TransTableEntry.h"
#include "TranspositionTable.h"


extern int WHITEBASE;
extern int BLACKBASE;
extern TranspositionTable table;
extern int movecount;




Moves::Moves()
{
	//Initialize pointers to linked lists.
	head=new OneMove();
	
	
	attackhead=new OneMove();
	normalhead=new OneMove();
	
	size=0;
	
	
	acurrent=attackhead;
	ncurrent=normalhead;
	attackhead->next=NULL;
	normalhead->next=NULL;
}


void Moves::add(int p,int source,int sourcey,int dx,int dy,int noa)
{
	//Create new node.	
	
	OneMove *newnode=new OneMove();
	newnode->sourcex=source;
	newnode->sourcey=sourcey;
	newnode->destx=dx;
	newnode->desty=dy;
	newnode->piece=p;
	
	newnode->next=NULL;
	
	//if move is attacking, add to attacklist.
	if (noa==1)
	{
		acurrent->next=newnode;
		acurrent=newnode;
		
		
	}
	else
	{
		//Add to normal list.
		ncurrent->next=newnode;
		ncurrent=newnode;
		
	}
	size++;
}

void Moves::combine()
{
	
	//Append normal head to attackhead and make head point to first element.
	if (attackhead->next!=NULL)
	{
		
		head=attackhead;
		acurrent->next=normalhead->next;
	}
	else
	{
		
		head=normalhead;
	}
}
//Loop and delete moves.	
void Moves::destroy()
{
	for (OneMove *temp=head;temp!=NULL;)
	{
		OneMove *tmp=temp->next;
		delete temp;
		temp=tmp;
		
	}
	
	if (attackhead->next==NULL) delete attackhead;
	if (head!=normalhead) delete normalhead;
	
}

//Macro to place correct condition according to color	
#define cond(color,check) (color==WHITE?(check>10 ):(check<10  && check!=0))

void Moves::GeneratePawnMoves(int board[8][8],int color)
{
	
	int piece;
	piece=(color==WHITE?WHITE_PAWN:BLACK_PAWN);
	if ((color==WHITE && WHITEBASE==0)	|| (color==BLACK && BLACKBASE==0))
	{
		
		for (int i=0;i<8;i++)
		{
			for (int j=0;j<8;j++)
			{
				
				
				if (board[i][j]==piece)
				{
					if (i<7 && j<7 && cond(color,board[i+1][j+1]))
					{
						add(piece,j,i,j+1,i+1,1);
					}
					if (i<7 && j>0 && cond(color,board[i+1][j-1]))
					{
						add(piece,j,i,j-1,i+1,1);
					}
					if (i<7 && board[i+1][j]==0)
					{
						add(piece,j,i,j,i+1,0);
					}
					
					
					if (i==1)
					{
						if (board[i+2][j]==0 && board[i+1][j]==0)
						{
							add(piece,j,i,j,i+2,0);
						}
					}
					
					
				}
			}
		}
	}
	else if( (color==WHITE && WHITEBASE==7) || (color==BLACK && BLACKBASE==7))
	{
		for (int i=0;i<8;i++)
		{
			for (int j=0;j<8;j++)
			{
				if (board[i][j]==piece)
				{
					if (i==6)
					{
						if (board[i-2][j]==0 && board[i-1][j]==0)
						{
							add(piece,j,i,j,i-2,0);
						}
					}
					if (i>0 && board[i-1][j]==0 )
					{
						add(piece,j,i,j,i-1,0);
					}
					if (i>0 && j>0 && cond(color,board[i-1][j-1]))
					{
						add(piece,j,i,j-1,i-1,1);
					}
					if (i>0 && j<7 && cond(color,board[i-1][j+1]))
					{
						add(piece,j,i,j+1,i-1,1);
					}
					
					
				}
			}
		}
		
	}
}
#define gencond(color,check) (color==WHITE?((check==0 || check>10)):(check < 10))

void Moves::GenerateKnightMoves(int board[8][8],int color)
{
	int dummy;
	
	int piece;
	piece=(color==WHITE?WHITE_KNIGHT:BLACK_KNIGHT);
	
	for (int i=0;i<8 ;i++)
	{
		for (int j=0;j<8;j++)
		{
			if (board[i][j]==piece)
			{
				
				if (i<6 && j<7 && gencond(color,board[i+2][j+1]))
				{
					if (board[i+2][j+1]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j+1,i+2,dummy);
				}
				if (i<6 && j>0 && gencond(color,board[i+2][j-1]))
				{
					if (board[i+2][j-1]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j-1,i+2,dummy);
				}
				if (i>1 && j<7 && gencond(color,board[i-2][j+1]))
				{
					if (board[i-2][j+1]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j+1,i-2,dummy);
				}
				if (i>1 && j>0 && gencond(color,board[i-2][j-1]))
				{
					if (board[i-2][j-1]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j-1,i-2,dummy);
				}
				//
				if (i<7 && j<6 && gencond(color,board[i+1][j+2]))
				{
					if (board[i+1][j+2]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j+2,i+1,dummy);
				}
				if (i<7 && j>1 && gencond(color,board[i+1][j-2]))
				{
					if (board[i+1][j-2]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j-2,i+1,dummy);
				}
				if (i>0 && j<6 && gencond(color,board[i-1][j+2]))
				{
					if (board[i-1][j+2]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j+2,i-1,dummy);
				}
				if (i>0 && j>1 && gencond(color,board[i-1][j-2]))
				{
					if (board[i-1][j-2]==0)
					{
						dummy=0;
					}
					else
					{
						dummy=1;
					}
					
					add(piece,j,i,j-2,i-1,dummy);
				}
				
				}
			}
		}
		
	}
	
#define cond2(color,check) (color==WHITE?(check > 10):(check < 10))
	void Moves::GenerateBishopMoves(int board[8][8],int color)
	{
		
		int piece;int k,m;
		piece=(color==WHITE?WHITE_BISHOP:BLACK_BISHOP);
		
		for (int i=0;i<8;i++)
		{
			for (int j=0;j<8;j++)
			{
				if (board[i][j]==piece)
				{
					
					for (k=i-1,m=j-1;k>=0 && m>=0;k--,m--)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
							}
							break;
						}
					}
					for (k=i-1,m=j+1;k>=0 && m<8;k--,m++)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
							}
							
							break;
						}
					}
					for (k=i+1,m=j+1;k<8 && m<8;k++,m++)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
							}
							
							break;	
						}
					}
					for (k=i+1,m=j-1;k<8  && m>=0;k++,m--)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
							}
							break;
						}
					}
				}
			}
		}
		
	}
	
	void Moves::GenerateRookMoves(int board[8][8],int color)
	{
		
		int piece;int k;
		piece=(color==WHITE?WHITE_ROOK:BLACK_ROOK);
		
		for (int i=0;i<8 ;i++)
		{
			for (int j=0;j<8;j++)
			{
				if (board[i][j]==piece)
				{
					for (k=i-1;k>=0;k--)
					{
						if (board[k][j]==0)
						{
							add(piece,j,i,j,k,0);
						}
						else 
						{
							if ( cond2(color,board[k][j]))
							{
								add(piece,j,i,j,k,1);
								
							}
							break;
						}
					}
					for (k=i+1;k<8;k++)
					{
						if (board[k][j]==0)
						{
							add(piece,j,i,j,k,0);
							
						}
						else
						{
							if (cond2(color,board[k][j]))
							{
								add(piece,j,i,j,k,1);
								
							}
							break;
						}
					}
					for (k=j+1;k<8;k++)
					{
						if (board[i][k]==0)
						{
							add(piece,j,i,k,i,0);
							
						}
						else
						{
							if (cond2(color,board[i][k]))
							{
								add(piece,j,i,k,i,1);
								break;
							}
							break;
						}
					}
					for (k=j-1;k>=0;k--)
					{
						if (board[i][k]==0 )
						{
							add(piece,j,i,k,i,0);
							
						}
						else
						{
							if (cond2(color,board[i][k]))
							{
								add(piece,j,i,k,i,1);
								
							}
							break;
						}
					}
				}
			}
			
		}
		
		
	}
	
	void Moves::GenerateQueenMoves(int board[8][8],int color)
	{
		int piece; int k;
		piece=(color==WHITE?WHITE_QUEEN:BLACK_QUEEN);
		for (int i=0;i<8;i++)  
		{
			for (int j=0;j<8;j++)
			{
				if (board[i][j]==piece)
				{
					
					//Search moves straight, up,left,right and down
					for (k=i-1;k>=0;k--)
					{
						if (board[k][j]==0 )
						{
							add(piece,j,i,j,k,0);
							
						}
						else
						{
							if ( cond2(color,board[k][j]))
							{
								add(piece,j,i,j,k,1);
								
							}
							
							break;
						}
						
						
					}
					for (k=i+1;k<8;k++)
					{
						if (board[k][j]==0)
						{
							add(piece,j,i,j,k,0);
							
						}
						else
						{
							if (cond2(color,board[k][j]))
							{
								add(piece,j,i,j,k,1);
								
							}
							break;
						}
					}
					for (k=j+1;k<8;k++)
					{
						if (board[i][k]==0 )
						{
							add(piece,j,i,k,i,0);
							
						}
						else
						{
							if ( cond2(color,board[i][k]))
							{
								add(piece,j,i,k,i,1);
								
							}
							break;
						}
					}
					for (k=j-1;k>=0;k--)
					{
						if (board[i][k]==0)
						{
							add(piece,j,i,k,i,0);
							
						}
						else
						{
							if (cond2(color,board[i][k]))
							{
								add(piece,j,i,k,i,1);
								
							}
							break;
						}
						
					}
					
					int m;
					//Now search diagnols.
					for (k=i-1,m=j-1;k>=0 && m>=0;k--,m--)
					{
						if (board[k][m]==0 )
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
								
							}
							break;
						}
					}
					for (k=i-1,m=j+1;k>=0 && m<8;k--,m++)
					{
						if (board[k][m]==0 )
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
								
							}
							break;
						}
					}
					for (k=i+1,m=j+1;k<8 && m<8;k++,m++)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
								
							}
							break;
						}
						
					}
					for (k=i+1,m=j-1;k<8 && m>=0;k++,m--)
					{
						if (board[k][m]==0)
						{
							add(piece,j,i,m,k,0);
						}
						else
						{
							if (cond2(color,board[k][m]))
							{
								add(piece,j,i,m,k,1);
								break;
							}
							break;
						}
					}
				}
				
			}
			
		}
		
	}
	
	void Moves::GenerateKingMoves(int board[8][8],int color)
	{
		int i,j;
		int found=0;
		int piece;
		piece=(color==WHITE?WHITE_KING:BLACK_KING);
		for (i=0;i<8 && !found;i++)
		{
			for (j=0;j<8;j++)
			{
				if (board[i][j]==piece)
				{
					found=1;
					break;
				}
			}
		}
		i--;
		
		if (found)
		{
			
			if (i<7 && (gencond(color,board[i+1][j])))
			{
				
				
				add(piece,j,i,j,i+1,0);
			}
			if (i>0 && (gencond(color,board[i-1][j])))
			{
				
				add(piece,j,i,j,i-1,0);
				
			}
			if (j<7 && (gencond(color,board[i][j+1])))
			{
				add(piece,j,i,j+1,i,0);
				
			}
			if (j>0 && (gencond(color,board[i][j-1])))
			{
				
				add(piece,j,i,j-1,i,0);
				
			}
			if (i<7 && j<7 && (gencond(color,board[i+1][j+1])))
			{
				add(piece,j,i,j+1,i+1,0);
				
			}
			if (i<7 && j>0 && (gencond(color,board[i+1][j-1])))
			{
				add(piece,j,i,j-1,i+1,0);
				
			}
			if (i>0 && j<7 && (gencond(color,board[i-1][j+1])))
			{
				add(piece,j,i,j+1,i-1,0);
				
			}
			if (i>0 && j>0 && (gencond(color,board[i-1][j-1])))
			{
				add(piece,j,i,j-1,i-1,0);
				
			}
			
		}
		
		
	}
	
	int Moves::GenerateAllMoves(int board[8][8],int color,int depth,int check_for_mate)
	{
		
		if (movecount<80)
		{
			
			GenerateKnightMoves(board,color);
			
			GenerateBishopMoves(board,color);
			
			GeneratePawnMoves(board,color);
			GenerateRookMoves(board,color);
			
			GenerateQueenMoves(board,color);
			
			GenerateKingMoves(board,color);
		}
		else
		{
			GeneratePawnMoves(board,color);
			GenerateRookMoves(board,color);
			
			GenerateQueenMoves(board,color);
			
			
			GenerateKnightMoves(board,color);
			
			GenerateBishopMoves(board,color);
			
			
			GenerateKingMoves(board,color);
		}
		
		
		
		
		combine();
		return 1;	
	}
	
	
	
	
	
	
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -