战舰:放置船只

时间:2014-04-17 04:12:12

标签: c

我在AVR设备上写了一个战舰游戏。一切正常,只有在游戏地图上放置船只几乎没有问题。有时船只被放在彼此旁边,即使我认为我的代码会阻止它。已经尝试过两天调试它。如果有人能够注意到我错在哪里,可以考虑将place_ships -function的代码放在这里。

int data_map[10][10]; //This has the data of where ships are, where player has shot etc.
char game_map[10][10]; //This is printed in UI. O for miss, X for hit.

int ship_sizes[] = {0,1,2,3,3,4,5};
int ships[] = {0,1,2,3,4,5,6};

void place_ships() {                        //Places the ships in the game map.

int other_ships;                        //Variabel for counting if there are already other ships in the area where trying place the ship.

for (i=6; i>0; i--) {

    while (1) {
        other_ships = 0;                //Initialize.
        ship_direction = rand() % 10;   //Get random ship direction (1-4 = horizontal, 6-10 = vertical)
        top_x = (rand() % 8) + 1;       //Get random x-coordinate, not from map edges
        top_y = (rand() % 8) + 1;       //Get random y-coordinate, not from map edges

        if (ship_direction < 5) {       

            if ((top_x-ship_sizes[i]) > -2) {       //Make sure that ship has room in game map.

                for (j=(top_y-1); j<(top_y+2); j++) {       //Following 2 for-loops and if-statement inside makes sure that no other ships are in
                                                            //the area where the ship is tried to place.
                    for (k=(top_x+1); k>(top_x-(ship_sizes[i]-2)); k--) {

                        if ((data_map[j][k] == 1) || (data_map[j][k] == 2) || (data_map[j][k] == 3) || (data_map[j][k] == 4) || (data_map[j][k] == 5) || (data_map[j][k] == 6)) {
                            other_ships = 1;        //Following 2 'breaks' and 'continue' are there for the situation if
                            break;                  //there are other ships in the area, stop placing ship and get new random coordinate and try again.
                        }
                    }

                if (other_ships == 1) {

                        break;
                }

                }

                if (other_ships == 1) {

                        continue;
                    }

                for (l=top_x; l>(top_x-ship_sizes[i]); l--) {

                    data_map[top_y][l] = ships[i];      //If no other ships in the area, place the ship.

                }

                loading();                              //Wait to optimize harware working. There are known timing issues on AVR. And this
                                                        //is here to try to avoid them.
                break;
            }
        }

        else if (ship_direction > 5) {

            if ((top_y-ship_sizes[i]) > -2) { //Make sure that ship has room in game map.

                for (j=(top_y+1); j>(top_y-(ship_sizes[i]-2)); j--) {   //Following 2 for-loops and if-statement inside makes sure that no other ships are in
                                                                        //the area where the ship is tryied toplace.
                    for (k=(top_x-1); k<(top_x+2); k++) {

                        if ((data_map[j][k] == 1) || (data_map[j][k] == 2) || (data_map[j][k] == 3) || (data_map[j][k] == 4) || (data_map[j][k] == 5) || (data_map[j][k] == 6)) {

                            other_ships = 1;        //Following 2 'breaks' and 'continue' are there for the situation if
                            break;                  //there are other ships in the area, stop placing ship and get new random coordinate and try again.
                        }
                    }

                if (other_ships == 1) {

                        break;
                }

                }

                if (other_ships == 1) {

                        continue;
                    }

                for (l=top_y; l>((top_y-(ship_sizes[i]))); l--) {

                    data_map[l][top_x] = ships[i];      //If no other ships in the area, place the ship.

                }

                loading();                              //Wait to optimize harware working. There are known timing issues on AVR. And this
                                                        //is here to try to avoid them.
                break;
            }
        }
    }
}
}

现在原来的问题已经解决了。还有一些船没有放置。什么船舶功能跳过,各不相同。

2 个答案:

答案 0 :(得分:1)

您在data_map上执行的查找其他船只的测试正在读取数组的末尾。你应该清理那些循环条件。例如,top_x在被分配(rand() % 8) + 1后可以高达8。然后ship_sizes[i]可以高达5.因此top_x+(ship_sizes[i]+2)可以是15。

我不确定是否可以解决您的问题,但这是一个问题。

您会发现问题出在数组索引中。 C中的数组是0索引的,在某些地方你可以将它们当作1个索引编号。

答案 1 :(得分:1)

在最后一个版本中:

for (k=(top_x+1); k>(top_x-(ship_sizes[i]-2)); k--) {

我认为条件应该是:

k > ( top_x - (ship_sizes[i] + 2) )  // not -2 but + 2

因为我想你要检查船只不会重叠ship_sizes [i]和相邻船只的所有长度。同样适用于y:

top_y-(ship_sizes[i] + 2)  // or top_y - ship_sizes[i] - 2

我建议你将这段代码解压缩到函数中,比如CheckOverlap,因为它会简化代码的读取和调试。

此外,从循环中提升条件的估值:

int length = top_x - (ship_sizes[i] + 2);
for (k= top_x+1; k > length; k--) {

更清晰的代码也将是:

int IsPlaced (j,k) {
    return 1 <= data_map[j][k] && data_map[j][k] <=6;
}

一般来说,尽量避免代码重复,将所有加倍的功能放在一起。它将减少倍增误差并大大简化您的程序设计,这对您和所有其他读者都有好处。