#include "view.h" #include <memory> #include <iostream> #include "textdisplay.h" #include "graphicdisplay.h" #include "cell.h" #include "scoreboard.h" #include "model.h" #include "board.h" #include <vector> #include "subscriptions.h" #include <algorithm> using namespace std; const int PLAYERS = 2; View::View(bool graphic, int width, int height) { if (graphic) displays.emplace_back(make_unique<GraphicDisplay>(width, height)); displays.push_back(make_unique<TextDisplay>(width, height)); } View::~View() { displays.clear(); } vector<SubscriptionType> View::subType() { return vector<SubscriptionType> { SubscriptionType::ModelInfoChange, SubscriptionType::ScoreChange, SubscriptionType::CellModified, SubscriptionType::BoardModified, SubscriptionType::PlayerLose, SubscriptionType::HintChange }; } void View::notify(Subject *whoNotified, SubscriptionType t) { vector<SubscriptionType> subs = subType(); if (find(subs.begin(), subs.end(), t) != subs.end()) { if (t == SubscriptionType::ModelInfoChange) { BiquadrisModel *model = dynamic_cast<BiquadrisModel *>(whoNotified); if (model != nullptr) updateByModel(model); } else if (t == SubscriptionType::ScoreChange) { Scoreboard *sb = dynamic_cast<Scoreboard *>(whoNotified); if (sb != nullptr) updateByScoreboard(sb); } else if (t == SubscriptionType::CellModified) { Cell *c = dynamic_cast<Cell *>(whoNotified); if (c != nullptr) updateByCell(c); } else if (t == SubscriptionType::BoardModified) { Board *b = dynamic_cast<Board *>(whoNotified); if (b != nullptr) updateByBoard(b); } else if (t == SubscriptionType::HintChange) { Board *b = dynamic_cast<Board *>(whoNotified); if (b != nullptr) updateHint(b); } else if (t == SubscriptionType::PlayerLose) { for (auto &d : displays) { d->playerLoses(); } } } } void View::updateByModel(BiquadrisModel *m) { const int nBoards = m->getPlayerCount(); for (auto &d : displays) { for (int i = 0; i < nBoards; ++i) { const int level = m->getLevel(i); const int nextBlock = m->getNextBlock(i); d->update(i, level, nextBlock); } } } void View::updateByScoreboard(Scoreboard *sb) { const int playerCount = sb->getPlayerCount(); for (auto &d : displays) { for (int p = 0; p < playerCount; ++p) { d->update(p, sb->getScore(p)); } d->update(sb->getHighScore()); } } void View::updateByBoard(Board *b) { const int boardId = b->getBoardId(); const int boardWidth = b->getWidth(); const int boardHeight = b->getHeight(); for (auto &d : displays) { for (int r = 0; r < boardHeight; ++r) { for (int c = 0; c < boardWidth; ++c) { d->update(boardId, r, c, b->getType(r, c)); } } } } void View::updateByCell(Cell *c) { const int boardId = c->getBoardId(); const int row = c->getRow(); const int col = c->getCol(); const char type = c->getType(); for (auto &d : displays) { d->update(boardId, row, col, type); } } void View::updateHint(Board *b) { for (auto &d : displays) { d->setHint(b->getHint()); } } ostream &operator<<(ostream &out, const View &v) { for (auto &d : v.displays) { if (d->printable()) d->print(out); } return out; }