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

📄 myframe.cpp

📁 一个人工智能的国际象棋游戏
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/****************************************************
Author: S. Senthil kumar
File: myframe.cpp
Purpose:    Implementation of GUI and various utility functions

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


#include "Global.h"
#include "OneMove.h"
#include "LastMove.h"
#include "myframe.h"
#include "SplashDialog.h"
#include "mydialog.h"
#include "OptionsDialog.h"
#include "NewDialog.h"
#include "TransTableEntry.h"
#include "TranspositionTable.h"
#include "MusicPlayer.h"
#include "AboutDialog.h"



extern volatile int timeover;
extern int movecount;
extern CStatusBarCtrl statusbar;
extern int WHITEBASE;
extern int BLACKBASE;
extern int search_depth;
extern int computer_color;
extern int firsttime;
extern volatile int searching;
extern int end_of_game;
extern TranspositionTable table;
extern int autoplay;
extern int CheckCheck(int board[8][8],int target,int whilethinking=0);
extern int sndenable;
extern CString GetMusicDirectory();
extern volatile int keep_music_playing;
extern int stalemate;
extern CWinThread *ponder_thread;
extern int pondering;
extern int drawthinking;

int rotated=0;			//Whether board has been rotated. Reset after playing one move on rotated board.
int rotatecount=2;		//To identify no. of moves since last rotation to reset rotated.
int SQUARE_SIZE=50;		//Size of square on board.
int ORIGINX= 30;		//Left origin
int ORIGINY= 30;		//Top origin
int XPADDING= 5;		//Gap between left origin and board.
int YPADDING= 20;		//Gap between right origin and board.
COLORREF BLACKSQUARE= RGB(100,100,115);
COLORREF WHITESQUARE= RGB(195,195,195);

extern int BOARDSIZE;


int can_undo=1;		//Flag variable to enable or disable Undo move menu item.
int pieceselected=0;	//Whether a piece has been clicked on. Used in LButtondown and MouseMove.
int first=1;			
int piececut=0;		//Whether a piece has been cut in current move. Used in unmakemove.
CBrush highlighter;	//Highlights or Flashes destination square before moving
CBrush moveshower;	//Highlights current square on MouseMove.
CBitmap mybitmap;	//Loads background bitmap
	myframe::myframe()
	{

	
		blackkingmoved=0;
		queen_blackrook=0;
		king_blackrook=0;
		queen_whiterook=0;
		king_whiterook=0;
		whitekingmoved=0;
		count=0;
		castling_move=0;
		playing=0;
		enable_menus=1;
		XPADDING=SQUARE_SIZE/10;
		YPADDING=XPADDING+15;
		lastmoved=0;
		movecount=0;
		
		mybitmap.LoadBitmap(IDB_BITMAP7);
		HBRUSH mybrush;
		HBITMAP hbitmap=(HBITMAP)mybitmap;
		mybrush=::CreatePatternBrush(hbitmap);
		CString mywindow;
		mywindow=AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW,AfxGetApp()->LoadStandardCursor(IDC_ARROW),mybrush,AfxGetApp()->LoadIcon(IDI_ICON1));
		
		//Create main window.	
		Create(mywindow,"The Genius::Chess Engine");
		//Create modeless splash screen
		SplashScreen *d=new SplashScreen;
		d->Create(IDD_DIALOG1,this);
		
		chessfont.CreateFont(SQUARE_SIZE/2+2,SQUARE_SIZE/10,0,0,0,0,0,0,DEFAULT_CHARSET,0,0,0,FF_DECORATIVE,"Chess Merida");
		
	
		white_cutpiece=black_cutpiece=500;
		movelist.Create(WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|WS_THICKFRAME|WS_CAPTION,CRect(500,10,600,110),this,10);	
		movelist.SetWindowText("Move List");
				
		
		
		statusbar.Create(WS_CHILD|WS_VISIBLE|CCS_BOTTOM,CRect(0,0,100,10),this,123);
		statusbar.SetSimple(FALSE);   
		int widtharray[3]={450,750,-1};
		statusbar.SetParts(3,widtharray);
		statusbar.SetBkColor(RGB(100,100,255));

		whitepieces.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|WS_THICKFRAME|WS_CAPTION|WS_HSCROLL,CRect(475,175,875,300),this,100);
		blackpieces.Create(WS_CHILD|WS_VISIBLE|WS_BORDER|WS_THICKFRAME|WS_CAPTION|WS_HSCROLL,CRect(475,350,875,500),this,0);
	
		whitepieces.SetFont(&chessfont);
		blackpieces.SetFont(&chessfont);
		highlighter.CreateSolidBrush(RGB(200,100,100));
		moveshower.CreateSolidBrush(RGB(100,100,210));
				
	}
	
BEGIN_MESSAGE_MAP(myframe,CFrameWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_FILE_BEGINGAME,StartGame)
ON_COMMAND(ID_FILE_SAVEGAME,SaveGame)
ON_COMMAND(ID_FILE_OPENGAME,OpenGame)
ON_UPDATE_COMMAND_UI_RANGE(40001,40003,disenable)
ON_COMMAND(ID_FILE_EXIT,Exit)
ON_COMMAND(ID_MOVE_UNDO,unmakemove)
ON_UPDATE_COMMAND_UI(ID_MOVE_UNDO,disenable)
ON_COMMAND(ID_HELP_HOWTOPLAY,debug_show)
ON_COMMAND(ID_HELP_ABOUT,about)
ON_COMMAND(ID_OPTIONS_ROTATEBOARD,RotateBoard)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_ROTATEBOARD,disenable)
ON_COMMAND_RANGE(ID_LEVELS_BEGINNER,ID_LEVELS_EXPERT,SetLevel)
ON_UPDATE_COMMAND_UI_RANGE(40009,40012,SetCheck)
ON_COMMAND(ID_OPTIONS_MOREOPTIONS,ShowOptions)
ON_COMMAND(ID_OPTIONS_CONTROLMUSIC,ControlMusic)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_CONTROLMUSIC,ShowHideMusicPlay)
ON_UPDATE_COMMAND_UI_RANGE(40020,40021,SetSelectedSize)
ON_COMMAND_RANGE(40020,40021,SetBoardSize)
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_HELP_CASTLING,ShowCastleHelp)
ON_COMMAND(ID_MOVES_PROPOSEDRAW,ConsiderDraw)
ON_COMMAND(ID_MOVES_RESIGN,OpponentResigned)
ON_UPDATE_COMMAND_UI_RANGE(40022,40024,disenable)
ON_COMMAND(ID_OPTIONS_REFRESHBOARD,RefreshBoard)
END_MESSAGE_MAP()
void myframe::debug_show()
{

	//Open IE with file frame.html from currentdirectory+"geniushelp"
	char *buf=new char[100];
	::GetCurrentDirectory(100,buf);
	ShellExecute(this->m_hWnd,"open","iexplore.exe",(CString)buf+(CString)"\\GeniusHelp\\frame.html","",SW_MAXIMIZE);
	delete [] buf;
}

void myframe::RefreshBoard()
{
	//Driver for refresh.
	Refresh(NULL);
}

void myframe::ConsiderDraw()
{
	//Starts searchagent after setting flag to 1.
	if (!end_of_game)
	{
		drawthinking=1;
		AfxBeginThread(StartSearch,this,THREAD_PRIORITY_NORMAL);
	}
	else
	{
		MessageBox("Game Over.Too Late. You can't offer a draw now");
	}

}

void myframe::OpponentResigned()
{
	if (!end_of_game)
	{
		end_of_game=1;
		MessageBox("So you can't stand up to the Genius?","Victory for the Genius",0);
	}
	else
	{
		MessageBox("Game Over. Too Late. You can't resign now");
	}
}




void myframe::ShowCastleHelp()
{
	
	CFont temp;
	temp.CreateFont(15,10,0,0,0,00,0,0,0,0,0,0,0,"Verdana");
	help.Create(WS_CHILD|WS_VISIBLE|WS_CAPTION|WS_VISIBLE|WS_BORDER|WS_THICKFRAME|WS_SYSMENU|ES_MULTILINE,CRect(100,100,600,400),this,2341);
	help.SetFont(&temp);
	help.SetWindowText("To Castle on the King Side, move your King two squares to the left.\r\n To Castle on the Queen Side, move your king to squares to the right. \r\nEither way, the rook is automatically placed in the right position.");

}

void myframe::SetBoardSize(int id)
{
	
	//Vary board size. Increases or decreases SQUARE_SIZE and Refreshes whole window.
	int xpos,ypos;
	CDC *p=GetDC();
	CBrush mybrush;
	if (SQUARE_SIZE==50)
	{
		//Make board bigger
		SQUARE_SIZE=60;
		xpos=40;
		ypos=2*ORIGINY;
		xpos=0;
		ypos=ORIGINY;
		
		
	}
	else
	{
		//Make board smaller and refresh window.
		mybrush.CreatePatternBrush(&mybitmap);
		CRect r;
		GetClientRect(r);
		p->SelectObject(mybrush);
		p->Rectangle(r);
		SQUARE_SIZE=50;
		
		
	}
	
			
		mybrush.CreateSolidBrush(RGB(100,100,210));
		p->SelectObject(mybrush);
		//Draw rounded rectangle
		p->RoundRect(CRect(0,0,2*ORIGINX+SQUARE_SIZE*8,2*ORIGINY+SQUARE_SIZE*8),CPoint(20,20));
		p->SetBkColor(RGB(0,0,0));
		p->Rectangle(ORIGINX-2,ORIGINY-2,SQUARE_SIZE*8+ORIGINX+2,SQUARE_SIZE*8+ORIGINY+2);		
		CFont temp;
		temp.CreateFont(15,10,0,0,0,00,0,0,0,0,0,0,0,"Verdana");
		char buf[10];
		
		//Write row numbers and column alphabets.
		int stx=ORIGINX;int sty=ORIGINY+SQUARE_SIZE*8+10;
		int changey=sty-30;;
		for (char i=97;i<105;i++)
		{
			p->SetBkMode(TRANSPARENT);
			p->SelectObject(&temp);
			p->TextOut(stx+20,sty,i);
			stx+=SQUARE_SIZE;
			p->TextOut(ORIGINX-20,changey,itoa((int)(i-96),buf,10));
			changey-=SQUARE_SIZE;
		}	
		//Try to refresh other windows. Not working currently.
		movelist.MoveWindow(500,10,100,100,TRUE);
		whitepieces.MoveWindow(475,175,400,125,TRUE);
		blackpieces.MoveWindow(475,350,400,125,TRUE);		
		//Redraw Board.
		Refresh();
}

void myframe::SetSelectedSize(CCmdUI *item)
{
	if (SQUARE_SIZE==50 && item->m_nID==ID_SMALL) item->SetCheck(TRUE);
	else item->SetCheck(FALSE);
	if (SQUARE_SIZE==60 && item->m_nID==ID_LARGE) item->SetCheck(TRUE);
	else item->SetCheck(FALSE);
}



void myframe::Exit()
{
	char ret[10];
	//Shut down music.
	mciSendString("status aria mode",ret,10,NULL);
	if (strcmp(ret,"playing")==0)
	{
		mciSendString("stop aria",ret,10,NULL);
	}
	mciSendString("close aria",ret,10,NULL);
	keep_music_playing=0;
	PostQuitMessage(0);
}



void myframe::OnCreate(LPCREATESTRUCT l)
{

	CFrameWnd::OnCreate(l);
	
	menu.LoadMenu(IDR_MENU1);
	SetMenu(&menu);
		
		
}
void myframe::disenable(CCmdUI *item)
{
	
	if (item->m_nID==ID_MOVE_UNDO)
	{
		if (movecount<4 || !can_undo)
		{
			item->Enable(FALSE);
		}
		else
		{
			item->Enable(TRUE);
		}
		return;
	}
	if (enable_menus==0)
	{
		item->Enable(FALSE);
	}
	else
	{
		item->Enable(TRUE);
	}

}

void myframe::ShowOptions()
{
	OptionsDialog d(IDD_DIALOG4);
	d.DoModal();
}



void myframe::RotateBoard()
{
	int newboard[8][8];
	for (int i=0;i<8;i++)
	{
		for (int j=0;j<8;j++)
		{
			newboard[i][j]=board[7-i][7-j];
		}
	}
	memcpy(board,newboard,BOARDSIZE);
	WHITEBASE=(WHITEBASE==0?7:0);
	BLACKBASE=(BLACKBASE==0?7:0);
	rotated=1;
	Refresh();
}







void myframe::OnPaint()
{
	//Calls initializeBoard(0,..) first time. Future calls only refresh and don't redraw the whole thing.
	CPaintDC d(this);
	initializeBoard(count,&d);
	if (count==0) count++;
}

void myframe::SetLevel(int id)
{
	//Set search depth according to received menu id.
	switch(id)
	{
	case ID_LEVELS_BEGINNER:
		search_depth=2;
		break;
	case ID_LEVELS_NOVICE:
		search_depth=4;
		break;
	case ID_LEVELS_INTERMEDIATE:
		search_depth=5;
		break;
	case ID_LEVELS_EXPERT:
		search_depth=7;
	}
}

void myframe::SetCheck(CCmdUI *item)
{
	
	//Check selected level.
	if (enable_menus==0)
	{
		item->Enable(FALSE);
		return;
	}
	else
	{
		item->Enable(TRUE);
	}
	int radio1=0,radio2=0,radio3=0,radio4=0;
	if (search_depth==2) radio1=1;
	else if (search_depth==4) radio2=1;
	else if(search_depth==5) radio3=1;
	else if(search_depth==7) radio4=1;
	if (item->m_nID==ID_LEVELS_BEGINNER)
	{
		item->SetRadio(radio1);
	}
		
	if(item->m_nID==ID_LEVELS_NOVICE)
	{
		item->SetRadio(radio2);
	}
	if (item->m_nID==ID_LEVELS_INTERMEDIATE) 
	{
		item->SetRadio(radio3);
	}
	if(item->m_nID==ID_LEVELS_EXPERT)
	{
		
		item->SetRadio(radio4);
		
	}
	
		
}




void myframe::about()
{
	AboutDialog d(IDD_DIALOG5);d.DoModal();
}


void myframe::StartGame()
{
	
	if (playing) //Stop current game and create new one
	{
		int val=MessageBox("Do you want to stop current game?","Stop Game?",1);
		if (val==1)
		{
			//Show new game dialog.
			NewDialog d(IDD_DIALOG2);
			d.DoModal();
			//Reset everything.
			computer_color=d.GetSelectedColor();
			search_depth=d.GetSelectedLevel();
			initializeBoard(0,GetDC());
			movecount=0;
			blackkingmoved=0;
			queen_blackrook=0;
			king_blackrook=0;
			queen_whiterook=0;
			king_whiterook=0;
			whitekingmoved=0;
			count=0;
			castling_move=0;
			playing=1;
			enable_menus=1;
			can_undo=0;
			movelist.ResetContent();
			if (computer_color==WHITE)
				ComputerPlay();	
			playing=1;	
		}
		
		end_of_game=0;
		return;
	}
	//Actual Start of a new game
		NewDialog d(IDD_DIALOG2);
		d.DoModal();
		end_of_game=0;
		computer_color=d.GetSelectedColor();
		search_depth=d.GetSelectedLevel();
		
		if (computer_color==WHITE)
		ComputerPlay();	
		playing=1;	
}

void myframe::SaveGame()
{
	CFileDialog d(0,"chs",NULL,0,"*.chs");
	int filesaved=d.DoModal();
	
	if (filesaved)
	{
		Game game;
		//Copy game board.
		memcpy(game.Board,board,BOARDSIZE);
		//Copy castle info.
		CanCastle_Save(&(game));
		//Copy miscellaneous info.
		game.WhoseTurn=lastmoved;
		game.Base=WHITEBASE;
		game.movecount=movecount;
		game.computer_color=computer_color;
		CString filename=d.GetFileName();
		//Save in file.
		ofstream out(filename,ios::out|ios::binary);
		out.write((char *)&game,sizeof(game));
		out.close();
		out.open(filename,ios::app);
		CString move;
		//Save move list.
		for (int i=0;i<movecount;i++)
 		{
			movelist.GetText(i,move);
			out<<move<<"\t";
		}
		//Save cut pieces.
		out<<endl;
		whitepieces.GetWindowText(move);
		out<<move<<endl;
		blackpieces.GetWindowText(move);
		out<<move<<endl;
		out.close();
	}
	
	
}


void myframe::OpenGame()
{
	CFileDialog d(1,".chs",NULL,0,"Chess Files (*.chs)|*.chs;||");
	int row=0,column=0;
	int fileopened=d.DoModal();
	if (fileopened)
	{
		CString filename=d.GetFileName();
		ifstream in(filename,ios::binary);
		if (!in) 
		{
			MessageBox("Not valid filename"); return; 
		}
		Game newgame;
		//Read game structure
		in.read((char *)&newgame,sizeof(newgame));
		if (newgame.Base==0)
		{
			WHITEBASE=0;
			BLACKBASE=7;
		}
		else
		{
			WHITEBASE=7;
			BLACKBASE=0;
		}
		//Initialize board with saved board.
		memcpy(board,newgame.Board,BOARDSIZE);
		Refresh();
		movecount=newgame.movecount; 
		
		movelist.ResetContent();
		
		char move[20];
		int mcount=0;
		//Loop and add moves in movelist.
		while (mcount<movecount)
		{
			in.getline(move,20,'\t');

⌨️ 快捷键说明

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