0

先週、私は 3*3 ボードを使って Tic-Tac-Toe ゲームをコーディングする課題を出しました。今、私は同じゲームを自分でやろうとしていますが、プレイヤーのカスタマイズ可能なボードサイズを使用しています.

行と列の数量をユーザーに尋ねます。ゲーム ボードを正しく作成し、<< オーバーロード関数を使用してこれを印刷します。すべて問題ないようです。しかし、移動 (ボードにマークを配置) しようとすると、ユーザーから渡された x 座標と y 座標が画面に表示されるものと一致しません。

エラーの原因が SetPosition() なのか AtPosition() なのかわかりません。この種の配列を扱うのはこれが初めてなので、誰かが私を助けてくれることを願っています. (私の悪い英語でごめんなさい)

私のドライバー ファイルと GameBoard.h と .cpp があります。さらに詳しい情報が必要な場合は、お問い合わせください。

    #include "GameBoard.h"
    #include <iostream> /*cout, cin*/
    #include <stdlib.h> /* rand, srand */
    #include <time.h>   /* time        */

    using namespace std;

    // ************Prototypes*************
    int RandomInt(int low, int high); // generate a random number
    // ***********************************


    int main(void)
    {
        // *************Variables************
        int x_size;                 // the user decide of the size of the board
        int y_size;                 // the user decide of the size of the board
        int x_player;               // the user x-coordinate
        int y_player;               // the user y-coordinate
        int ID_player = 1;          // player ID
        int x_computer;             // the computer x-coordinate
        int y_computer;             // the computer y-coordinate 
        int ID_computer = 2;        // computer ID  
        int keepplaying = 0;        // use this for game loop until we do not have the check win function
        // **********************************
        srand(time(0));

        // ask to the user which size he wants to use
        cout << "Welcome to my Tic Tae Toe Game!" << endl;
        cout << "What size do you want?" << endl;
        cout << "Insert number of rows" << endl;
        cin >> x_size;
        cout << "Insert number of columns" << endl;
        cin >> y_size;

        cout << "This is the GameBoard we are using" << endl;

        // create the GameBoard    
        Board myBoard(x_size, y_size);
        // set all the array to 0
        myBoard.ResetBoard();
        // prints the 2D array
        cout << myBoard << endl;

        cout << "You are the player 1 and you play against the computer (number 2). Good Luck!" << endl;

        do
        {

            // ask to the user the coordinates in which he wants to place the mark
            do
            {
                cout << "Player 1 turn! " << endl;
                cout << "Insert x coordinate: ";
                cin >> x_player ;
                cout << "Insert y coordinate: ";
                cin >> y_player ;
            }
            while( (x_player < 0 || x_player > x_size) || (y_player < 0 || y_player > y_size) || myBoard.AtPosition(x_player, y_player) != 0 );
            // while the cell is not available or the coordinates are not valide
            myBoard.SetPosition(x_player, y_player , ID_player); // the mark has been placed

            // print the move
            cout << myBoard << endl; 
            cout << "End of turn!" << endl;

            // The computer place a mark: the x and y coordinates are randomly generated
            cout << "Computer Turn:" << endl;
            do
            {
                x_computer = RandomInt(0,x_size);
                y_computer = RandomInt(0,y_size);
            }while(myBoard.AtPosition(x_computer, y_computer) != 0);
            myBoard.SetPosition(x_computer, y_computer, ID_computer);
            cout << myBoard << endl; 

        }while(keepplaying != 1) ;         

        //return 0;
    }

    // This function create a random number
    int RandomInt(int low, int high)
    {
      int number = rand() % (high - low + 1) + low;
      return number;
    }

これは main.cpp です。ユーザーのデータを要求し、クラス Board で宣言および定義された関数を呼び出します。

    #include <iostream> /*cout, cin, ostream*/

    class Board
    {
        public:
       /* Board()
        { 
            x = 3;
            y = 3;
            //player_ID = 1;
            //computer_ID = 2;

        }*/
        Board(int x_, int y_); // non-default constructor



        void SetPosition(int x, int y, int player);     // Place a mark
        int AtPosition(int x, int y);                   // return the ID of the cell
        void ResetBoard(void);                        // set all the array to be 0

        friend std::ostream& operator<<(std::ostream &os, const Board &rhs); // overload the << operator

        private:    
        int x;                              // x-coordinates
        int y;                              // y-coordinates
        int *board;                    // contains the board in a 2D array (3*3 gameboard)


        int player_ID;                         // player ID 
        int computer_ID;                        // computer ID

    };

そこに私のクラスのヘッダーファイルがあります

    #include "GameBoard.h"

    // non-default constructor
    Board::Board(int x_, int y_)
    {
        x = x_;
        y = y_;    
        board = new int[x*y];
    }
    // Goes through the board array and set all the ID to 0
    void Board::ResetBoard()
    {
        for(int i = 0; i < x*y; i++)
        {
            board[i] = 0;      
        }
    }

    // returns the ID of the passed cell
    int Board::AtPosition(int x, int y)
    {
       return board[x*y];
    }

    // put a mark in the cell and return true
    void Board::SetPosition(int x, int y, int player_ID)
    {
        board[x*y +x] = player_ID;
        //value = pd[row * 4 + column];
    }

    std::ostream& operator<<(std::ostream &os, const Board &rhs)
    {
      for (int i = 0; i < rhs.x*rhs.y; i++)
      {


        if(i % rhs.y == 0)
        {
          os << std::endl;
        }
        os << rhs.board[i]; 

      }   
        return os;
    }

すべてが明確で、よくコメントされていることを願っています

4

2 に答える 2

0

したがって、Boardクラスには次のものがあります。

// returns the ID of the passed cell
int Board::AtPosition(int x, int y)
{
   return board[x*y];
}

// put a mark in the cell and return true
void Board::SetPosition(int x, int y, int player_ID)
{
    board[x*y +x] = player_ID;
    //value = pd[row * 4 + column];
}

したがって、x および y クラス メンバーをシャドウするパラメーター名としてxandを使用しています。y何をしようとしているのかを考える必要があります。3 x 3 配列の場合:

0 1 2
3 4 5
6 7 8

あなたのコードでは、 x を列番号として、 y を行番号として使用するつもりのようです(ただし、一貫していないため、確信が持てません)。x=1 と y=2 の場合、インデックスは 5 です。あなたが持っている:

board[x*y +x] = player_ID;

必要なもの (次のようなもの):

board[this->x*y +x] = player_ID;

また、次のAtPositionものが必要です。

return board[this->x*y +x];

ただし、シャドウイングを避けるために変数の名前を変更することをお勧めします。xsizeおそらく、メンバ vars は/ysizeまたはxlen/と呼ぶほうがよいでしょうylen

また、次のoperator<<ものがあります。

if(i % rhs.y == 0)
{
    os << std::endl;
}
os << rhs.board[i]; 

私が考える必要があるのは:

if(i % rhs.x == 0)
{
    os << std::endl;
}
os << rhs.board[i]; 

(私はrhs.x幅だと推測しているためですが、そうでない場合は、他のコードが間違っています。)

于 2013-03-03T11:25:28.003 に答える
0

まず、このクラスの機能がめちゃくちゃです。ボードをメモリ内に動的に作成する場合は、直接アクセスできます。std::ostream 関数を呼び出すときは、単に show という関数を作成する必要があります。もう少し明確に説明するのに役立つコードを次に示します。

include "GameBoard.h" #include "Player.h"

   int main() {    GameBoard* board = new GameBoard;    board->show();    Player* player = new Player(board);//passing a pointer to a pointer this is called    //dynamic passing which allows a class to manipulate another with a class    int* row = new int;    int* col = new int;    row = 1 , col = 1; //the middle spot on 3x3 board    player->setPiece(row,col);//now the player class would control the rest    delete col; delete row; delete player;//delete all but the board    board->show();//the players piece would still be there this is what dynamic pass-    //ing can do    delete board;    return 0; }

正しく行われた場合、プレーヤーはボードへのポインターを使用して、ボードを独自のクラス内で制御および操作します。これはデータの抽象化と呼ばれ、クラス内および show 関数内で機能を許可し、cout を使用し、ostream を参照しないでください。これは悪いプログラミング手法であり、プログラム全体でひどいエラーが発生する可能性があります。私も難しい方法を学びました笑。とにかく、この資料を練習すれば、ほとんどすべてのプログラムを書く天才になります。そして、これは PP(手続き型プログラミング) ではなく、OOP(オブジェクト指向プログラミング) であることを常に覚えておいてください。

于 2013-10-17T05:20:55.407 に答える