Skip to content

Commit

Permalink
feats: add importing SGF related ➕
Browse files Browse the repository at this point in the history
  • Loading branch information
Joker2770 committed Jul 9, 2024
1 parent 83ad2b1 commit 36d41b7
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
105 changes: 105 additions & 0 deletions src/SGFOption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ std::string SGFOption::idx_2_s(const std::pair<int, int> &idx)
return sTmp;
}

std::pair<int, int> SGFOption::s_2_idx(const std::string &StringPropertyValue)
{
std::pair<int, int> idx(-1, -1);
if (!StringPropertyValue.empty() && StringPropertyValue.length() == 2)
{
idx.first = StringPropertyValue.at(0) - 'a';
idx.second = StringPropertyValue.at(1) - 'a';
}

return idx;
}

/// @brief Prints the raw message text of all ISgfcMessage objects in the
/// supplied collection to standard output.
///
Expand Down Expand Up @@ -88,6 +100,35 @@ void SGFOption::PrintDocumentContent(std::shared_ptr<ISgfcDocument> document)
std::cout << std::endl;
}

/// @brief Reads the SGF file @a inputFilePath. If @a printOutput is true also
/// prints the document content to standard output.
///
/// This demonstrates the usage of ISgfcDocumentReader.
std::shared_ptr<ISgfcDocument> SGFOption::ReadDocument(const std::string &inputFilePath, bool printOutput)
{
std::shared_ptr<ISgfcDocumentReader> documentReader = SgfcPlusPlusFactory::CreateDocumentReader();

// Uncomment the following to see an invalid command line
// documentReader->GetArguments()->AddArgument(SgfcArgumentType::DeletePropertyType, SgfcPropertyType::BO);

std::shared_ptr<ISgfcDocumentReadResult> result = documentReader->ReadSgfFile(inputFilePath);

if (printOutput)
{
std::cout << "ReadSgfFile sgfcExitCode = " << static_cast<int>(result->GetExitCode()) << std::endl;
std::cout << "IsSgfDataValid = " << result->IsSgfDataValid() << std::endl;
std::cout << std::endl;

std::cout << "Printing parse results..." << std::endl;
PrintMessages(result->GetParseResult());

if (result->GetExitCode() != SgfcExitCode::FatalError)
PrintDocumentContent(result->GetDocument());
}

return result->GetDocument();
}

/// @brief Writes the content of @a document to the SGF file @a outputFilePath.
///
/// This demonstrates the usage of ISgfcDocumentWriter.
Expand Down Expand Up @@ -170,3 +211,67 @@ void SGFOption::record_2_sgf(const std::string &outputFilePath, std::vector<std:

WriteDocument(document, outputFilePath);
}

int SGFOption::loadSgf(const std::string &inputFilePath, std::vector<std::pair<int, int>> &vRecord, unsigned int *bSize)
{
int iFlag = -1;
Board bTmp;
vRecord.clear();
std::shared_ptr<ISgfcDocument> document = ReadDocument(inputFilePath, true);
if (document->IsEmpty())
{
return iFlag;
}

std::shared_ptr<ISgfcGame> game = document->GetGame();
if (SgfcGameType::GomokuAndRenju != game->GetGameType())
{
return iFlag;
}

std::shared_ptr<ISgfcNode> rootNode = game->GetRootNode();
if (nullptr != rootNode)
{
if (rootNode->HasProperties())
{
std::shared_ptr<ISgfcProperty> property;
property = rootNode->GetProperty(SgfcPropertyType::SZ);
if (nullptr != property && property->HasPropertyValues())
{
std::string s_size = property->GetPropertyValue()->ToSingleValue()->GetRawValue();
*bSize = (unsigned int)std::stoi(s_size);
}
}
std::shared_ptr<ISgfcNode> currentNode;
currentNode = rootNode;

while (currentNode->HasChildren())
{
currentNode = currentNode->GetFirstChild();
if (currentNode->HasProperties())
{
std::shared_ptr<ISgfcProperty> property;
property = currentNode->GetProperty(SgfcPropertyType::W);
if (nullptr == property)
{
property = currentNode->GetProperty(SgfcPropertyType::B);
}
if (nullptr != property && property->HasPropertyValues())
{
std::string sTmp = property->GetPropertyValue()->ToSingleValue()->GetRawValue();
int coord = bTmp.idx2Coord((s_2_idx(sTmp)));
int color = SgfcPropertyType::B == property->GetPropertyType() ? STONECOLOR::BLACK : STONECOLOR::WHITE;
std::pair pTmp(coord, color);
vRecord.push_back(pTmp);
}
}
}
}
else
{
return iFlag;
}
iFlag = 0;

return iFlag;
}
5 changes: 5 additions & 0 deletions src/SGFOption.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
#include <libsgfcplusplus/SgfcPlusPlusFactory.h>
#include <libsgfcplusplus/ISgfcArguments.h>
#include <libsgfcplusplus/ISgfcDocument.h>
#include <libsgfcplusplus/ISgfcDocumentReader.h>
#include <libsgfcplusplus/ISgfcDocumentWriter.h>
#include <libsgfcplusplus/ISgfcDocumentReadResult.h>
#include <libsgfcplusplus/ISgfcDocumentWriteResult.h>
#include <libsgfcplusplus/ISgfcGame.h>
#include <libsgfcplusplus/ISgfcMovePropertyValue.h>
Expand All @@ -49,10 +51,13 @@ class SGFOption
SGFOption();
~SGFOption();
std::string idx_2_s(const std::pair<int, int> &idx);
std::pair<int, int> s_2_idx(const std::string &propertyValue);
void PrintMessages(const std::vector<std::shared_ptr<ISgfcMessage>> &messages);
void PrintDocumentContent(std::shared_ptr<ISgfcDocument> document);
std::shared_ptr<ISgfcDocument> ReadDocument(const std::string &inputFilePath, bool printOutput);
int WriteDocument(std::shared_ptr<ISgfcDocument> document, const std::string &outputFilePath);
void record_2_sgf(const std::string &outputFilePath, std::vector<std::pair<int, int>> &vRecord, unsigned int bSize);
int loadSgf(const std::string &inputFilePath, std::vector<std::pair<int, int>> &vRecord, unsigned int *bSize);
};

#endif
56 changes: 56 additions & 0 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ MainWindow::MainWindow(QWidget *parent)
this->pMenuShow = new QMenu(tr("Show"), this);
this->pMenuAbout = new QMenu(tr("About"), this);
this->pSubMenuOfLanguage = new QMenu(tr("LanguageSubMenu"), this);
this->pActionImportSgf = new QAction(tr("Import from SGF"), this);
this->pActionExportSgf = new QAction(tr("Export to SGF"), this);
this->pActionBoardSize = new QAction(tr("Board Size"), this);
this->pActionTimeoutMatch = new QAction(tr("Match Timeout"), this);
Expand Down Expand Up @@ -78,6 +79,7 @@ MainWindow::MainWindow(QWidget *parent)
this->pActionVer = new QAction(tr("Ver Info"), this);
this->pActionFeedback = new QAction(tr("Feedback"), this);
this->pActionLicense = new QAction(tr("License"), this);
this->pActionImportSgf->setShortcut(QKeySequence(Qt::Key_I));
this->pActionExportSgf->setShortcut(QKeySequence(Qt::Key_E));
this->pActionStart->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
this->pActionPause->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
Expand Down Expand Up @@ -127,6 +129,7 @@ MainWindow::MainWindow(QWidget *parent)
this->pMenuSetting->addAction(this->pActionTimeoutMatch);
this->pMenuSetting->addAction(this->pActionTimeoutTurn);
this->pMenuSetting->addAction(this->pActionMaxMemory);
this->pMenuFile->addAction(this->pActionImportSgf);
this->pMenuFile->addAction(this->pActionExportSgf);
this->pMenuGame->addAction(this->pActionStart);
this->pMenuGame->addAction(this->pActionPause);
Expand Down Expand Up @@ -270,6 +273,7 @@ MainWindow::MainWindow(QWidget *parent)

this->m_effect = new QSoundEffect(this);

connect(this->pActionImportSgf, SIGNAL(triggered()), this, SLOT(OnActionImport2SGF()));
connect(this->pActionExportSgf, SIGNAL(triggered()), this, SLOT(OnActionExport2SGF()));
connect(this->pActionStart, SIGNAL(triggered()), this, SLOT(OnActionStart()));
connect(this->pActionPause, SIGNAL(triggered()), this, SLOT(OnActionPause()));
Expand Down Expand Up @@ -524,6 +528,16 @@ MainWindow::~MainWindow()
delete this->pActionVer;
this->pActionVer = nullptr;
}
if (nullptr != this->pActionExportSgf)
{
delete this->pActionExportSgf;
this->pActionExportSgf = nullptr;
}
if (nullptr != this->pActionImportSgf)
{
delete this->pActionImportSgf;
this->pActionImportSgf = nullptr;
}
if (nullptr != this->pMenuFile)
{
delete this->pMenuFile;
Expand Down Expand Up @@ -3480,3 +3494,45 @@ void MainWindow::OnActionExport2SGF()
this->mSgfOpt->record_2_sgf(aFileName.toStdString(), this->mBoard->getVRecord(), this->mBoard->getBSize().first);
}
}

void MainWindow::OnActionImport2SGF()
{
QString curPath = QDir::currentPath();
QString dlgTitle = tr("Choose a file");
// QString filter="executable file(*.exe)";
QString aFileName = QFileDialog::getOpenFileName(this, dlgTitle, curPath, "SGF files(*.sgf)");
if (!aFileName.isEmpty())
{
unsigned int b_size = 0;
std::vector<pair<int, int>> vRec;
this->mSgfOpt->loadSgf(aFileName.toStdString(), vRec, &b_size);

this->OnActionClearBoard();
std::pair<unsigned int, unsigned int> pTmp(b_size, b_size);
if (this->mBoard->setBSize(pTmp))
{
resize((this->mBoard->getBSize().first + 2) * RECT_WIDTH, (this->mBoard->getBSize().second + 3) * RECT_HEIGHT + 2 * this->pMenuBar->height());
}

this->mBoard->Notify();

if (nullptr != this->m_T1)
this->m_T1->stop();
if (nullptr != this->m_T2)
this->m_T2->stop();

this->mState = GAME_STATE::IDLE;
this->pRuleActionGroup->setEnabled(true);
this->m_customs->setCfgValue("Board", "size", b_size);

if (this->mState == GAME_STATE::IDLE)
{
for (const auto &v : vRec)
{
this->mBoard->placeStone(this->mBoard->coord2idx(v.first), (STONECOLOR::BLACK == v.second) ? STONECOLOR::BLACK : STONECOLOR::WHITE);
}

this->mBoard->Notify();
}
}
}
2 changes: 2 additions & 0 deletions src/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class MainWindow : public QMainWindow
QMenu *pMenuShow;
QMenu *pMenuAbout;
QMenu *pSubMenuOfLanguage;
QAction *pActionImportSgf;
QAction *pActionExportSgf;
QAction *pActionBoardSize;
QAction *pActionTimeoutMatch;
Expand Down Expand Up @@ -140,6 +141,7 @@ class MainWindow : public QMainWindow
QActionGroup *pLanguageActionGroup;

public slots:
void OnActionImport2SGF();
void OnActionExport2SGF();
void OnActionStart();
void OnActionPause();
Expand Down

0 comments on commit 36d41b7

Please sign in to comment.