0

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

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

谢谢!

4

1 回答 1

2

您可以做的是设置按钮应具有的最大大小,然后简单地划分容器大小以找到您想要的按钮数量。这部分很简单,添加按钮并不是什么问题。您可以使用该Tag属性来跟踪井字游戏数组中的按钮位置。

我在想,由于您需要的按钮数量最多,您可以从一开始就创建 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 分钟的解决方案)。希望对你有效。免费的网页设计不是必需的,我想你可以把它留到以后的问题;)

于 2010-01-07T02:03:35.653 回答