0

TicTacToeのゲームを作りたいです。ウィンドウのサイズを変更すると、インターフェイスに表示されるボタンが増えます。ウィンドウのサイズを変更する量に応じて、3x3 から 4x4 などのマトリックスから 9x9 まで。どうすればいいですか?

私は、有効な回答 (および、tictactoe をプレイするための完全なプログラムのための特別な何か) を提供してくれる人に、無料の Web サイトのデザインを作成します。

ありがとうございました!

4

1 に答える 1

2

ボタンの最大サイズを設定し、コンテナサイズを分割して、必要なボタンの数を見つけることができます。この部分はすべて簡単で、ボタンの追加は実際には問題ありません。このプロパティを使用して、Tag三目並べ配列内のボタンの位置を追跡できます。

必要なボタンの数が最大であるため、最初から9x9のボタンを作成し、必要に応じてVisibleプロパティをfalse表示するように設定するだけでよいと思います。サイズ変更ルーチンは、ボタンのサイズを変更するだけで済みます。

フォームコンストラクターでボタンを作成する方法の簡単な例を示しましたが、これは非常に単純ですが、上記の点を説明するのに役立つだけです。2次元配列ではなく、1次元配列を使用していることに注意してください。これは、後で勝者を見つけやすくするためです。

// Declare constants used for our tic tac toe example
const int minButtons = 3; // The minimum number of buttons in either direction
const int maxButtons = 9; // The maximum number of buttons in either direction
const int buttonDistance = 5; // The distance between the buttons
const int buttonSize = 50; // The targeted button size.

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
 : TForm(Owner)
{
    // Create our buttons and set some tag value to identify them later.
    for (int i = 0; i < maxButtons; i++)
    {
        for (int j = 0; j < maxButtons; j++)
        {
            int idx = i * maxButtons + j;

            buttons[idx] = new TButton(this);
            buttons[idx]->Parent = this;

            // Assign the on click event (we define this later)
            buttons[idx]->OnClick = ButtonPressed;
        }
    }

    // Let the X player start
    currentPlayer = "X";
}

ボタンを作成した後、フォームOnResizeイベントで表示するボタンの数とサイズを制御できます。

void __fastcall TForm1::FormResize(TObject *Sender)
{
    // Calculate the number of buttons to display.
    int btd = std::min(ClientWidth, ClientHeight) / buttonSize;

    // Make sure we have atleast minButtons and at most maxButtons buttons.
    btd = (btd < minButtons) ? minButtons : (btd > maxButtons) ? maxButtons : btd;

    // Write the tic tac toe board size in the form caption
    Caption = IntToStr(btd) + " x " + IntToStr(btd);

    // Calculate the new button size.
    int buttonWidth = (ClientWidth - (btd - 1) * buttonDistance) / btd;
    int buttonHeight = (ClientHeight - (btd - 1) * buttonDistance) / btd;

    // Show and position buttons
    for (int i = 0; i < maxButtons; i++)
    {
        for (int j = 0; j < maxButtons; j++)
        {
            int idx = i * maxButtons + j;

            if (i < btd && j < btd)
            {
                buttons[idx]->Visible = true;
                buttons[idx]->Width = buttonWidth;
                buttons[idx]->Height = buttonHeight;
                buttons[idx]->Left = i * buttonWidth + i * buttonDistance;
                buttons[idx]->Top = j * buttonHeight + j * buttonDistance;
            }
            else
            {
                buttons[idx]->Visible = false;
            }
        }
    }
}

ここで、ユーザー入力を処理するコードが必要です。つまり、ユーザーがボタンの1つを押すたびに、SenderパラメーターをTButtonにキャストします。これにより、単一の関数でクリック処理を実行できます。

void __fastcall TForm1::ButtonPressed(TObject *Sender)
{
    TButton *btn = dynamic_cast<TButton*>(Sender);
    if (btn)
    {
        // Check if this button is free to be pressed
        if (btn->Enabled)
        {
            btn->Caption = currentPlayer;
            btn->Enabled = false;


            if (IsWinner())
                ShowMessage(currentPlayer + " is the winner :)");

            if (currentPlayer == "X") currentPlayer = "O";
            else currentPlayer = "X";
        }
    }
}

最後に、現在のプレーヤーが勝者であるかどうかを確認する簡単な関数を追加します。これは明らかに、よりスマートに、はるかに最適化できますが、これはインスピレーションの源として機能する単純な例です。

bool __fastcall TForm1::IsWinner()
{
    bool foundWinner;

    // Calculate the number of buttons to display.
    int btd = std::min(ClientWidth, ClientHeight) / buttonSize;

    // Make sure we have atleast minButtons and at most maxButtons buttons.
    btd = (btd < minButtons) ? minButtons : (btd > maxButtons) ? maxButtons : btd;

    // Check for a winner in the direction top to bottom
    for (int i = 0; i < btd; i++)
    {
        foundWinner = true;

        for (int j = 0; j < btd; j++)
        {
            if (buttons[i * maxButtons + j]->Caption != currentPlayer)
                foundWinner = false;
        }

        if (foundWinner) return true;
    }

    // Check for a winner in the direction left to right
    for (int j = 0; j < btd; j++)
    {
        foundWinner = true;

        for (int i = 0; i < btd; i++)
        {
            if (buttons[i * maxButtons + j]->Caption != currentPlayer)
                foundWinner = false;
        }

        if (foundWinner) return true;
    }

    // Check for a winner in the diagonal directions
    foundWinner = true;
    for (int i = 0; i < btd; i++)
    {
        if (buttons[i * maxButtons + i]->Caption != currentPlayer)
            foundWinner = false;
    }

    if (foundWinner) return true;

    foundWinner = true;
    for (int i = btd - 1; i >= 0; i--)
    {
        if (buttons[i * maxButtons + i]->Caption != currentPlayer)
            foundWinner = false;
    }

   return foundWinner;
}

明らかに、やるべきことがたくさん残っています。勝った人の処理全体(更新は簡単なチェックを追加しただけです)、新しいゲームを開始するためのインターフェイスの作成などです。ゲームは完全にエラープルーフではありませんが、現在のバージョンではゲームが開始した後でもサイズを変更すると、ゲームは余分なボタンを追加します。これはおそらくあなたが望むものではありませんが、これを修正することはサイズ変更機能にチェックを追加するという簡単な質問です。とにかく、私はあなたのためにゲーム全体を作成しようとはしていません、私はあなたがそれを自分でやりたいと確信しています。

あなたがそれが有用であると思うなら、あなたはそれを使うことができます、そうでなければ、おそらく(そしておそらく)あなたは私のアプローチ(実際には2分間の解決策です)に触発されることができます。それがあなたのために働くことを願っています。無料のウェブデザインは必要ありません、私はあなたが後でいくつかの質問のためにそれを保存することができると思います;)

于 2010-01-07T02:03:35.653 に答える