Возникли проблемы с размещением кораблей в моей программе Battleship на C

#c

#c

Вопрос:

Я боролся с этим около 2 часов. По какой-то причине вместо размещения символов над ~, которые составляют мою доску, символы размещаются в случайных местах, которые не являются кординатами, которые я ввожу. Надеюсь, кто-нибудь может помочь мне направить меня в правильном направлении.

 void place_ships(int board[ROWS][COLS])
{

    int ship_type = 1, ship_length = 0, row = 0, col = 0, direction = 0, count = 0;

    for (ship_type = 1; ship_type < 6; ship_type  )
    {
                    if (ship_type == 1)
                    {
                        printf("Please enter where you would like to place your Carrier (5 spots).nn");
                        ship_length = 5;
                    }
                    else if (ship_type == 2)
                    {
                        printf("Please enter where you would like to place your Battleship (4 spots).nn");
                        ship_length = 4;
                    }
                    else if (ship_type == 3)
                    {
                        printf("Please enter where you would like to place your Submarine (3 spots).nn");
                        ship_length = 3;
                    }
                    else if (ship_type == 4)
                    {
                        printf("Please enter where you would like to place your Cruiser (3 spots).nn");
                        ship_length = 3;
                    }
                    else if (ship_type == 5)
                    {
                        printf("Please enter where you would like to place your Destroyer (2 spots).nn");
                        ship_length = 2;
                    }

        printf("Choose the direction of your ship. (0 is vertical, 1 is horizontal)nn");
        scanf("%d",amp;direction);

            printf("Please choose ROW number.n");
            scanf("%d",amp;row);
            printf("Please choose COLUMN number.n");
            scanf("%d",amp;col);

            if (direction == 0)
            {

                    for (count = 0; count < ship_length; count  )
                    {
                            if (ship_type == 1)
                            {
                                board[row count][col] = 'c';
                                print_board (board, row, col);
                            }
                            else if (ship_type == 2)
                            {
                                board[row count][col] = 'b';
                            }
                            else if (ship_type == 3)
                            {
                                board[row count][col] = 's';
                            }
                            else if (ship_type == 4)
                            {
                                board[row count][col] = 'r';
                            }
                            else if (ship_type == 5)
                            {
                                board[row count][col] = 'd';
                            }
                    }
            }

            if (direction == 1)
            {
                    for (count = 0; count < ship_length; count  )
                    {
                            if (ship_type == 1)
                            {
                                board[row][col count] = 'c';
                            }
                            else if (ship_type == 2)
                            {
                                board[row][col count] = 'b';
                            }
                            else if (ship_type == 3)
                            {
                                board[row][col count] = 's';
                            }
                            else if (ship_type == 4)
                            {
                                board[row][col count] = 'r';
                            }
                            else if(ship_type == 5)
                            {
                                board[row][col count] = 'd';
                            }
                        }
                }
        }
}
  

Функция печатной платы:

 void print_board (char board[ROWS][COLS], int num_rows, int num_cols)
{
    int row_index = 0, col_index = 0;

    for (row_index = 0; row_index < num_rows; row_index  )
    {
        for (col_index = 0; col_index < num_cols; col_index  )
        {
            printf ("%c ", board[row_index][col_index]);
        }
        putchar ('n');
    }
}
  

хорошо, так вот на что я это изменил. Нужно ли мне определять структуру в моем заголовке? Опять же, я большой новичок…

 void place_ships(int board[ROWS][COLS])
{

    int ship_type = 0, ship_length = 0, row = 0, col = 0, direction = 0, count = 0;
    char * typestr[] = { "Ship type 0", "Carrier", "Battleship", "Submarine", "Cruiser", "Destroyer" };
    char* tag = "0cbsrd"; 

    for (ship_type = 0; ship_type < 6; ship_type  )
    {
        ship_length = 7 - ship_type;
        prinf("Please enter where you would like to place %s (%s) spots).nn",typstr[ship_type], ship_length);

        printf("Choose the direction of your ship. (0 is vertical, 1 is horizontal)nn");
        scanf("%d",amp;direction);

        printf("Please choose ROW number.n");
        scanf("%d",amp;row);
        printf("Please choose COLUMN number.n");
        scanf("%d",amp;col);

        if (direction == 0)
        {
            board[row count][col] = tag[ship_type];
        }
        else
        {
            board[row][col count] = tag[ship_type];
        }
    }
}
  

Комментарии:

1. Пара общих предложений: вместо использования магических чисел для типов кораблей используйте enum . И вместо больших if...else if списков используйте switch .

2. единственная проблема, с которой я сталкиваюсь, заключается в том, что я новичок в классе Cpts 121, и я не знаю, что такое enum. Я немного разбираюсь в переключателях, как бы я использовал это вместо этого?

3. Кроме того, вы можете захотеть добавить проверки, чтобы никакие координаты не находились за пределами доски, в том числе при размещении кораблей.

4. Лучше, чем swithc, было бы — в данном случае — вычисление, printf() вывод и, возможно, поиск по массиву. Возможно, это раскрывает причины, по которым они не работают лучше…

5. У меня болят глаза… Это ужасный помощник по кодированию… В любом случае semms отлично работает для меня, что я вижу при отладке. Возможно, ваша проблема не в этой функции… Не могли бы вы, пожалуйста, поделиться функцией print_board() ?

Ответ №1:

Я вижу несколько потенциальных проблем, которые могут испортить вам это:

scanf немного сложнее, поскольку он также оставит символ новой строки в буфере после считывания номера. Возможно, вы захотите использовать fgets() вместо этого для чтения с клавиатуры, а затем использовать sscanf в строке для извлечения числа (или atoi).

когда вы записываете в матрицу, вам нужно убедиться, что корабль подходит, поэтому после того, как пользователь ввел координату и направление, вам нужно проверить, подходит ли корабль, например

 if ( direction == vertical )
{
  ok = ( row   ship_length < ROWS ) // assuming row index [0, ROWS-1]
}
else 
{
  ok = ( col   ship_length < COLS )
}
  

и да, как уже упоминал кто-то другой, пожалуйста, используйте перечисления для постоянных значений
например

 enum directions { vertical, horizontal };
  

Ответ №2:

Некоторые предложения по улучшению:

  • не используйте if() материал, если вы можете что-то вычислить.

    Т. е. вместо

                     if (ship_type == 1)
                    {
                        printf("Please enter where you would like to place your Carrier (5 spots).nn");
                        ship_length = 5;
                    }
                                    ...
                    else if (ship_type == 5)
                    {
                        printf("Please enter where you would like to place your Destroyer (2 spots).nn");
                        ship_length = 2;
                    }
      

    лучше использовать

     ship_length = 7 - ship_type;
    printf("Please enter where you would like to place your %s (%s spots).nn", typestr[ship_type], ship_length);
      

    при условии, что вы где-то определили

      char * typestr[] = { "Ship type 0", "Carrier", "Battleship", "Submarine", "Cruiser", "Destroyer" };
      

    и вместо

     if (ship_type == 1)
    {
        board[row count][col] = 'c';
        print_board (board, row, col);
    }
    ...
      

    использовать

     if (direction == 0) {
        board[row count][col] = tag[ship_type];
    } else {
        board[row][col count] = tag[ship_type];
    }
    print_board (board, row, col);
      

    с

     char* tag = "0cbsrd";
      
  • Добавьте некоторые выходные данные после чтения данных. Это показывает, действительно ли вы прочитали правильные данные.

  • Верны ли границы вашего массива?

Комментарии:

1. может ли char * typestr[] = {«Тип корабля 0», «Авианосец», «Линкор», «Подводная лодка», «Крейсер», «Разрушитель» }; быть определен в функции или это должно быть в заголовке?

2. В функции все было бы в порядке, но затем с static . Если нет, это будет перестраиваться при каждом вызове функции, что было бы не очень хорошо.

3. меня еще не научили, что такое static, но typestr — это структура, верно?

4. Нет, это массив указателей символов. Каждый из них указывает на строку с нулевым завершением.

Ответ №3:

Простая инструкция switch вместо списка if-else:

 switch (ship_type)
{
case 1:
    board[row count][col] = 'c';
    break;
case 2:
    board[row count][col] = 'b';
    break;
case 3:
    board[row count][col] = 's';
    break;
case 4:
    board[row count][col] = 'r';
    break;
case 5:
    board[row count][col] = 'd';
    break;
}
  

На самом деле, лучшее решение может быть таким:

 char ship_symbols[] = { 'c', 'b', 's', 'r', 'd' };
board[row count][col] = ship_symbols[ship_type - 1];  /* -1 because array indexes start at 0 */