【问题标题】:C - Battleship, random ship placementC - 战舰,随机舰船放置
【发布时间】:2017-10-15 20:03:27
【问题描述】:

因此,我必须在 10x10 板上制作用户与计算机的 Battleship 游戏,用于编程课程。我必须让电脑随机放置五艘大小为 5、4、3、3 和 2 的船。

我所做的是,我生成了两个介于 0 和 9 之间的随机数作为我的 x 和 y 坐标,然后是第三个数字来决定船的放置方向。然后我使用 switch 语句来检查板上是否有足够的空间来首先放置船,如果有,则修改板阵列(好吧,这就是它应该做的)。

    int main(void)
{   int x,y, bato[5]={5,4,3,3,2}, NbCases=17, countShip, dir, lenShip, countCaseEmpt, countLenShip, nbCaseOk, countModCase,i, dirTest;
    time_t t;

    srand(time(&t));
    // gestir(plato a, int * bato, int x, int y)

    // plato coord={{5,3,2,2,2},{5,3},{5,3},{5,3},{5},{0},{1,1}};
    // plato is a custom data type defined as "int plato[10][10]"
    plato coord={0}; //plateau vide
    i=0;

    for (countShip=5 ; countShip>0 ; countShip--)
    {
        do{
        i++;
        printf("%d\n",i); //counter used to check if the do while loop worked at all

            nbCaseOk=0;
            dirTest=0;

            do {x=abs(rand())%10; y=abs(rand())%10;} while (coord[y][x]!=0);  //start coordinates selection

            dir = rand()%4;     //direction selection

            switch (countShip){             //ship lenght determination
                case 0: lenShip=2; break; 
                case 1: lenShip=3; break; 
                case 2: lenShip=3; break; 
                case 3: lenShip=4; break; 
                case 4: lenShip=5; break;}


            switch (dir){                   //empty case checker and square modifier
                case 0: //right
                {
                    if (x+lenShip-1<10)
                        for (countLenShip=1 ; countLenShip<lenShip ; countLenShip++)
                            if (coord[y][x+countLenShip]==0) nbCaseOk+=1;

                    if (nbCaseOk==lenShip-1) {dirTest=1;
                        for (countModCase=0 ; countModCase<lenShip ; countModCase++)
                            coord[y][x+countModCase]=countShip; break;}}

                case 1: //up
                {   
                    if (y+lenShip-1<10)
                        for (countLenShip=1 ; countLenShip<lenShip ; countLenShip++)
                            if (coord[y+countLenShip][x]==0) nbCaseOk+=1;

                    if (nbCaseOk==lenShip-1) {dirTest=1;
                        for (countModCase=0 ; countModCase<lenShip ; countModCase++)
                            coord[y+countModCase][x]=countShip; break;}}

                case 2: //left
                {
                    if (x-lenShip+1>=0)
                        for (countLenShip=1 ; countLenShip<lenShip ; countLenShip++)
                            if (coord[y][x-countLenShip]==0) nbCaseOk+=1;

                    if (nbCaseOk==lenShip-1) {dirTest=1;
                        for (countModCase=0 ; countModCase<lenShip ; countModCase++)
                            coord[y][x-countModCase]=countShip; break;}}

                case 3: //down
                {
                    if (y-lenShip+1>=0)
                        for (countLenShip=1 ; countLenShip<lenShip ; countLenShip++)
                            if (coord[y-countLenShip][x]==0) nbCaseOk+=1;

                    if (nbCaseOk==lenShip-1) {dirTest=1;
                        for (countModCase=0 ; countModCase<lenShip ; countModCase++)
                            coord[y-countModCase][x]=countShip; break;}}
        }} while (dirTest==0);


    }

    aff(coord);

    while (NbCases>0)
    {
        printf("Rentrer une coordonnee x, puis une coordonnee y, comprises entre 0 et 9:"); //"enter a coordinate between 0 and 9 for x, then another one for y:
        scanf("%d",&x); scanf("%d",&y);

        NbCases+=gestir(coord, bato, x, y);
        aff(coord);
    }

    printf("état bateau: %d\n nombre cases: %d",coord[0][0], NbCases); //ship state and number of empty squares         
return 0;
}

我的问题是我得到了一个无限循环。我很确定错误出现在我的 switch 语句中。我使用调试器查看导致问题的原因是什么,并且我注意到在执行 swotch 语句时二维数组(坐标)没有被修改,即使有足够的空间可以放置船。 我将 do while 循环的条件设置为 (dirTest==0),但即使在 switch 语句的末尾 dirTest 明显等于 1,循环也不会结束。

PS:如果我的代码乱七八糟,我真的很抱歉,今年之前我一生中唯一做过的编程是去年的一些非常轻量级的 python。

【问题讨论】:

  • “在此之前我一生中唯一做过的编程......” - 哇 - 在我看来,这是一个相当复杂的第一个项目。
  • 如果我不够清楚,我很抱歉。在这个之前,我确实喜欢过十几个其他的 C 程序,但是这个是第一个真正引起争论的程序。

标签: c switch-statement do-while


【解决方案1】:

您的格式没有帮助;请尽量采用更传统的风格。但是,我可以看到几个问题。

  • switch (dir) 块内的break 语句仅在if (nbCaseOk==lenShip-1) 评估为真时才会到达。因此,当dir == 0 时,您可能会仔细阅读此代码的每一部分。

  • for (countShip=5 ; countShip&gt;0 ; countShip--) 可以,但除非您有充分的理由倒数,否则请改用for (countShip=0; countShip&lt;5 ; countShip++)。无论如何,countShip 在您编写的代码中将具有 5、4、3、2 和 1 的值。不是 switch (countShip) 代码块所期望的 4、3、2、1、0。我不确定您的代码中 nbCaseOk 发生了什么,但也许您的循环没有退出,因为 lenShip 永远不等于 2?

  • abs(rand())%10 是多余的。 rand()%10 就可以了。

  • 在更一般的注释上;你在这里重复了很多代码。尝试使用相同的代码处理所有dir 案例(例如,通过修改两个变量dxdy)。

【讨论】:

  • 将你的代码分解成更小的函数会对你有很大帮助。这样,您可以仔细调试较小的函数以确保它们按预期执行,并且在调试这些函数时可以专注于调用函数的逻辑。这样,您必须一次调试所有内容。
  • 非常感谢!事实证明问题一直是 for(countShip=0;countShip
【解决方案2】:

看起来在 for 循环的第一次运行 countShip 等于 5,并且此值未在您的开关中处理,这意味着您没有为 lenShip 分配任何有意义的值。因为nbCaseOk==lenShip-1 条件永远不会满足,所以你永远不会执行dirTest=1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 2021-11-30
    • 2022-01-02
    • 2013-07-28
    相关资源
    最近更新 更多