diff --git a/.vs/ProjectSettings.json b/.vs/ProjectSettings.json new file mode 100644 index 0000000..51b37fe --- /dev/null +++ b/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "无配置" +} \ No newline at end of file diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..646abdd --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\doc", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..c8fcde3 Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/.vs/软1_薄靖驰_个人项目/v15/.suo b/.vs/软1_薄靖驰_个人项目/v15/.suo new file mode 100644 index 0000000..d832b3d Binary files /dev/null and b/.vs/软1_薄靖驰_个人项目/v15/.suo differ diff --git a/.vs/软1_薄靖驰_个人项目/v15/Browse.VC.db b/.vs/软1_薄靖驰_个人项目/v15/Browse.VC.db new file mode 100644 index 0000000..95aa9aa Binary files /dev/null and b/.vs/软1_薄靖驰_个人项目/v15/Browse.VC.db differ diff --git a/README.md b/README.md deleted file mode 100644 index ee97a14..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# MathsQuestionSystem - diff --git a/doc/readme.md b/doc/readme.md new file mode 100644 index 0000000..081e712 --- /dev/null +++ b/doc/readme.md @@ -0,0 +1,94 @@ +中小学数学卷子自动生成程序 - 使用说明 + +1.- 测试环境:Linux平台 WSL-Ubuntu + +登录验证:系统预设小学、初中、高中各3个账号,默认密码统一为“123”。 + + + +题目查重:每位教师生成的题目将进行历史查重,确保不出现重复题目。 + + + +题目生成:根据当前学段自动生成对应难度的题目,小学含四则运算及括号,初中增加乘方与开方,高中增加三角函数等内容。 + + + +身份切换:登录后支持通过输入指定指令(如“切换为初中”)实时切换题目生成所对应的学段。 + + + +文件保存:生成的题目自动保存至相应用户的专属文件夹,文件命名格式为“年-月-日-时-分-秒.txt”。 + +3\. 预设账号 + +| 学段 | 用户名 | 密码 | + +|--------|------|------| + +| 小学 | 张三 1 | 123 | + +| 小学 | 张三 2 | 123 | + +| 小学 | 张三 3 | 123 | + +| 初中 | 李四 1 | 123 | + +| 初中 | 李四 2 | 123 | + +| 初中 | 李四 3 | 123 | + +| 高中 | 王五 1 | 123 | + +| 高中 | 王五 2 | 123 | + +| 高中 | 王五 3 | 123 | + + + +4\. 使用步骤 + +1. 登录:输入“用户名 密码”,登录成功后显示当前学段。 + +2. 生成题目:输入10-30的数字,程序自动生成并保存题目。 + +3. 切换学段:输入“切换为初中”,切换后可生成对应学段题目。 + +4. 退出登录:输入-1,返回登录界面。 + + + +5\. 注意事项 + + 题目数量仅支持10-30,输入其他数字(除-1外)会提示重试。 + + 生成的题目保存在项目根目录./src/exams下的用户文件夹中,请勿手动删除 + + 切换学段时需严格按照“切换为小学/初中/高中”格式输入,否则提示无效。 + + + + 6. 功能说明 + + 切换功能示例展示: + + 请输入用户名和密码(用空格隔开)输入exit退出: 张三1 123 + + 当前选择为小学出题 + + 准备生成小学数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)或输入‘切换为XX(XX包括小学,初中,高中三个)’: 切换为初中 + + 准备生成初中数学题目,请输入生成题目数量: 准备生成初中数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)或输入‘切换为XX(XX包括小学,初中,高中三个)’: 切换为高中 + + 准备生成高中数学题目,请输入生成题目数量: 准备生成高中数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)或输入‘切换为XX(XX包括小学,初中,高中三个)’: 30 + + 题目已生成并保存到: ./exams/张三1/2025-09-26-13-09-55.txt + + 准备生成高中数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)或输入‘切换为XX(XX包括小学,初中,高中三个)’: 30 + + 题目已生成并保存到: ./exams/张三1/2025-09-26-13-09-59.txt + + 准备生成高中数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)或输入‘切换为XX(XX包括小学,初中,高中三个)’: -1 + + 请输入用户名和密码(用空格隔开)输入exit退出: exit + diff --git a/src/FileManager.cpp b/src/FileManager.cpp new file mode 100644 index 0000000..83b23b9 --- /dev/null +++ b/src/FileManager.cpp @@ -0,0 +1,45 @@ +#include "FileManager.h" +#include +#include +#include +#include +#include + +using namespace std; + +FileManager::FileManager() {} + +bool FileManager::saveQuestions(const vector& questions, const string& username, const UserType& type) { + string filename = username + "_" + getCurrentTimestamp() + ".txt"; + + ofstream file(filename.c_str()); + if (!file.is_open()) { + cout << "޷ļ: " << filename << endl; + return false; + } + + for (size_t i = 0; i < questions.size(); i++) { + file << (i + 1) << ". " << questions[i] << endl; + if (i < questions.size() - 1) { + file << endl; + } + } + + file.close(); + cout << "Ŀѱ浽: " << filename << endl; + return true; +} + +vector FileManager::loadExistingQuestions(const string& username) { + return vector(); +} + +string FileManager::getCurrentTimestamp() const { + time_t now = time(NULL); + struct tm* tstruct = localtime(&now); + + char buf[80]; + strftime(buf, sizeof(buf), "%Y-%m-%d-%H-%M-%S", tstruct); + + return string(buf); +} diff --git a/src/FileManager.h b/src/FileManager.h new file mode 100644 index 0000000..88ef391 --- /dev/null +++ b/src/FileManager.h @@ -0,0 +1,20 @@ +#ifndef FILEMANAGER_H +#define FILEMANAGER_H + +#include "IFileManager.h" +#include +#include + +class FileManager : public IFileManager { +public: + FileManager(); + virtual ~FileManager() {} + + virtual bool saveQuestions(const std::vector& questions, const std::string& username, const UserType& type); + virtual std::vector loadExistingQuestions(const std::string& username); + +private: + std::string getCurrentTimestamp() const; +}; + +#endif diff --git a/src/FileManager.o b/src/FileManager.o new file mode 100644 index 0000000..736ef58 Binary files /dev/null and b/src/FileManager.o differ diff --git a/src/IFileManager.h b/src/IFileManager.h new file mode 100644 index 0000000..17f11d5 --- /dev/null +++ b/src/IFileManager.h @@ -0,0 +1,15 @@ +#ifndef IFILEMANAGER_H +#define IFILEMANAGER_H + +#include +#include +#include "UserType.h" + +class IFileManager { +public: + virtual ~IFileManager() {} + virtual bool saveQuestions(const std::vector& questions, const std::string& username, const UserType& type) = 0; + virtual std::vector loadExistingQuestions(const std::string& username) = 0; +}; + +#endif diff --git a/src/IQuestionGenerator.h b/src/IQuestionGenerator.h new file mode 100644 index 0000000..92b674d --- /dev/null +++ b/src/IQuestionGenerator.h @@ -0,0 +1,15 @@ +#ifndef IQUESTIONGENERATOR_H +#define IQUESTIONGENERATOR_H + +#include +#include +#include "UserType.h" + +class IQuestionGenerator { +public: + virtual ~IQuestionGenerator() {} + virtual std::vector generateQuestions(const UserType& type, int count, const std::string& username) = 0; + virtual void addExistingQuestions(const std::vector& questions) = 0; +}; + +#endif diff --git a/src/IUserManager.h b/src/IUserManager.h new file mode 100644 index 0000000..1bb8450 --- /dev/null +++ b/src/IUserManager.h @@ -0,0 +1,18 @@ +#ifndef IUSERMANAGER_H +#define IUSERMANAGER_H + +#include +#include "UserType.h" + +class IUserManager { +public: + virtual ~IUserManager() {} + + virtual bool authenticate(const std::string& username, const std::string& password) = 0; + virtual UserType getCurrentUserType() const = 0; + virtual std::string getCurrentUsername() const = 0; + virtual void logout() = 0; + virtual bool isLoggedIn() const = 0; +}; + +#endif diff --git a/src/Makefile.win b/src/Makefile.win new file mode 100644 index 0000000..8ed1faa --- /dev/null +++ b/src/Makefile.win @@ -0,0 +1,49 @@ +# Project: Ŀ1 +# Makefile created by Dev-C++ 5.11 + +CPP = g++.exe +CC = gcc.exe +WINDRES = windres.exe +OBJ = QuestionGenerator.o UserManager.o User.o UserType.o FileManager.o main.o QuestionChecker.o SessionManager.o +LINKOBJ = QuestionGenerator.o UserManager.o User.o UserType.o FileManager.o main.o QuestionChecker.o SessionManager.o +LIBS = -L"D://Dev-Cpp/MinGW64/lib" -L"D://Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc +INCS = -I"D://Dev-Cpp/MinGW64/include" -I"D://Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D://Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" +CXXINCS = -I"D://Dev-Cpp/MinGW64/include" -I"D://Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"D://Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"D://Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" +BIN = test.exe +CXXFLAGS = $(CXXINCS) +CFLAGS = $(INCS) +RM = rm.exe -f + +.PHONY: all all-before all-after clean clean-custom + +all: all-before $(BIN) all-after + +clean: clean-custom + ${RM} $(OBJ) $(BIN) + +$(BIN): $(OBJ) + $(CPP) $(LINKOBJ) -o $(BIN) $(LIBS) + +QuestionGenerator.o: QuestionGenerator.cpp + $(CPP) -c QuestionGenerator.cpp -o QuestionGenerator.o $(CXXFLAGS) + +UserManager.o: UserManager.cpp + $(CPP) -c UserManager.cpp -o UserManager.o $(CXXFLAGS) + +User.o: User.cpp + $(CPP) -c User.cpp -o User.o $(CXXFLAGS) + +UserType.o: UserType.cpp + $(CPP) -c UserType.cpp -o UserType.o $(CXXFLAGS) + +FileManager.o: FileManager.cpp + $(CPP) -c FileManager.cpp -o FileManager.o $(CXXFLAGS) + +main.o: main.cpp + $(CPP) -c main.cpp -o main.o $(CXXFLAGS) + +QuestionChecker.o: QuestionChecker.cpp + $(CPP) -c QuestionChecker.cpp -o QuestionChecker.o $(CXXFLAGS) + +SessionManager.o: SessionManager.cpp + $(CPP) -c SessionManager.cpp -o SessionManager.o $(CXXFLAGS) diff --git a/src/QuestionChecker.cpp b/src/QuestionChecker.cpp new file mode 100644 index 0000000..f79c414 --- /dev/null +++ b/src/QuestionChecker.cpp @@ -0,0 +1,34 @@ +#include "QuestionChecker.h" +#include + +QuestionChecker::QuestionChecker(IFileManager* file_manager) + : file_manager_(file_manager) {} + +bool QuestionChecker::isDuplicate(const std::string& question, const std::string& username) { + // 鱾λỰǷظ + if (current_session_questions_.find(question) != current_session_questions_.end()) { + return true; + } + + std::vector history_questions = file_manager_->loadExistingQuestions(username); + for (std::vector::iterator it = history_questions.begin(); + it != history_questions.end(); ++it) { + if (*it == question) { + return true; + } + } + + return false; +} + +void QuestionChecker::addGeneratedQuestion(const std::string& question, const std::string& username) { + current_session_questions_.insert(question); +} + +void QuestionChecker::clearUserCache(const std::string& username) { + current_session_questions_.clear(); +} + +int QuestionChecker::getUserQuestionCount(const std::string& username) const { + return current_session_questions_.size(); +} diff --git a/src/QuestionChecker.h b/src/QuestionChecker.h new file mode 100644 index 0000000..05dba9f --- /dev/null +++ b/src/QuestionChecker.h @@ -0,0 +1,23 @@ +#ifndef QUESTIONCHECKER_H +#define QUESTIONCHECKER_H + +#include +#include +#include +#include "IFileManager.h" + +class QuestionChecker { +public: + QuestionChecker(IFileManager* file_manager); + + bool isDuplicate(const std::string& question, const std::string& username); + void addGeneratedQuestion(const std::string& question, const std::string& username); + void clearUserCache(const std::string& username); + int getUserQuestionCount(const std::string& username) const; + +private: + IFileManager* file_manager_; + std::set current_session_questions_; +}; + +#endif diff --git a/src/QuestionChecker.o b/src/QuestionChecker.o new file mode 100644 index 0000000..7785e8f Binary files /dev/null and b/src/QuestionChecker.o differ diff --git a/src/QuestionGenerator.cpp b/src/QuestionGenerator.cpp new file mode 100644 index 0000000..d099afb --- /dev/null +++ b/src/QuestionGenerator.cpp @@ -0,0 +1,103 @@ +#include "QuestionGenerator.h" +#include +#include +#include +#include + +using namespace std; + +QuestionGenerator::QuestionGenerator() { + srand(static_cast(time(NULL))); +} + +vector QuestionGenerator::generateQuestions(const UserType& type, int count, const string& username) { + vector questions; + + for (int i = 0; i < count; ) { + string question; + + if (type == UserType::PRIMARY) { + question = generatePrimaryQuestion(); + } else if (type == UserType::JUNIOR) { + question = generateJuniorQuestion(); + } else if (type == UserType::SENIOR) { + question = generateSeniorQuestion(); + } + + // أǷѴ + if (existingQuestions.find(question) == existingQuestions.end()) { + questions.push_back(question); + existingQuestions.insert(question); + i++; + } + } + + return questions; +} + +void QuestionGenerator::addExistingQuestions(const vector& questions) { + for (size_t i = 0; i < questions.size(); i++) { + existingQuestions.insert(questions[i]); + } +} + +string QuestionGenerator::generatePrimaryQuestion() { + int operandCount = 2 + rand() % 3; // 2-4 + stringstream ss; + + for (int i = 0; i < operandCount; i++) { + ss << (rand() % 100 + 1); + if (i < operandCount - 1) { + char ops[] = {'+', '-', '*', '/'}; + ss << " " << ops[rand() % 4] << " "; + } + } + ss << " = "; + return ss.str(); +} + +string QuestionGenerator::generateJuniorQuestion() { + stringstream ss; + + // ȷһƽ򿪸 + if (rand() % 2 == 0) { + ss << (rand() % 20 + 1) << "ƽ"; + } else { + ss << "" << (rand() % 100 + 1); + } + + // ͨ + if (rand() % 2 == 0) { + char ops[] = {'+', '-', '*', '/'}; + ss << " " << ops[rand() % 4] << " " << (rand() % 100 + 1); + } + + ss << " = "; + return ss.str(); +} + +string QuestionGenerator::generateSeniorQuestion() { + stringstream ss; + + // ȷһǺ + const char* trig[] = {"sin", "cos", "tan"}; + ss << trig[rand() % 3] << "(" << (rand() % 100) << ")"; + + // ͨ + if (rand() % 2 == 0) { + char ops[] = {'+', '-', '*', '/'}; + ss << " " << ops[rand() % 4] << " " << (rand() % 100 + 1); + } + + ss << " = "; + return ss.str(); +} + +int QuestionGenerator::getRandomNumber(int min, int max) { + return rand() % (max - min + 1) + min; +} + +char QuestionGenerator::getRandomOperator() { + char operators[] = {'+', '-', '*', '/'}; + return operators[rand() % 4]; +} diff --git a/src/QuestionGenerator.h b/src/QuestionGenerator.h new file mode 100644 index 0000000..79784cc --- /dev/null +++ b/src/QuestionGenerator.h @@ -0,0 +1,26 @@ +#ifndef QUESTIONGENERATOR_H +#define QUESTIONGENERATOR_H + +#include "IQuestionGenerator.h" +#include +#include + +class QuestionGenerator : public IQuestionGenerator { +public: + QuestionGenerator(); + virtual ~QuestionGenerator() {} + + virtual std::vector generateQuestions(const UserType& type, int count, const std::string& username); + virtual void addExistingQuestions(const std::vector& questions); + +private: + std::string generatePrimaryQuestion(); + std::string generateJuniorQuestion(); + std::string generateSeniorQuestion(); + int getRandomNumber(int min, int max); + char getRandomOperator(); + + std::set existingQuestions; +}; + +#endif diff --git a/src/QuestionGenerator.o b/src/QuestionGenerator.o new file mode 100644 index 0000000..31fcf19 Binary files /dev/null and b/src/QuestionGenerator.o differ diff --git a/src/SessionManager.cpp b/src/SessionManager.cpp new file mode 100644 index 0000000..ceb2742 --- /dev/null +++ b/src/SessionManager.cpp @@ -0,0 +1,75 @@ +#include "SessionManager.h" +#include + +SessionManager::SessionManager(IUserManager* user_manager, + IQuestionGenerator* question_generator, + QuestionChecker* question_checker) + : user_manager_(user_manager), + question_generator_(question_generator), + question_checker_(question_checker), + current_type_(UserType::PRIMARY), // ʹþUserTypeʼ + type_switched_(false) {} + +bool SessionManager::switchUserType(const std::string& target_type) { + if (target_type == "Сѧ") { + current_type_ = UserType::PRIMARY; + type_switched_ = true; + std::cout << "лСѧģʽ" << std::endl; + return true; + } else if (target_type == "") { + current_type_ = UserType::JUNIOR; + type_switched_ = true; + std::cout << "лгģʽ" << std::endl; + return true; + } else if (target_type == "") { + current_type_ = UserType::SENIOR; + type_switched_ = true; + std::cout << "лгģʽ" << std::endl; + return true; + } + std::cout << "лʧܣ'Сѧ'''''" << std::endl; + return false; +} + +UserType SessionManager::getCurrentUserType() const { + if (type_switched_) { + return current_type_; + } + return user_manager_->getCurrentUserType(); +} + +std::string SessionManager::getCurrentUsername() const { + return user_manager_->getCurrentUsername(); +} + +bool SessionManager::isLoggedIn() const { + return user_manager_->isLoggedIn(); +} + +bool SessionManager::login(const std::string& username, const std::string& password) { + type_switched_ = false; + return user_manager_->authenticate(username, password); +} + +void SessionManager::logout() { + type_switched_ = false; + user_manager_->logout(); + question_checker_->clearUserCache(getCurrentUsername()); +} + +std::vector SessionManager::generateQuestions(int count) { + std::vector valid_questions; + std::string username = getCurrentUsername(); + UserType type = getCurrentUserType(); + + // ֱĿQuestionGeneratorڲIJ + valid_questions = question_generator_->generateQuestions(type, count, username); + + // ¼ + for (std::vector::iterator it = valid_questions.begin(); + it != valid_questions.end(); ++it) { + question_checker_->addGeneratedQuestion(*it, username); + } + + return valid_questions; +} diff --git a/src/SessionManager.h b/src/SessionManager.h new file mode 100644 index 0000000..51b6957 --- /dev/null +++ b/src/SessionManager.h @@ -0,0 +1,30 @@ +#ifndef SESSIONMANAGER_H +#define SESSIONMANAGER_H + +#include +#include "UserType.h" +#include "IUserManager.h" +#include "IQuestionGenerator.h" +#include "QuestionChecker.h" + +class SessionManager { +public: + SessionManager(IUserManager* user_manager, IQuestionGenerator* question_generator, QuestionChecker* question_checker); + + bool switchUserType(const std::string& target_type); + UserType getCurrentUserType() const; + std::string getCurrentUsername() const; + bool isLoggedIn() const; + bool login(const std::string& username, const std::string& password); + void logout(); + std::vector generateQuestions(int count); + +private: + IUserManager* user_manager_; + IQuestionGenerator* question_generator_; + QuestionChecker* question_checker_; + UserType current_type_; + bool type_switched_; +}; + +#endif diff --git a/src/SessionManager.o b/src/SessionManager.o new file mode 100644 index 0000000..2669a07 Binary files /dev/null and b/src/SessionManager.o differ diff --git a/src/User.cpp b/src/User.cpp new file mode 100644 index 0000000..13b0178 --- /dev/null +++ b/src/User.cpp @@ -0,0 +1,8 @@ +#include "User.h" + +User::User(const std::string& username, const std::string& password, const UserType& type) + : username(username), password(password), type(type) {} + +bool User::authenticate(const std::string& inputPassword) const { + return password == inputPassword; +} diff --git a/src/User.h b/src/User.h new file mode 100644 index 0000000..ae963ea --- /dev/null +++ b/src/User.h @@ -0,0 +1,23 @@ +#ifndef USER_H +#define USER_H + +#include +#include "UserType.h" + +class User { +public: + User(const std::string& username, const std::string& password, const UserType& type); + + std::string getUsername() const { return username; } + std::string getPassword() const { return password; } + UserType getType() const { return type; } + + bool authenticate(const std::string& inputPassword) const; + +private: + std::string username; + std::string password; + UserType type; +}; + +#endif diff --git a/src/User.o b/src/User.o new file mode 100644 index 0000000..39bb0b7 Binary files /dev/null and b/src/User.o differ diff --git a/src/UserManager.cpp b/src/UserManager.cpp new file mode 100644 index 0000000..3e72c09 --- /dev/null +++ b/src/UserManager.cpp @@ -0,0 +1,53 @@ +#include "UserManager.h" +#include + +UserManager::UserManager() : currentUser(NULL), loggedIn(false) { + initializeUsers(); +} + +void UserManager::initializeUsers() { + presetUsers.push_back(User("1", "123", UserType::PRIMARY)); + presetUsers.push_back(User("2", "123", UserType::PRIMARY)); + presetUsers.push_back(User("3", "123", UserType::PRIMARY)); + presetUsers.push_back(User("1", "123", UserType::JUNIOR)); + presetUsers.push_back(User("2", "123", UserType::JUNIOR)); + presetUsers.push_back(User("3", "123", UserType::JUNIOR)); + presetUsers.push_back(User("1", "123", UserType::SENIOR)); + presetUsers.push_back(User("2", "123", UserType::SENIOR)); + presetUsers.push_back(User("3", "123", UserType::SENIOR)); +} + +bool UserManager::authenticate(const std::string& username, const std::string& password) { + for (size_t i = 0; i < presetUsers.size(); i++) { + if (presetUsers[i].getUsername() == username && + presetUsers[i].authenticate(password)) { + currentUser = &presetUsers[i]; + loggedIn = true; + return true; + } + } + return false; +} + +UserType UserManager::getCurrentUserType() const { + if (currentUser) { + return currentUser->getType(); + } + return UserType::PRIMARY; +} + +std::string UserManager::getCurrentUsername() const { + if (currentUser) { + return currentUser->getUsername(); + } + return ""; +} + +void UserManager::logout() { + currentUser = NULL; + loggedIn = false; +} + +bool UserManager::isLoggedIn() const { + return loggedIn; +} diff --git a/src/UserManager.h b/src/UserManager.h new file mode 100644 index 0000000..a6f0ead --- /dev/null +++ b/src/UserManager.h @@ -0,0 +1,27 @@ +#ifndef USERMANAGER_H +#define USERMANAGER_H + +#include "IUserManager.h" +#include +#include "User.h" + +class UserManager : public IUserManager { +public: + UserManager(); + virtual ~UserManager() {} + + virtual bool authenticate(const std::string& username, const std::string& password); + virtual UserType getCurrentUserType() const; + virtual std::string getCurrentUsername() const; + virtual void logout(); + virtual bool isLoggedIn() const; + +private: + std::vector presetUsers; + const User* currentUser; + bool loggedIn; + + void initializeUsers(); +}; + +#endif diff --git a/src/UserManager.o b/src/UserManager.o new file mode 100644 index 0000000..c5daec9 Binary files /dev/null and b/src/UserManager.o differ diff --git a/src/UserType.cpp b/src/UserType.cpp new file mode 100644 index 0000000..a5c1dce --- /dev/null +++ b/src/UserType.cpp @@ -0,0 +1,5 @@ +#include "UserType.h" + +const UserType UserType::PRIMARY(0, "Сѧ"); +const UserType UserType::JUNIOR(1, ""); +const UserType UserType::SENIOR(2, ""); diff --git a/src/UserType.h b/src/UserType.h new file mode 100644 index 0000000..cb2ef79 --- /dev/null +++ b/src/UserType.h @@ -0,0 +1,28 @@ +#ifndef USERTYPE_H +#define USERTYPE_H + +#include + +class UserType { +public: + static const UserType PRIMARY; + static const UserType JUNIOR; + static const UserType SENIOR; + + UserType() : value(-1), name("δ֪") {} // ĬϹ캯 + UserType(const UserType& other) : value(other.value), name(other.name) {} + + std::string getName() const { return name; } + int getValue() const { return value; } + + bool operator==(const UserType& other) const { return value == other.value; } + bool operator!=(const UserType& other) const { return value != other.value; } + +private: + UserType(int val, const std::string& n) : value(val), name(n) {} + + int value; + std::string name; +}; + +#endif diff --git a/src/UserType.o b/src/UserType.o new file mode 100644 index 0000000..442f9ae Binary files /dev/null and b/src/UserType.o differ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e327754 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include "IUserManager.h" +#include "IQuestionGenerator.h" +#include "IFileManager.h" +#include "QuestionChecker.h" +#include "SessionManager.h" +#include "UserManager.h" +#include "QuestionGenerator.h" +#include "FileManager.h" + +using namespace std; + +bool isNumber(const string& str); +int stringToInt(const string& str); +void displayWelcome(); +void handleLogin(SessionManager* session_manager); +void displayMainMenu(); +void handleGenerateQuestions(SessionManager* session_manager, IFileManager* file_manager); +void handleSwitchType(SessionManager* session_manager); +void handleUserChoice(SessionManager* session_manager, IFileManager* file_manager, const string& choice); +void cleanupResources(SessionManager* session_manager, QuestionChecker* question_checker, + IFileManager* file_manager, IQuestionGenerator* question_generator, + IUserManager* user_manager); + + +bool isNumber(const string& str) { + if (str.empty()) return false; + for (size_t i = 0; i < str.length(); i++) { + if (!isdigit(str[i]) && !(i == 0 && str[i] == '-')) { + return false; + } + } + return true; +} + +int stringToInt(const string& str) { + int result = 0; + int sign = 1; + size_t start = 0; + + if (str[0] == '-') { + sign = -1; + start = 1; + } + + for (size_t i = start; i < str.length(); i++) { + if (str[i] >= '0' && str[i] <= '9') { + result = result * 10 + (str[i] - '0'); + } + } + + return result * sign; +} + +void displayWelcome() { + cout << "СѧѧԶɳ" << endl; + cout << "=================================" << endl; +} + +void handleLogin(SessionManager* session_manager) { + string username, password; + cout << "û루ÿո: "; + cin >> username >> password; + + if (session_manager->login(username, password)) { + UserType current_type = session_manager->getCurrentUserType(); + cout << "¼ɹǰѡΪ" << current_type.getName() << "" << endl; + } else { + cout << "ȷû" << endl; + } +} + +void displayMainMenu() { + cout << "\nѡ:" << endl; + cout << "1. Ŀ" << endl; + cout << "2. л" << endl; + cout << "3. ˳" << endl; + cout << "-1. ˳ǰû" << endl; + cout << "ѡ: "; +} + +void displayCurrentStatus(SessionManager* session_manager, QuestionChecker* question_checker) { + cout << "\nǰû: " << session_manager->getCurrentUsername() << endl; + cout << "ǰ: " << session_manager->getCurrentUserType().getName() << endl; + cout << "Ŀ: " << question_checker->getUserQuestionCount( + session_manager->getCurrentUsername()) << "" << endl; +} + +void handleGenerateQuestions(SessionManager* session_manager, IFileManager* file_manager) { + cout << "׼" << session_manager->getCurrentUserType().getName() + << "ѧĿĿ10-30: "; + string input; + cin >> input; + + if (!isNumber(input)) { + cout << "Ч" << endl; + return; + } + + int count = stringToInt(input); + if (count < 10 || count > 30) { + cout << "ĿӦ1030֮" << endl; + return; + } + + vector questions = session_manager->generateQuestions(count); + + if (file_manager->saveQuestions(questions, session_manager->getCurrentUsername(), + session_manager->getCurrentUserType())) { + cout << "ɹ" << questions.size() << "ظ" + << session_manager->getCurrentUserType().getName() << "ѧĿ" << endl; + + if (questions.size() < (size_t)count) { + cout << "ע⣺Ŀظʵ" << questions.size() + << "ĿҪ" << count << "" << endl; + } + } +} + +void handleSwitchType(SessionManager* session_manager) { + cout << "ҪлͣСѧ//У: "; + string target_type; + cin >> target_type; + session_manager->switchUserType(target_type); +} + +void handleUserChoice(SessionManager* session_manager, IFileManager* file_manager, + QuestionChecker* question_checker, const string& choice) { + if (choice == "1") { + handleGenerateQuestions(session_manager, file_manager); + } + else if (choice == "2") { + handleSwitchType(session_manager); + } + else if (choice == "-1") { + session_manager->logout(); + cout << "˳ǰû" << endl; + } + else if (choice == "3") { + cout << "лʹãټ" << endl; + exit(0); + } + else { + cout << "Чѡ" << endl; + } +} + +void cleanupResources(SessionManager* session_manager, QuestionChecker* question_checker, + IFileManager* file_manager, IQuestionGenerator* question_generator, + IUserManager* user_manager) { + delete session_manager; + delete question_checker; + delete file_manager; + delete question_generator; + delete user_manager; +} + +int main() { + // + IUserManager* user_manager = new UserManager(); + IQuestionGenerator* question_generator = new QuestionGenerator(); + IFileManager* file_manager = new FileManager(); + QuestionChecker* question_checker = new QuestionChecker(file_manager); + SessionManager* session_manager = new SessionManager(user_manager, question_generator, question_checker); + + displayWelcome(); + + // ѭ + while (true) { + if (!session_manager->isLoggedIn()) { + handleLogin(session_manager); + continue; + } + + displayCurrentStatus(session_manager, question_checker); + displayMainMenu(); + + string choice; + cin >> choice; + + handleUserChoice(session_manager, file_manager, question_checker, choice); + } + + cleanupResources(session_manager, question_checker, file_manager, question_generator, user_manager); + return 0; +} diff --git a/src/main.o b/src/main.o new file mode 100644 index 0000000..d9459fc Binary files /dev/null and b/src/main.o differ diff --git a/src/test.dev b/src/test.dev new file mode 100644 index 0000000..e0796d2 --- /dev/null +++ b/src/test.dev @@ -0,0 +1,232 @@ +[Project] +FileName=test.dev +Name=Ŀ1 +Type=1 +Ver=2 +ObjFiles= +Includes= +Libs= +PrivateResource= +ResourceIncludes= +MakeIncludes= +Compiler= +CppCompiler= +Linker= +IsCpp=1 +Icon= +ExeOutput= +ObjectOutput= +LogOutput= +LogOutputEnabled=0 +OverrideOutput=0 +OverrideOutputName= +HostApplication= +UseCustomMakefile=0 +CustomMakefile= +CommandLine= +Folders= +IncludeVersionInfo=0 +SupportXPThemes=0 +CompilerSet=0 +CompilerSettings=0000000000000000000000000 +UnitCount=18 + +[VersionInfo] +Major=1 +Minor=0 +Release=0 +Build=0 +LanguageID=1033 +CharsetID=1252 +CompanyName= +FileVersion= +FileDescription=Developed using the Dev-C++ IDE +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion= +AutoIncBuildNr=0 +SyncProduct=1 + +[Unit8] +FileName=UserType.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit7] +FileName=UserType.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit6] +FileName=User.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit5] +FileName=User.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit4] +FileName=UserManager.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit3] +FileName=UserManager.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit2] +FileName=QuestionGenerator.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit1] +FileName=QuestionGenerator.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit9] +FileName=FileManager.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit10] +FileName=FileManager.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit11] +FileName=main.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit12] +FileName=IQuestionGenerator.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit13] +FileName=IFileManager.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit14] +FileName=IUserManager.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit15] +FileName=QuestionChecker.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit16] +FileName=QuestionChecker.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit17] +FileName=SessionManager.h +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit18] +FileName=SessionManager.cpp +CompileCpp=1 +Folder= +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/test.exe b/src/test.exe new file mode 100644 index 0000000..d352199 Binary files /dev/null and b/src/test.exe differ diff --git a/src/test.layout b/src/test.layout new file mode 100644 index 0000000..e21361f --- /dev/null +++ b/src/test.layout @@ -0,0 +1,93 @@ +[Editors] +Order=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17 +Focused=17 +[Editor_0] +CursorCol=5 +CursorRow=61 +TopLine=1 +LeftChar=1 +[Editor_1] +CursorCol=7 +CursorRow=26 +TopLine=1 +LeftChar=1 +[Editor_2] +CursorCol=2 +CursorRow=53 +TopLine=1 +LeftChar=1 +[Editor_3] +CursorCol=7 +CursorRow=27 +TopLine=1 +LeftChar=1 +[Editor_4] +CursorCol=2 +CursorRow=8 +TopLine=1 +LeftChar=1 +[Editor_5] +CursorCol=7 +CursorRow=23 +TopLine=1 +LeftChar=1 +[Editor_6] +CursorCol=44 +CursorRow=5 +TopLine=1 +LeftChar=1 +[Editor_7] +CursorCol=3 +CursorRow=26 +TopLine=1 +LeftChar=1 +[Editor_8] +CursorCol=7 +CursorRow=20 +TopLine=1 +LeftChar=1 +[Editor_9] +CursorCol=76 +CursorRow=33 +TopLine=3 +LeftChar=1 +[Editor_10] +CursorCol=2 +CursorRow=190 +TopLine=158 +LeftChar=1 +[Editor_11] +CursorCol=7 +CursorRow=15 +TopLine=1 +LeftChar=1 +[Editor_12] +CursorCol=7 +CursorRow=15 +TopLine=1 +LeftChar=1 +[Editor_13] +CursorCol=7 +CursorRow=18 +TopLine=1 +LeftChar=1 +[Editor_16] +CursorCol=7 +CursorRow=30 +TopLine=1 +LeftChar=1 +[Editor_17] +CursorCol=1 +CursorRow=12 +TopLine=1 +LeftChar=1 +[Editor_15] +CursorCol=1 +CursorRow=23 +TopLine=1 +LeftChar=1 +[Editor_14] +CursorCol=7 +CursorRow=23 +TopLine=1 +LeftChar=1 diff --git a/软件工程导论-个人项目需求-2025.docx b/软件工程导论-个人项目需求-2025.docx new file mode 100644 index 0000000..5782b70 Binary files /dev/null and b/软件工程导论-个人项目需求-2025.docx differ