diff --git a/作业/数据结构-金健/C++/第三章作业/CMakeLists.txt b/作业/数据结构-金健/C++/第三章作业/CMakeLists.txt new file mode 100644 index 0000000..b7aee37 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/CMakeLists.txt @@ -0,0 +1,65 @@ +cmake_minimum_required(VERSION 3.0.0) +project(第三章作业 VERSION 0.1.0 LANGUAGES C CXX) + +include(CTest) +enable_testing() + +aux_source_directory(./src SRC_LIST) +# aux_source_directory(./test TEST_LIST) +include_directories(./include) + +add_executable(chapter3 ${SRC_LIST}) # 它好像是在这里添加了某个文件才会不给这个文件报错 +if (CMAKE_BUILD_TYPE STREQUAL Debug) + add_executable(test_model ./test/test_model.cpp) + add_executable(test_view ./test/test_view.cpp) + add_executable(test_controller ./test/test_controller.cpp) + + add_test( + NAME test_model + COMMAND $ + ) + + add_test( + NAME test_view + COMMAND $ + ) + + add_test( + NAME test_controller + COMMAND $ + ) + + add_definitions(-D_DEBUG) + # add_definitions(-D_HAS_STD_BYTE=0) 这个好像没用 +endif() + +if (CMAKE_BUILD_TYPE STREQUAL Release) + # 也可以set(CMAKE_CXX_FLAGS_RELEASE ...) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexec-charset=GBK") +endif() + +set(CPACK_PROJECT_NAME ${PROJECT_NAME}) +set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) +SET(EXECUTABLE_OUTPUT_PATH R:/) +include(CPack) + +# 增加了安装的配置还是可能会有找不到库或者库不对的问题, +# 目前需要...\mingw64\bin里的libstdc++-6.dll、libgcc_s_seh-1.dll、libwinpthread-1.dll这三个文件,库的版本不对也可能运行出错,手动从编译并运行成功的设备上复制这三个文件到目标设备上和exe文件同一个目录中是可以运行的 +install(CODE [[ +file(GET_RUNTIME_DEPENDENCIES + RESOLVED_DEPENDENCIES_VAR RESOLVED_DEPS + UNRESOLVED_DEPENDENCIES_VAR UNRESOLVED_DEPS + # EXECUTABLES $ # 这样总是会出错 + # file Failed to run dumpbin on: + # $ + EXECUTABLES R:/chapter3.exe # 所以只能改成这样 + DIRECTORIES $ + PRE_INCLUDE_REGEXES $ + PRE_EXCLUDE_REGEXES "system32" + POST_INCLUDE_REGEXES $ + POST_EXCLUDE_REGEXES "system32" +) +foreach(DEP_LIB ${RESOLVED_DEPS}) + file(INSTALL ${DEP_LIB} DESTINATION R:/bin) +endforeach() +]]) \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/include/MVC.h b/作业/数据结构-金健/C++/第三章作业/include/MVC.h new file mode 100644 index 0000000..d94d527 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/include/MVC.h @@ -0,0 +1,36 @@ +// @Time : 2023-10-28 18:25:30 +// @FileName: MVC.h +// @Author : 423A35C7 +// @Software: VSCode + +#ifndef _MVC +#define _MVC + +#include "constants.h" + + +// 在Simple中都是通过全局变量设置的 + +// 在Multi中, +// 以下的是通过向类传递参数设置的 +extern int probability_num; // 每个时刻有1/probability_num的概extern 率来人 +extern int speed; // 每个窗口办理的速度 +extern int_ total_time; // 总时刻数 +extern int max_money; // 最大携带金额 +extern int window_num; // 柜台数量 +extern double walk_speed; // 人的走路速度 + +// 以下的是通过全局变量设置的 +extern int sleep_time; // 每次刷新间隔多少毫秒 +extern int base_x; // 起始位置距离终端上边几个字符的距离 +extern int base_y; // 起始位置距离终端左边几个字符的距离 +extern int sep; // 每个窗口间隔多少距离 +extern int gate_x; // 大门的位置终端上边几个字符的距离 +extern int gate_y; // 大门的位置终端左边几个字符的距离 + +class Simple; +class Multi; +Status main_simple(); +Status main_multi(); + +#endif \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/include/constants.h b/作业/数据结构-金健/C++/第三章作业/include/constants.h new file mode 100644 index 0000000..2fd2924 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/include/constants.h @@ -0,0 +1,44 @@ +// @Time : 2023-10-23 21:42:40 +// @FileName: constants.h +// @Author : 423A35C7 +// @Software: VSCode + +#ifndef _CONSTANTS +#define _CONSTANTS +#include + +typedef int Status; +typedef int int_; // 用来扩展,可以更改来实现long long长度的,但好像违反了对修改封闭的原则 +#define int_MAX INT_MAX // 配合上面的扩展用 +using coordinate = std::pair; + + +#define DEFAULT_PROBABILITY_NUM 10 // 默认每个时刻有1/DEFAULT_PROBABILITY_NUM的概率来人 +#define DEFAULT_SPEED 1e2 // 默认每个窗口办理的速度 +#define DEFAULT_TOTAL_TIME 1e4 // 默认的总时刻数 +#define MAX_MONEY 200000 // 最大携带金额 +#define DEFAULT_WINDOW_NUM 10 // 默认柜台数量 +#define DEFAULT_BASE_X 5 // 默认起始位置距离终端上边几个字符的距离 +#define DEFAULT_BASE_Y 5 // 默认起始位置距离终端左边几个字符的距离 +#define DEFAULT_SEP 20 // 默认每个窗口间隔多少距离 +#define DEFAULT_WALK_SPEED 2.0 // 默认的人的走路速度 +#define DEFAULT_GATE_X 50 // 默认的大门的位置终端上边几个字符的距离 +#define DEFAULT_GATE_Y 100 // 默认的大门的位置终端左边几个字符的距离 +#define DEFAULT_SLEEP_TIME 10 // 默认每次刷新间隔多少毫秒 + +#define DEFAULT_RANDOM_SEED (unsigned)std::time(NULL) // 默认的随机数种子 + +const Status OK = 0; +const Status ERROR = -1; + +// const unsigned seed = DEFAULT_RANDOM_SEED; + +// https://www.cnblogs.com/shirishiqi/p/5431627.html +// 此宏展开后,类似于printf("123"),printf("456"); +#define TRACE_CMH_1 (printf("%s(%d)-<%s>: ", __FILE__, __LINE__, __FUNCTION__), printf) + +// 此宏展开后,类似于printf("%d""%d", 1, 2); +#define TRACE_CMH_2(fmt, ...) \ + printf("%s(%d)-<%s>: "##fmt, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__) + +#endif \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/include/controller.hpp b/作业/数据结构-金健/C++/第三章作业/include/controller.hpp new file mode 100644 index 0000000..ce73254 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/include/controller.hpp @@ -0,0 +1,93 @@ +// @Time : 2023-10-24 11:17:40 +// @FileName: controller.h +// @Author : 423A35C7 +// @Software: VSCode + +#ifndef _CONTROLLER +#define _CONTROLLER + +#include "constants.h" +// #include "model.hpp" // view里已经依赖model了 +#include "view.hpp" + +class Controller { + // virtual Status main() = 0; +}; + +template +class DriftingController; + +template +class SingleQueueController : Controller { +friend class DriftingController; +private: + int_ consumed_time = 0; + int speed = DEFAULT_SPEED; + + SingleQueueModel &model; + // BackgroundView background_view; + QueueView> &view; + // void (View:: a)() = background_view.init; + // 捕获了this的lambda函数好像不能转化为void函数指针 + // initializer_list temp { + // [&](this){background_view.init();}, + // [&](this){view.refresh(model);} + // }; +public: + // refresh可以认为是controller内部自己进行更新 + void refresh() { + if (this->model.get_length() <= 0) { + this->consumed_time = 0; + } else { + this->consumed_time++; + if (this->consumed_time * this->speed >= this->model.top().cash) { + this->model.shift(); + this->consumed_time = 0; + } + } + } + SingleQueueController(SingleQueueModel &model, QueueView> &view, int speed = DEFAULT_SPEED) : model(model), view(view), speed(speed) { + this->refresh(); + } +}; + +template +class DriftingController : Controller { +private: + std::vector>> &single_queue_controllers; + DriftingView &drifting_view; + double walk_speed = DEFAULT_WALK_SPEED; +public: + void push(T data, int target, coordinate current_pos = std::make_pair(DEFAULT_GATE_X, DEFAULT_GATE_Y), double walk_speed = DEFAULT_WALK_SPEED) { + auto &view = this->single_queue_controllers[target]->view; + coordinate target_pos = view.get_last_pos(); + int_ remained_time = (int_)(sqrt(pow(target_pos.first - current_pos.first, 2) + pow(target_pos.second - current_pos.second, 2)) / walk_speed); + // DriftingView::Node temp ; + // 如果形参是引用的话会出现如下问题: + // error: cannot bind non-const lvalue reference of type 'DriftingView::Node&' to an rvalue of type 'DriftingView::Node' + this->drifting_view.push({ + data, + view, + remained_time, + current_pos + }); + } + DriftingController( + std::vector>> &single_queue_controllers, + DriftingView &drifting_view + ) : + single_queue_controllers(single_queue_controllers), + drifting_view(drifting_view) {} +}; + +Status mainloop(std::function main, std::function refresh, int_ total_time = DEFAULT_TOTAL_TIME) { + Status temp; + for (int i = 0; i < total_time; i++) { + if ((temp = main()) != OK) + return temp; + refresh(); + } + return OK; +} + +#endif \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/include/model.hpp b/作业/数据结构-金健/C++/第三章作业/include/model.hpp new file mode 100644 index 0000000..718c629 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/include/model.hpp @@ -0,0 +1,156 @@ +// @Time : 2023-10-23 20:09:23 +// @FileName: model.h +// @Author : 423A35C7 +// @Software: VSCode + +#ifndef _MODEL +#define _MODEL + +#include "constants.h" +#include + +// using namespace std; // 会导致byte冲突 + +class Model { + // virtual void init(...) = 0; +}; + +template +struct __SingleQueueModel_iterator; + +template +class SingleQueueModel : Model { +public: // 这里用保护属性会在view的resfresh里报错 + class Node; + +private: + // unique_ptr head(new Node()); // 这样会报错error: expected identifier before 'new' + // vector内对一个对象可能有多个引用,所以可能使用了unique_ptr就无法放置在vector里 + std::shared_ptr head = std::make_shared(); // 好像用unique_ptr直接初始化会报错 + Node *tail = head.get(); + typedef __SingleQueueModel_iterator const_iterator; + +protected: + int_ length = 0; + +public: + void init(){}; + + void push(const T &data) { + this->tail->next = new Node(data); // head指向的头结点无值 + this->tail = this->tail->next; // tail指向的始终有值 + this->length ++; + } + // Status pop(T&) = 0; + T shift() { + if (this->head->next == this->tail) { + this->tail = this->head.get(); // 只剩下一个元素的情况下删除后尾指针应指向头结点 + } + Node node = *this->head->next; // 这个临时的结点在退出此函数时也会调用析构函数 + delete this->head->next; // 这里会调用析构函数 + this->head->next = node.next; + this->length --; + return node.data; + } + + T &top() { + return this->head->next->data; + } + + int_ get_length() { + return this->length; + } + + // https://blog.csdn.net/qq_54851255/article/details/123939684 + const_iterator begin() const { + return const_iterator(this->head->next); + } + + const_iterator end() const { + return const_iterator(this->tail->next); + } +}; + +template +struct __SingleQueueModel_iterator { + typedef class SingleQueueModel::Node Node; + typedef __SingleQueueModel_iterator self; + Node *_node; + + __SingleQueueModel_iterator(Node *x) + : _node(x) {} + Ref operator*() { + return _node->data; + } + + Ptr operator->() { + return &_node->data; + } + + self &operator++() { + _node = _node->next; + return *this; + } + + self operator++(int) { + self tmp(*this); + _node = _node->next; + return tmp; + } + + bool operator!=(const self& it) const + { + return _node != it._node; + } +}; + +// template +// class SimpleQueueModel : public SingleQueueModel { +// class Node; // 这一行必须得加上,表示子类需要重写父类的成员,否则在外部定义时会报错invalid class name in declaration of 'class SimpleQueueModel::Node' +// }; + +template +class SingleQueueModel::Node { +public: + T data; + Node *next = NULL; + Node() {} + // Node(Node *) {} + Node(const T &data) { + this->data = data; + } +#if _DEBUG + ~Node() { + TRACE_CMH_1; + std::cout << "Node " << data << " at " << this << " destructed" << std::endl; + } +#endif +}; + +template +class ComplexSingleQueueModel : SingleQueueModel { +public: + Status push(T) = 0; + Status pop(T &) = 0; + Status shift(T &) = 0; +}; + +template +class MultiQueueModel : Model { +public: + Status init(int_ queue_num) = 0; + Status get(int_ index, SingleQueueModel &) = 0; + Status move(int_ start, int_ destination) = 0; +}; + +struct Customer { + int_ number; + long cash; +}; + +std::ostream &operator<<(std::ostream &out, const Customer &customer) { + out << customer.number << " " << customer.cash; + return out; +}; + +#endif \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/include/view.hpp b/作业/数据结构-金健/C++/第三章作业/include/view.hpp new file mode 100644 index 0000000..e084d82 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/include/view.hpp @@ -0,0 +1,161 @@ +// @Time : 2023-10-23 21:37:53 +// @FileName: view.h +// @Author : 423A35C7 +// @Software: VSCode + +#ifndef _VIEW +#define _VIEW + +#include "constants.h" +#include "model.hpp" +#include + +#define move_and_output(x, y, str) printf("\033[s\033[%d;%dH%s\033u", x, y, str) +#define moveto(x, y) printf("\033[s\033[%d;%dH", x, y) +// 下移光标 +#define movedown(x) printf("\033[%dB", (x)) +#define save_cursor() printf("\033[s") +#define restore_cursor() printf("\033[u") +#define clear_char(num) \ + for (int i = 0; i < num; i++) \ + printf(" ") + + +class View { +public: + virtual void refresh() = 0; +}; + +class BackgroundView : View { +private: + int gate_x; + int gate_y; + +public: + + void refresh() { + printf("\033[2J\033[?25l"); + move_and_output(this->gate_x + 1, this->gate_y, "大门"); + } + + BackgroundView(int gate_x, int gate_y) : gate_x(gate_x), gate_y(gate_y) { + this->refresh(); + } + ~BackgroundView() { + printf("\033[2J\033[0m\033[?25h"); + } +}; + +template +class QueueView : View { +protected: + virtual void init() {} + QueueModel &queue_model; +public: + QueueView() {} + QueueView(QueueModel &_queue_model) : queue_model(_queue_model) {} + // 这里如果不使用引用会在调用时报错: + // 无法引用 函数 "SingleQueueModel::SingleQueueModel(const SingleQueueModel &) [其中 T=Customer]" (已隐式声明) -- 它是已删除的函数C/C++(1776) + virtual void refresh() {} + + // 此方法不一定合理,因为View直接更改了Model + void push_to_model(T &data) { + this->queue_model.push(data); + } + virtual std::pair get_last_pos() { + return std::make_pair(-1, -1); + } +}; + +// MVC中的View不应该依赖Model,这里的模板中只是使用了Model的名称,实际上并不依赖model实现的代码,只要这个模板类型有迭代器的实现就行 +template +class SimpleQueueView : public QueueView { +friend View; +private: + int_ base_x; // x是向下增加 + int_ base_y; // y是向右增加 + int_ tail_y; + +protected: + QueueModel &queue_model; + +public: + SimpleQueueView(QueueModel &_queue_model) : queue_model(_queue_model), QueueView(_queue_model) { + this->base_x = 0; + this->base_y = 0; + } + SimpleQueueView(QueueModel &_queue_model, int_ base_x, int_ base_y) : queue_model(_queue_model), QueueView(_queue_model) { + this->base_x = base_x; + this->base_y = base_y; + } + std::pair get_last_pos() { + return std::make_pair(this->base_x + 1 + this->queue_model.get_length(), this->base_y); + } + + void refresh() { + move_and_output(base_x, base_y, "柜台"); + // this->base_x++; + moveto(base_x + 1, base_y); + for (auto node = this->queue_model.begin(); node != this->queue_model.end(); node++) { + save_cursor(); + std::cout << *node; + restore_cursor(); + movedown(1); + } + restore_cursor(); + } +}; + +class MultiQueueView : View { + virtual Status init(int_ queue_num) = 0; + virtual Status move(int_ start, int_ destination) = 0; +}; + + +// 还没法转成动态多态,不然还是需要一个T的模板,所以还不如直接用Model作为模板 +// 这个类可能只能弄成有状态的,也就是说每次刷新的行为不仅与当前时刻的model有关,还与之前时刻的model有关 +// 还是直接用T作为模板吧,虽然增加了模块之间互相依赖,即controller需要直接向view传节点,但减少了代码量 +template +class DriftingView : View { + public: + struct Node { + T data; + // ../include/view.hpp:152:58: error: passing 'const QueueView >' as 'this' argument discards qualifiers [-fpermissive] +// 152 | coordinate target = node.target->get_last_pos(); + // | ~~~~~~~~~~~~~~~~~~~~~~~~~^~ + QueueView> & target; + int_ remained_time; + coordinate current; + }; + private: + std::list state; + public: + void push(Node node) { + this->state.push_back(node); + } + Status main() { + // 如果用auto遍历,node就应该不是迭代器类型 + for (auto node = this->state.begin(); node != this->state.end();) { + coordinate target = node->target.get_last_pos(); + node->current.first += (target.first - node->current.first) / node->remained_time; + node->current.second += (target.second - node->current.second) / node->remained_time; + node->remained_time--; + if (node->remained_time <= 0) { + node->target.push_to_model(node->data); // View应该直接调用Model吗? + this->state.erase(node++); // 遍历时需要先自增再删除 + } else { + node++; + } + } + return OK; + } + void refresh() { + for (auto &node : this->state) { + moveto(node.current.first, node.current.second); + std::cout << node.data; + restore_cursor(); + } + } +}; + +#endif \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/src/MVC.cpp b/作业/数据结构-金健/C++/第三章作业/src/MVC.cpp new file mode 100644 index 0000000..ae35473 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/src/MVC.cpp @@ -0,0 +1,139 @@ +// @Time : 2023-10-28 16:11:17 +// @FileName: MVC.cpp +// @Author : 423A35C7 +// @Software: VSCode + +#include "controller.hpp" +#include "MVC.h" +// #ifdef __WIN32__ +// 添加"-D_HAS_STD_BYTE=0",的方法不知道为什么没用 +// #include +// #else +// #include +// #define Sleep(a) usleep(a * 1000) // 需要小于一秒 +// #endif +// 用_sleep了,虽然会提示不建议使用了,但是用window.h编译出来的会被认为是病毒 + + +class Simple { +private: + SingleQueueModel model; + SimpleQueueView> view{model, 5, 5}; + // SimpleQueueView> view = SimpleQueueView>(model, 5, 5, 20); + BackgroundView background_view{gate_x, gate_y}; + SingleQueueController controller{model, view, speed}; + // int probability_num = DEFAULT_PROBABILITY_NUM; + +public: + // main可以认为是外部对Controller的操作 + // num是序号 + Status _main() { + static int_ num = 0; + if (rand() % probability_num == 0) { // 0.01的概率 + Customer customer{num++, rand() % (max_money) + 1}; + this->model.push(customer); + } + return OK; + } + + // 可以认为此操作不应出错 + void refresh() { + this->controller.refresh(); + this->background_view.refresh(); + this->view.refresh(); + _sleep(sleep_time); + } +}; + +class Multi { + using one_model = SingleQueueModel; + using one_view = SimpleQueueView>; + using one_controller = SingleQueueController; + + std::vector> models; + std::vector> views; + BackgroundView background_view{gate_x, gate_y}; + std::vector> controllers; + DriftingView drifting_view; + DriftingController drift_controller; + int len = 0; + int probability_num = DEFAULT_PROBABILITY_NUM; + int speed = DEFAULT_SPEED; + int max_money = MAX_MONEY; + double walk_speed = DEFAULT_WALK_SPEED; + +public: + Multi(int len, int probability_num = DEFAULT_PROBABILITY_NUM, int speed = DEFAULT_SPEED, int max_money = MAX_MONEY, double walk_speed = DEFAULT_WALK_SPEED) : len(len), probability_num(probability_num), speed(speed), max_money(max_money), walk_speed(walk_speed), drift_controller(controllers, drifting_view) { + if (len < 1) + throw std::bad_array_new_length(); // 异常这样用好像不太对 + for (int i = 0; i < len; i++) { + // one_model _model {}; + // one_view _view(_model, 5 + i * 20, 5); + // one_controller _controller(_model, _view); // 这里的引用很奇怪,可能是自己创建的类在_model离开作用域后继续引用它无法保证它不被修改,也就是说它引用的可能还是原来的变量名,但原来的变量名被更改了,但vector里可以继续正确引用 + // one_view _view(this->models.back()); // 这样也无法正确引用,看来还是得用指针 + // one_controller _controller(this->models.back(), this->views.back()); + + // vector内对一个对象可能有多个引用,所以可能使用了unique_ptr就无法放置在vector里 + std::shared_ptr _model(new one_model()); + std::shared_ptr _view(new one_view(*_model, base_x, base_y + i * sep)); + std::shared_ptr _controller(new one_controller(*_model, *_view, this->speed)); + this->models.push_back(_model); + this->views.push_back(_view); + this->controllers.push_back(_controller); + } + } + + // 如果有多个最短的,最左边的优先 + int get_shortest_queue() { + int min_value = int_MAX; + int argmin = 0; + for (int i = 0; i < this->len; i++) { + if (this->models[i]->get_length() < min_value) { + min_value = this->models[i]->get_length(); + argmin = i; + } + } + return argmin; + } + + Status _main() { + static int_ num = 0; + this->drifting_view.main(); + if (rand() % this->probability_num == 0) { // 0.01的概率 + Customer customer{num++, rand() % (this->max_money) + 1}; + // this->models[this->get_shortest_queue()]->push(customer); + this->drift_controller.push( + customer, + this->get_shortest_queue(), + std::make_pair(gate_x, gate_y), + this->walk_speed); + } + return OK; + } + + void refresh() { + for (auto _controller : this->controllers) { + _controller->refresh(); + } + this->background_view.refresh(); + for (auto _view : this->views) { + _view->refresh(); + } + this->drifting_view.refresh(); + _sleep(sleep_time); + } +}; + +Status main_simple() { + Simple simple; + std::function _main = std::bind(&Simple::_main, &simple); + std::function refresh = std::bind(&Simple::refresh, &simple); + return mainloop(_main, refresh, total_time); +} + +Status main_multi() { + Multi multi(window_num, probability_num, speed, max_money); + std::function _main = std::bind(&Multi::_main, &multi); + std::function refresh = std::bind(&Multi::refresh, &multi); + return mainloop(_main, refresh, total_time); +} \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/src/main.cpp b/作业/数据结构-金健/C++/第三章作业/src/main.cpp new file mode 100644 index 0000000..3e57f4d --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/src/main.cpp @@ -0,0 +1,66 @@ +// @Time : 2023-10-23 19:40:03 +// @FileName: main.cpp +// @Author : 423A35C7 +// @Software: VSCode + +#include "MVC.h" // 应该是cmake里不应该重复include一遍 +using namespace std; + +// 以下的是通过向类传递参数设置的 +int probability_num = DEFAULT_PROBABILITY_NUM; // 每个时刻有1/probability_num的概率来人 +int speed = DEFAULT_SPEED; // 每个窗口办理的速度 +int_ total_time = DEFAULT_TOTAL_TIME; // 总时刻数 +int max_money = MAX_MONEY; // 最大携带金额 +int window_num = DEFAULT_WINDOW_NUM; // 柜台数量 +double walk_speed = DEFAULT_WALK_SPEED; // 人的走路速度 + +// 以下的是通过全局变量设置的 +int sleep_time = DEFAULT_SLEEP_TIME; // 每次刷新间隔多少毫秒 +int base_x = DEFAULT_BASE_X; // 起始位置距离终端上边几个字符的距离 +int base_y = DEFAULT_BASE_Y; // 起始位置距离终端左边几个字符的距离 +int sep = DEFAULT_SEP; // 每个窗口间隔多少距离 +int gate_x = DEFAULT_GATE_X; // 大门的位置终端上边几个字符的距离 +int gate_y = DEFAULT_GATE_Y; // 大门的位置终端左边几个字符的距离 +unsigned seed = DEFAULT_RANDOM_SEED; // 随机数种子 + +template +Status get_input(T &variable, string prompt) { + cout << "请输入" << prompt << "(默认值" << variable << "): "; + while (true) { + if (cin >> variable) { + break; + } + cin.clear(); + cin.ignore(2048, '\n'); + cout << "输入错误,请重新输入:"; + } + return OK; +} + +int main(int, char **) { + // std::cout << "Hello, from 第三章作业!\n"; + srand(seed); + int mode = 2; + get_input(mode, "模式,1为单个队列,2为多个队列,3为自定义,其他整数表示退出"); + switch (mode) { + case 1: + return main_simple(); + break; + case 2: + return main_multi(); + break; + case 3: + get_input(probability_num, "每个时刻有1/{输入值}的概率来人"); + get_input(speed, "每个窗口办理的速度"); + get_input(total_time, "总时刻数"); + get_input(max_money, "最大携带金额"); + get_input(window_num, "柜台数量"); + get_input(walk_speed, "人的走路速度(浮点数)"); + get_input(sleep_time, "每次刷新间隔多少毫秒"); + get_input(seed, "随机数种子"); + srand(seed); + return main_multi(); + break; + } + return OK; +} diff --git a/作业/数据结构-金健/C++/第三章作业/test/test_controller.cpp b/作业/数据结构-金健/C++/第三章作业/test/test_controller.cpp new file mode 100644 index 0000000..dcab808 --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/test/test_controller.cpp @@ -0,0 +1,36 @@ +// @Time : 2023-10-26 16:40:50 +// @FileName: test_controller.cpp +// @Author : 423A35C7 +// @Software: VSCode + +#include "../src/MVC.cpp" +// #ifdef __WIN32__ +// 添加"-D_HAS_STD_BYTE=0",的方法不知道为什么没用 +// #include +// #else +// #include +// #define Sleep(a) usleep(a * 1000) // 需要小于一秒 +// #endif + +// 以下的是通过向类传递参数设置的 +int probability_num = DEFAULT_PROBABILITY_NUM; // 每个时刻有1/probability_num的概率来人 +int speed = DEFAULT_SPEED; // 每个窗口办理的速度 +int_ total_time = 1e2; // 总时刻数 +int max_money = MAX_MONEY; // 最大携带金额 +int window_num = DEFAULT_WINDOW_NUM; // 柜台数量 +double walk_speed = DEFAULT_WALK_SPEED; // 人的走路速度 + +// 以下的是通过全局变量设置的 +int sleep_time = DEFAULT_SLEEP_TIME; // 每次刷新间隔多少毫秒 +int base_x = DEFAULT_BASE_X; // 起始位置距离终端上边几个字符的距离 +int base_y = DEFAULT_BASE_Y; // 起始位置距离终端左边几个字符的距离 +int sep = DEFAULT_SEP; // 每个窗口间隔多少距离 +int gate_x = DEFAULT_GATE_X; // 大门的位置终端上边几个字符的距离 +int gate_y = DEFAULT_GATE_Y; // 大门的位置终端左边几个字符的距离 + +int main() { + Status temp = main_simple(); + if (temp != OK) return temp; + temp = main_multi(); + return temp; +} \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/test/test_model.cpp b/作业/数据结构-金健/C++/第三章作业/test/test_model.cpp new file mode 100644 index 0000000..7a2919c --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/test/test_model.cpp @@ -0,0 +1,15 @@ +#include "model.hpp" + +int main() { + SingleQueueModel simple_queue; + Customer person = {1, 2}; + Customer person2 = {3243, 999}; + simple_queue.push(person); + simple_queue.push(person2); + std::cout << simple_queue.shift() << std::endl; + simple_queue.push(person2); + std::cout << simple_queue.shift() << std::endl; + std::cout << simple_queue.shift() << std::endl; + printf("\033[2J\033[10;37Hhello world\033[5m"); + return 0; +} \ No newline at end of file diff --git a/作业/数据结构-金健/C++/第三章作业/test/test_view.cpp b/作业/数据结构-金健/C++/第三章作业/test/test_view.cpp new file mode 100644 index 0000000..b4b479f --- /dev/null +++ b/作业/数据结构-金健/C++/第三章作业/test/test_view.cpp @@ -0,0 +1,31 @@ +// @Time : 2023-10-24 19:10:31 +// @FileName: test_view.cpp +// @Author : 423A35C7 +// @Software: VSCode + +#include +#include "view.hpp" + +using namespace std; + +template +class TestModel : public vector { + public: + using vector::vector; // 这样好像可以继承构造函数 + int_ get_length() { + return this->size(); + } +}; + +int main() { + TestModel a {1, 2, 3, 4, 5}; + auto background_view = BackgroundView(DEFAULT_GATE_X, DEFAULT_GATE_Y); + auto queue_view = SimpleQueueView>(a, 10, 10); + // queue_view.init(); + queue_view.refresh(); + TestModel b {10, 20, 30, 40, 50}; + auto queue_view2 = SimpleQueueView>(b, 20, 50); + // queue_view2.init(); + queue_view2.refresh(); + return 0; +} \ No newline at end of file