Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.92
notgosu
9 / 9 / 1
Регистрация: 16.02.2011
Сообщений: 17
#1

Морской бой. Ф-ция автоматической рассатновки кораблей. - C++

21.02.2011, 17:58. Просмотров 5325. Ответов 3
Метки нет (Все метки)

Добрый день, ув. форумчане! Есть задание написать консольный морской бой. Есть задача расстановки кораблей компьютера случайным образом. Массив [10][10], заполненный '0' - игровое поле. 'X' - корабль.
В ф-ции расстановки кораблей перед заполнением 'Х' идет проверка на наличие кораблей в случайно выбранном элементе и вокруг него(чтобы корабли не соприкасались). Мною написана ф-ция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
void AutoSet(char field[10][10], int  m, int n)
{
    //Расстановка однопалубных кораблей
    srand(time(NULL));
    for(int i=0; i<4; i++){
        m=rand()%10;
        n=rand()%10;
        while (field[m][n]=='X' || field[m][n+1]=='X' || field[m][n-1]=='X' || field[m+1][n]=='X' || field[m-1][n]=='X'
            || field[m+1][n+1]=='X' || field[m+1][n-1]=='X' || field[m-1][n+1]=='X' || field[m-1][n-1]=='X'){
            m=rand()%10;
            n=rand()%10;
        }
        field[m][n]='X';
    }
 
    //Расстановка двохпалубных кораблей
    for(int i=0; i<3; i++){
        int k=rand()%2;
        switch(k){
        case 0://вертикальное расположение корабля
            m=rand()%9;
            n=rand()%10;
            while(field[m][n]=='X' || field[m-1][n-1]=='X' || field[m-1][n]=='X' || field[m-1][n+1]=='X' ||
                  field[m][n-1]=='X' || field[m][n+1]=='X' || field[m+1][n-1]=='X' || field[m+1][n]=='X' ||
                  field[m+1][n+1]=='X' || field[m+2][n-1]=='X' || field[m+2][n]=='X' || field[m+2][n+1]=='X'){
                  m=rand()%9;
                  n=rand()%10;
            }
            field[m][n]='X';
            field[m+1][n]='X';
            break;
        case 1://горизонтальное расположение корабля
            m=rand()%10;
            n=rand()%9;
            while(field[m][n]=='X' || field[m][n+1]=='X' || field[m-1][n-1]=='X' || field[m-1][n]=='X' ||
                field[m-1][n+1]=='X' || field[m-1][n+2]=='X' || field[m][n-1]=='X' || field[m][n+2]=='X' ||
                field[m+1][n-1]=='X' || field[m+1][n]=='X' || field[m+1][n+1]=='X' || field[m+1][n+2]=='X'){
                m=rand()%10;
                n=rand()%9;
            }
            field[m][n]='X';
            field[m][n+1]='X';
            break;
        }   
    }
 
    //Расстановка трехпалубных кораблей
    for (int i=0; i<2; i++){
        int n=rand()%2;
        switch(n){
        case 0://вертикальное положение корабля
            m=rand()%8;
            n=rand()%10;
            while(field[m][n]=='X' || field[m+1][n]=='X' || field[m+2][n]=='X' || field[m-1][n-1]=='X' ||
                field[m-1][n]=='X' || field[m-1][n+1]=='X' || field[m][n-1]=='X' || field[m][n+1]=='X' ||
                field[m+1][n-1]=='X' || field[m+1][n+1]=='X' || field[m+2][n-1]=='X' || field[m+2][n+1]=='X' ||
                field[m+3][n-1]=='X' || field[m+3][n]=='X' || field[m+3][n+1]=='X'){
                m=rand()%8;
                n=rand()%10;
            }
            field[m][n]='X';
            field[m+1][n]='X';
            field[m+2][n]='X';
            break;
        case 1:
            m=rand()%10;
            n=rand()%8;
            while(field[m][n]=='X' || field[m][n+1]=='X' || field[m][n+2]=='X' || field[m-1][n-1]=='X' ||
                field[m-1][n]=='X' || field[m-1][n+1]=='X' || field[m-1][n+2]=='X' || field[m-1][n+3]=='X' ||
                field[m][n-1]=='X' || field[m][n+3]=='X' || field[m+1][n-1]=='X' || field[m+1][n]=='X' ||
                field[m+1][n+1]=='X' || field[m+1][n+2]=='X' || field[m+1][n+3]=='X'){
                m=rand()%10;
                n=rand()%8;
            }
            field[m][n]='X';
            field[m][n+1]='X';
            field[m][n+2]='X';
            break;
        }//switch
    }//for
 
    //Расстановка четырехпалубного корабля
    int l=rand()%2;
    switch(l){
    case 0://вертикальное положение
        m=rand()%7;
        n=rand()%10;
        while(field[m][n]=='X' || field[m+1][n]=='X' || field[m+2][n]=='X' || field[m+3][n]=='X' ||
            field[m-1][n-1]=='X' || field[m-1][n]=='X' || field[m-1][n+1]=='X' || field[m][n-1]=='X' ||
            field[m][n+1]=='X' || field[m+1][n-1]=='X' || field[m+1][n+1]=='X' || field[m+2][n-1]=='X' ||
            field[m+2][n+1]=='X' || field[m+3][n-1]=='X' || field[m+3][n+1]=='X' || field[m+4][n-1]=='X' ||
            field[m+4][n]=='X' || field[m+4][n+1]=='X'){
            m=rand()%7;
            n=rand()%10;
        }
        field[m][n]='X';
        field[m+1][n]='X';
        field[m+2][n]='X';
        field[m+3][n]='X';
        break;
    case 1://горизонтальное положение
        m=rand()%10;
        n=rand()%7;
        while(field[m][n]=='X' || field[m][n+1]=='X' || field[m][n+2]=='X' || field[m][n+3]=='X' ||
            field[m-1][n-1]=='X' || field[m-1][n]=='X' || field[m-1][n+1]=='X' || field[m-1][n+2]=='X' ||
            field[m-1][n+3]=='X' || field[m-1][n+4]=='X' || field[m][n-1]=='X' || field[m][n+4]=='X' ||
            field[m+1][n-1]=='X' || field[m+1][n]=='X' || field[m+1][n+1]=='X' || field[m+1][n+2]=='X' ||
            field[m+1][n+3]=='X' || field[m+1][n+4]=='X'){
            m=rand()%10;
            n=rand()%7;
        }
        field[m][n]='X';
        field[m][n+1]='X';
        field[m][n+2]='X';
        field[m][n+3]='X';
        break;
    }//switch
}
Проблема в расстановке четырехпалубного корабля - иногда консоль появляеться пустой(я так понял безконечный цыкл появляется) и ничего не происходит. Проблема сугубо в коде расстановки четырехпалубного корабля, без него все работает на ура.
Вот код программы, выводящей заполненное поле на экран:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
 
void AutoSet(char field[10][10], int m, int n);
 
void main()
{
    setlocale(LC_ALL, "rus");
    const int m=10, n=10;
    char pfield[m][n], efield[m][n], nazv[m]={'A','B','C','D','E','F','G','H','I','J'};
    
    for (int i=0; i<m; i++)     //Заполнение
        for(int j=0; j<n; j++)  //поля игрока
            pfield[i][j]=0;     //нолями
    for (int i=0; i<m; i++)     //Заполнение
        for(int j=0; j<n; j++)  //поля компьютера
            efield[i][j]='0';   //нолями
    
    AutoSet(efield,m,n);
    cout<<"   ";
    for (int i=0; i<10; i++)
        cout<<nazv[i]<<" ";
    cout<<"\n";
    for (int i=0; i<10; i++)
        cout<<" ";
    cout<<"\n";
    for (int i=0; i<m; i++){    
        if (i== 9)
            cout<<(i+1)<<" ";
        else
        cout<<(i+1)<<"  ";
        for(int j=0; j<n; j++){
            cout<<efield[i][j]<<" ";
        }
        cout<<"\n";
    }
    
}
Просьба к коллегам - посмотрите свежей головой где я начудил, а то уже мозги кипят. Проблема 99% что в расстановке четырехпалубного корабля. Заранее благодарен.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2011, 17:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Морской бой. Ф-ция автоматической рассатновки кораблей. (C++):

Расстановка кораблей (морской бой) - C++
Доброго времени суток, при расстановке 2х палубных кораблей возникает проблема... При выборе точки уже занятой, система ломается и...

Консольный морской бой. Расстановка кораблей - C++
Добрый вечер, уважаемые форумчане. Хочу написать консольный морской бой. Начал с функции автоматической расстановки кораблей. Весь...

Морской бой - программа зацикливается на расстановке кораблей - C++
Нужно написать курсовую(игру). Решила написать морской бой(пока что консольно). Написала программу для расстановки кораблей. Не могу...

Проверить правильность расстановки кораблей. Морской бой - C++
Есть матрица NxM, где расставлены корабли. Корабли не стоят на краю матрицы, кол-во 4-х клеточных кораблей - 1, 3-х клет. - 2, 2-х...

Морской бой: расставляется кораблей больше, чем положено - C++
Здравствуйте! Пишу игру &quot;Морской бой&quot; в консоли, и попалась одна неприятная ситуация. Есть функция заполнения поля случайными кораблями,...

Случайное распределение кораблей по полю в игре "морской бой" - C++
Привет всем кто читал мой предыдущий пост про векторы в морском боем, в той же фунции появилась новая проблема :) После починки...

3
Mr.X
Эксперт С++
3051 / 1696 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
22.02.2011, 01:06 #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/////////////////////////////////////////////////////////////////////////////////////////
//Есть задача расстановки кораблей компьютера случайным образом. Массив [10][10], 
//заполненный '0' - игровое поле. 'X' - корабль.
//В ф-ции расстановки кораблей перед заполнением 'Х' идет проверка на наличие кораблей 
//в случайно выбранном элементе и вокруг него(чтобы корабли не соприкасались). 
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <ctime>
#include <iostream>
#include <cstdlib>
/////////////////////////////////////////////////////////////////////////////////////////
const int  FIELD_DIM   = 10;
const char WATER_SYMB  = ' ';
const char SHIP_SYMB   = 'X';
/////////////////////////////////////////////////////////////////////////////////////////
bool  ship_is_good
    (
        int         size, 
        bool        is_horiz, 
        int         row_top, 
        int         col_left, 
        const char  field[][FIELD_DIM]
    )
{
    if(is_horiz)
    {
        for(int i =   std::max(0,              row_top - 1); 
                i <=  std::min(FIELD_DIM - 1,  row_top + 1); 
                ++i)
        {
            for(int j =   std::max(0,              col_left - 1); 
                    j <=  std::min(FIELD_DIM - 1,  col_left + size); 
                    ++j)
            {
                if(field[i][j] == SHIP_SYMB) return false;
            }        
        }
        return  true;
    }
    else//вертикальный
    {
        for(int i =   std::max(0,             row_top - 1); 
                i <=  std::min(FIELD_DIM - 1, row_top + size); 
                ++i)
        {
            for(int j =   std::max(0,             col_left - 1); 
                    j <=  std::min(FIELD_DIM - 1, col_left + 1); 
                    ++j)
            {
                if(field[i][j] == SHIP_SYMB) return false;
            }        
        }
        return  true;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////
void  set_ship_with_size(int  size, char  field[][FIELD_DIM])
{
    bool  is_horiz  = rand() % 2 == 0;
    int   row_top   = 0;
    int   col_left  = 0;
 
    do
    {
        do
        {
            row_top = rand() % FIELD_DIM;
        }while(   !is_horiz 
               && row_top > FIELD_DIM - size);
 
        do
        {
            col_left = rand() % FIELD_DIM;
        }while(   is_horiz 
               && col_left > FIELD_DIM - size);        
    }while(!ship_is_good(size, is_horiz, row_top, col_left, field)); 
 
    if(is_horiz)
    {
        for(int j = col_left; j < col_left + size; ++j)
        {
            field[row_top][j] = SHIP_SYMB;
        }
    }
    else//вертикальный
    {
        for(int i = row_top; i < row_top + size; ++i)
        {
            field[i][col_left] = SHIP_SYMB;
        }    
    }
}
/////////////////////////////////////////////////////////////////////////////////////////
void  set_ships(char  field[][FIELD_DIM])
{
    for(int i = 0; i < 1; ++i)
    {
        set_ship_with_size(4, field);
    }
 
    for(int i = 0; i < 2; ++i)
    {
        set_ship_with_size(3, field);
    }
 
    for(int i = 0; i < 3; ++i)
    {
        set_ship_with_size(2, field);
    }
 
    for(int i = 0; i < 4; ++i)
    {
        set_ship_with_size(1, field);
    }
}
/////////////////////////////////////////////////////////////////////////////////////////
void  print_field(const char  field[][FIELD_DIM])
{
    for(int  i = 0; i < FIELD_DIM; ++i)
    {
        for(int  j = 0; j < FIELD_DIM; ++j)
        {
            std::cout << field[i][j]
                      << ' ';
        }    
        std::cout << std::endl;
    }
}
/////////////////////////////////////////////////////////////////////////////////////////
void  set_water(char  field[][FIELD_DIM])
{
    for(int  i = 0; i < FIELD_DIM; ++i)
    {
        for(int  j = 0; j < FIELD_DIM; ++j)
        {
            field[i][j] = WATER_SYMB;
        }            
    }
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    srand(static_cast<unsigned>(time(0)));
    
    char  field[FIELD_DIM][FIELD_DIM];  
    set_water    (field);
    set_ships    (field);
    print_field  (field);
}
1
notgosu
9 / 9 / 1
Регистрация: 16.02.2011
Сообщений: 17
26.02.2011, 19:09  [ТС] #3
Mr.X, действительно ваш вариант реализации намного проще и компактней чем моя лабуда) Спасибо. Но позвольте еще поинтересоваться, что делает след. кусок кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(is_horiz)
    {
        for(int i =   std::max(0,              row_top - 1); 
                i <=  std::min(FIELD_DIM - 1,  row_top + 1); 
                ++i)
        {
            for(int j =   std::max(0,              col_left - 1); 
                    j <=  std::min(FIELD_DIM - 1,  col_left + size); 
                    ++j)
            {
                if(field[i][j] == SHIP_SYMB) return false;
            }        
        }
        return  true;
а именно
std::max(0, row_top - 1)
std::min(FIELD_DIM - 1, row_top + 1)
Находит мин и макс значение в диапазоне (а, b)? И если да, то какая библиотека за это отвечает. Еще раз спасибо.

Добавлено через 57 минут
И можно ли реализовать цыкл без min/max?

Добавлено через 3 часа 40 минут
Разобрался, переделал и доделал) Спасибо Mr.X, за помощь! Тему можно закрывать.
0
Григорий Алекса
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 49
23.04.2011, 11:58 #4
Можт я не совсем вовремя и не в тему, прост я щас тоже пишу морской бой...в твоем первоначальном коде была небольшая "недодумка")) над было сначало 4х палубник поставить, потом3х ну и т.д.
0
23.04.2011, 11:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.04.2011, 11:58
Привет! Вот еще темы с ответами:

Игра "Морской бой" Рассстановка кораблей - C++
Пишу игру &quot;Морской бой&quot;. Нужно пока что только расставить корабли. На данный момент логика следующая. Все поле забито нулями (ноль - пустая...

Морской Бой - C++
прошу в помощи написания этой игры ,спасибо

Морской бой C++ - C++
имеется следующий класс Text,в котором два метода drawText(...) который отвечает за прорисовку текста на экране i renderingText() - за...

Морской бой - C++
Здравствуйте.Прошу помочь. Задался целью написать морской бой под консолью. Для начала решил рандомно заполнить поле игрока тремя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru