void SGFReader::parseLine(Game& game, std::string line) { while(!line.empty() && (isspace(line.front()) || line.front() == ';')) line.erase(0, 1); if(line.empty()) return; if(line == "(") { game.startAlternativePath(); return; } else if(line == ")") { game.endAlternativePath(); return; } for(Dispatch::type_map::const_iterator i = s_dispatch.map().begin(); i != s_dispatch.map().end(); ++i) { std::size_t pos_bracket = line.find('['); if(pos_bracket == std::string::npos) throw InvalidLine(line); if(line.substr(0, pos_bracket) != i->first) continue; line.erase(0, i->first.size()); if(line.size() < 2 || *line.begin() != '[' || *(--line.end()) != ']') throw InvalidLine(line); line.erase(0, 1); line.pop_back(); pos_bracket = line.find(']'); if(pos_bracket != std::string::npos) //several instructions on a single line!! { std::string leftOver = line.substr(pos_bracket + 1) + ']'; line = line.substr(0, pos_bracket); i->second(game, line); parseLine(game, leftOver); } else i->second(game, line); return; } throw UnreckognizedCommand(line); }
uint8_t SGFReader::parsePosition(char c) throw(InvalidLine) { if(c >= 'a' && c < 'z') { return (uint8_t)(c - 'a'); } if(c >= 'A' && c < 'Z') { return (uint8_t)(c - 'A' + 27); } std::ostringstream oss; oss << c << " isn't a valid position"; throw InvalidLine(oss.str()); return -1; }
void Node::updateOpen() { int count = 0; // Blank it again fill(&open[0], &open[0]+4, true); // By default every direction is open // For each of the connections, set open[dir] to false for (int i = 0; i < 3; i++) { if (connections[i].exists()) { const Coord* other; // Keep track so we can check if it's valid afterwards ++count; // Note that this can be simplified if we always make sure a line // ends with the node pointed to by dest, but until then, check // based on coordinates const Line& line = *(connections[i].line); // A line must be at least the beginning and ending node if (line.size() < 2) throw InvalidLine(line); if (line.front() == loci) // At beginning other = &line[1]; else if (line.back() == loci) // At end other = &line[line.size()-2]; else // In the middle? It should be at the beginning or end! throw InvalidLine(line); // It can't be the same point if (loci == *other) throw InvalidLine(line); // Determine direction if (loci.x == other->x) // Vertical { if (loci.y < other->y) // Down { if (open[Down]) open[Down] = false; else throw NodeEntryCollision(); } else // Up { if (open[Up]) open[Up] = false; else throw NodeEntryCollision(); } } else if (loci.y == other->y) // Horizontal { if (loci.x < other->x) // Right { if (open[Right]) open[Right] = false; else throw NodeEntryCollision(); } else // Left { if (open[Left]) open[Left] = false; else throw NodeEntryCollision(); } } else // Neither, so invalid { throw InvalidLine(line); } } } // If there's only two, they must be 180 degrees from each other if (count == 2 && !((open[Left] == false && open[Right] == false) || (open[Up] == false && open[Down] == false))) throw InvalidCorner(); }
Point SGFReader::parsePoint(const std::string& line) throw(InvalidLine) { if(line.size() != 2) throw InvalidLine(line + " isn't a valid position for a move"); return Point(parsePosition(line.front()), parsePosition(line.back())); }
void SGFReader::parseGM(Game& /*game*/, std::string line) { if(line != "1") throw InvalidLine("Impossible to parsing anything other than a game of go."); }
void SGFReader::parseFF(Game& /*game*/, std::string line) { if(line != "4") throw InvalidLine("SGF" + line + " not supported"); }