#include <fstream> #include <sstream> #include <istream> #include "controller.h" #include "model.h" #include "view.h" std::map<std::string, std::string> Controller::commands { {"left", "left"}, {"right", "right"}, {"down", "down"}, {"clockwise", "clockwise"}, {"counterclockwise", "counterclockwise"}, {"drop", "drop"}, {"levelup", "levelup"}, {"leveldown", "leveldown"}, {"norandom", "norandom"}, {"random", "random"}, {"sequence", "sequence"}, {"hint", "hint"}, {"I", "I"}, {"J", "J"}, {"L", "L"}, {"O", "O"}, {"S", "S"}, {"Z", "Z"}, {"T", "T"}, {"restart", "restart"}, {"rename", "rename"} }; Controller::Controller(View &view, std::istream *input): input{input}, defaultInput{input}, view{view} {} // Private std::string Controller::findCommand(std::string keyword) { int counter = 0; int hilength = 0; int hilengthcount = 0; std::string command = ""; for (auto key : commands) { bool isKey = false; int length = 0; for (size_t i = 0; i < key.first.length(); ++i) { if (key.second[i] != keyword[i]) { break; } else { ++length; } } if (length != 0) { ++counter; if (hilength < length) { isKey = true; hilength = length; hilengthcount = 1; } else if (hilength == length) { ++hilengthcount; } } std::string k = key.first; if (isKey) { command = k; } } if (hilengthcount == 1) { return command; } else { return ""; } } void Controller::getCommandInput() { std::string keyword, cmd; std::cout << view; while (true) { std::cout << "Player " << model->getCurrPlayer() << "'s turn: " << std::endl; if (!std::getline(*input, keyword)) break; std::istringstream ss(keyword); std::string second, third; ss >> keyword; ss >> second; ss >> third; int n = 0; // Parses multiplier prefix int i = 0; while (keyword[i] >= '0' && keyword[i] <= '9') { n = 10 * n + keyword[i] - '0'; ++i; } keyword = keyword.substr(i); if (n == 0 && i == 0) n = 1; cmd = findCommand(keyword); if (cmd.empty()) { std::cout << "Invalid Command!" << std::endl; } else { if (cmd == "left") { model->move('l', n); std::cout << view; } else if (cmd == "right") { model->move('r', n); std::cout << view; } else if (cmd == "down") { model->move('d', n); std::cout << view; } else if (cmd == "clockwise") { model->rotate(true, n); std::cout << view; } else if (cmd == "counterclockwise") { model->rotate(false, n); std::cout << view; } else if (cmd == "drop") { model->drop(n); std::cout << view; } else if (cmd == "levelup") { for (int i = 0; i < n; ++i) { model->levelUp(); } std::cout << view; } else if (cmd == "leveldown") { for (int i = 0; i < n; ++i) { model->levelDown(); } std::cout << view; } else if (cmd == "norandom") { if (second != "") { model->setRandom(false); model->setSequence(second); } } else if (cmd == "random") { model->setRandom(true); } else if (cmd == "sequence") { if (second != "") { std::ifstream sequence; sequence.open(second); input = &sequence; getCommandInput(); sequence.close(); input = defaultInput; } } else if (cmd == "I" || cmd == "J" || cmd == "L" || cmd == "O" || cmd == "S" || cmd == "Z" || cmd == "T") { // Replace with corresponding block type if possible model->replaceCurrBlock(cmd[0]); std::cout << view; } else if (cmd == "restart") { model->restart(); std::cout << view; } else if (cmd == "hint") { model->hint(); std::cout << view; } else if (cmd == "rename") { if (second != "" && third != "") { std::string s = findCommand(second); if (s != "") { commands[s] = third; } } } } } } void Controller::addModel(BiquadrisModel *model) { this->model = model; } void Controller::getSpecialActionCommand() { std::cout << "Enter a Special Action: " << std::endl; std::string cmd; while (true) { if (!std::getline(*input, cmd)) break; if (cmd == "blind") { model->addBlind(); break; } else if (cmd == "heavy") { model->addHeavy(); break; } else if (cmd == "force") { std::cout << "Choose a Block: "; char type; input->get(type); model->replaceCurrBlock(type, false); break; } else { std::cout << std::endl << "Special Action: blind, heavy, force" << std::endl; } } }