2012-09-13 106 views
0

好的,所以继承人勺:我正在为我的c + +类建立一个扫雷风格的程序,我使用二维数组来创建板,第二个二维数组来存储猜测。对于电路板阵列中的每个值,我运行一个随机数gen,并为其分配一个介于0和99之间的值。如果数组的值大于85,则该数组中的每个值都被认为是炸弹。程序接受用户输入并确定它是否为是炸弹。如果它不是相应的布尔数组(isGuessed),则位置更改为true。这个布尔数组然后被发送到reDraw函数来重绘。所有的假布尔显示为'?'并且全部为真都显示为'X'。但是,当我重新绘制时,它将数组中的多个位置更改为只有一个猜测的X.我的想法是,董事会不是与阵列位置相关的。有人可以帮忙吗?只是要清楚,我试图了解为什么reDraw函数不能正常工作。这是我所有的代码。2D阵列帮助C++

#include <iostream> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 

//Function Prototypes 

void reDraw (bool guessed [] [10], int rows, int columns); 
void newBoard (int rows, int columns); 


int main(int argc, const char * argv[]) 
{ 
//Declare Variables 
    const int ROWS = 10; 
    const int COLUMNS = 10; 
int board [ROWS][COLUMNS]; 
bool wasGuessed [10] [10]; 
bool playAgain = true; 
char newGame; 
int rowGuess, columnGuess, numOfBombs = 0, score = 0; 
bool bomb = false; 
srand((unsigned) time(0)); 


// Welcome User, Give Direction 

cout<<"\n\n\t\tWelcome To Matt's Minesweeper\n\n"; 

while (playAgain) { 



//function to randomly populate array elements 
    for (int row = 0; row < ROWS; row++) { 
     for (int column = 0; column < COLUMNS; column++) { 
      board [row] [column] = rand() % 100; 
      if (board [row] [column] >= 85) { //counter for bombs 
       numOfBombs++; 
     } 
    } 
} 

// Create a new Display Board 
newBoard(10, 10); 

//Begin Game 
cout<<"\nTotal Bombs In This Game: "<<numOfBombs; 


// Process Guesses 
do { 
    cout<<"\nPlease Input your ROW & COLUMN Guess coordinate (i.e. 3 2): "; 
    cin>>rowGuess>>columnGuess; 

    if (board [rowGuess] [columnGuess] >= 85) { 
     bomb = true; 
     cout<<"\n\n\t\tXXXXXX BOMB HIT XXXXXXX\n\t\t\tGame Over.\n\n"; 
     cout<<"Your Score Score: "<<score; 
     cout<<"\n\n Play Again (y/n):"; 
     cin>>newGame; 
     switch (newGame) { 
      case 'y': 
       cout<<"\n\n"; 
       playAgain = true; 
       break; 
      default: 
       playAgain = false; 
       break; 

     } 
    } else { 
     wasGuessed [rowGuess] [columnGuess] = true; 
     score++; 
     reDraw(wasGuessed, 10, 10); 
    } 
} while (!bomb); 

} 


return 0; 
} 

    void reDraw (bool guessed [] [10], int rows, int columns) 
{ 
    // Format row and column headers 
    cout<<" 0 1 2 3 4 5 6 7 8 9\n"; 
    cout<<"0"; 
for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < columns; j++) { 

     if ((j+1) % 10 == 0) 
      if ((i+1) == 10) { 
       if (guessed [i] [j]) 
        cout<<"X "<<" \n"; 
       else 
        cout<<"? "<<" \n"; 
      }else{ 
       if (guessed [i] [j]) 
        cout<<"X "<<" \n"<<i+1; 
       else     
        cout<<"? "<<" \n"<<i+1; 
      } 
     if ((j+1) % 10 != 0) 
      if (guessed [j] [i]) 
       cout<<" X"<<" "; 
      else 
       cout<<" ?"<<" "; 

    } 
} 

} 
void newBoard (int rows, int columns) 
{ 

cout<<" 0 1 2 3 4 5 6 7 8 9\n"; 
cout<<"0"; 
for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < columns; j++) { 

     if ((j+1) % 10 == 0) 
      if ((i+1) == 10) { 
       cout<<"? "<<" \n"; 
      }else 
       cout<<"? "<<" \n"<<i+1; 
     if ((j+1) % 10 != 0) 
      cout<<" ?"<<" "; 
    } 

} 


} 

感谢您的帮助伙计!

+0

为什么“C”的标签? –

+1

你应该结合newBoard和reDraw,因为猜测是不同的。 newBoard没有猜测。 –

+0

@FredLarson我不确定C标签是什么 – metaDNA

回答

1

我很无聊,所以我让你的程序更好。这些都在一个文件中,但将其分解为多个文件很容易。将每个类的成员和类定义分开,并将它们放在它们自己的文件中,然后将main放在它自己的文件中。

我做了几件事情,可能会让你觉得奇特。如果你看到的东西,问它在一个评论,我会解释自己

// include all of the things 
#include <cstdlib> 
#include <ctime> 
#include <iostream> 
#include <iomanip> 
#include <string> 

// use all of the things 
using std::rand; 
using std::srand; 
using std::time; 
using std::cout; 
using std::cin; 
using std::endl; 
using std::right; 
using std::left; 
using std::setw; 
using std::string; 

// MineSweepBoard.h 

class MineSweepBoard 
{ 
public: 
    MineSweepBoard(int rows, int cols, float per); 
    MineSweepBoard(int rows, int cols); 
    MineSweepBoard(); 
    virtual ~MineSweepBoard(); 

    static const int ROW_DEFAULT, COL_DEFAULT; 
    static const float CHANCE_DEFAULT; 
    static const unsigned char MINE_MASK, UNCOVERED_MASK; 
    static void Randomize(); 

    void RandomizeBoard(); 
    bool IsMine(int r, int c); 
    bool IsUncovered(int r, int c); 
    int UncoverSpace(int r, int c); 
    int GetAdjMineCount(int r, int c); 
    bool IsOnBoard(int r, int c); 
    char GetBoardSquare(int r, int c); 

    int GetRows(); 
    int GetCols(); 
    float GetPercentage(); 
    int GetMineCount(); 
    int GetSafeCount(); 

private: 
    int rowcount, colcount; 
    int minecount, safecount; 

    float percentage; 
    char * board; 
    bool safedummy; 

    void Init(int rows, int cols, float per); 
}; 

// MineSweeper.h 

class MineSweeper : public MineSweepBoard 
{ 
public: 
    MineSweeper(); 
    MineSweeper(int rows, int cols, float difficulty); 
    MineSweeper(int rows, int cols, float difficulty, char mchar, char bchar, char uchar); 

    static const char MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT; 

    void PrintBoard(); 
    char GetCharForSpace(int r, int c); 
    void Play(); 
    bool WonGame(); 
private: 
    char minechar, blankchar, unknownchar; 
    int cleared; 

    void Init(char mchar, char bchar, char uchar); 
}; 

// MineSweepBoard.cpp 

const int MineSweepBoard::ROW_DEFAULT = 10, MineSweepBoard::COL_DEFAULT = 10; 
const float MineSweepBoard::CHANCE_DEFAULT = 0.85; 
const unsigned char MineSweepBoard::MINE_MASK = 0x1, MineSweepBoard::UNCOVERED_MASK = 0x2; 

void MineSweepBoard::Randomize() 
{ 
    srand(time(NULL)); 
} 

int MineSweepBoard::GetRows() 
{ 
    return rowcount; 
} 

int MineSweepBoard::GetCols() 
{ 
    return colcount; 
} 

float MineSweepBoard::GetPercentage() 
{ 
    return percentage; 
} 

int MineSweepBoard::GetMineCount() 
{ 
    return minecount; 
} 

int MineSweepBoard::GetSafeCount() 
{ 
    return safecount; 
} 

MineSweepBoard::MineSweepBoard() 
{ 
    Init(ROW_DEFAULT, COL_DEFAULT, CHANCE_DEFAULT); 
} 

MineSweepBoard::MineSweepBoard(int rows, int cols) 
{ 
    Init(rows, cols, CHANCE_DEFAULT); 
} 

MineSweepBoard::MineSweepBoard(int rows, int cols, float per) 
{ 
    Init(rows, cols, per); 
} 

MineSweepBoard::~MineSweepBoard() 
{ 
    delete[] board; 
} 

void MineSweepBoard::Init(int rows, int cols, float per) 
{ 
    minecount = 0; 
    safecount = rows * cols; 
    percentage = per; 
    rowcount = rows; 
    colcount = cols; 
    board = new char [rows * cols]; 
    RandomizeBoard(); 
} 

char MineSweepBoard::GetBoardSquare(int r, int c) 
{ 
    return board[r * colcount + c]; 
} 

void MineSweepBoard::RandomizeBoard() 
{ 
    for (int i = 0, j = rowcount * colcount; i != j; ++i) 
    { 
     float r = (((float) rand())/((float) RAND_MAX)); 
     board[i] = (percentage < r); 
     if (board[i]) ++minecount; 
    } 
    safecount -= minecount; 
} 

bool MineSweepBoard::IsOnBoard(int r, int c) 
{ 
    return (
       (r >= 0 && r < rowcount) && 
       (c >= 0 && c < colcount) 
      ); 
} 

bool MineSweepBoard::IsMine(int r, int c) 
{ 
    return (
       (IsOnBoard(r, c)) && 
       (GetBoardSquare(r, c) & MINE_MASK) 
      ); 
} 

bool MineSweepBoard::IsUncovered(int r, int c) 
{ 
    return (
       (IsOnBoard(r, c)) && 
       (GetBoardSquare(r, c) & UNCOVERED_MASK) 
      ); 
} 

int MineSweepBoard::UncoverSpace(int r, int c) 
{ 
    int uncovered = 0; 
    while (IsOnBoard(r, c) && !IsUncovered(r, c)) 
    { 
     board[r * colcount + c] |= UNCOVERED_MASK; 
     if (!(GetBoardSquare(r, c) & MINE_MASK)) ++uncovered; 
     else break; 

     if (GetAdjMineCount(r, c) == 0) 
     { 
      uncovered += UncoverSpace(r + 0, c + 1); 
      uncovered += UncoverSpace(r + 0, c - 1); 
      uncovered += UncoverSpace(r + 1, c + 0); 
      uncovered += UncoverSpace(r - 1, c + 0); 
     } 

     break; 
    } 
    return uncovered; 
} 

int MineSweepBoard::GetAdjMineCount(int r, int c) 
{ 
    return IsMine(r + 0, c + 1) + IsMine(r + 0, c - 1) + 
      IsMine(r + 1, c + 0) + IsMine(r - 1, c + 0) + 
      IsMine(r + 1, c + 1) + IsMine(r - 1, c - 1) + 
      IsMine(r + 1, c - 1) + IsMine(r - 1, c + 1); 
} 

// MineSweeper.cpp 

const char MineSweeper::MINE_DEFAULT = 'X', MineSweeper::BLANK_DEFAULT = ' ', MineSweeper::UNKNOWN_DEFAULT = '?'; 

MineSweeper::MineSweeper() : MineSweepBoard() 
{ 
    Init(MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT); 
} 

MineSweeper::MineSweeper(int rows, int cols, float difficulty) : MineSweepBoard(rows, cols, difficulty) 
{ 
    Init(MINE_DEFAULT, BLANK_DEFAULT, UNKNOWN_DEFAULT); 
} 

MineSweeper::MineSweeper(int rows, int cols, float difficulty, char mchar, char bchar, char uchar) : MineSweepBoard(rows, cols, difficulty) 
{ 
    Init(mchar, bchar, uchar); 
} 

void MineSweeper::Init(char mchar, char bchar, char uchar) 
{ 
    minechar = mchar; 
    blankchar = bchar; 
    unknownchar = uchar; 
} 

void MineSweeper::PrintBoard() 
{ 
    for (int i = 0; i < GetCols(); ++i) cout << setw(4) << right << i; 
    cout << left << endl << endl; 
    for (int r = 0; r < GetCols(); ++r) 
    { 
     cout << setw(3) << r; 
     for (int c = 0; c < GetRows(); ++c) 
     { 
      cout << setw(4) << GetCharForSpace(r, c); 
     } 
     cout << endl; 
    } 
} 

char MineSweeper::GetCharForSpace(int r, int c) 
{ 
    if (IsUncovered(r, c)) 
    { 
     if (IsMine(r, c)) 
      return minechar; 
     int count = GetAdjMineCount(r, c); 
     if (count == 0) 
      return blankchar; 
     else 
      return '0' + count; 
    } 
    else 
     return unknownchar; 
} 

void MineSweeper::Play() 
{ 
    int score = 0; 
    PrintBoard(); 
    cout << "Total Bombs In This Game: " << GetMineCount() << endl; 

    while (true) 
    { 
     string dummy; 
     int inputrow = -1, inputcol = -1; 
     cout << "Please Input Your ROW & COLUMN Guess Coordinate (i.e. 3 2): "; 
     cin >> inputrow >> inputcol; 
     if (!cin || IsUncovered(inputrow, inputcol) || !IsOnBoard(inputrow, inputcol)) 
     { 
      cout << "Invalid Selection! "; 
      if (!cin) 
      { 
       cin.clear(); 
       cin >> dummy; 
      } 
      continue; 
     } 

     int uncovered = UncoverSpace(inputrow, inputcol); 
     PrintBoard(); 
     if (IsMine(inputrow, inputcol)) 
     { 
      cout << endl << endl << "\t\tXXXXXX BOMB HIT XXXXXX" << endl << "\t\t\tGame Over." << endl << endl; 
      break; 
     } 
     else 
     { 
      score += uncovered; 
      cleared += uncovered; 
      if (WonGame()) 
      { 
       cout << endl << endl << "\t\t------ ALL BOMBS CLEARED ------" << endl << "\t\t\tYou Win!" << endl << endl; 
       break; 
      } 

     } 
    } 
    cout << "your Score: " << score << endl; 
} 

bool MineSweeper::WonGame() 
{ 
    return (cleared == GetSafeCount()); 
} 

// main.cpp 

int main(int argc, char * argv[]) 
{ 
    MineSweepBoard::Randomize(); 

    cout << endl << endl << "\t\tWelcome To Wug's Minesweeper" << endl << endl; 

    while(true) 
    { 
     char again = 'n'; 
     MineSweeper m; 
     m.Play(); 
     cout << endl << "Play Again? (y/n) "; 
     cin >> again; 
     if (again == 'y') 
     { 
      cout << endl << endl; 
      continue; 
     } 
     else break; 
    } 
    return 0; 
} 

此代码显示出你的原始版本没有以下特点:

  • 你可以赢得比赛
  • 与windows扫雷一样,在空的空间中间拾取一块清除整个空间
  • 输入验证
  • 内存管理(您刚刚在堆栈上使用了内存,它没有已经以新的和删除任何
  • 继承
  • 压痕是否一致(不一致的缩进阅读代码是不好玩)
+0

毋庸置疑,这绝对是对我原有概念的重大改进。我将研究你的代码,并试图破译它是如何做到的,我坐在那里玩了将近半个小时。我真的很喜欢它如何显示地雷和吹灭部分。非常感谢你今晚感到无聊。对此,我真的非常感激!!!! - 马特 – metaDNA

3

确定它已修复。查看新代码:

更改 - 添加reset()并将wasGuessed [rowGuess] [columnGuess] = true;移到cin<<之后。

它就像一个魅力,并吸引了X的'?曾经站在猜测之前。

#include <iostream> 
#include <ctime> 
#include <cstdlib> 

using namespace std; 


//Declare Variables 
const int ROWS = 10; 
const int COLUMNS = 10; 
int board [ROWS][COLUMNS]; 
bool wasGuessed [ROWS] [COLUMNS]; 
bool playAgain = true; 
char newGame; 
int rowGuess, columnGuess, numOfBombs = 0, score = 0; 
bool bomb = false; 


//Function Prototypes 

void reDraw (bool guessed [] [10], int rows, int columns); 
void newBoard (int rows, int columns); 
void reset(); 

int main(int argc, const char * argv[]) 
{ 

srand((unsigned) time(0)); 

reset(); 

// Welcome User, Give Direction 

cout<<"\n\n\t\tWelcome To Matt's Minesweeper\n\n"; 

while (playAgain) { 



//function to randomly populate array elements 
    for (int row = 0; row < ROWS; row++) { 
     for (int column = 0; column < COLUMNS; column++) { 
      board [row] [column] = (rand() % 100) + 0; 
      if (board [row] [column] >= 85) { //counter for bombs 
       numOfBombs++; 
     } 
    } 
} 

// Create a new Display Board 
newBoard(10, 10); 

//Begin Game 
cout<<"\nTotal Bombs In This Game: "<<numOfBombs; 


// Process Guesses 
do { 
    cout<<"\nPlease Input your ROW & COLUMN Guess coordinate (i.e. 3 2): "; 
    cin>>rowGuess>>columnGuess; 
    wasGuessed [rowGuess] [columnGuess] = true; 
    if (board [rowGuess] [columnGuess] >= 85) { 
     bomb = true; 
     cout<<"\n\n\t\tXXXXXX BOMB HIT XXXXXXX\n\t\t\tGame Over.\n\n"; 
     cout<<"Your Score Score: "<<score; 
     cout<<"\n\n Play Again (y/n):"; 
     cin>>newGame; 
     switch (newGame) { 
      case 'y': 
       cout<<"\n\n"; 
       playAgain = true; 
       reset(); 
       break; 
      default: 
       playAgain = false; 
       break; 

     } 
    } else { 
     wasGuessed [rowGuess] [columnGuess] = true; 
     score++; 
     reDraw(wasGuessed, 10, 10); 
    } 
} while (!bomb); 

} 


return 0; 
} 

    void reDraw (bool guessed [] [10], int rows, int columns) 
{ 
    // Format row and column headers 
    cout<<" 0 1 2 3 4 5 6 7 8 9\n"; 
    cout<<"0"; 
for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < columns; j++) { 

     if ((j+1) % 10 == 0) 
      if ((i+1) == 10) { 
       if (guessed [i] [j]) 
        cout<<"X "<<" \n"; 
       else 
        cout<<"? "<<" \n"; 
      }else{ 
       if (guessed [i] [j]) 
        cout<<"X "<<" \n"<<i+1; 
       else     
        cout<<"? "<<" \n"<<i+1; 
      } 
     if ((j+1) % 10 != 0) 
      if (guessed [j] [i]) 
       cout<<" X"<<" "; 
      else 
       cout<<" ?"<<" "; 

    } 
} 

} 
void newBoard (int rows, int columns) 
{ 

cout<<" 0 1 2 3 4 5 6 7 8 9\n"; 
cout<<"0"; 
for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < columns; j++) { 

     if ((j+1) % 10 == 0) 
      if ((i+1) == 10) { 
       cout<<"? "<<" \n"; 
      }else 
       cout<<"? "<<" \n"<<i+1; 
     if ((j+1) % 10 != 0) 
      cout<<" ?"<<" "; 
    } 

} 


} 

void reset() 
{ 
    for (int row = 0; row < ROWS; row++) 
    { 
      for (int column = 0; column < COLUMNS; column++) 
      { 
       wasGuessed [row] [column] = false; 

      } 
     } 
} 
+1

+1有耐心通过代码趟过 – learnvst

+0

Dude!非常感谢你,这真棒! – metaDNA

+0

我的代码有什么问题,它没有按照它应有的方式工作? – metaDNA