00001
00002
00003
00004
00005
00006 #include "SgSystem.h"
00007 #include "SgGameWriter.h"
00008
00009 #include <iostream>
00010 #include "SgDebug.h"
00011 #include "SgException.h"
00012 #include "SgNode.h"
00013
00014 using namespace std;
00015 using SgPropUtil::GetPointFmt;
00016
00017
00018
00019 SgGameWriter::SgGameWriter(ostream& out)
00020 : m_out(out),
00021 m_fileFormat(4),
00022 m_numPropsOnLine(0)
00023 {
00024 }
00025
00026 void SgGameWriter::WriteGame(SgNode& root, bool allProps, int fileFormat,
00027 const string& application, int gameNumber,
00028 int defaultSize)
00029 {
00030 if (! m_out)
00031 throw SgException("SgGameWriter: write error");
00032
00033
00034 if (fileFormat != 0)
00035 m_fileFormat = fileFormat;
00036 else if (root.HasProp(SG_PROP_FORMAT))
00037 m_fileFormat = root.GetIntProp(SG_PROP_FORMAT);
00038 root.Add(new SgPropInt(SG_PROP_FORMAT, m_fileFormat));
00039 if (application != "")
00040 root.Add(new SgPropText(SG_PROP_APPLIC, application));
00041 root.Add(new SgPropInt(SG_PROP_GAME, gameNumber));
00042
00043
00044
00045 SgPropList& props = root.Props();
00046 props.MoveToFront(SG_PROP_PLAYER);
00047 props.MoveToFront(SG_PROP_ADD_EMPTY);
00048 props.MoveToFront(SG_PROP_ADD_WHITE);
00049 props.MoveToFront(SG_PROP_ADD_BLACK);
00050 props.MoveToFront(SG_PROP_USER);
00051 props.MoveToFront(SG_PROP_SOURCE);
00052 props.MoveToFront(SG_PROP_ROUND);
00053 props.MoveToFront(SG_PROP_EVENT);
00054 props.MoveToFront(SG_PROP_PLACE);
00055 props.MoveToFront(SG_PROP_DATE);
00056 props.MoveToFront(SG_PROP_RESULT);
00057 props.MoveToFront(SG_PROP_PLAYER_BLACK);
00058 props.MoveToFront(SG_PROP_RANK_BLACK);
00059 props.MoveToFront(SG_PROP_TEAM_BLACK);
00060 props.MoveToFront(SG_PROP_PLAYER_WHITE);
00061 props.MoveToFront(SG_PROP_RANK_WHITE);
00062 props.MoveToFront(SG_PROP_TEAM_WHITE);
00063 props.MoveToFront(SG_PROP_GAME_NAME);
00064 props.MoveToFront(SG_PROP_APPLIC);
00065 props.MoveToFront(SG_PROP_SIZE);
00066 props.MoveToFront(SG_PROP_FORMAT);
00067 props.MoveToFront(SG_PROP_GAME);
00068
00069 SgPropPointFmt fmt = GetPointFmt(gameNumber);
00070 WriteSubtree(root, allProps, defaultSize, fmt);
00071 m_out.put('\n');
00072 }
00073
00074 void SgGameWriter::WriteSubtree(const SgNode& nodeRef, bool allProps,
00075 int boardSize, SgPropPointFmt fmt)
00076 {
00077
00078 StartNewLine();
00079
00080
00081 m_out.put('(');
00082
00083
00084 const SgNode* node = &nodeRef;
00085 do
00086 {
00087 HandleProps(node, boardSize);
00088 m_out.put(';');
00089 WriteNode(*node, allProps, boardSize, fmt);
00090 node = node->LeftMostSon();
00091 } while (node && ! node->HasRightBrother());
00092
00093
00094
00095 while (node)
00096 {
00097 HandleProps(node, boardSize);
00098 WriteSubtree(*node, allProps, boardSize, fmt);
00099 node = node->RightBrother();
00100 }
00101
00102
00103 m_out.put(')');
00104 }
00105
00106 void SgGameWriter::HandleProps(const SgNode* node, int& boardSize) const
00107 {
00108 int value;
00109 bool hasSizeProp = node->GetIntProp(SG_PROP_SIZE, &value);
00110 if (hasSizeProp)
00111 {
00112 if (value >= SG_MIN_SIZE && value <= SG_MAX_SIZE)
00113 boardSize = value;
00114 else
00115 SgWarning() << "Invalid size " << value;
00116 }
00117 }
00118
00119 void SgGameWriter::WriteNode(const SgNode& node, bool allProps, int boardSize,
00120 SgPropPointFmt fmt)
00121 {
00122 for (SgPropListIterator it(node.Props()); it; ++it)
00123 {
00124 SgProp* prop = *it;
00125 vector<string> values;
00126
00127 if ((allProps || ShouldWriteProperty(*prop))
00128 && prop->ToString(values, boardSize, fmt, m_fileFormat))
00129 {
00130
00131
00132 if (prop->Flag(SG_PROPCLASS_NEWLINE))
00133 StartNewLine();
00134 m_out << prop->Label();
00135 for (vector<string>::const_iterator it2 = values.begin();
00136 it2 != values.end(); ++it2)
00137 m_out << '[' << (*it2) << ']';
00138
00139 if (++m_numPropsOnLine >= 10)
00140 StartNewLine();
00141 } }
00142
00143
00144 if (node.HasProp(SG_PROP_GAME))
00145 StartNewLine();
00146 }
00147
00148 void SgGameWriter::StartNewLine()
00149 {
00150
00151 if (m_numPropsOnLine > 0)
00152 {
00153 m_numPropsOnLine = 0;
00154 m_out.put('\n');
00155 }
00156 }
00157
00158 bool SgGameWriter::ShouldWriteProperty(const SgProp& prop)
00159 {
00160
00161
00162 if (m_fileFormat == 3 && prop.Flag(SG_PROPCLASS_NOTCLEAN))
00163 return false;
00164
00165 if (prop.Label() == "")
00166 return false;
00167
00168
00169 if (prop.ID() == SG_PROP_TIME_BLACK || prop.ID() == SG_PROP_TIME_WHITE)
00170 return false;
00171
00172
00173 return true;
00174 }
00175
00176
00177