C++ 三目並べゲーム

Ammar Ali 2024年2月15日
  1. C++ 三目並べゲーム
  2. 手順 1: 3 行 3 列のグリッドを描画する関数を作成する
  3. ステップ 2: ユーザーに行番号と列番号の入力を求める
  4. ステップ 3: ユーザーが入力した位置が占有されているかどうかを確認する
  5. ステップ 4: ゲームの勝者を確認する関数を作成する
C++ 三目並べゲーム

このチュートリアルでは、C++ で条件文とループを使用して三目並べゲームを作成する方法について説明します。

C++ 三目並べゲーム

Tic tac toe は 2 人で行うゲームで、各プレイヤーが 3 行 3 列のグリッド内の場所に印を付け、水平、垂直、または斜めの直線上に 3つのマークを配置することに成功したプレイヤーがゲームの勝者になります。 . ゲームの例の画像を以下に示します。

C++ 三目並べゲーム

プレーヤー X の 3つのマーカーが対角線上にあるため、プレーヤー X が三目並べゲームの勝者であることがわかります。 C++ で同じゲームを作成するには、同じアルゴリズムを使用して、ペンと紙を使用してゲームをプレイする必要があります。

ペンを使用して紙に 3 x 3 のグリッドを描画し、各プレイヤーは向きを変えて、空いているスペースのグリッド内にマーカーを配置します。 1 人のプレーヤーが 3つのマーカーを一直線に並べると、そのプレーヤーがゲームに勝利し、ゲームは終了します。

どのプレイヤーも 3つのマーカーを直線上に配置しないか、グリッド内のすべての場所が占有されている場合、ゲームは引き分けで終了します。 同じアルゴリズムを使用して、C++ で三目並べゲームを作成できます。

最初のステップでは、3 行 3 列のグリッドを描画する関数を作成する必要があります。 2 番目のステップでは、ユーザーから行番号と列番号の形式で入力を取得し、入力が有効かどうかを確認する必要があります。

3 番目のステップでは、ユーザーが入力した位置が占有されているかどうかを確認する必要があります。占有されていない場合は、グリッド内のユーザーが入力した位置にプレーヤーのマーカーを配置します。 場所が占有されている場合、プレーヤーに別の位置に入るように依頼します。 すべてのポジションが占有されている場合は、ゲームを終了し、引き分けであると発表します。

4 番目のステップでは、いずれかのプレイヤーの 3つのマーカーが直線上にあるかどうかを確認します。 プレーヤーのマーカーが一直線上にある場合は、ゲームを終了し、ゲームに勝ったプレーヤーの名前を発表します。マーカーが一直線上にない場合は、2 番目のステップに戻って繰り返します。

手順 1: 3 行 3 列のグリッドを描画する関数を作成する

それでは、3 x 3 のボードを描く最初のステップからゲームの作成を始めましょう。 パイプ文字|の組み合わせを使用してボードを描くことができます およびダッシュ文字 - をキーボードから入力します。

ダッシュ文字 - を使用して水平線を描画し、パイプ文字 | を使用できます。 グリッドに存在する垂直線を描画し、数字を使用してグリッドの行番号と列番号をマークできます。 たとえば、C++ cout() 関数を使用して 3 行 3 列のグリッドを描画してみましょう。

以下のコードを参照してください。

#include <iomanip>
#include <iostream>

using namespace std;
void drawGameBoard(char Gameboard[][3]);

int main() {
  char Gameboard[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
  drawGameBoard(Gameboard);
  return 0;
}

void drawGameBoard(char Gameboard[][3]) {
  cout << "     1   2   3" << endl;
  cout << "   -------------" << endl;

  cout << " 1"
       << " | " << Gameboard[0][0] << " | " << Gameboard[0][1] << " | "
       << Gameboard[0][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 2"
       << " | " << Gameboard[1][0] << " | " << Gameboard[1][1] << " | "
       << Gameboard[1][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 3"
       << " | " << Gameboard[2][0] << " | " << Gameboard[2][1] << " | "
       << Gameboard[2][2] << " | " << endl;
  cout << "   -------------" << endl;
}

出力:

     1   2   3
   -------------
 1 |   |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------

上記のコードは、endl ステートメントを使用して、カーソルを新しい行に移動します。 上記の出力では、縦方向に再生される数字は行番号を表し、横方向の数字は列番号を表します。

ステップ 2: ユーザーに行番号と列番号の入力を求める

2 番目のステップでは、ユーザーがマーカーを配置したい行と列の番号を入力するようユーザーに求めることができます。 条件ステートメントを使用してユーザー入力をチェックし、行番号または列番号が 1 から 3 の範囲内にない場合はエラーを表示し、ユーザーに入力を再入力するように求めます。

ループを使用してユーザーからの入力を受け取り、ユーザーが有効な行番号と列番号を入力するまでループが続きます。 たとえば、while ループと if-else ステートメントを使用して、ユーザーからの入力を取得してみましょう。

以下のコードを参照してください。

#include <iomanip>
#include <iostream>

using namespace std;
void drawGameBoard(char Gameboard[][3]);

int main() {
  int Boardrow;
  int Boardcolumn;
  bool is_Boardrow;
  bool is_Boardcolumn;
  char Gameboard[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
  drawGameBoard(Gameboard);

  is_Boardrow = false;
  while (!is_Boardrow) {
    cout << "BoardRow: ";
    cin >> Boardrow;
    if (Boardrow == 1 || Boardrow == 2 || Boardrow == 3) {
      is_Boardrow = true;
    } else {
      cout << endl << "Invalid Boardrow!" << endl;
    }
  }
  is_Boardcolumn = false;
  while (!is_Boardcolumn) {
    cout << "BoardColumn: ";
    cin >> Boardcolumn;
    if (Boardcolumn == 1 || Boardcolumn == 2 || Boardcolumn == 3) {
      is_Boardcolumn = true;
    } else {
      cout << endl << "Invalid Boardcolumn!" << endl;
    }
  }
  return 0;
}

void drawGameBoard(char Gameboard[][3]) {
  cout << "     1   2   3" << endl;
  cout << "   -------------" << endl;

  cout << " 1"
       << " | " << Gameboard[0][0] << " | " << Gameboard[0][1] << " | "
       << Gameboard[0][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 2"
       << " | " << Gameboard[1][0] << " | " << Gameboard[1][1] << " | "
       << Gameboard[1][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 3"
       << " | " << Gameboard[2][0] << " | " << Gameboard[2][1] << " | "
       << Gameboard[2][2] << " | " << endl;
  cout << "   -------------" << endl;
}

出力:

     1   2   3
   -------------
 1 |   |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------
BoardRow: 5

Invalid Boardrow!
BoardRow: 1
BoardColumn: 6

Invalid Boardcolumn!
BoardColumn: 2

上記のコードでは、BoardrowBoardcolumn の 2つの整数を使用して、ユーザー入力を格納しました。 入力のステータスを格納するために、2つのブール変数 is_boardRowis_boardColumn を使用しました。

2つのブール変数を false に設定すると、ループが繰り返され、ユーザーに行と列の番号を入力するように求められます。入力された数値が有効な場合、ブール値は true に設定され、 ループが壊れます。 2つのループを使用しました。1つは行番号用で、もう 1つは列番号用です。

上記の出力は、無効な行番号または列番号を入力すると、コードが無効な行番号または列番号を表示し、ユーザーに入力を再入力するように求めることを示しています。

ステップ 3: ユーザーが入力した位置が占有されているかどうかを確認する

3 番目のステップでは、ユーザーが入力した位置にプレーヤーのマーカーを配置する必要がありますが、その前に、入力した位置が占有されているかどうかを確認する必要があります。

ポジションが占有されている場合は、ユーザーに別のポジションを入力するように求めます。ポジションが占有されていない場合は、プレイヤーのマーカーをボード内の入力された位置に配置します。

1 人のプレーヤーがゲーム ボードまたはグリッドにマーカーを配置した後、プレーヤーを変更する必要があります。 たとえば、ループと条件文を使用してマーカーをボードに配置してみましょう。

以下のコードを参照してください。

#include <iomanip>
#include <iostream>

using namespace std;

void drawGameBoard(char Gameboard[][3]);
char checkGameWinner3by3(char Gameboard[][3]);

int main() {
  char Gameboard[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
  char Gameplayer = 'X';
  char Gamewinner = ' ';
  int Boardrow;
  int Boardcolumn;
  bool is_Validmove;
  bool is_Boardrow;
  bool is_Boardcolumn;

  cout << "************ TIC TAC TOE Game ************\n";
  while (Gamewinner == ' ') {
    is_Validmove = false;
    is_Boardrow = false;
    is_Boardcolumn = false;
    drawGameBoard(Gameboard);
    cout << "GamePlayer ";

    if (Gameplayer == 'X') {
      cout << 'X';
    } else {
      cout << 'O';
    }
    cout << "'s turn:" << endl;
    is_Validmove = false;

    while (!is_Validmove) {
      is_Boardrow = false;
      while (!is_Boardrow) {
        cout << "BoardRow: ";
        cin >> Boardrow;
        if (Boardrow == 1 || Boardrow == 2 || Boardrow == 3) {
          is_Boardrow = true;
        } else {
          cout << endl << "Invalid Boardrow!" << endl;
        }
      }
      is_Boardcolumn = false;
      while (!is_Boardcolumn) {
        cout << "BoardColumn: ";
        cin >> Boardcolumn;
        if (Boardcolumn == 1 || Boardcolumn == 2 || Boardcolumn == 3) {
          is_Boardcolumn = true;
        } else {
          cout << endl << "Invalid Boardcolumn!" << endl;
        }
      }

      if (Gameboard[Boardrow - 1][Boardcolumn - 1] == ' ') {
        Gameboard[Boardrow - 1][Boardcolumn - 1] = Gameplayer;
        is_Validmove = true;
        if (Gameplayer == 'X') {
          Gameplayer = 'O';
        } else {
          Gameplayer = 'X';
        }
      } else {
        cout << "The selected space is occupied!" << endl;
        cout << "Select a different space:" << endl << endl;
        drawGameBoard(Gameboard);
      }
    }
    cout << endl;
  }
  system("pause");
  return 0;
}

void drawGameBoard(char Gameboard[][3]) {
  cout << "     1   2   3" << endl;
  cout << "   -------------" << endl;

  cout << " 1"
       << " | " << Gameboard[0][0] << " | " << Gameboard[0][1] << " | "
       << Gameboard[0][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 2"
       << " | " << Gameboard[1][0] << " | " << Gameboard[1][1] << " | "
       << Gameboard[1][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 3"
       << " | " << Gameboard[2][0] << " | " << Gameboard[2][1] << " | "
       << Gameboard[2][2] << " | " << endl;
  cout << "   -------------" << endl;
}

出力:

************ TIC TAC TOE Game ************
     1   2   3
   -------------
 1 |   |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer X's turn:
BoardRow: 1
BoardColumn: 1

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer O's turn:
BoardRow: 2
BoardColumn: 2

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 |   | O |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer X's turn:
BoardRow:

上記のコードでは、別のブール変数 is_validMove を使用して、入力された位置のステータスを保存しました。 ブール値は false に設定され、while ループが繰り返されます。 ブール値は true に設定されており、ユーザーがまだ占有されていない位置に入った場合は true に設定します。

空の文字列に設定された別の変数 Gamewinner を使用しました。これは、次のステップで勝者を宣言してゲームを停止するために使用されます。

ユーザーからの入力を受け取る while ループの下で、if-else ステートメントを使用して、Gameboard 配列内で入力された位置を確認し、位置が空いている場合は、プレイヤーのマーカーを追加して設定します。 is_validmove ブール値を true に変更し、プレーヤーを変更します。スペースが空いていない場合は、スペースが占有されていることを表示し、ユーザーに別のスペースまたは位置に入るように求めます。その後、 ゲームボードを描きます。

上記の出力では、プレイヤー マーカーがゲーム ボード内に配置されていることがわかります。

ステップ 4: ゲームの勝者を確認する関数を作成する

最後のステップでは、ゲームの勝者を確認する関数を作成します。 ゲームの勝者を確認するには、グリッドまたはゲーム ボードの各行、列、および対角線のエントリを確認する必要があります。

ボードの行、列、または対角線のエントリのいずれかに 3つの同じマーカーがある場合、そのマーカーを返します。3つのマーカーがない場合は、空の文字列を返します。

ゲームの勝者関数の出力を Gamewinner 変数内に保存し、ゲームの勝者がいる場合はメイン ループを停止します。 それ以外の場合は続行されます。

勝者がいる場合は、それを発表してゲームを終了します。 それ以外の場合、ゲームは引き分けになります。 たとえば、for ループと条件ステートメントを使用して、ゲームの勝者関数を作成してみましょう。

以下のコードを参照してください。

#include <iomanip>
#include <iostream>

using namespace std;

void drawGameBoard(char Gameboard[][3]);
char checkGameWinner3by3(char Gameboard[][3]);

int main() {
  char Gameboard[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
  char Gameplayer = 'X';
  char Gamewinner = ' ';
  int Boardrow;
  int Boardcolumn;
  bool is_Validmove;
  bool is_Boardrow;
  bool is_Boardcolumn;

  cout << "************ TIC TAC TOE Game ************\n";
  while (Gamewinner == ' ') {
    is_Validmove = false;
    is_Boardrow = false;
    is_Boardcolumn = false;
    drawGameBoard(Gameboard);
    cout << "GamePlayer ";
    if (Gameplayer == 'X') {
      cout << 'X';
    } else {
      cout << 'O';
    }
    cout << "'s turn:" << endl;
    is_Validmove = false;
    while (!is_Validmove) {
      is_Boardrow = false;
      while (!is_Boardrow) {
        cout << "BoardRow: ";
        cin >> Boardrow;
        if (Boardrow == 1 || Boardrow == 2 || Boardrow == 3) {
          is_Boardrow = true;
        } else {
          cout << endl << "Invalid Boardrow!" << endl;
        }
      }
      is_Boardcolumn = false;
      while (!is_Boardcolumn) {
        cout << "BoardColumn: ";
        cin >> Boardcolumn;
        if (Boardcolumn == 1 || Boardcolumn == 2 || Boardcolumn == 3) {
          is_Boardcolumn = true;
        } else {
          cout << endl << "Invalid Boardcolumn!" << endl;
        }
      }
      if (Gameboard[Boardrow - 1][Boardcolumn - 1] == ' ') {
        Gameboard[Boardrow - 1][Boardcolumn - 1] = Gameplayer;
        is_Validmove = true;
        if (Gameplayer == 'X') {
          Gameplayer = 'O';
        } else {
          Gameplayer = 'X';
        }
      } else {
        cout << "The selected space is occupied!" << endl;
        cout << "Select a different space:" << endl << endl;
        drawGameBoard(Gameboard);
      }
    }
    cout << endl;
    Gamewinner = checkGameWinner3by3(Gameboard);
    if (Gamewinner == 'X' || Gamewinner == 'O') {
      drawGameBoard(Gameboard);
      cout << "Congratulations! GamePlayer ";
      if (Gamewinner == 'X') {
        cout << 'X';
      } else {
        cout << 'O';
      }
      cout << " is the Gamewinner!" << endl;
    } else if (Gamewinner == 'T') {
      drawGameBoard(Gameboard);
      cout << "It's a tie!" << endl;
    }
  }

  system("pause");
  return 0;
}

void drawGameBoard(char Gameboard[][3]) {
  cout << "     1   2   3" << endl;
  cout << "   -------------" << endl;

  cout << " 1"
       << " | " << Gameboard[0][0] << " | " << Gameboard[0][1] << " | "
       << Gameboard[0][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 2"
       << " | " << Gameboard[1][0] << " | " << Gameboard[1][1] << " | "
       << Gameboard[1][2] << " | " << endl;
  cout << "   -------------" << endl;

  cout << " 3"
       << " | " << Gameboard[2][0] << " | " << Gameboard[2][1] << " | "
       << Gameboard[2][2] << " | " << endl;
  cout << "   -------------" << endl;
}
char checkGameWinner3by3(char Gameboard[][3]) {
  for (int i = 0; i < 3; i++) {
    if (Gameboard[i][0] == Gameboard[i][1] &&
        Gameboard[i][0] == Gameboard[i][2]) {
      return Gameboard[i][0];
    }
  }

  for (int i = 0; i < 3; i++) {
    if (Gameboard[0][i] == Gameboard[1][i] &&
        Gameboard[0][i] == Gameboard[2][i]) {
      return Gameboard[0][i];
    }
  }

  if (Gameboard[0][0] == Gameboard[1][1] &&
      Gameboard[1][1] == Gameboard[2][2]) {
    return Gameboard[0][0];
  }

  if (Gameboard[0][2] == Gameboard[1][1] &&
      Gameboard[1][1] == Gameboard[2][0]) {
    return Gameboard[0][2];
  }

  return ' ';
}

出力:

************ TIC TAC TOE Game ************
     1   2   3
   -------------
 1 |   |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer X's turn:
BoardRow: 1
BoardColumn: 1

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 |   |   |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer O's turn:
BoardRow: 2
BoardColumn: 1

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 | O |   |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer X's turn:
BoardRow: 2
BoardColumn: 2

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 | O | X |   |
   -------------
 3 |   |   |   |
   -------------
GamePlayer O's turn:
BoardRow: 3
BoardColumn: 1

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 | O | X |   |
   -------------
 3 | O |   |   |
   -------------
GamePlayer X's turn:
BoardRow: 3
BoardColumn: 3

     1   2   3
   -------------
 1 | X |   |   |
   -------------
 2 | O | X |   |
   -------------
 3 | O |   | X |
   -------------
Congratulations! GamePlayer X is the Gamewinner!

コードには checkGameWinner3by3() 関数があり、ボードを入力として受け取り、2つの for ループと 2つの if ステートメントを含んでいます。 for ループは行と列のチェックに使用され、if ステートメントは対角エントリのチェックに使用されます。

著者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook