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

📄 sgfparser.cpp

📁 qgo-1.5.4-r3.tar.gz linux下一个很好玩的游戏
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// Black player name	if (!parseProperty(toParse, "PB", tmp))		return false;	if (!tmp.isEmpty())		gameData->playerBlack = tmp;	else		gameData->playerBlack = "Black";		// Black player rank	if (!parseProperty(toParse, "BR", tmp))		return false;	if (!tmp.isEmpty())		gameData->rankBlack = tmp;	else		gameData->rankBlack = "";		// Board size	if (!parseProperty(toParse, "SZ", tmp))		return false;	if (!tmp.isEmpty())		gameData->size = tmp.toInt();	else		gameData->size = 19;		// Komi	if (!parseProperty(toParse, "KM", tmp))		return false;	if (!tmp.isEmpty())		gameData->komi = tmp.toFloat();	else		gameData->komi = 0.0;		// Handicap	if (!parseProperty(toParse, "HA", tmp))		return false;	if (!tmp.isEmpty())		gameData->handicap = tmp.toInt();	else		gameData->handicap = 0;		// Result	if (!parseProperty(toParse, "RE", tmp))		return false;	if (!tmp.isEmpty())		gameData->result = tmp;	else		gameData->result = "";		// Date	if (!parseProperty(toParse, "DT", tmp))		return false;	if (!tmp.isEmpty())		gameData->date = tmp;	else		gameData->date = "";		// Place	if (!parseProperty(toParse, "PC", tmp))		return false;	if (!tmp.isEmpty())		gameData->place = tmp;	else		gameData->place = "";		// Copyright	if (!parseProperty(toParse, "CP", tmp))		return false;	if (!tmp.isEmpty())		gameData->copyright = tmp;	else		gameData->copyright = "";		// Game Name	if (!parseProperty(toParse, "GN", tmp))		return false;	if (!tmp.isEmpty())		gameData->gameName = tmp;	else		gameData->gameName = "";	// Comments style	if (!parseProperty(toParse, "ST", tmp))		return false;	if (!tmp.isEmpty())		gameData->style = tmp.toInt();	else		gameData->style = 1;	// Timelimit	if (!parseProperty(toParse, "TM", tmp))		return false;	if (!tmp.isEmpty())	{		gameData->timelimit = tmp.toInt();		gameData->timeSystem = absolute;	}	else	{		gameData->timelimit = 0;		gameData->timeSystem = none;	}	// Overtime == time system	if (!parseProperty(toParse, "OT", tmp))		return false;	if (!tmp.isEmpty())	{		gameData->overtime = tmp;		if (tmp.contains("byo-yomi"))		{			// type: OT[5x30 byo-yomi]			gameData->timeSystem = byoyomi;			int pos1, pos2;			if ((pos1 = tmp.find("x")) != -1)			{				pos2 = tmp.find("byo");				QString time = tmp.mid(pos1+1, pos2-pos1-1);				gameData->byoTime = time.toInt();				gameData->byoPeriods = tmp.left(pos1).toInt();				gameData->byoStones = 0;				qDebug(QString("byoyomi time system: %1 Periods at %2 seconds").arg(gameData->byoPeriods).arg(gameData->byoTime));			}		}		else if (tmp.contains(":"))		{			// type: OT[3:30] = byo-yomi?;			int pos1;			gameData->timeSystem = byoyomi;			if ((pos1 = tmp.find(":")) != -1)			{				QString time = tmp.left(pos1);				int t = time.toInt()*60 + tmp.right(tmp.length() - pos1 - 1).toInt();				gameData->byoTime = 30;				gameData->byoPeriods = t/gameData->byoTime;				gameData->byoStones = 0;				qDebug(QString("byoyomi time system: %1 Periods at %2 seconds").arg(gameData->byoPeriods).arg(gameData->byoTime));			}		}		else if (tmp.contains("Canadian"))		{			// type: OT[25/300 Canadian]			gameData->timeSystem = canadian;			int pos1, pos2;			if ((pos1 = tmp.find("/")) != -1)			{				pos2 = tmp.find("Can");				QString time = tmp.mid(pos1+1, pos2-pos1-1);				gameData->byoTime = time.toInt();				gameData->byoStones = tmp.left(pos1).toInt();				qDebug(QString("Canadian time system: %1 seconds at %2 stones").arg(gameData->byoTime).arg(gameData->byoStones));			}		}		// simple check		if (gameData->byoStones < 0)			gameData->byoStones = 0;		if (gameData->byoTime <= 0)		{			gameData->byoTime = 0;//			gameData->timeSystem = none;		}	}	else	{		gameData->overtime = "";//		gameData->timeSystem = none;		gameData->byoStones = 0;	}	// Game number	gameData->gameNumber = 0;	gameData->fileName = fileName;		boardHandler->board->initGame(gameData, true);  // Set sgf flag		return true;}bool SGFParser::exportSGFtoClipB(QString *str, Tree *tree){	CHECK_PTR(tree);		if (stream != NULL)		delete stream;	stream = new QTextStream(str, IO_WriteOnly);		bool res = writeStream(tree);		delete stream;	stream = NULL;	return res;}bool SGFParser::doWrite(const QString &fileName, Tree *tree){	CHECK_PTR(tree);		QFile file(fileName);		if (!file.open(IO_WriteOnly))	{		QMessageBox::warning(0, PACKAGE, Board::tr("Could not open file:") + " " + fileName);		return false;	}		if (stream != NULL)		delete stream;	stream = new QTextStream(&file);		bool res = writeStream(tree);		file.flush();	file.close();	delete stream;	stream = NULL;	return res;}bool SGFParser::writeStream(Tree *tree){	CHECK_PTR(stream);	if (!initStream(stream))	{		QMessageBox::critical(0, PACKAGE, Board::tr("Invalid text encoding given. Please check preferences!"));		delete stream;		return false;	}		Move *root = tree->getRoot();	if (root == NULL)		return false;		GameData *gameData = boardHandler->getGameData();		// Traverse the tree recursive in pre-order	isRoot = true;	traverse(root, gameData);		return true;}void SGFParser::writeGameHeader(GameData *gameData){	// Assemble data for root node	*stream << ";GM[1]FF[4]"						// We play Go, we use FF 4		<< "AP[" << PACKAGE << ":" << VERSION << "]";		// Application name : Version	if (gameData->style >= 0 && gameData->style <= 4)		*stream << "ST[" << gameData->style << "]";	else		*stream << "ST[1]";						// We show vars of current node	if (gameData->gameName.isEmpty())					// Skip game name if empty		*stream << endl;	else		*stream << "GN[" << gameData->gameName << "]"		// Game Name		<< endl;	*stream << "SZ[" << gameData->size << "]"				// Board size		<< "HA[" << gameData->handicap << "]"			// Handicap		<< "KM[" << gameData->komi << "]";				// Komi//		<< endl;		if (gameData->timelimit != 0)		*stream << "TM[" << gameData->timelimit << "]";		// Timelimit		if (!gameData->overtime.isEmpty())		*stream << "OT[" << gameData->overtime << "]" << endl;		// Overtime		if (!gameData->playerWhite.isEmpty())		*stream << "PW[" << gameData->playerWhite << "]";  // White name		if (!gameData->rankWhite.isEmpty())		*stream << "WR[" << gameData->rankWhite << "]";    // White rank		if (!gameData->playerBlack.isEmpty())		*stream << "PB[" << gameData->playerBlack << "]";  // Black name		if (!gameData->rankBlack.isEmpty())		*stream << "BR[" << gameData->rankBlack << "]";    // Black rank		if (!gameData->result.isEmpty())		*stream << "RE[" << gameData->result << "]";       // Result		if (!gameData->date.isEmpty())		*stream << "DT[" << gameData->date << "]";         // Date		if (!gameData->place.isEmpty())		*stream << "PC[" << gameData->place << "]";         // Place		if (!gameData->copyright.isEmpty())		*stream << "CP[" << gameData->copyright << "]";    // Copyright		*stream << endl;}void SGFParser::traverse(Move *t, GameData *gameData){	*stream << "(";	int col = -1, cnt = 6;		do {		if (isRoot)		{			writeGameHeader(gameData);			*stream << t->saveMove(isRoot);			isRoot = false;		}		else		{			// do some formatting: add single B[]/W[] properties to one line, max: 10			// if more properties, e.g. B[]PL[]C] -> new line			QString txt = t->saveMove(false);			int cnt_old = cnt;			cnt = txt.length();			if (col % 10 == 0 || col == 1 && cnt != 6 || cnt_old != 6 || col == -1)			{				*stream << endl;				col = 0;			}			*stream << txt;			col++;		}				Move *tmp = t->son;		if (tmp != NULL && tmp->brother != NULL)		{			do {				*stream << endl;				traverse(tmp, NULL);			} while ((tmp = tmp->brother) != NULL);			break;		}	} while ((t = t->son) != NULL);	*stream << endl << ")";}bool SGFParser::parseASCII(const QString &fileName, ASCII_Import *charset, bool isFilename){	QTextStream *txt = NULL;	bool result = false;	asciiOffsetX = asciiOffsetY = 0;	#if 0	qDebug("BLACK STONE CHAR %c\n"		"WHITE STONE CHAR %c\n"		"STAR POINT  CHAR %c\n"		"EMPTY POINT CHAR %c\n"		"HOR BORDER CHAR %c\n"		"VER BORDER CHAR %c\n",		charset->blackStone,		charset->whiteStone,		charset->starPoint,		charset->emptyPoint,		charset->hBorder,		charset->vBorder);#endif		if (isFilename)  // Load from file	{		QFile file;				if (fileName.isNull() || fileName.isEmpty())		{			QMessageBox::warning(0, PACKAGE, Board::tr("No filename given!"));			delete txt;			return false;		}				file.setName(fileName);		if (!file.exists())		{			QMessageBox::warning(0, PACKAGE, Board::tr("Could not find file:") + " " + fileName);			delete txt;			return false;		}				if (!file.open(IO_ReadOnly))		{			QMessageBox::warning(0, PACKAGE, Board::tr("Could not open file:") + " " + fileName);			delete txt;			return false;		}				txt = new QTextStream(&file);		if (!initStream(txt))		{			QMessageBox::critical(0, PACKAGE, Board::tr("Invalid text encoding given. Please check preferences!"));			delete txt;			return false;		}				result = parseASCIIStream(txt, charset);		file.close();	}	else  // a string was passed instead of a filename, copy from clipboard	{		if (fileName.isNull() || fileName.isEmpty())		{			QMessageBox::warning(0, PACKAGE, Board::tr("Importing ASCII failed. Clipboard empty?"));			delete txt;			return false;		}				QString buf(fileName);		txt = new QTextStream(buf, IO_ReadOnly);		if (!initStream(txt))		{			QMessageBox::critical(0, PACKAGE, Board::tr("Invalid text encoding given. Please check preferences!"));			delete txt;			return false;		}				result = parseASCIIStream(txt, charset);	}		delete txt;	return result;}bool SGFParser::parseASCIIStream(QTextStream *stream, ASCII_Import *charset){	CHECK_PTR(stream);		QStrList asciiLines;	asciiLines.setAutoDelete(TRUE);		int i=0, first=-1, last=-1, y=1;	bool flag=false;	QString dummy = QString(QChar(charset->vBorder)).append(charset->vBorder).append(charset->vBorder);  // "---"		while (!stream->atEnd())	{		QString tmp = stream->readLine();		asciiLines.append(tmp.latin1());				if (tmp.find('.') != -1)			flag = true;				if (tmp.find(dummy) != -1)		{			if (first == -1 && !flag)				first = i;			else				last = i;		}		i++;	}	if (!flag)	{		GameData gd;		QString  ascii = asciiLines.getFirst();		// do some fast checks: one line string?qDebug("no standard ASCII file");		int nr = ascii.contains("0") + ascii.contains("b") + ascii.contains("w");		if (nr == 81)		{qDebug("found 9x9");			gd.size = 9;			gd.komi = 3.5;		}		else if (nr == 169)		{qDebug("found 13x13");			gd.size = 13;			gd.komi = 4.5;		}		else if (nr == 361)		{qDebug("found 19x19");			gd.size = 19;			gd.komi = 5.5;		}		else		{qDebug(QString("found nr == %1").arg(nr));			return false;		}		gd.handicap = 0;		if (gd.size != boardHandler->board->getBoardSize())			boardHandler->board->initGame(&gd, true);		int i = 0;		for (int y = 1; y <= gd.size; y++)			for (int x = 1; x <= gd.size; x++)			{				while (ascii[i] != 'b' && ascii[i] != 'w' && ascii[i] != '0')					i++;				if (ascii[i] == 'b')				{					boardHandler->addStone(stoneBlack, x, y);				}				else if (ascii[i] == 'w')				{					boardHandler->addStone(stoneWhite, x, y);				}				i++;			}		asciiLines.clear();		return true;	}		// qDebug("Y: FIRST = %d, LAST = %d", first, last);   		if (first == -1 && last != -1)		asciiOffsetY = boardHandler->board->getBoardSize() - last;		QStrListIterator it(asciiLines);	for (; it.current() && y < boardHandler->board->getBoardSize(); ++it)		if (!doASCIIParse(it.current(), y, charset))			return false;			asciiLines.clear();	return true;}bool SGFParser::doASCIIParse(const QString &toParse, int &y, ASCII_Import *charset){	int pos, x = 0, length = toParse.length();		if (!checkBoardSize(toParse, charset))		return false;		for (pos=toParse.find(charset->emptyPoint, 0); pos<length; pos++)	{		// qDebug("READING %d/%d", x, y);		if (x >= boardHandler->board->getBoardSize() - asciiOffsetX)  // Abort if right edge of board reached			break;				// Empty point or star point		if (toParse[pos] == charset->emptyPoint ||			toParse[pos] == charset->starPoint)			x++;				// Right border		else if (x>0 && toParse[pos] == charset->hBorder)			break;				// White stone		else if (toParse[pos] == charset->whiteStone && x && y)		{			x++;			// qDebug("W %d/%d", x, y);			boardHandler->addStone(stoneWhite, asciiOffsetX+x, asciiOffsetY+y);		}				// Black stone		else if (toParse[pos] == charset->blackStone && x && y)		{			x++;			// qDebug("B %d/%d", x, y);			boardHandler->addStone(stoneBlack, asciiOffsetX+x, asciiOffsetY+y);		}				// Text label: a-z		else if (toParse[pos] >= 'a' && toParse[pos] <= 'z')		{			x++;			// qDebug("MARK: %d/%d - %c", x, y, toParse[pos].latin1());			boardHandler->editMark(asciiOffsetX+x, asciiOffsetY+y, markText, toParse[pos]);		}				// Number label: 1-9		else if (toParse[pos] >= '1' && toParse[pos] <= '9')		{			x++;			// qDebug("NUMBER: %d/%d - %c", x, y, toParse[pos].latin1());			boardHandler->editMark(asciiOffsetX+x, asciiOffsetY+y, markNumber, toParse[pos]);		}	}		if (x)		y++;		return true;}bool SGFParser::checkBoardSize(const QString &toParse, ASCII_Import *charset){	// Determine x offset	int left = toParse.find(charset->hBorder),		right = toParse.find(charset->hBorder, left+1);		// qDebug("Left = %d, Right = %d", left, right);		if (right == -1)	{		int first = toParse.find(charset->emptyPoint),			tmp = toParse.find(charset->starPoint);		first = first > tmp && tmp != -1 ? tmp : first;				if (left > first)			asciiOffsetX = boardHandler->board->getBoardSize() - (left - first)/2 - ((left-first)%2 ? 1 : 0);		else			asciiOffsetX = 0;		// qDebug("ASSUMING PART OF BOARD ONLY. First = %d, ASCII_OFFSET_X = %d", first, asciiOffsetX);	}	else if (left > -1 && right > -1)	{		// qDebug("ASSUMING FULL BOARD. BOARD SIZE = %d", boardHandler->board->getBoardSize());		asciiOffsetX = 0;		if ((right - left)/2 != boardHandler->board->getBoardSize())  // TODO: Warning and abort?			qWarning("Board size does not fit.");	}	else		asciiOffsetX = 0;		return true;}

⌨️ 快捷键说明

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