0

OK では、スクープを紹介します。C++ クラス用の掃海艇スタイルのプログラムを作成しています。2D 配列を使用してボードを作成し、2 番目の 2D 配列を使用して推測を保存しています。ボード配列の各値に対して、乱数 gen を実行し、0 から 99 までの値を割り当てます。配列内の各値は、その値が 85 より大きい場合、爆弾と見なされます。プログラムはユーザー入力を受け入れ、爆弾です。対応する bool 配列 (isGuessed) でない場合、position は true に変更されます。次に、この bool 配列が reDraw 関数に送られ、再描画されます。すべての false bool は「?」として表示されます。true はすべて「X」として表示されます。ただし、再描画すると、配列内の複数の場所が 1 つの推測だけで X に変更されます。私の考えでは、ボードは配列の位置に関連して描かれていません。誰かが助けてくれますか。明確にするために、関数 reDraw が正しく機能しない理由を理解しようとしています。これがすべての私のコードです。

#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<<" ?"<<"  ";
    }

}


}

助けてくれてありがとう!

4

2 に答える 2

3

わかりました。修正されました。新しいコードをチェックしてください:

変更点 - の後に追加 し、先頭にreset()移動しました。wasGuessed [rowGuess] [columnGuess] = true;cin<<

それは魔法のように機能し、推測の前に 's がかつて立っていXた 'sを描画します。?

#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;

            }
        }
}
于 2012-09-13T20:40:01.277 に答える
1

私は退屈だったので、あなたのプログラムをより良くしました。すべてが 1 つのファイルにまとめられていますが、複数に分割するのは簡単です。各クラスのメンバーとクラス定義を分離し、それらを独自のファイルに入れ、メインを独自のファイルに入れるだけです。

私はあなたが奇妙だと思うかもしれないいくつかのことをします. 何かを見つけたら、コメントで質問してください。説明します

// 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;
}

このコードには、元のバージョンにはなかった次の特徴があります。

  • あなたはゲームに勝つことができます
  • 窓のマインスイーパと同じように、空きスペースの真ん中にあるピースを拾うと、スペース全体がクリアされます
  • 入力検証
  • メモリ管理(スタック上のメモリを使用しただけで、新しいものや削除する必要はありませんでした
  • 継承
  • インデントに一貫性がある (一貫性のないインデントでコードを読むのは面白くない)
于 2012-09-13T22:49:05.583 に答える