如何在战舰中隐藏“战舰”而不重叠?

时间:2019-02-13 20:40:20

标签: c#

在将飞船对象隐藏在button [,]。Tag(游戏图块)内部之前,我检查了IF(button [,]。tag == null),但是我仍然会随机地重叠飞船吗?在平均5场比赛中,可能发生了2/3次?它似乎也是随机的,有时它们会在末端,中间或完全覆盖彼此重叠。

我正在重新创建战舰游戏,并在隐藏“战舰”时遇到问题。船是我创建的对象,图块是面板中的按钮。我选择了3个随机数,其中2个用于坐标,最后一个随机数决定了船只是垂直还是水平。然后,我在For循环内有一个If语句,该语句检查button [1st#,2nd#]。Tag == null,如果为null,则将飞船对象放置在button [1st#,2nd#]。Tag中。 for循环将根据舰船的大小进行迭代,或者根据舰船的水平或垂直状态在第一个或第二个数字上加上+1。

private void HideShips() // method to hide the ships in the buttons
        {
            foreach(Ship s in AllShips)
            {
                //pick 2 random numbers
                int firstNum = rnd.Next(0, (19 - s.Size)); // game board is 20x20
                int secondNum = rnd.Next(0, (19 - s.Size));
                int rando = rnd.Next(0, 100);

                //decides horizontal/vertical at random
                if (rando > 50)
                {
                    //horizontal
                    for (int x = 0; x < s.Size; x++)
                    {
                        if (SeaButtons[firstNum + x, secondNum].Tag == null)
                        {
                            SeaButtons[firstNum + x, secondNum].Tag = s;
                        }
                    }
                }
                else
                {
                    //vertical
                    for (int x = 0; x < s.Size; x++)
                    {
                        if (SeaButtons[firstNum, secondNum + x].Tag == null)
                        {
                            SeaButtons[firstNum, secondNum + x].Tag = s;
                        }
                    }
                }
            }
        }

在将飞船对象放入SeaButtons [1Num,2Num] .Tag之前,我希望程序测试SeaButtons [1Num,2Num] .Tag ==是否为null?我在该程序中有另一个方法称为Stop();哪个测试所有按钮。标记值确定船是否隐藏在其中并结束游戏+显示隐藏的船,效果很好?

3 个答案:

答案 0 :(得分:0)

问题在于,在分配它们之前,您没有选中船将使用的所有按钮。 实际上,您的程序开始放置您的飞船,并且仅在找到已使用的按钮时才卸下零件。这样您的船就可以减半。

创建第一个循环,检查每个按钮,并在所有位置均空的情况下以布尔值分配,然后在该位置放置您的船

答案 1 :(得分:0)

看起来,当您在测试以查看某个特定按钮是否已在船上时,实际上并没有处理该情况。如果您放置的是5个长块,而第2点与另一个重叠,则不会设置该块的标签,但您将继续使用该船的其余部分。

一个可能的解决方案是创建一个函数来测试是否可以放置一块,如果可以的话,可以这样做。如果不是,请选择另一个随机点。例如,

private bool CanPlace(int x, int y, int size, bool horizontal)
{
    if (horizontal)
    {
        for (int x = 0; x < size; x++)
        {
            if (SeaButtons[firstNum + x, secondNum].Tag != null)
            {
                return false;
            }
        }
    }
    else
    {
        //same as above
    }
    return true;
}

private void HideShips() // method to hide the ships in the buttons
{
    foreach(Ship s in AllShips)
    {
        //pick 2 random numbers
        int firstNum = rnd.Next(0, (19 - s.Size)); // game board is 20x20
        int secondNum = rnd.Next(0, (19 - s.Size));
        int rando = rnd.Next(0, 100);

        while (!CanPlace(firstNum, secondNum, s.Size, rando > 50)
        {
            firstNum = rnd.Next(0, (19 - s.Size));
            secondNum = rnd.Next(0, (19 - s.Size));
            rando = rnd.Next(0, 100);
        }

        //decides horizontal/vertical at random
        if (rando > 50)
        {
            //horizontal
            for (int x = 0; x < s.Size; x++)
            {
                SeaButtons[firstNum + x, secondNum].Tag = s;
            }
        }
        else
        {
            //vertical
            for (int x = 0; x < s.Size; x++)
            {
                SeaButtons[firstNum, secondNum + x].Tag = s;
            }
        }
    }
}

一个缺点是您可能会受到很大的欢迎,并且需要经常重新选择一个位置。

答案 2 :(得分:0)

您可以采用另一种方法来排序字段,而不是像这样的od(x,y)坐标

| 0 | 1 | 2 | 3 |
| 4 | 5 | 6 | 7 |
| 8 | 9 | 10| 11|

,然后从0到(width * height)-1中选择n个数字, 然后将其转换为(x,y)坐标,如下所示:

x = number % width
y = number / width