2

私は C を学んでいるので、テーブルとして ASCII アートを使用して Tic Tac Toe ゲームを作成しようと決めました。

まだあまり持ってない…

#include <stdio.h> 

#define WIDTH 2;

#define HEIGHT 2;

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

    printf("Welcome to Tic Tac Toe!\n\n");

    int width = WIDTH;
    int height = HEIGHT;

    // Make grid

    for (int y = 0; y <= height; y++) {

        for (int x = 0; x <= width; x++) {

            printf("%d%d", x, y);

            if (x != width) {
                printf("||");
            }

        }


        if (y != height) {
            printf("\n");

            for (int i = 0; i < (width + (width * 4)); i++) {
                printf("=");
            }

            printf("\n");
        } else {
            printf("\n");
        }


    }

    // Ask for user input

    printf("Please enter the cell where you would like to place an X, e.g. for example the first top left cell is '00'\n");

}

コマンドラインで実行すると、この出力が得られます

Welcome to Tic Tac Toe!

00||10||20
==========
01||11||21
==========
02||12||22
Please enter the cell where you would like to place an X, e.g. for example the first top left cell is '00'

ここで、複数の文字の入力を取得する方法を理解したら (getchar()これまでのところ、個々の文字を取得する方法しか知りませんが、この例では問題なく動作する可能性があります)、もう一度ループして、対応するセルの X。

X を配置するために 'int markerX, int markerY' などの引数を取るテーブルを印刷するための関数を作成する必要がありますか?

ゲームが勝ったかどうかを確認できるように、マーカーの位置をどのように保存しますか?

コマンドラインでゲームのユーザー入力を求めるには、マーカーを配置するセルを選択するのが最善の方法ですか?

ありがとう!

4

4 に答える 4

3

これで、三目並べボードを画面に出力する方法をかなりうまく理解できましたが、現在欠けているのは、プログラムが変更して使用できるメモリー内の三目並べボードのモデルです。ボードの現在のステータスを再印刷します。

通常、モデル化する要素の 2 次元グリッドがある場合、これらを表す最も単純なモデルは2 次元配列です。次のように定義できます。

int board[WIDTH][HEIGHT]

次に、ボード上の任意の要素の現在の状態に、そのインデックスで参照することでアクセスできます (次のように、配列内の要素の数より常に 0 から 1 少ない値になります)。

int element = board[0][1]

ボードをユーザーに再出力するには、現在の状態を含むボードを出力する関数を実装する必要があります。その関数が存在すると、何度も繰り返す必要なく、コード内でいつでも呼び出すことができます。

最後に、ループを実装する必要があります。whileこれに最も適した構造です。条件が真になるまでループします。

int shouldExit = 0;
while (shouldExit == 0) {
    printBoard();
    getPlayerInput();
    updateBoard();

    // you can set shouldExit to 1 if the game is over 
    // (someone won, or the player inputted something that indicates they want to quit.
}
于 2010-08-12T00:10:26.697 に答える
1

次のように、ボードを印刷することが唯一の仕事である関数を作成します(テストされていません)。

void board_print(const char b[3][3]) }
   int i = 1;
   printf(        "     A   B   C\n");     // NOTE: Letters on top, like a spreadsheet
   while (1) {
      printf(      "%i  %c | %c | %c\n", i, b[i][0], b[i][1], b[i][2]);
      if (++i <=3) {
          printf(  "  ---+---+---\n");
      } else {
         break;
      }
   }
}

次に、次のようなボードを作成します。

int main(void) {
    char board[3][3] =
        {{ ' ', ' ', ' ' },
         { ' ', ' ', ' ' },
         { ' ', ' ', ' ' }};

    while (1) {
       board_print(board);
       printf("Place X at : ");

次に、XまたはOをある位置に配置することを全体の仕事とする別の関数を作成します。

int board_place(char board [3] [3]、charマーカー、char行、char列);

markerここでは、「x」または「o」のいずれかになります。

board_placeプレイの一般的な状態を判断するために使用できる値を返すことができます。たとえば、その位置にすでにマーカーがあったためにboard_placeが移動できなかった場合、行が範囲外の場合とは異なるエラーコードを返す必要があります。これは、勝者がいるかどうかを判断する場所でもあります(現在の手が勝者の手になるため、{現在の正方形を含む線をテストするだけでよいため簡単です})、またはボードがいっぱいで勝者がなく、リターンがない場合これらのそれぞれに異なるもの。

次に、メインコードは、board_placeの戻り値に基づいて何をするかを決定します(ユーザーにエラーメッセージを発行して別の位置を要求し、Oの移動を試み、ユーザーの勝利を祝福し、猫であることをユーザーに伝えますそれを勝ち取った、...)。

その位置で読む限り、それはユーザーインターフェースがテキスト処理と出会う場所です。単純なscanf呼び出しで十分な場合もあれば、getcharを数回呼び出すだけの場合もあります。ほとんどの人にとっておそらく簡単なので、行と列に異なるインデックスを付けることをお勧めします(私は文字と数字を使用しました)。次にboard_place、board_place内のインデックスの調整を前に調整するか、単に処理することができます。

于 2010-08-12T16:18:28.423 に答える
0

ゲーム ステータスを何らかのデータ構造に格納することはおそらく良い考えです。プレーヤー 1 またはプレーヤー 2 がそこにマーカーを配置したかどうかを格納する文字の 2 次元配列をお勧めします。

char board[WIDTH][HEIGHT];

次に、配列内の各要素を初期化した後、そこにマーカーがあるかどうかにアクセスできます

board[1][2]

たとえば、1、2 でマーカーを取得したい場合。

これで、ボードが変更されるたびに、以前と同様にネストされた for ループを使用してボードを再度出力する関数を作成できますが、代わりに 2 次元配列にアクセスすることになります。

于 2010-08-12T00:05:43.217 に答える
0

値をどこにも保存していないため、現在セルを参照できません。セルに値を格納する変数を作成する必要があります。セルの値を変更するには、関連する変数の値を変更してテーブルを再描画するだけです。

簡単にするためdraw_tableに、変数の現在の値を使用して三目並べを描画する関数を作成できます。

入力のみに を使用getchしている場合は、2 桁の数字を使用する代わりに、セルを 1 ~ 9 と呼ぶことがあります。これにより、変数の追跡が容易になる場合もあります。変数を 、 などと呼ぶことができますcell1cell2配列を使用することもできますが、始めたばかりの場合は複雑すぎる可能性があります。

于 2010-08-12T00:07:28.750 に答える