void PylosMove::operator=(const std::string &src) { char wd1[11], wd2[11], wd3[11], bk1, bk2, bk3, bk4, extra; std::pair<short, short> p1, p2, p3, p4; int res; short type; LocVector temp; sscanf(src.c_str(), "%10s", wd1); if (!strcmp(wd1, "Play")) { type = kReserve; res = sscanf(src.c_str(), " Play at [ %hd , %hd %c %6s [ %hd , %hd %c %3s" " [ %hd , %hd %c %c", &p1.first, &p1.second, &bk1, wd1, &p2.first, &p2.second, &bk2, wd2, &p3.first, &p3.second, &bk3, &extra); if (res == 3 && bk1 == ']' || res == 7 && bk1 == ']' && bk2 == ']' && !strcmp(wd1, "taking") || res == 11 && bk1 == ']' && bk2 == ']' && bk3 == ']' && !strcmp(wd1, "taking") && !strcmp(wd2, "and")) { temp.push_back(p1); if (res >= 7) temp.push_back(p2); if (res == 11) temp.push_back(p3); } else { throw BaseException(FString("Bad Pylos move: %s", src.c_str())); } } else if (!strcmp(wd1, "Promote")) { type = kPromote; res = sscanf(src.c_str(), " Promote from [ %hd , %hd %c %2s [ %hd , %hd " "%c %6s [ %hd , %hd %c %3s [ %hd , %hd %c %c", &p1.first, &p1.second, &bk1, wd1, &p2.first, &p2.second, &bk2, wd2, &p3.first, &p3.second, &bk3, wd3, &p4.first, &p4.second, &bk4, &extra); if (res == 7 && bk1 == ']' && bk2 == ']' && !strcmp(wd1, "to") || res == 11 && bk1 == ']' && bk2 == ']' && bk3 == ']' && !strcmp(wd1, "to") && !strcmp(wd2, "taking") || res == 15 && bk1 == ']' && bk2 == ']' && bk3 == ']' && bk4 == ']' && !strcmp(wd1, "to") && !strcmp(wd2, "taking") && !strcmp(wd3, "and")) { temp.push_back(p2); temp.push_back(p1); if (res >= 11) temp.push_back(p3); if (res == 15) temp.push_back(p4); } else { throw BaseException(FString("Bad Pylos move: %s", src.c_str())); } } else { throw BaseException(FString("Bad Pylos move: %s", src.c_str())); } for (LocVector::const_iterator iter = temp.begin(); iter != temp.end(); iter++) { if (!InRange<short>(0, iter->first, PylosBoard::kDim) || !InRange<short>(0, iter->second, PylosBoard::kDim)) { throw BaseException(FString("Out of bounds Pylos move: %s", src.c_str())); } } mType = type; mLocs = temp; }
// [Staley] Refine the parsing and string-handling in PylosMove::operator= to // [Staley] deal with all error conditions. Throw a BaseException with an // [Staley] appropriate error message string in it when an error is found. // [Staley] (Recall the FString class) Add a try-catch block to your BoardTest // [Staley] main to catch and print any BaseExceptions that result from your // [Staley] commands. Test PylosMove::operator= thoroughly by giving all // [Staley] sorts of bad PylosMoves to the enterMove command. For this step, // [Staley] you'll need information on sscanf, which you can obtain from the // [Staley] online documentation or from class discussion. void PylosMove::operator=(const string &src) { char wd1[11]={'\0'}, wd2[11]={'\0'}, wd3[11]={'\0'}, brack1, brack2, brack3; pair<short, short> p1, p2, p3, p4; int res; char type; LocVector temp; sscanf(src.c_str(), "%10s", wd1); if (!strcmp(wd1, "Play")) { type = kReserve; // Clear out wd1, now that we know what the mType of this move is. for (int i = 0; i < 11; ++i) wd1[i] = '\0'; res = sscanf(src.c_str(), " Play at [ %hd , %hd %c %6s [ %hd , %hd %c %3s " "[ %hd , %hd %c %1s", &p1.first, &p1.second, &brack1, wd1, &p2.first, &p2.second, &brack2, wd2, &p3.first, &p3.second, &brack3, wd3); // [Staley] Test result of scanf for good format. Had a total of 7 terms // [Staley] in this test. // Verify that the words wd1, wd2, etc. are what the spec expects // them to be. The 'wd' immediately after the last expected token is // the one that needs to be == '\0'. if (res == kPlayOne && brack1 == ']' && wd1[0] == '\0') { // [Staley] Fill in temp temp.push_back(p1); } else if (res == kPlayTwo && brack1 == ']' && brack2 == ']' && string(wd1).compare("taking") == 0 && wd2[0] == '\0') { temp.push_back(p1); temp.push_back(p2); } else if (res == kPlayThree && brack1 == ']' && brack2 == ']' && brack3 == ']' && string(wd1).compare("taking") == 0 && string(wd2).compare("and") == 0 && wd3[0] == '\0') { temp.push_back(p1); temp.push_back(p2); temp.push_back(p3); } else if (res == EOF) throw BaseException(FString("Bad Pylos move: %s", src.c_str())); else throw BaseException(FString("Bad Pylos move: %s", src.c_str())); } else if (!strcmp(wd1, "Promote")) { // [Staley] Similar logic for Promote type = kPromote; // Clear out wd1, now that we know what the mType of this move is. for (int i = 0; i < 11; ++i) wd1[i] = '\0'; res = sscanf(src.c_str(), " Promote from [ %hd , %hd ] to [ %hd , %hd %c " "%6s [ %hd , %hd %c %3s [ %hd , %hd %c %1s", &p2.first, &p2.second, &p1.first, &p1.second, &brack1, wd1, &p3.first, &p3.second, &brack2, wd2, &p4.first, &p4.second, &brack3, wd3); // [Staley] Test result of scanf for good format. // // Verify that the words wd1, wd2, etc. are what the spec expects // them to be. The 'wd' immediately after the last expected token is // the one that needs to be == '\0'. if (res == kPromTwo && brack1 == ']' && wd1[0] == '\0') { temp.push_back(p1); temp.push_back(p2); } else if (res == kPromThree && brack1 == ']' && brack2 == ']' && string(wd1).compare("taking") == 0 && wd2[0] == '\0') { temp.push_back(p1); temp.push_back(p2); temp.push_back(p3); } else if (res == kPromFour && brack1 == ']' && brack2 == ']' && brack3 == ']' && string(wd1).compare("taking") == 0 && string(wd2).compare("and") == 0 && wd3[0] == '\0') { temp.push_back(p1); temp.push_back(p2); temp.push_back(p3); temp.push_back(p4); } else if (res == EOF) throw BaseException(FString("Bad Pylos move: %s", src.c_str())); else throw BaseException(FString("Bad Pylos move: %s", src.c_str())); } else throw BaseException(FString("Bad Pylos move: %s", src.c_str())); // [Staley] About 5 lines of wrapup logic and final error checks needed here. for (LocVector::const_iterator iter = temp.begin(); iter != temp.end(); iter++) { if (iter->first < 0 || iter->first >= PylosBoard::kDim || iter->second < 0 || iter->second >= PylosBoard::kDim) { throw BaseException( FString("Out of bounds Pylos move: %s", src.c_str())); } } mLocs = temp; mType = type; AssertMe(); }