C Builder 6 中按钮的动态分配?

发布于 2024-08-17 12:16:40 字数 155 浏览 5 评论 0原文

我想制作一款井字棋游戏。当我调整窗口大小时,我想在界面上显示更多按钮。从 3x3 到 4x4 等到 9x9 的矩阵,具体取决于我调整窗口大小的程度。我该怎么做?

我将为任何向我提供有效答案的人制作一个免费的网站设计(以及玩井字游戏的完整程序的额外内容)。

谢谢你!

I want to make a game of TicTacToe. WhenI resize the window I want to appear more buttons on the interface. From a matrix of 3x3 to 4x4 etc up to 9x9, depending on how much I resize the window. How do I do this?

I will make a free web site design to whoever provides me with a working answer (and something extra for the full program of playing tictactoe).

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的他你的她 2024-08-24 12:16:40

您可以做的是设置按钮应具有的最大大小,然后只需除以容器大小即可找到您想要的按钮数量。这部分很简单,添加按钮并不是什么问题。您可以使用 Tag 属性来跟踪 tic tac toe 数组中的按钮位置。

我在想,既然您想要的按钮数量达到了上限,您可以从头开始创建 9x9 按钮,只需将其 Visible 属性设置为 false 显示当您需要它们时。然后,调整大小例程只需调整按钮的大小。

我提供了一个如何在表单构造函数中创建按钮的简单示例,请注意,虽然这非常简单,但只是为了说明我的上述观点。请注意,我使用的是一维数组,而不是二维数组,这是为了以后更容易找到获胜者。

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

现在我们需要代码来处理用户输入,即每当用户按下其中一个按钮时,我们将 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 分钟完成的解决方案)。希望它对你有用。免费的网页设计不是必需的,我想您可以将其保存到以后的问题中;)

What you could do is set a maximum size a button should have, and then simply divide the container size to find the amount of buttons you'd want. This part is all easy, adding buttons is not really any problem. You could use the Tag property to keep track of the buttons position in the tic tac toe array.

I'm thinking though since you have a maximum amount of buttons you'd want, you could create the 9x9 buttons from the beginning, simply setting their Visible property to false showing them as you need them. The resize routine then only has to resize the buttons.

I have provided a simple example of how to create the buttons in the form constructor, note though that this is extremely simple, but simply serves to illustrate my above point. Note that I'm using a single dimensional array, instead of a 2 dimensional one, this is to make it easier finding a winner later on.

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

After creating the buttons you can control how many to display and size these in the forms OnResize event:

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

Now we need the code to process the user input, that is whenever the user presses one of our buttons, we cast the Sender parameter to a TButton, this way we can do the click processing in a single function.

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

Finally we add a simple function to check if the current player is the winner, this can obviously be made more smart and much more optimized, but this is just a simple example serving as source of inspiration:

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

Obviously there is a lot left to be done, the whole processing of who has won (update just added a simple check), creating an interface to start a new game etc. Besides the game is not entirely error proof, in the current version the game adds extra buttons when you resize even after the game has started, this is most likely not what you want, but fixing this is a simple question of adding a check to the resize function. Anyway I'm not about to create the entire game for you, I'm quite certain you'd wanna do that yourself.

If you find it useful you can use it, if not then perhaps (and most likely) you can be inspired by my approach (which is really a 2 minute made solution). Hope it works for you. The free webdesign won't be neccesary, I guess you can save that for some later question ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文