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

📄 finalrole.cpp

📁 C语言大赛的平台。分为环境模块和策略模块。
💻 CPP
字号:
#include "FinalRole.h"

FinalRole::FinalRole(DEBUGFUNCTION debugFunction):
	mhStdinRd(NULL),
	mhStdinWr(NULL),
	mhStdoutWr(NULL),
	mhStdoutRd(NULL),
	mhProcess(NULL),
	mhThread(NULL),
	mhThreadProc(NULL),
	mState(ROLE_STATE_NULL),
	mAction(INVALID_ACTION),
	mDebugFunction(debugFunction)
{
}

FinalRole::~FinalRole(void)
{
	release();
}

int FinalRole::init(wchar_t *fileName)
{
	if(mState != ROLE_STATE_NULL)
		return -1;

	// create pipes
	SECURITY_ATTRIBUTES saAttr;

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;
	if(!CreatePipe(&mhStdinRd, &mhStdinWr, &saAttr, 0))
	{
		MessageBox(NULL, L"初始化子进程标准输入失败!", L"程序异常", MB_OK | MB_ICONERROR);
		PostQuitMessage(0);
	}
	SetHandleInformation(mhStdinWr, HANDLE_FLAG_INHERIT, 0);

	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;
	if(!CreatePipe(&mhStdoutRd, &mhStdoutWr, &saAttr, 0))
	{
		MessageBox(NULL, L"初始化子进程标准输出失败!", L"程序异常", MB_OK | MB_ICONERROR);
		PostQuitMessage(0);
	}
	SetHandleInformation(mhStdoutRd, HANDLE_FLAG_INHERIT, 0);

	// create process
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(STARTUPINFO);
	si.hStdInput = mhStdinRd;
	si.hStdOutput = mhStdoutWr;
	si.hStdError = mhStdoutWr;
	si.dwFlags = STARTF_USESTDHANDLES;

	ZeroMemory(&pi, sizeof(pi));
	if(CreateProcess(
				NULL,
				(LPWSTR)fileName,
				NULL,
				NULL,
				TRUE,
				NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
				NULL,
				NULL,
				&si,
				&pi) == 0)
	{
		MessageBox(NULL, L"创建子进程失败!请检查文件是否存在!", L"警告", MB_OK | MB_ICONWARNING);
		release();
		return -1;
	}
	else
	{
		mhProcess = pi.hProcess;
		mhThread = pi.hThread;
	}

	// create server thread
	mhThreadProc = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FinalRole::ThreadProc, (LPVOID)this, 0, NULL);
	if(mhThreadProc == NULL)
	{
		MessageBox(NULL, L"创建伺服线程失败!", L"程序异常", MB_OK | MB_ICONERROR);
		PostQuitMessage(0);
	}

	mState = ROLE_STATE_READY;

	return 0;
}

int FinalRole::pause(void)
{
	if(mState != ROLE_STATE_RUNNING)
		return -1;

	DWORD retval = SuspendThread(mhThread);
	if(retval == (DWORD)(-1))
	{
		MessageBox(NULL, L"挂起子程序失败!", L"程序异常", MB_OK | MB_ICONERROR);
		return -1;
	}
	if(retval > 1)
	{
		MessageBox(NULL, L"重复挂起子程序!", L"警告", MB_OK | MB_ICONWARNING);
		ResumeThread(mhThread);
		return -1;
	}

	return 0;
}

int FinalRole::resume(void)
{
	if(mState != ROLE_STATE_RUNNING)
		return -1;

	DWORD retval = ResumeThread(mhThread);
	if(retval == (DWORD)(-1))
	{
		MessageBox(NULL, L"恢复子程序失败!", L"程序异常", MB_OK | MB_ICONERROR);
		return -1;
	}
	if(retval > 1)
	{
		MessageBox(NULL, L"重复挂起子程序!", L"警告", MB_OK | MB_ICONWARNING);
		while(retval > 1)
			retval = ResumeThread(mhThread);
	}

	return 0;
}

void FinalRole::unInit(void)
{
	mState = ROLE_STATE_NULL;
	release();
}

int FinalRole::start(void)
{
	if(mState != ROLE_STATE_READY)
		return -1;

	char startSignal = 'S';
	DWORD count;
	if((!WriteFile(mhStdinWr, &startSignal, sizeof(startSignal), &count, NULL)) ||
			(count != sizeof(startSignal)))
	{
		// 猜测选手程序有问题
		mState = ROLE_STATE_BAD;
		release();
		MessageBox(NULL, L"发送 startSignal 失败!", L"程序异常", MB_OK | MB_ICONERROR);
		return -1;
	}

	mState = ROLE_STATE_RUNNING;
	mRoundOut = 0;

	return 0;
}

int FinalRole::getAction(unsigned char &action)
{
	if(mState != ROLE_STATE_RUNNING)
		return -1;

	// 检查选手是否已经返回决策
	if(mAction == INVALID_ACTION)
	{
		action = NONE;
		mRoundOut++;
		if(mRoundOut > ROUND_OUT)
		{
			mState = ROLE_STATE_BAD;
			release();
		}
		return -1;
	}

	action = mAction;
	return 0;
}

int FinalRole::feedback(bool isQueenHere,
		unsigned char x0, unsigned char y0, unsigned char direction0,
		unsigned char x1, unsigned char y1, unsigned char direction1)
{
	if(mState != ROLE_STATE_RUNNING)
		return -1;

	if(mAction == INVALID_ACTION)
		return -1;

	DWORD count;
	RETURNPACKAGE returnPackage;
	returnPackage.isQueenHere = isQueenHere;
	returnPackage.x0 = x0;
	returnPackage.y0 = y0;
	returnPackage.direction0 = direction0;
	returnPackage.x1 = x1;
	returnPackage.y1 = y1;
	returnPackage.direction1 = direction1;
	if((!WriteFile(mhStdinWr, &returnPackage, sizeof(returnPackage), &count, NULL)) ||
			(count != sizeof(returnPackage)))
	{
		// 猜测选手程序有问题
		mState = ROLE_STATE_BAD;
		release();
		MessageBox(NULL, L"发送反馈信息失败!", L"程序异常", MB_OK | MB_ICONERROR);
		return -1;
	}

	mAction = INVALID_ACTION; // 允许接纳下一个 action
	return 0;
}

int FinalRole::setState(bool isCompleted)
{
	if((mState != ROLE_STATE_RUNNING) && (mState != ROLE_STATE_FINISHED))
		return -1;

	if(isCompleted)
		mState = ROLE_STATE_COMPLETED;
	else
		mState = ROLE_STATE_FAILED;

	release();

	return 0;
}

unsigned char FinalRole::getState(void)
{
	return mState;
}

void FinalRole::release(void)
{
	if(mhThreadProc != NULL)
	{
		TerminateThread(mhThreadProc, 0);
		CloseHandle(mhThreadProc);
		mhThreadProc = NULL;
	}
	if(mhProcess != NULL)
	{
		TerminateThread(mhThread, 0);
		TerminateProcess(mhProcess, 0);
		CloseHandle(mhProcess);
		CloseHandle(mhThread);
		mhProcess = NULL;
		mhThread = NULL;
	}
	if(mhStdinRd != NULL)
	{
		CloseHandle(mhStdinRd);
		mhStdinRd = NULL;
	}
	if(mhStdinWr != NULL)
	{
		CloseHandle(mhStdinWr);
		mhStdinWr = NULL;
	}
	if(mhStdoutWr != NULL)
	{
		CloseHandle(mhStdoutWr);
		mhStdoutWr = NULL;
	}
	if(mhStdoutRd != NULL)
	{
		CloseHandle(mhStdoutRd);
		mhStdoutRd = NULL;
	}
}

DWORD WINAPI FinalRole::ThreadProc(LPVOID lParam)
{
	FinalRole *pRole = (FinalRole*)lParam;
	DWORD count;

	char id;
	unsigned char action;
	char message[MAXDEBUGMESSAGESIZE];

	bool flag = true;
	while(flag)
	{
		if(!ReadFile(pRole->mhStdoutRd, &id, sizeof(id), &count, NULL) ||
				(count != sizeof(id)))
		{
			// 猜测选手程序有问题
			pRole->mState = ROLE_STATE_BAD;
			pRole->release();
			MessageBox(NULL, L"主进程接收数据 id 失败!", L"程序异常", MB_OK | MB_ICONERROR);
			break;
		}
		switch(id)
		{
			case 'A':
				if(!ReadFile(pRole->mhStdoutRd, &action, sizeof(action), &count, NULL) ||
						(count != sizeof(action)))
				{
					// 猜测选手程序有问题
					pRole->mState = ROLE_STATE_BAD;
					pRole->release();
					flag = false;
					MessageBox(NULL, L"主进程接收决策数据失败!", L"程序异常", MB_OK | MB_ICONERROR);
				}
				else
				{
					if(pRole->mAction != INVALID_ACTION)
					{
						// 猜测选手程序有问题
						pRole->mState = ROLE_STATE_BAD;
						pRole->release();
						flag = false;
						MessageBox(NULL, L"重复置入决策数据!", L"程序异常", MB_OK | MB_ICONERROR);
					}
					else
					{
						if(action == INVALID_ACTION)
							action = NONE;
						pRole->mAction = action;
					}
				}
				break;
			case 'D':
				if(!ReadFile(pRole->mhStdoutRd, message, sizeof(message), &count, NULL) ||
						(count != sizeof(message)))
				{
					// 猜测选手程序有问题
					pRole->mState = ROLE_STATE_BAD;
					pRole->release();
					flag = false;
					MessageBox(NULL, L"主进程接收调试信息失败!", L"程序异常", MB_OK | MB_ICONERROR);
					break;
				}
				else if(pRole->mDebugFunction != NULL)
				{
					message[MAXDEBUGMESSAGESIZE - 1] = 0;
					pRole->mDebugFunction(message);
				}
				break;
			case 'F':
				pRole->mState = ROLE_STATE_FINISHED;
				pRole->release();
				flag = false;
				break;
			default:
				// 猜测选手程序有问题
				pRole->mState = ROLE_STATE_BAD;
				pRole->release();
				flag = false;
				MessageBox(NULL, L"主进程接收到错误的数据 id !", L"程序异常", MB_OK | MB_ICONERROR);
		}
	}

	return 0;
}

⌨️ 快捷键说明

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