Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.92
notgosu
8 / 8 / 1
Регистрация: 16.02.2011
Сообщений: 17
21.02.2011, 17:58     Морской бой. Ф-ция автоматической рассатновки кораблей. #1
Добрый день, ув. форумчане! Есть задание написать консольный морской бой. Есть задача расстановки кораблей компьютера случайным образом. Массив [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% что в расстановке четырехпалубного корабля. Заранее благодарен.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.02.2011, 17:58     Морской бой. Ф-ция автоматической рассатновки кораблей.
Посмотрите здесь:

Игра "Морской бой" Рассстановка кораблей C++
Консольный морской бой. Расстановка кораблей C++
C++ Морской бой=)
Расстановка кораблей (морской бой) C++
C++ Морской бой
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Mr.X
Эксперт С++
 Аватар для Mr.X
2802 / 1578 / 247
Регистрация: 03.05.2010
Сообщений: 3,666
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);
}
notgosu
8 / 8 / 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, за помощь! Тему можно закрывать.
Григорий Алекса
1 / 1 / 0
Регистрация: 12.12.2010
Сообщений: 49
23.04.2011, 11:58     Морской бой. Ф-ция автоматической рассатновки кораблей. #4
Можт я не совсем вовремя и не в тему, прост я щас тоже пишу морской бой...в твоем первоначальном коде была небольшая "недодумка")) над было сначало 4х палубник поставить, потом3х ну и т.д.
Yandex
Объявления
23.04.2011, 11:58     Морской бой. Ф-ция автоматической рассатновки кораблей.
Ответ Создать тему
Опции темы

Текущее время: 16:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru