#include "graphicdisplay.h" #include <iostream> #include <iomanip> #include <sstream> using namespace std; const int MARGIN = 20; const int CELL_WIDTH = 20; const int CELL_HEIGHT = 20; const int BOARD_GAP_WIDTH = 120; const int TEXT_HEIGHT = 22; const int HEADER_HEIGHT = TEXT_HEIGHT * 2; const int FOOTER_HEIGHT = TEXT_HEIGHT; const int MAX_BLOCK_LENGTH = 4; map<char,int> GraphicDisplay::colors = { {'I', Xwindow::Cyan}, {'J', Xwindow::DarkBlue}, {'L', Xwindow::Coral}, {'O', Xwindow::Yellow}, {'S', Xwindow::Green}, {'Z', Xwindow::Red}, {'T', Xwindow::DeepPink}, {' ', Xwindow::Black}, {'*', Xwindow::Brown}, {'?', Xwindow::White} }; const int BORDER_COLOR = Xwindow::Brown; const int NUM_BOARDS = 2; const int windowWidth = 4 * MARGIN + (2 * ((11 + 2) * CELL_WIDTH)) + 10 * CELL_WIDTH + BOARD_GAP_WIDTH; void GraphicDisplay::updateLevel(int boardId, int level) { const int boardWidth = (width + 2) * CELL_WIDTH; ostringstream ss; ss << "Level:" << setw(5) << level; w->fillRectangle(80 + 5 + boardId * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN - 7, 100, TEXT_HEIGHT, Xwindow::Black); w->drawString(80 + 5 + boardId * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + TEXT_HEIGHT - 7, ss.str()); } void GraphicDisplay::updateScore(int boardId, int score) { const int boardWidth = (width + 2) * CELL_WIDTH; ostringstream ss; ss << "Score:" << setw(5) << score; w->fillRectangle(80 + 5 + boardId * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + TEXT_HEIGHT - 7, 250, TEXT_HEIGHT, Xwindow::Black); w->drawString(80 + 5 + boardId * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + 2 * TEXT_HEIGHT - 7, ss.str()); } void GraphicDisplay::updateHighScore(int highScore) { ostringstream ss; ss << "High Score:" << setw(5) << highScore; w->fillRectangle((width + 3) * CELL_WIDTH, MARGIN + TEXT_HEIGHT, 125, TEXT_HEIGHT, Xwindow::Black); w->drawString((width + 3) * CELL_WIDTH, MARGIN + 2 * TEXT_HEIGHT, ss.str()); } GraphicDisplay::GraphicDisplay(int width, int height) : BiquadrisDisplay{NUM_BOARDS, width, height}, w{make_unique<Xwindow>(2 * MARGIN + (2 * ((width + 2) * CELL_WIDTH)) + BOARD_GAP_WIDTH, 2 * MARGIN + ((height + 2) * CELL_HEIGHT) + HEADER_HEIGHT + FOOTER_HEIGHT + MAX_BLOCK_LENGTH * CELL_HEIGHT)} { w->fillRectangle(0, 0, 4 * MARGIN + (2 * ((width + 2) * CELL_WIDTH)) + BOARD_GAP_WIDTH, 2 * MARGIN + ((height + 2) * CELL_HEIGHT) + HEADER_HEIGHT + FOOTER_HEIGHT + MAX_BLOCK_LENGTH * CELL_HEIGHT); const int boardWidth = (width + 2) * CELL_WIDTH; // Draw boards for (int i = 0; i < NUM_BOARDS; ++i) { w->fillRectangle(i * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + HEADER_HEIGHT, boardWidth, (height + 2) * CELL_HEIGHT, Xwindow::Silver); w->fillRectangle(CELL_WIDTH + i * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + HEADER_HEIGHT + CELL_HEIGHT, width * CELL_WIDTH, height * CELL_HEIGHT, Xwindow::Black); } // Draws scoreboards and other info for (int i = 0; i < amount; ++i) { updateLevel(i, 0); updateScore(i, 0); updateHighScore(0); w->drawString(5 + i * (boardWidth + 2 * MARGIN + BOARD_GAP_WIDTH), MARGIN + HEADER_HEIGHT + (height + 2) * CELL_HEIGHT + TEXT_HEIGHT, "Next Block:"); } } void GraphicDisplay::update(int _highScore) { coverHint(); highScore = _highScore; updateHighScore(highScore); } void GraphicDisplay::update(int boardId, int score) { coverHint(); updateScore(boardId, score); } void GraphicDisplay::update(int boardId, int level, char nextBlock) { coverHint(); updateLevel(boardId, level); Shapes theShape(nextBlock); vector<pair<int,int>> layout = theShape.getLayout(0); const int color = colors.find(nextBlock)->second; w->fillRectangle(boardId * (((width + 4) * CELL_WIDTH) + BOARD_GAP_WIDTH), MARGIN + HEADER_HEIGHT + TEXT_HEIGHT + (height + 2) * CELL_HEIGHT + 5, MAX_BLOCK_LENGTH * CELL_WIDTH, MAX_BLOCK_LENGTH * CELL_HEIGHT, Xwindow::Black); for (auto p : layout) { w->fillRectangle(boardId * (((width + 4) * CELL_WIDTH) + BOARD_GAP_WIDTH) + p.second * CELL_WIDTH, 5 + HEADER_HEIGHT + TEXT_HEIGHT + (height + 2 + MAX_BLOCK_LENGTH) * CELL_HEIGHT + p.first * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT, color); } } void GraphicDisplay::update(int boardId, int row, int col, char type) { coverHint(); const int color = colors.find(type)->second; w->fillRectangle(CELL_WIDTH + boardId * ((width + 4) * CELL_WIDTH + BOARD_GAP_WIDTH) + col * CELL_WIDTH, HEADER_HEIGHT + (row + 2) * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT, color); } void GraphicDisplay::coverHint() { w->fillRectangle(width * CELL_WIDTH + 50, MARGIN, 200, TEXT_HEIGHT, Xwindow::Black); } void GraphicDisplay::setHint(string hint) { w->drawString(width * CELL_WIDTH + 50, MARGIN + TEXT_HEIGHT, hint); } bool GraphicDisplay::printable() { return false; } void GraphicDisplay::playerLoses() {}