0

dò mìn

đã đăng vào 26, Tháng 7, 2026, 12:28

include <iostream>

include

include <ctime>

include <cstdlib>

include <iomanip>

using namespace std;

// Cấu hình kích thước bàn cờ và số mìn const int BOARDSIZE = 9; const int TOTALMINES = 10;

// Các ký tự hiển thị const char CELLHIDDEN = '#'; const char CELLMINE = '*'; const char CELL_FLAG = 'F';

// Cấu trúc một ô trên bàn cờ struct Cell { bool isMine = false; bool isRevealed = false; bool isFlagged = false; int neighborMines = 0; };

Cell board[BOARDSIZE][BOARDSIZE]; bool gameOver = false; bool gameWon = false;

// Hàm kiểm tra tọa độ có hợp lệ không bool isValid(int r, int c) { return (r >= 0 && r < BOARDSIZE && c >= 0 && c < BOARDSIZE); }

// Khởi tạo bàn cờ và rải mìn ngẫu nhiên void Setup() { srand(time(0)); gameOver = false; gameWon = false;

// 1. Rải mìn ngẫu nhiên
int minesPlaced = 0;
while (minesPlaced < TOTAL_MINES) {
    int r = rand() % BOARD_SIZE;
    int c = rand() % BOARD_SIZE;
    if (!board[r][c].isMine) {
        board[r][c].isMine = true;
        minesPlaced++;
    }
}

// 2. Tính số mìn xung quanh mỗi ô
for (int r = 0; r < BOARD_SIZE; r++) {
    for (int c = 0; c < BOARD_SIZE; c++) {
        if (board[r][c].isMine) continue;

        int count = 0;
        // Duyệt 8 ô xung quanh
        for (int dr = -1; dr <= 1; dr++) {
            for (int dc = -1; dc <= 1; dc++) {
                if (isValid(r + dr, c + dc) && board[r + dr][c + dc].isMine) {
                    count++;
                }
            }
        }
        board[r][c].neighborMines = count;
    }
}

}

// Vẽ bàn cờ ra màn hình void Draw() { system("cls"); // Xóa màn hình cũ để cập nhật giao diện mới cout << " GAME DO MIN (MINESWEEPER)\n\n";

// In chỉ số cột
cout << "    ";
for (int c = 0; c < BOARD_SIZE; c++) cout << c << " ";
cout << "\n   ";
for (int c = 0; c < BOARD_SIZE; c++) cout << "--";
cout << "\n";

// In từng hàng của bàn cờ
for (int r = 0; r < BOARD_SIZE; r++) {
    cout << r << " | "; // In chỉ số hàng
    for (int c = 0; c < BOARD_SIZE; c++) {
        if (board[r][c].isRevealed) {
            if (board[r][c].isMine) {
                cout << CELL_MINE << " ";
            } else if (board[r][c].neighborMines == 0) {
                cout << ". " ; // Ô trống không có mìn xung quanh
            } else {
                cout << board[r][c].neighborMines << " ";
            }
        } else if (board[r][c].isFlagged) {
            cout << CELL_FLAG << " ";
        } else {
            // Nếu thua game, hiển thị toàn bộ mìn ẩn cho người chơi xem
            if (gameOver && board[r][c].isMine) {
                cout << CELL_MINE << " ";
            } else {
                cout << CELL_HIDDEN << " ";
            }
        }
    }
    cout << "\n";
}
cout << "\nSo min can tim: " << TOTAL_MINES << "\n";

}

// Thuật toán Đệ quy Loang (Flood Fill) để mở các ô trống lân cận void RevealCell(int r, int c) { if (!isValid(r, c) || board[r][c].isRevealed || board[r][c].isFlagged) return;

board[r][c].isRevealed = true;

// Nếu ô đó không có mìn xung quanh, tự động loang ra 8 ô bên cạnh
if (board[r][c].neighborMines == 0 && !board[r][c].isMine) {
    for (int dr = -1; dr <= 1; dr++) {
        for (int dc = -1; dc <= 1; dc++) {
            if (dr != 0 || dc != 0) {
                RevealCell(r + dr, c + dc);
            }
        }
    }
}

}

// Kiểm tra xem người chơi đã mở hết các ô an toàn chưa bool CheckWin() { for (int r = 0; r < BOARDSIZE; r++) { for (int c = 0; c < BOARDSIZE; c++) { // Nếu vẫn còn ô không phải mìn mà chưa được mở -> Chưa thắng if (!board[r][c].isMine && !board[r][c].isRevealed) { return false; } } } return true; }

// Xử lý lượt chơi của người dùng void Input() { int r, c; char action; cout << "Nhap hanh dong (M: Mo o, C: Cam co) va Toa do (Hang Cot).\n"; cout << "Vi du: M 3 4 (de mo o hang 3 cot 4): "; cin >> action >> r >> c;

if (!isValid(r, c)) {
    cout << "Toa do khong hop le! Nhan phim bat ky de thu lai...";
    cin.ignore(); cin.get();
    return;
}

if (action == 'M' || action == 'm') {
    if (board[r][c].isFlagged) return; // Không cho mở ô đang cắm cờ

    if (board[r][c].isMine) {
        board[r][c].isRevealed = true;
        gameOver = true; // Dẫm phải mìn -> Thua cuộc
    } else {
        RevealCell(r, c);
        if (CheckWin()) gameWon = true;
    }
} 
else if (action == 'C' || action == 'c') {
    if (!board[r][c].isRevealed) {
        board[r][c].isFlagged = !board[r][c].isFlagged; // Đảo trạng thái cắm cờ
    }
}

}

int main() { Setup();

while (!gameOver && !gameWon) {
    Draw();
    Input();
}

// Vẽ lại bàn cờ cuối cùng để cập nhật kết quả
Draw();

if (gameWon) {
    cout << "\nCHUC MUNG! Ban da xuat sac pha dao game Do Min!\n";
} else {
    cout << "\nBUMMMM!!! Ban da dam phai min. GAME OVER!\n";
}

return 0;

}


Bình luận

Hãy đọc nội quy trước khi bình luận.



  • 0
    NongQuyTung  đã bình luận lúc 26, Tháng 7, 2026, 5:29

    lol