2016-12-09 3 views
2

私がしたいことは、普通の掃海艇のゲームと同じように、隣り合っているすべての0を「回す」ことができることです。Minesweeper、どのくらい多くの0がお互いに隣り合っているのか分かりますか?

#include <cmath> 
#include <cstdlib> 
#include <iomanip> 
#include <ctime> 
#include <iostream> 

int buscamina(); 
using namespace std; 

int main() { 
    buscamina(); 
    return 0; 
} 


int buscamina(){ 
    srand(time(NULL)); 

    int size=12, minastot=10; 
    int tablero[size][size]; 
    char lqeuv[size-2][size-2]; 
    int x, y, cm=0; 

    for(int i=0; i<size-2; i++) 
    for(int j=0; j<size-2; j++) 
     lqeuv[i][j]=88; 

    for(int i=0; i<size; i++) 
    for(int j=0; j<size; j++) 
     tablero[i][j]=0; 

    for(int i=0; i<minastot; i++){ 
    int a=0, b=0; 

    a=rand()%(size-2); 
    b=rand()%(size-2); 
    ++a; ++b; 

    if(tablero[a][b]==9) 
     minastot++; 

    tablero[a][b]=9; 
    } 

    for(int i=0; i<size; i++) 
    for(int j=0; j<size; j++) 
     if(tablero[i][j]==9) 
     for(int a=i-1; a<i+2; a++) 
      for(int b=j-1; b<j+2; b++) 
      if(tablero[a][b]!=9) 
       tablero[a][b]++; 

    for(int i=0; i<size; i++) 
    for(int j=0; j<size; j++) 
     if(tablero[i][j]==9) 
     ++cm; 

    do{ 
    cout << endl; 
    cout << setw(5); 
    for(int i=0; i<size-2; i++) 
     cout << i << " "; 
    cout << endl << endl; 
    for(int i=0; i<size-2; i++){ 
     cout << i << setw(4); 
     for(int j=0; j<size-2; j++) 
     cout << lqeuv[i][j] << " "; 
     cout << endl; 
    } 

    do { 
     cout << "Coordenadas: "; 
    } while(scanf("%d %d", &x, &y)!=2); 

    if(tablero[x+1][y+1]==0) 
     lqeuv[x][y]=32; 
    else 
    lqeuv[x][y]=(tablero[x+1][y+1]+48); 

    }while (tablero[x+1][y+1]!=9); 

    for(int i=0; i<size; i++){ 
    for(int j=0; j<size; j++) 
     cout << tablero[i][j] << " "; 
    cout << endl; 
    } 
    return 0; 
} 

はそれでは、ユーザーは座標0 2に入りましょう、ゼロであることを起こる、私は何をしたいだけではなく、その特定が空白にX座標から変更することができるようにすることですが、また、それの隣にある他のすべての0も、正規のMinesweeperのように、また私が使用した変数名はスペイン語であるので、翻訳もタイプさせてください。

  • buscamina - 掃海艇
  • tablero - ボード
  • lqeuv - wtus(ユーザーが見ているもの)
  • minastot - totmines(総鉱山)
  • センチメートル - MC(鉱山カウンタ)

答えて

1

これには、フラッドフィルアルゴリズムを使用できます。プレイヤーが選んだ位置から開始して、その周辺のすべてのタイルを埋める。

また、88と9の代わりに 'X'と ''を使用することをお勧めします。内部が何であるか、何が表示されているか、選択されたかどうか、それが本当に役立つでしょうが、それはこの質問のポイントではありませんでした。

だからここに私が作った修正版です:

#include <cmath> 
#include <cstdlib> 
#include <iomanip> 
#include <ctime> 
#include <iostream> 

using namespace std; 

template <size_t size> 
class Buscamina { 
public: 
    Buscamina() : minastot(3) {} 

    void run() { 
     srand(time(NULL)); 
     int x, y, cm=0; 

     // Fill draw with X 
     for(int i=0; i<size; i++) 
      for(int j=0; j<size; j++) 
       lqeuv[i][j]= 'X'; 

     // Fill mines with empty 
     for(int i=0; i<size; i++) 
      for(int j=0; j<size; j++) 
       tablero[i][j]=0; 

     // Generate mines 
     for(int i=0; i<minastot; i++){ 
      int a=0, b=0; 

      a=rand()%(size-2); 
      b=rand()%(size-2); 
      ++a; ++b; 

      if(tablero[a][b]==9) 
       minastot++; 

      tablero[a][b]=9; 
     } 

     // Set count of surrounding mines 
     for(int i=0; i<size; i++) 
      for(int j=0; j<size; j++) 
       if(tablero[i][j]==9) 
        for(int a=i-1; a<=i+1; a++) 
         for(int b=j-1; b<=j+1; b++) 
          if(tablero[a][b]!=9) 
           tablero[a][b]++; 

     // Set total mines 
     for(int i=0; i<size; i++) 
      for(int j=0; j<size; j++) 
       if(tablero[i][j]==9) 
        ++cm; 

     // Main loop 
     do{ 
      // Print table 
      cout << endl; 
      cout << setw(5); 
      for(int i=0; i<size; i++) 
       cout << i << " "; 
      cout << endl << endl; 
      for(int i=0; i<size; i++){ 
       cout << i << setw(4); 
       for(int j=0; j<size; j++) 
        cout << lqeuv[i][j] << " "; 
       cout << endl; 
      } 

      // Get input 
      do { 
       cout << "Coordenadas: "; 
      } while(scanf("%d %d", &x, &y)!=2); 

      // Pick a mine 
      floodfill(x, y); 

     }while (tablero[x][y]!=9); 

     for(int i=0; i<size; i++){ 
      for(int j=0; j<size; j++) 
       cout << tablero[i][j] << " "; 
      cout << endl; 
     } 
    } 

    void floodfill(int x, int y) { 
     if (x < 0 || y < 0 || x >= size || y >= size || lqeuv[x][y] != 'X') 
      return; 
     if (tablero[x][y] == 0) { 
      lqeuv[x][y] = ' '; 
      floodfill(x, y - 1); 
      floodfill(x - 1, y); 
      floodfill(x + 1, y); 
      floodfill(x, y + 1); 
     } else { 
      lqeuv[x][y]=(tablero[x][y]+48); 
     } 

    } 

    int minastot; 
    int tablero[size][size]; 
    char lqeuv[size][size]; 
}; 

int main() { 
    Buscamina<10> game; 
    game.run(); 
    return 0; 
} 

は、私は簡単に2つのアレイにアクセスできるように、私はクラスの中にあなたの全体buscamina機能を入れています。また、私は2つの配列を同じサイズにして、レンジガードを含めました。サイズが違うので、実際に不必要に作業するのが難しくなりました。

クラスを使用したくない場合は、buscaminaと同じようにfloodfill非メンバ関数を作成し、2つの引数を追加して、lqeuvとtableroへの参照を渡すことができます。

したがって、問題の解決方法は、フラッドフィル機能です。あなたは単にそれをxとyのプレイヤーに入力するだけです。最初に境界チェックを行い、タイルがまだ選択されていないかどうかをチェックします。はいの場合は単に返されます。あなたのバージョンのように、それはタイルが0かどうかをチェックします。それがそうであれば、それはlqeuvを ''に設定し、周囲の4つのタイルすべてに対して自分自身を呼び出します。これにより、接続されているすべてのタイルが0に設定されるようになります。次に、タイルが隣接する鉱山を有する場合(したがって、tablero!= 0)、それはlqeuvを上記の数に設定する。
はまた、入力0 0のための結果は以下のようになります。あなたが持っている場合は

0 1 2 3 4 5 6 7 8 9 

0      
1  1 1 2 1 1  
2  1 X X X 1  
3  1 X X X 1  
4   1 X 1   
5   1 X 1   
6   1 1 1   
7      
8      
9 

は、他の質問はお気軽に。また、あなたのプログラムをより良く組織するためのヒントをお知りになりたいなら、私は喜んで手伝ってくれるでしょう。

+0

マローさん、ありがとうございました。私は大学での講座を取っているので、あなたが提案したように別の機能を作ってしまいました。私はクラスを使用することができませんでした。私は元のコードでコメントしました。あなたがコーディングを改善することができる他のヒントはありますか? –

+0

ゲームを書くには、runメソッドを、入力(この場合はコード内にコメントを入力する)、ステップ(マイニングコメントを選択)、描画(テーブルのコメントを表示)などの呼び出し関数の無限ループのみを含むようにしてくださいあなたの短い例ではそれほど重要ではありませんでした。次に、C言語の入力をC++のcinに置き換えるといいかもしれません。また、コードの可読性も非常に重要です。 'lqeuv [i] [j] = 'X'は' lqeuv [i] [j] = 88'よりはるかに優れています。また、答えたように質問をチェックすることも役に立ちます。 –

+1

私はC++で昏睡状態で区切られた2つの数字入力を得る方法がわからないので、Cスタイルの入力だけを使用しました。私は今質問に答えました!どうもありがとう。 –

関連する問題