📄 readefg.cc
字号:
buf += c; m_file.get(c); while (isdigit(c)) { buf += c; m_file.get(c); } m_file.unget(c); FromText(buf, m_lastRational); return (m_lastSymbol = symRATIONAL); } else { m_file.unget(c); m_lastInteger = atoi((char *) buf); return (m_lastSymbol = symINTEGER); } } else if (c == '"') { // The operator>> for gText handles quote-escaping m_file.unget(c); m_file >> m_lastText; return (m_lastSymbol = symTEXT); } throw ParserError();}static void ReadPlayers(ParserState &p_state, TreeData &p_treeData){ if (p_state.GetNextSymbol() != symLBRACE) { throw ParserError(); } while (p_state.GetNextSymbol() == symTEXT) { p_treeData.AddPlayer(p_state.GetLastText()); } if (p_state.GetCurrentSymbol() != symRBRACE) { throw ParserError(); }}static void ParseOutcome(ParserState &p_state, TreeData &p_treeData, NodeData *p_node){ if (p_state.GetCurrentSymbol() == symTEXT) { p_node->m_outcomeData = new OutcomeData(p_state.GetLastText()); if (p_state.GetNextSymbol() != symLBRACE) { throw ParserError(); } p_state.GetNextSymbol(); do { if (p_state.GetCurrentSymbol() == symINTEGER) { p_node->m_outcomeData->m_payoffs.Append(p_state.GetLastInteger()); } else if (p_state.GetCurrentSymbol() == symDOUBLE) { p_node->m_outcomeData->m_payoffs.Append(p_state.GetLastDouble()); } else if (p_state.GetCurrentSymbol() == symRATIONAL) { p_node->m_outcomeData->m_payoffs.Append(p_state.GetLastRational()); } else { throw ParserError(); } if (p_state.GetNextSymbol() == symCOMMA) { p_state.GetNextSymbol(); } } while (p_state.GetCurrentSymbol() != symRBRACE); p_state.GetNextSymbol(); }}static void ParseChanceNode(ParserState &p_state, TreeData &p_treeData){ if (p_state.GetNextSymbol() != symTEXT) { throw ParserError(); } gText nodeName = p_state.GetLastText(); if (p_state.GetNextSymbol() != symINTEGER) { throw ParserError(); } int nodeInfoset = p_state.GetLastInteger().as_long(); NodeData *node = p_treeData.AddNode(nodeName, 0, nodeInfoset); p_state.GetNextSymbol(); if (p_state.GetCurrentSymbol() == symTEXT) { // information set name is specified InfosetData *infoset = node->AddInfosetData(p_state.GetLastText()); if (p_state.GetNextSymbol() != symLBRACE) { throw ParserError(); } p_state.GetNextSymbol(); do { if (p_state.GetCurrentSymbol() != symTEXT) { throw ParserError(); } infoset->AddAction(p_state.GetLastText()); p_state.GetNextSymbol(); if (p_state.GetCurrentSymbol() == symINTEGER) { infoset->AddProb(p_state.GetLastInteger()); } else if (p_state.GetCurrentSymbol() == symDOUBLE) { infoset->AddProb(p_state.GetLastDouble()); } else if (p_state.GetCurrentSymbol() == symRATIONAL) { infoset->AddProb(p_state.GetLastRational()); } else { throw ParserError(); } p_state.GetNextSymbol(); } while (p_state.GetCurrentSymbol() != symRBRACE); p_state.GetNextSymbol(); } if (p_state.GetCurrentSymbol() != symINTEGER) { throw ParserError(); } node->m_outcome = p_state.GetLastInteger().as_long(); p_state.GetNextSymbol(); ParseOutcome(p_state, p_treeData, node);}static void ParsePersonalNode(ParserState &p_state, TreeData &p_treeData){ if (p_state.GetNextSymbol() != symTEXT) { throw ParserError(); } gText nodeName = p_state.GetLastText(); if (p_state.GetNextSymbol() != symINTEGER) { throw ParserError(); } int nodePlayer = p_state.GetLastInteger().as_long(); if (p_state.GetNextSymbol() != symINTEGER) { throw ParserError(); } int nodeInfoset = p_state.GetLastInteger().as_long(); NodeData *node = p_treeData.AddNode(nodeName, nodePlayer, nodeInfoset); p_state.GetNextSymbol(); if (p_state.GetCurrentSymbol() == symTEXT) { // information set name is specified InfosetData *infoset = node->AddInfosetData(p_state.GetLastText()); if (p_state.GetNextSymbol() != symLBRACE) { throw ParserError(); } p_state.GetNextSymbol(); do { if (p_state.GetCurrentSymbol() != symTEXT) { throw ParserError(); } infoset->AddAction(p_state.GetLastText()); p_state.GetNextSymbol(); } while (p_state.GetCurrentSymbol() != symRBRACE); p_state.GetNextSymbol(); } if (p_state.GetCurrentSymbol() != symINTEGER) { throw ParserError(); } node->m_outcome = p_state.GetLastInteger().as_long(); p_state.GetNextSymbol(); ParseOutcome(p_state, p_treeData, node);}static void ParseTerminalNode(ParserState &p_state, TreeData &p_treeData){ if (p_state.GetNextSymbol() != symTEXT) { throw ParserError(); } NodeData *node = p_treeData.AddNode(p_state.GetLastText(), -1, -1); if (p_state.GetNextSymbol() != symINTEGER) { throw ParserError(); } node->m_outcome = p_state.GetLastInteger().as_long(); p_state.GetNextSymbol(); ParseOutcome(p_state, p_treeData, node);}static void Parse(ParserState &p_state, TreeData &p_treeData){ SymbolSet symbol; if (p_state.GetNextSymbol() != symEFG) { throw ParserError(); } if (p_state.GetNextSymbol() != symINTEGER) { throw ParserError(); } if (p_state.GetLastInteger() != 2) { throw ParserError(); } symbol = p_state.GetNextSymbol(); if (symbol != symD && symbol != symR) { throw ParserError(); } if (p_state.GetNextSymbol() != symTEXT) { throw ParserError(); } p_treeData.m_title = p_state.GetLastText(); ReadPlayers(p_state, p_treeData); if (p_state.GetNextSymbol() == symTEXT) { // Read optional comment p_treeData.m_comment = p_state.GetLastText(); p_state.GetNextSymbol(); } while (p_state.GetCurrentSymbol() != symEOF) { switch (p_state.GetCurrentSymbol()) { case symC: ParseChanceNode(p_state, p_treeData); break; case symP: ParsePersonalNode(p_state, p_treeData); break; case symT: ParseTerminalNode(p_state, p_treeData); break; default: throw ParserError(); break; } }}//=========================================================================// Tree-building routines//=========================================================================//// These routines use the temporary data structures to construct // the actual tree to be returned//static void BuildSubtree(efgGame *p_efg, Node *p_node, TreeData &p_treeData, NodeData **p_nodeData){ p_node->SetName((*p_nodeData)->m_name); if ((*p_nodeData)->m_outcome > 0) { if (p_treeData.GetOutcome((*p_nodeData)->m_outcome)) { p_efg->SetOutcome(p_node, p_treeData.GetOutcome((*p_nodeData)->m_outcome)); } else { efgOutcome *outcome = p_efg->NewOutcome(); p_efg->SetOutcomeName(outcome, (*p_nodeData)->m_outcomeData->m_name); p_treeData.m_outcomes.Append(new DefinedOutcomeData((*p_nodeData)->m_outcome, outcome)); p_efg->SetOutcome(p_node, outcome); for (int pl = 1; pl <= p_efg->NumPlayers(); pl++) { p_efg->SetPayoff(outcome, pl, (*p_nodeData)->m_outcomeData->m_payoffs[pl]); } } } if ((*p_nodeData)->m_player > 0) { PlayerData *player = p_treeData.m_firstPlayer; for (int i = 1; i < (*p_nodeData)->m_player; i++, player = player->m_next); if (player->GetInfoset((*p_nodeData)->m_infoset)) { Infoset *infoset = player->GetInfoset((*p_nodeData)->m_infoset); p_efg->AppendNode(p_node, infoset); } else { Infoset *infoset = p_efg->AppendNode(p_node, p_efg->Players()[(*p_nodeData)->m_player], (*p_nodeData)->m_infosetData->m_actions.Length()); infoset->SetName((*p_nodeData)->m_infosetData->m_name); for (int act = 1; act <= infoset->NumActions(); act++) { infoset->SetActionName(act, (*p_nodeData)->m_infosetData->m_actions[act]); } player->AddInfoset((*p_nodeData)->m_infoset, infoset); } *(p_nodeData) = (*(p_nodeData))->m_next; for (int i = 1; i <= p_efg->NumChildren(p_node); i++) { BuildSubtree(p_efg, p_node->GetChild(i), p_treeData, p_nodeData); } } else if ((*p_nodeData)->m_player == 0) { PlayerData *player = &p_treeData.m_chancePlayer; if (player->GetInfoset((*p_nodeData)->m_infoset)) { Infoset *infoset = player->GetInfoset((*p_nodeData)->m_infoset); p_efg->AppendNode(p_node, infoset); } else { Infoset *infoset = p_efg->AppendNode(p_node, p_efg->GetChance(), (*p_nodeData)->m_infosetData->m_actions.Length()); infoset->SetName((*p_nodeData)->m_infosetData->m_name); for (int act = 1; act <= infoset->NumActions(); act++) { infoset->SetActionName(act, (*p_nodeData)->m_infosetData->m_actions[act]); p_efg->SetChanceProb(infoset, act, (*p_nodeData)->m_infosetData->m_probs[act]); } } *(p_nodeData) = (*(p_nodeData))->m_next; for (int i = 1; i <= p_efg->NumChildren(p_node); i++) { BuildSubtree(p_efg, p_node->GetChild(i), p_treeData, p_nodeData); } } else { // Terminal node *(p_nodeData) = (*(p_nodeData))->m_next; }}static void BuildEfg(efgGame *p_efg, TreeData &p_treeData){ p_efg->SetTitle(p_treeData.m_title); p_efg->SetComment(p_treeData.m_comment); for (PlayerData *player = p_treeData.m_firstPlayer; player; player = player->m_next) { p_efg->NewPlayer()->SetName(player->m_name); } NodeData *node = p_treeData.m_firstNode; BuildSubtree(p_efg, p_efg->RootNode(), p_treeData, &node);}//=========================================================================// ReadEfgFile: Global visible function to read an extensive form savefile//=========================================================================efgGame *ReadEfgFile(gInput &p_file){ ParserState parser(p_file); TreeData treeData; efgGame *efg = new efgGame; try { Parse(parser, treeData); BuildEfg(efg, treeData); return efg; } catch (ParserError &) { delete efg; return 0; } catch (...) { delete efg; return 0; }}#include "base/garray.imp"#include "base/gblock.imp"template class gArray<DefinedOutcomeData *>;template class gBlock<DefinedOutcomeData *>;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -