Skip to content

Mini Projects - Dự án nhỏ thực hành

🎯 Giới thiệu

Các mini projects này giúp bạn áp dụng kiến thức C++ đã học vào các ứng dụng thực tế. Mỗi project tập trung vào một số concepts cụ thể và có độ khó tăng dần.

📝 Project 1: Máy tính console đơn giản

Mục tiêu

  • Áp dụng: Input/output, functions, switch-case
  • Độ khó: Beginner
  • Thời gian: 2-3 giờ

Yêu cầu

cpp
#include <iostream>
#include <cmath>
using namespace std;

class Calculator {
public:
    void run() {
        char operation;
        double num1, num2;
        
        cout << "=== CALCULATOR ===" << endl;
        cout << "Nhập phép tính (+ - * / ^ s q): ";
        cin >> operation;
        
        if (operation == 's' || operation == 'q') {
            cout << "Nhập số: ";
            cin >> num1;
            performUnaryOperation(operation, num1);
        } else {
            cout << "Nhập số thứ nhất: ";
            cin >> num1;
            cout << "Nhập số thứ hai: ";
            cin >> num2;
            performBinaryOperation(operation, num1, num2);
        }
    }
    
private:
    void performBinaryOperation(char op, double a, double b) {
        switch(op) {
            case '+': cout << "Kết quả: " << a + b << endl; break;
            case '-': cout << "Kết quả: " << a - b << endl; break;
            case '*': cout << "Kết quả: " << a * b << endl; break;
            case '/': 
                if (b != 0) cout << "Kết quả: " << a / b << endl;
                else cout << "Lỗi: Chia cho 0!" << endl;
                break;
            case '^': cout << "Kết quả: " << pow(a, b) << endl; break;
            default: cout << "Phép tính không hợp lệ!" << endl;
        }
    }
    
    void performUnaryOperation(char op, double a) {
        switch(op) {
            case 's': 
                if (a >= 0) cout << "Kết quả: " << sqrt(a) << endl;
                else cout << "Lỗi: Căn bậc hai của số âm!" << endl;
                break;
            case 'q': cout << "Kết quả: " << a * a << endl; break;
        }
    }
};

Mở rộng

  • Thêm history của các phép tính
  • Support cho nhiều operations liên tiếp
  • GUI đơn giản

🎮 Project 2: Game Đoán số

Mục tiêu

  • Áp dụng: Random numbers, loops, conditions
  • Độ khó: Beginner
  • Thời gian: 3-4 giờ

Yêu cầu

cpp
#include <iostream>
#include <random>
#include <vector>
using namespace std;

class NumberGuessingGame {
private:
    int secretNumber;
    int attempts;
    int maxAttempts;
    vector<int> guessHistory;
    int score;
    
public:
    NumberGuessingGame() : attempts(0), maxAttempts(7), score(100) {
        random_device rd;
        mt19937 gen(rd());
        uniform_int_distribution<> dis(1, 100);
        secretNumber = dis(gen);
    }
    
    void play() {
        cout << "🎮 GAME ĐOÁN SỐ" << endl;
        cout << "Tôi đang nghĩ một số từ 1-100. Bạn có " << maxAttempts << " lần đoán!" << endl;
        
        while (attempts < maxAttempts) {
            int guess = getPlayerGuess();
            attempts++;
            guessHistory.push_back(guess);
            
            if (guess == secretNumber) {
                cout << "🎉 Chúc mừng! Bạn đã đoán đúng!" << endl;
                cout << "Số bí mật là: " << secretNumber << endl;
                cout << "Số lần đoán: " << attempts << endl;
                cout << "Điểm số: " << score << endl;
                return;
            } else {
                score -= 10;
                if (guess < secretNumber) {
                    cout << "Quá nhỏ! ";
                } else {
                    cout << "Quá lớn! ";
                }
                cout << "Còn " << (maxAttempts - attempts) << " lần." << endl;
            }
        }
        
        cout << "😞 Hết lượt! Số bí mật là: " << secretNumber << endl;
        showStatistics();
    }
    
private:
    int getPlayerGuess() {
        int guess;
        cout << "Lần " << (attempts + 1) << " - Nhập số đoán: ";
        cin >> guess;
        return guess;
    }
    
    void showStatistics() {
        cout << "\n📊 THỐNG KÊ:" << endl;
        cout << "Lịch sử đoán: ";
        for (int g : guessHistory) {
            cout << g << " ";
        }
        cout << endl;
    }
};

📖 Project 3: Quản lý thư viện sách

Mục tiêu

  • Áp dụng: OOP, vectors, file I/O
  • Độ khó: Intermediate
  • Thời gian: 6-8 giờ

Yêu cầu

cpp
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
using namespace std;

class Book {
public:
    string title, author, isbn;
    bool isAvailable;
    
    Book(string t, string a, string i) 
        : title(t), author(a), isbn(i), isAvailable(true) {}
    
    void display() const {
        cout << "📚 " << title << " - " << author 
             << " [" << isbn << "] " 
             << (isAvailable ? "✅" : "❌") << endl;
    }
    
    string toFileString() const {
        return title + "|" + author + "|" + isbn + "|" + 
               (isAvailable ? "1" : "0");
    }
};

class Library {
private:
    vector<Book> books;
    string filename;
    
public:
    Library(string file = "library.txt") : filename(file) {
        loadFromFile();
    }
    
    ~Library() {
        saveToFile();
    }
    
    void addBook() {
        string title, author, isbn;
        cout << "Nhập tên sách: ";
        cin.ignore();
        getline(cin, title);
        cout << "Nhập tác giả: ";
        getline(cin, author);
        cout << "Nhập ISBN: ";
        getline(cin, isbn);
        
        books.emplace_back(title, author, isbn);
        cout << "✅ Đã thêm sách thành công!" << endl;
    }
    
    void displayAllBooks() {
        if (books.empty()) {
            cout << "📚 Thư viện trống!" << endl;
            return;
        }
        
        cout << "\n📚 DANH SÁCH SÁCH:" << endl;
        for (size_t i = 0; i < books.size(); i++) {
            cout << (i + 1) << ". ";
            books[i].display();
        }
    }
    
    void searchBook() {
        string keyword;
        cout << "Nhập từ khóa tìm kiếm: ";
        cin.ignore();
        getline(cin, keyword);
        
        cout << "\n🔍 KẾT QUẢ TÌM KIẾM:" << endl;
        bool found = false;
        
        for (const auto& book : books) {
            if (book.title.find(keyword) != string::npos ||
                book.author.find(keyword) != string::npos) {
                book.display();
                found = true;
            }
        }
        
        if (!found) {
            cout << "❌ Không tìm thấy sách nào!" << endl;
        }
    }
    
    void borrowBook() {
        displayAllBooks();
        if (books.empty()) return;
        
        int index;
        cout << "Nhập số thứ tự sách muốn mượn: ";
        cin >> index;
        index--; // Convert to 0-based
        
        if (index >= 0 && index < books.size()) {
            if (books[index].isAvailable) {
                books[index].isAvailable = false;
                cout << "✅ Đã mượn sách: " << books[index].title << endl;
            } else {
                cout << "❌ Sách đã được mượn!" << endl;
            }
        } else {
            cout << "❌ Số thứ tự không hợp lệ!" << endl;
        }
    }
    
    void returnBook() {
        cout << "\n📚 SÁCH ĐANG ĐƯỢC MƯỢN:" << endl;
        vector<int> borrowedIndices;
        
        for (size_t i = 0; i < books.size(); i++) {
            if (!books[i].isAvailable) {
                cout << borrowedIndices.size() + 1 << ". ";
                books[i].display();
                borrowedIndices.push_back(i);
            }
        }
        
        if (borrowedIndices.empty()) {
            cout << "📚 Không có sách nào đang được mượn!" << endl;
            return;
        }
        
        int choice;
        cout << "Nhập số thứ tự sách muốn trả: ";
        cin >> choice;
        choice--; // Convert to 0-based
        
        if (choice >= 0 && choice < borrowedIndices.size()) {
            int bookIndex = borrowedIndices[choice];
            books[bookIndex].isAvailable = true;
            cout << "✅ Đã trả sách: " << books[bookIndex].title << endl;
        } else {
            cout << "❌ Số thứ tự không hợp lệ!" << endl;
        }
    }
    
    void showMenu() {
        int choice;
        do {
            cout << "\n📚 HỆ THỐNG QUẢN LÝ THỦ VIỆN" << endl;
            cout << "1. Thêm sách" << endl;
            cout << "2. Hiển thị tất cả sách" << endl;
            cout << "3. Tìm kiếm sách" << endl;
            cout << "4. Mượn sách" << endl;
            cout << "5. Trả sách" << endl;
            cout << "0. Thoát" << endl;
            cout << "Chọn: ";
            cin >> choice;
            
            switch (choice) {
                case 1: addBook(); break;
                case 2: displayAllBooks(); break;
                case 3: searchBook(); break;
                case 4: borrowBook(); break;
                case 5: returnBook(); break;
                case 0: cout << "👋 Tạm biệt!" << endl; break;
                default: cout << "❌ Lựa chọn không hợp lệ!" << endl;
            }
        } while (choice != 0);
    }
    
private:
    void loadFromFile() {
        ifstream file(filename);
        if (!file.is_open()) return;
        
        string line;
        while (getline(file, line)) {
            // Parse line: title|author|isbn|available
            size_t pos1 = line.find('|');
            size_t pos2 = line.find('|', pos1 + 1);
            size_t pos3 = line.find('|', pos2 + 1);
            
            if (pos1 != string::npos && pos2 != string::npos && pos3 != string::npos) {
                string title = line.substr(0, pos1);
                string author = line.substr(pos1 + 1, pos2 - pos1 - 1);
                string isbn = line.substr(pos2 + 1, pos3 - pos2 - 1);
                bool available = line.substr(pos3 + 1) == "1";
                
                Book book(title, author, isbn);
                book.isAvailable = available;
                books.push_back(book);
            }
        }
        file.close();
    }
    
    void saveToFile() {
        ofstream file(filename);
        if (!file.is_open()) return;
        
        for (const auto& book : books) {
            file << book.toFileString() << endl;
        }
        file.close();
    }
};

🎲 Project 4: Game Tic-Tac-Toe

Mục tiêu

  • Áp dụng: 2D arrays, game logic, AI cơ bản
  • Độ khó: Intermediate
  • Thời gian: 4-6 giờ

Yêu cầu cơ bản

  • Board 3x3
  • 2 players hoặc vs AI
  • Check win conditions
  • Game loop

💰 Project 5: Personal Finance Tracker

Mục tiêu

  • Áp dụng: File I/O, STL containers, data analysis
  • Độ khó: Intermediate-Advanced
  • Thời gian: 8-12 giờ

Features

  • Income/expense tracking
  • Categories và tags
  • Monthly/yearly reports
  • Budget planning
  • Data visualization (text-based)

🌟 Project Guidelines

Coding Standards

  1. Naming conventions: camelCase or snake_case consistent
  2. Comments: Explain complex logic
  3. Error handling: Handle invalid inputs gracefully
  4. Code organization: Separate into functions/classes
  5. Documentation: README với instructions

Testing Checklist

  • [ ] Handle edge cases
  • [ ] Input validation
  • [ ] Memory management (no leaks)
  • [ ] File I/O error handling
  • [ ] User-friendly interface

Enhancement Ideas

  1. Add persistence: Save/load data
  2. Improve UI: Colors, formatting
  3. Add features: More functionality
  4. Optimize: Performance improvements
  5. Cross-platform: Works on different OS

🎯 Project Submission

Portfolio Building

  1. GitHub repository cho mỗi project
  2. README.md với screenshots
  3. Code comments và documentation
  4. Demo video (optional)

Learning Outcomes

  • Problem solving: Break down complex problems
  • Code organization: Structure large applications
  • Debugging skills: Find và fix issues
  • User experience: Design user-friendly interfaces
  • Version control: Git workflow

🚀 Next Steps

Sau khi hoàn thành mini projects:

  1. Code review: Tự review hoặc nhờ người khác
  2. Refactoring: Improve code quality
  3. Advanced projects: Larger applications
  4. Open source: Contribute to existing projects
  5. Team projects: Collaborate với others

Khóa học C++ miễn phí