mine

踩地雷 Mine Sweeper

引用標頭檔

#include<iostream>

#include<windows.h>

宣告函式

void init();//初始化

void clearScreen();//清除螢幕(全部填入空白)

void Check_Show(int*,int*); //檢查並顯示地雷區 

void input(); //輸入動作與座標 

void showArr(int*); //顯示陣列(測試用) 

int  calMine(int*,int,int); //計算周圍地雷數

游標位置、控制游標、改變文字及背景顏色---Global

//獲取目前游標位置 

COORD getCurrentCursorPosition() {

    CONSOLE_SCREEN_BUFFER_INFO csbi;

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);


    if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) {

        // 獲取失敗返回 (-1, -1)

        COORD invalidCoord = { -1, -1 };

        return invalidCoord;

    }


    return csbi.dwCursorPosition;

}

//移動游標至指定位置 

void moveCursorToPosition(int x, int y) {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    COORD position = { static_cast<SHORT>(x), static_cast<SHORT>(y) };

    SetConsoleCursorPosition(hConsole, position);

}

//設定文字顏色 

void SetColor(int color = 7){

  HANDLE hConsole;

  hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  SetConsoleTextAttribute(hConsole,color);

}

//公用變數宣告 

//定義地雷陣列

int arr[10][10]={

{0,0,0,0,0,0,0,0,0,0},

{1,0,1,0,1,0,1,0,1,1},

{0,0,0,0,0,0,0,0,0,0},

{0,0,1,0,1,0,1,0,1,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,0,0}

};

int* ap=arr[0];//取得二維陣列arr開頭位址 


//定義周圍地雷數量

int MineNumber[10][10]={

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}

};

int* ap1=num[0];//取得二維陣列MineNumber開頭位址 


//定義已選位置 : 0=翻開、1=標記。

int mark[10][10]={

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},

{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}

};

int* ap2=mark[0];//取得二維陣列mark開頭位址 


//

COORD cursorPos;

int s, row, col; //s:動作選擇、row:列座標、col:欄座標 

bool hit = false;

//

主程式

int main() {

showArr(); //顯示地雷地圖 

while (not hit){

input();

}


SetColor(206);

printf("Game Over! 座標(%d,%d)是地雷!!",row,col);

  SetColor();


  return 0;

}

主程式後面的副程式


//清除螢幕(全部填入空白) 

void clearScreen() {

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    CONSOLE_SCREEN_BUFFER_INFO csbi;

    GetConsoleScreenBufferInfo(hConsole, &csbi);

    COORD screenSize = { csbi.srWindow.Right + 1, csbi.srWindow.Bottom + 1 };

    DWORD dwBytesWritten;

    FillConsoleOutputCharacter(hConsole, ' ', screenSize.X * screenSize.Y, { 0, 0 }, &dwBytesWritten);

    SetConsoleCursorPosition(hConsole, { 0, 0 });

}


//檢查並顯示地雷區 

void Check_Show() {

clearScreen();

//標記已選位置

*(ap2+row*10+col) = 1; //使用全域指標 mark

//檢查是否踩到地雷

if(*(ap+row*10+col) == 1) { //檢查arr

printf("你踩到地雷了!!Boom...\n");

*(ap1+row*10+col) = 9; //本身即地雷 MineNumber

hit = true;

} else{

printf("還有%d個地雷未標示\n",counter);

}


showArr(); //印出地雷區 arr

    

return;

}


//輸入動作與座標 

void input(){

moveCursorToPosition(cursorPos.X ,cursorPos.Y); //移動游標

scanf("%d%d%d", &s, &row, &col);

int count = calMine(ap,row,col);

*(ap1+row*10+col) = count;

    //std::cout << count << std::endl;

}


//顯示地雷區陣列arr 

void showArr(){

printf("還有%d個地雷未標示\n",counter);

printf("  0 1 2 3 4 5 6 7 8 9\n");

for (int i = 0; i < 10; i++) {

printf("%d ", i);

for(int j=0;j<10;j++){

if(*(ap2+i*10+j) == -1){ //檢查mark陣列 

printf("- ");

}else{

if(*(ap2+i*10+j) == 0){ //mark陣列=0 翻開

SetColor(240);

printf("%d",*(ap1+i*10+j)); //讀取Mine_Number

} else { //mark陣列=1 標記 

SetColor(100); //更改標示位置顏色 

printf("?");

}

SetColor();

printf(" ");

}

}

printf("\n");

}

return;

}


//計算周圍地雷數 

int calMine(int* p,int x,int y){

int count = 0;

for(int i=row-1;i<=row+1;i++){

for(int j=col-1;j<=col+1;j++){

if(i>=0 && j>=0){

if(*(p+i*10+j)==1){

count++;

if(i==row && j==col)

count--;

}

}

}

}


return count;

}


//標示並顯示地雷區 

void Mark_Show() {

clearScreen();

//檢查是否已標示

if(*(ap2+row*10+col)) { //檢查mark

printf("不得重複標示!!\n");

} else{

*(ap2+row*10+col) = 1; //標記已選位置

counter -= 1;

printf("還有%d個地雷未標示\n",counter);

}


showArr(); //印出地雷區 arr 


return;

}