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

📄 judge.cpp

📁 搜索算法部分使用minmax递归
💻 CPP
字号:
#include "stdafx.h"
#include "Othello.h"


#include "Judge.h"
#include "OthelloDoc.h"
#include <mmsystem.h>
#include "AI_kua.h"

CJudge::CJudge(COthelloDoc* doc):pDoc(doc) {
	m_Model = H2A;
	m_Player = NULL;
	m_Black = m_White = 2;
	m_GoHuman = false;
	m_GoAI = false;
	m_Player1 = HUMAN;
	m_Player2 = AI;
	m_Turn = BLACK;
	m_Gameover = true;
	m_Hint = true;
	m_Counter = 0;
	m_Change = false;
	m_Depth = 6;
	m_EvaluateType = 2;
	temp = 0;
	m_WinDlg = NULL;
	Initiate();
}

CJudge::~CJudge() {
	if(m_Player!=NULL) {
		delete m_Player;
		m_Player = NULL;
	}
	if(m_WinDlg!=NULL) 
		delete m_WinDlg;
}

void CJudge::Initiate() {
/*============ clean ==============*/
	m_GoHuman = false;
	m_GoAI = false;
	m_Gameover = true;
	m_Board.Reset();		//clean board
	if(m_Player!=NULL)	{	//clean player
		delete m_Player;
		m_Player = NULL;
	}
	m_Record.m_Pointer = -1;
	m_Record.DelRecord();	//clean record
/*=========== initiate ============*/
	m_Turn = BLACK;			//black first
	SetModel();		//set model
	m_Black = m_White = 2;	//initiate couter
	WhoseTurn();//new
	m_Gameover = false;
}

void CJudge::Open() {
	if(m_Player!=NULL)	{	//clean player
		delete m_Player;
		m_Player = NULL;
	}
	m_GoHuman = false;
	m_GoAI = false;
	Counter();
	SetModel();		//set model
	WhoseTurn();//new
	m_Gameover = false;

}
void CJudge::GoOn() {
	m_Change = false;
	m_Board.Clean();
		delete m_Player;
		m_Player = NULL;
		TurnChange();
		WhoseTurn();

}
void CJudge::Play() {
	if(m_Player->m_X == -1) {
		GetBoard();
		if(m_Player == NULL) {
			AfxMessageBox("computer wrong");
		}
		int temp1 = m_Player->Think(m_Turn,m_Depth,m_EvaluateType);
/*		if(temp == 0) {
			if(temp1==1) {
				AfxMessageBox("Computer is hungry.");
				temp = 1;
			}
		}*/
	}
	int x = m_Player->m_X;
	int y = m_Player->m_Y;
	CleanState();
	Search();
	if( m_Board.Get(x,y) == ENABLE ) {
		Drop(x,y,m_Turn);
		m_Record.DelRecord();
		m_Record.Record(x,y);
		m_Change = true;
/*		delete m_Player;
		m_Player = NULL;
		TurnChange();
		WhoseTurn();*/
	}
	else {
	PlaySound((LPCSTR)IDR_ERROR,NULL,SND_RESOURCE | SND_ASYNC);
		UnChange();
	}
}

void CJudge::Draw(CDC* pDC,int cell,int change) {
	if(m_Hint) {
		m_Board.m_Hint = m_Turn;
	}
	else {
		m_Board.m_Hint = SPACE;
	}
	m_Board.Draw(pDC,cell,change);

/*====== Couter ===========*/

	Counter();
	CString black,white,num;
	black = "Black:  ";
	white = "White:  ";
	num.Format("%d",m_Black);
	black += num+" ";
	num.Format("%d",m_White);
	white += num+" ";
	CFont font;
	font.CreateFont(cell/12,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH || FF_MODERN,"Monotype Corsiva");
	CFont* oldFont = pDC->SelectObject(&font);
	pDC->TextOut(cell,cell/25,black);
	pDC->TextOut(cell,cell-cell/6,white);

	
//	int rx,ry;
/*	if(m_GoHuman)
	pDC->TextOut(50,50,"4");
	m_BackGround = 0;
*/
}

void CJudge::SetModel() {
	switch(m_Model) {
	case H2A:
		m_Player1 = HUMAN;
		m_Player2 = AI;
		break;
	case H2H:
		m_Player1 = HUMAN;
		m_Player2 = HUMAN;
		break;
	case A2A:
		m_Player1 = AI;
		m_Player2 =	AI;

		break;
	case A2H:
		m_Player1 = AI;
		m_Player2 = HUMAN;
		break;
	}
}
void CJudge::GetBoard() {
	CleanState();
	for(int i=0;i<8;i++)
		for(int j=0;j<8;j++) {
			if(m_Player == NULL)
				AfxMessageBox("wrong");
			m_Player->m_State[i+1][j+1]=m_Board.Get(i,j);
		}
}
void CJudge::WhoseTurn() {
	CleanState();
	bool flag = Search();
	if(flag) {
		if(m_Player!=NULL) {
			delete m_Player;
			m_Player = NULL;
		}
		if(m_Turn == BLACK) {
			if(m_Player1 == AI) {
				m_Player = new CAI_kua;
				m_GoAI = true;
			}
			if(m_Player1 == HUMAN) {
				m_Player = new CHuman;
				m_GoHuman = true;
			}
		}
		else {
			if(m_Player2 == AI) {
				m_Player = new CAI_kua;
				m_GoAI = true;
			}
			if(m_Player2 == HUMAN) {
				m_Player = new CHuman;
				m_GoHuman = true;
			}
		}
	}
	else {
		Pass();
	}
}

void CJudge::UnChange() {
	if(m_Turn == BLACK) {
			if(m_Player1 == AI) {
				m_GoAI = true;
			}
			if(m_Player1 == HUMAN) {
				m_GoHuman = true;
			}
		}
		else {
			if(m_Player2 == AI) {
				m_GoAI = true;
			}
			if(m_Player2 == HUMAN) {
				m_GoHuman = true;
			}
		}
}


bool CJudge::Search() {
	bool flag = false;
	for(int i=0;i<8;i++) {
		for(int j=0;j<8;j++) {
			if(m_Board.Get(i,j)==SPACE) {
				bool enable = Direction8(i,j);
				if(enable) {
					m_Board.SetState(i,j,ENABLE);
					flag = true;
				}
			}
		}
	}
	return flag;
}

bool CJudge::Direction8(int x,int y) {
	bool flag = false; 
	int other;
	if(m_Turn == BLACK)
		other = WHITE;
	else
		other = BLACK;
	for(int i=-1;i<2;i++) {
		for(int j=-1;j<2;j++) {
            int cx,cy;
			cx=x+i;cy=y+j;
			while((cx>=0)&&(cx<8)&&(cy>=0)&&(cy<8)) {
				if( m_Board.Get(cx,cy) == other ) {
					cx += i;
					cy += j;
				}
				else {
					if(m_Board.Get(cx,cy) == m_Turn && !( cx == (x+i) && cy == (y+j) ) ) {
						flag = true;
						i = j = 2;
					}
					break;
				}
			}
		}

	}
	return flag;
}

void CJudge::CleanState() {
	for(int i=0;i<8;i++) {
		for(int j=0;j<8;j++) {
			int state = m_Board.Get(i,j);
			if(state == ENABLE)
				m_Board.SetState(i,j,SPACE);
		}
	}
}

void CJudge::Change(int x,int y) {
	int other;
	if(m_Turn == BLACK)
		other = WHITE;
	else
		other = BLACK;
	for(int i=-1;i<2;i++) {
		for(int j=-1;j<2;j++) {
            int cx,cy;
			cx=x+i;cy=y+j;
			while((cx>=0)&&(cx<8)&&(cy>=0)&&(cy<8)) {
				if( m_Board.Get(cx,cy) == other ) {
					cx += i;
					cy += j;
				}
				else {
					if(m_Board.Get(cx,cy) == m_Turn && !( cx == (x+i) && cy == (y+j) ) ) {
						while( !( cx == x+i && cy == y+j ) ) {
									cx-=i;
									cy-=j;
									m_Board.Change(cx,cy,m_Turn);
						}
						
					}
					break;
				}
			}
		}

	}
}

void CJudge::TurnChange() {
	if(m_Turn == BLACK)
		m_Turn = WHITE;
	else
		m_Turn = BLACK;
}
void CJudge::Drop(int x,int y,int color) {
	m_Board.Drop(x,y,color);
	PlaySound( (LPCSTR)IDR_DROP,NULL,SND_RESOURCE | SND_ASYNC);
	pDoc->UpdateAllViews(NULL);
	Change(x,y);
}
void CJudge::Pass() {
	TurnChange();
	CleanState();
	bool flag = Search();
	if(flag) {
		CString who;
		if(m_Turn==	WHITE)
			who = "Black";
		else
			who = "White";
		AfxMessageBox(who+" Pass");
		m_Record.DelRecord();
		m_Record.Record(-1,-1);

		WhoseTurn();
	}
	else {
		delete m_Player;
		m_Player = NULL;
		m_GoHuman = m_GoAI = false;
		m_Gameover = true;
		Counter();
		CString black,white;
		black.Format("%d",m_Black);
		white.Format("%d",m_White);
		CString win;
		int winner;
		if(m_Black>m_White) {
			win = "    BLACK WIN !\n";
			winner = m_Player1;
		}
		else {
			if(m_Black<m_White) {
				win = "    WHITE WIN !\n";
				winner = m_Player2;
			}
			else {
				win = "    WE LOVE PEACE !\n";
				winner = SPACE;
			}
		}
		CString sound[2],ai,human;
		ai = "./res/win.wav";
		human = "./res/lose.wav";
		sound[AI-AI] = ai;
		sound[AI-HUMAN] = human;
/*		if(m_Player1!=m_Player2) {
			if(m_Black>m_White) {
				PlaySound(sound[AI-m_Player1],NULL,SND_ASYNC);
			}
			else
				PlaySound(sound[AI-m_Player2],NULL,SND_ASYNC);
		}
		else
			PlaySound(sound[0],NULL,SND_ASYNC);*/
//		AfxMessageBox("Black: "+black+"   White: "+white+"     \n\n"+win);
		if(winner == AI) {
			PlaySound( (LPCSTR)IDR_LOSE,NULL,SND_RESOURCE | SND_ASYNC);

		}
		else {
			PlaySound( (LPCSTR)IDR_WIN,NULL,SND_RESOURCE | SND_ASYNC);
		}
	}


}
void CJudge::Counter() {
	m_Black = m_White = 0;
	for(int i=0;i<8;i++)
		for(int j=0;j<8;j++) {
			if(m_Board.Get(i,j) == BLACK)
				m_Black++;
			if(m_Board.Get(i,j) ==WHITE)
				m_White++;
		}
}
int CJudge::Undo() {
	if(m_Change) {
		return 1;
	}
	m_GoHuman = false;
	m_Gameover = false;
	m_GoAI = false;
	switch(m_Model) {
	case H2A:
		if(m_Record.m_Pointer > -1) {
			while(m_Record.m_X == -1) {
				m_Record.m_Pointer -= 2;
				m_Record.GetRec(m_Record.m_Pointer+1);
			}
		}
		else {
			m_GoHuman = true;
			return 1;
		}
		break;
	case A2H:
		if(m_Record.m_Pointer > 0) {
			while(m_Record.m_X == -1) {
				m_Record.m_Pointer -= 2;
				m_Record.GetRec(m_Record.m_Pointer+1);
			}
		}
		else {
			m_GoHuman = true;
			return 1;
		}
		break;
	case H2H:
		if(m_Record.m_Pointer > -1) {
			m_Record.GetRec(m_Record.m_Pointer);
			if(m_Record.m_X == -1) {
				m_Record.m_Pointer--;
			}
			m_Record.m_Pointer--;
		}
		else {
			m_GoHuman = true;
			return 1;
		}
		break;
	case A2A:
		m_Gameover = true;
		m_GoHuman = false;
		return 1;
	}
	PlaySound((LPCSTR)IDR_UNDO,NULL,SND_RESOURCE | SND_ASYNC);
	m_Board.Reset();
	for(int i=0;i<=m_Record.m_Pointer;i++) {
		int x,y;
		m_Record.GetRec(i);
		x = m_Record.m_X;
		y = m_Record.m_Y;
		if(x!=-1) {
			m_Turn = i%2+1;
			m_Board.Drop(x,y,m_Turn);
			Change(x,y);
			m_Board.Clean();
		}
	}
	m_Record.m_X = m_Record.m_Y = -1;
	pDoc->UpdateAllViews(NULL);
	m_Turn = i%2+1;
	delete m_Player;
	m_Player = NULL;
	WhoseTurn();
	return 0;
}

int CJudge::Redo() {
	if(m_Change) {
		return 1;
	}
	int loop = 0;
	switch(m_Model) {
		case H2A:
			loop = 2;
			while( (m_Record.m_Pointer+loop+1) < m_Record.m_Counter ) {
				m_Record.GetRec(m_Record.m_Pointer+loop+1);
				if(m_Record.m_X == -1) {
					loop += 2;
				}
				else
					break;
			}
				break;
		case A2H:
			loop = 2;
			while( (m_Record.m_Pointer+loop+1) < m_Record.m_Counter ) {
				m_Record.GetRec(m_Record.m_Pointer+loop+1);
				if(m_Record.m_X == -1) {
					loop += 2;
				}
				else
					break;
			}
				break;
		case H2H:
				loop = 1;
				break;
		case A2A:
				m_GoHuman = false;
				return 1;
	}

	if(	(m_Record.m_Pointer+1) < m_Record.m_Counter) {
	m_GoHuman = false;
	m_GoAI = false;
		for(int i=0;i<loop;i++) {
			int x,y;
			m_Record.m_Pointer++;
			m_Record.GetRec(m_Record.m_Pointer);
			x = m_Record.m_X;
			y = m_Record.m_Y;
			if(x!=-1) {
				m_Turn = m_Record.m_Pointer%2+1;
				m_Board.Drop(x,y,m_Turn);
				Change(x,y);
				m_Board.Clean();
			}
		}
		m_Record.m_X = m_Record.m_Y = -1;
		pDoc->UpdateAllViews(NULL);
		m_Turn = (m_Record.m_Pointer+1)%2+1;
		delete m_Player;
		m_Player = NULL;
		WhoseTurn();
		m_Gameover = false;
	}
	return 0;
}
int CJudge::Display() {
	m_Board.Clean();
	if(m_Record.m_Pointer+1<m_Record.m_Counter) {
		int x,y;
		m_Record.m_Pointer++;
		m_Record.GetRec(m_Record.m_Pointer);
		x = m_Record.m_X;
		y = m_Record.m_Y;
		if(x!=-1) {
			m_Turn = m_Record.m_Pointer%2+1;
			m_Board.Drop(x,y,m_Turn);
			Change(x,y);
		}
	}
	else {
		return 0;
	}
	return 1;
}

void CJudge::Repeat() {
	if(m_Gameover) {
		m_Record.m_Pointer = -1;
		m_Board.Reset();
		pDoc->UpdateAllViews(NULL);
	}
}

⌨️ 快捷键说明

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