Display.h #ifndef DISPLAY_H #define DISPLAY_H #include <ostream> class Display { public: /** * デストラクタ */ virtual ~Display(); /** * 表示前処理(純粋仮想関数) */ virtual void start() = 0; /** * 表示後処理(純粋仮想関数) */ virtual void end() = 0; /** * 1文字出力処理 (純粋仮想関数) * @param c 出力文字 */ virtual void put(char c) = 0; /** * 改行処理(純粋仮想関数) */ virtual void newLine() = 0; protected: /** * 出力先の参照(純粋仮想関数) * @return 出力先の参照 */ virtual std::ostream &stream() = 0; }; #endif /* DISPLAY_H*/ |
Display.cpp #include "Display.h" Display::~Display() { } |
MazePrinter.h #ifndef MAZEPRINTER_H #define MAZEPRINTER_H #include "Display.h" #include "MazeMap.h" class MazePrinter { public: /** * コンストラクタ * @param display Displayインスタンスのポインタ */ MazePrinter(Display *display); /** * 出力 * @param mazeMap MazeMapインスタンスのポインタ */ virtual void output(MazeMap *mazeMap); private: /** Displayインスタンスのポインタ*/ Display *display; }; #endif /* MAZEPRINTER_H */ |
MazePrinter.cpp #include "MazePrinter.h" MazePrinter::MazePrinter(Display *display) { this->display = display; } void MazePrinter::output(MazeMap *mazeMap) { display->start(); // 表示前処理 for (int y = 0; y < mazeMap->getHeight(); ++y) { for (int x = 0; x < mazeMap->getWidth(); ++x) { display->put(mazeMap->get(x, y)); // 1文字表示処理 } display->newLine(); // 改行処理 } display->end(); // 表示後処理 } |
DisplayScreen.h #ifndef DISPLAYSCREEN_H #define DISPLAYSCREEN_H #include <iostream> #include "Display.h" class DisplayScreen : public Display { public: virtual void start(); virtual void end(); virtual void put(char c); virtual void newLine(); protected: virtual std::ostream& stream(); }; #endif /* DISPLAYSCREEN_H */ |
DisplayScreen.cpp #include "DisplayScreen.h" void DisplayScreen::start() { } void DisplayScreen::end() { } void DisplayScreen::put(char c) { stream() << c; } void DisplayScreen::newLine() { stream() << std::endl; } std::ostream& DisplayScreen::stream() { return std::cout; } |
DisplayScreenWide.h #ifndef DISPLAYSCREENWIDE_H #define DISPLAYSCREENWIDE_H #include "DisplayScreen.h" class DisplayScreenWide : public DisplayScreen { public: virtual void put(char c); }; #endif /* DISPLAYSCREENWIDE_H */ |
DisplayScreenWide.cpp #include "DisplayScreenWide.h" void DisplayScreenWide::put(char c) { stream() << c << c; } |
DisplayFile.h #ifndef DISPLAYFILE_H #define DISPLAYFILE_H #include <fstream> #include "DisplayScreen.h" class DisplayFile : public DisplayScreen { public: /** * コンストラクタ * @param fileName 出力ファイル名(指定しない場合"output.txt") */ DisplayFile(const char *fileName = "output.txt"); virtual ~DisplayFile(); protected: virtual std::ostream& stream(); private: std::ofstream ofs; }; #endif /* DISPLAYFILE_H */ |
DisplayFile.cpp #include "DisplayFile.h" DisplayFile::DisplayFile(const char *fileName) { /* ここを実装してください */ } DisplayFile::~DisplayFile() { /* ここを実装してください */ } std::ostream& DisplayFile::stream() { return ofs; } |
DisplayFileWide.h #ifndef DISPLAYFILEWIDE_H #define DISPLAYFILEWIDE_H #include "DisplayFile.h" class DisplayFileWide : public DisplayFile { public: virtual void put(char c); }; #endif /* DISPLAYFILEWIDE_H */ |
DisplayFileWide.cpp #include "DisplayFileWide.h" void DisplayFileWide::put(char c) { /* ここを実装してください */ } |
DisplayHtml.h #ifndef DISPLAYHTML_H #define DISPLAYHTML_H #include "DisplayFile.h" class DisplayHtml : public DisplayFile { public: /** * コンストラクタ * @param fileName 出力ファイル名(指定しない場合"output.html") */ DisplayHtml(const char *fileName = "output.html"); virtual void start(); virtual void end(); virtual void put(char c); virtual void newLine(); }; #endif /* DISPLAYHTML_H */ |
DisplayHtml.cpp #include "DisplayHtml.h" DisplayHtml::DisplayHtml(const char* fileName) : DisplayFile(fileName) { } void DisplayHtml::start() { stream() << "<html><body>\n<table>\n<tr>\n"; } void DisplayHtml::end() { stream() << "</tr>\n</table>\n</body>\n</html>\n" << std::endl; } void DisplayHtml::put(char c) { stream() << "<td>" << c << "</td>"; } void DisplayHtml::newLine() { stream() << "</tr>\n<tr>\n" ; } |
DisplayHtmlWide.h #ifndef DISPLAYHTMLWIDE_H #define DISPLAYHTMLWIDE_H #include "DisplayHtml.h" class DisplayHtmlWide : public DisplayHtml { public: virtual void put(char c); }; #endif /* DISPLAYHTMLWIDE_H */ |
DisplayHtmlWide.cpp #include "DisplayHtmlWide.h" void DisplayHtmlWide::put(char c) { stream() << "<td>" << c << c << "</td>"; } |
main.cpp
#include <cstdlib> #include "MazeMap.h" #include "MazeMakerSimple.h" #include "MazePrinter.h" #include "Display.h" #include "DisplayScreen.h" #include "DisplayScreenWide.h" #include "DisplayFile.h" #include "DisplayFileWide.h" #include "DisplayHtml.h" #include "DisplayHtmlWide.h" /** * 表示方法の選択 * @return Displayインスタンスのポインタ * @attention Displayインスタンスを生成しているので,不要になった時点でdeleteすること */ Display *selectDisplay() { int outputMode; Display *display = NULL; do { std::cout << "output mode [1-6] ? "; std::cin >> outputMode; switch (outputMode) { case 1: display = new DisplayScreen; // 画面に出力 break; case 2: display = new DisplayFile; // ファイルに出力 break; case 3: display = new DisplayHtml; // HTMLファイルに出力 break; case 4: display = new DisplayScreenWide; // 画面に横長に出力 break; case 5: display = new DisplayFileWide; // ファイルに横長に出力 break; case 6: display = new DisplayHtmlWide; // HTMLファイルに横長に出力 break; default: std::cout << "illegal output mode " << outputMode << std::endl; break; } } while (display == NULL); return display; } int main(int argc, char **argv) { // 乱数の初期化設定 // 本来は実行する度に変化する時刻情報などを用いたほうが良いが,開発を容易に(実行の度に結果が変わらないように)するために,乱数の初期値を手動で設定し固定する int seed; std::cout << "seed ? "; std::cin >> seed; srand(seed); // 乱数種の設定 // 迷路幅,迷路高の基底の設定 int w, h; std::cout << "size (w, h) ? "; std::cin >> w >> h; // 迷路マップ情報生成 MazeMap mazeMap(w, h); // 迷路作成 MazeMakerSimple mazeMaker(&mazeMap); mazeMaker.generate(); // 迷路出力 Display *display = selectDisplay(); MazePrinter mazePrinter(display); mazePrinter.output(&mazeMap); // selectDisplay()内で生成したインスタンスを解放 delete display; return 0; }
出力例
seed ? 172900 size (w, h) ? 20 10 output mode [1-6] ? 4 OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO SS OO OO OO OO OO OO OO OOOOOO OOOOOO OOOOOOOOOO OO OOOOOO OOOOOO OOOOOO OO OO OOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOO OO OOOOOOOOOOOOOOOOOO OOOOOO OOOOOOOOOOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOOOOOOOOOOOOOOOOOO OO OO OOOOOOOOOO OO OOOOOOOOOO OOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOO OO OOOOOO OO OO OOOOOO OO OOOOOOOOOO OOOOOOOOOOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOOOOOO OOOOOOOOOOOOOO OOOOOO OO OO OO OO OO OO OOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOOOOOO OOOOOO OOOOOOOOOOOOOO OO OO OO OOOOOOOOOO OO OOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOOOOOO OO OO OO OOOOOOOOOO OO OOOOOOOOOO OO OOOOOO OO OOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOO OO OOOOOOOOOOOOOOOOOO OO OOOOOOOOOO OOOOOOOOOOOOOO OO OO OO OO OO OO OO OO OO OO OO OO OOOOOOOOOOOOOO OOOOOO OO OO OO OO OOOOOO OO OOOOOOOOOOOOOOOOOO OO OO OO OO OO OO OO OO GG OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO 続行するには何かキーを押してください . . .