powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Рациональный подход
16 сообщений из 16, страница 1 из 1
Рациональный подход
    #33037065
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пишу игру SeaWar. Как упростить вот такую вот проверку (проверяет все клетки вокруг однопалубного корабля, ищет совпадения по всему полю)? Нужен рациональный подход. Представь, что получится, если я стану проверять таким макаром четырех палубник :-)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
for(int row= 0 ; row< 10 ; row++){ 
        for(int cell= 0 ; cell< 10 ; cell++){ 
            if((str[row][cell]==ship)&& 
            (str[row+ 1 ][cell] !=ship)&& 
            (str[row- 1 ][cell+ 1 ] != ship)&& 
            (str[row+ 1 ][cell+ 1 ] != ship)&& 
            (str[row- 1 ][cell- 1 ] != ship)&& 
            (str[row][cell- 1 ] != ship)&& 
            (str[row+ 1 ][cell- 1 ] != ship)&& 
            (str[row][cell+ 1 ] != ship)&& 
            (str[row- 1 ][cell] != ship)){ 
                if(j!= 4 ){ 
                 one++; 
                 j++; 
                } 
            }         
        }     
    }
...
Рейтинг: 0 / 0
Рациональный подход
    #33037069
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так проверяй не на ship, а на ship1, то есть измени классификацию ячейки. Введи ship1, ship2, ship3, ship4 и будет счастье.
...
Рейтинг: 0 / 0
Рациональный подход
    #33037081
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Анатолий ШироковТак проверяй не на ship, а на ship1, то есть измени классификацию ячейки. Введи ship1, ship2, ship3, ship4 и будет счастье.
Я только начинаю программировать, мне иногда трудно понять некоторые моменты. Будь добр разъясни на примере . Что значит классификация ячейки?
У меня корабли расставляются случайно, мне нужно проверять, чтоб не получилась "куча".
...
Рейтинг: 0 / 0
Рациональный подход
    #33037674
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalcer Анатолий ШироковТак проверяй не на ship, а на ship1, то есть измени классификацию ячейки. Введи ship1, ship2, ship3, ship4 и будет счастье.
Я только начинаю программировать, мне иногда трудно понять некоторые моменты. Будь добр разъясни на примере . Что значит классификация ячейки?
У меня корабли расставляются случайно, мне нужно проверять, чтоб не получилась "куча".

Проверку на наличие однопалубных кораблей можно сделать примерно так:
(это только идея, набросок, код сырой, так что ногами не пинать :))

Код: plaintext
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.
int str[ 10 ][ 10 ];
const int ship =  1 ;
const int empty =  0 ;

bool check_1(int i, int j)
{
	bool bResult = true;
	if(str[i][j] == ship)
	{
		for(int dx = i - 1 ; dx <= (i +  1 ); dx++)
			if((dx >  0 ) &&  (dx <  10 ) && (dx != i))
				for(int dy = j - 1 ; dy <= (j +  1 ); dy++)
					if((dy >  0 ) &&  (dy <  10 ) && (dy != j))
						if(str[dx][dy] != empty)
							bResult = false;
			
	}
	else 
		bResult = false;

	return bResult;
}

int main( int argc, char *argv[] )
{
	for(int i =  0 ; i <  10 ; i++)
		for(int j =  0 ; j <  10 ; j++)
			str[i][j] = empty;

	str[ 1 ][ 1 ] = ship;
	str[ 1 ][ 5 ] = ship;
	str[ 4 ][ 8 ] = ship;
	str[ 9 ][ 2 ] = ship;

	for(int i =  0 ; i <  10 ; i++)
		for(int j =  0 ; j <  10 ; j++)
			if(check_1(i, j))
				cout << i << " " << j << endl;
			
	return  0 ;
}

Алгоритм можно докрутить для 1,2 и более палубных кораблей. Когда сам писал морской бой. то делал примерно так.
...
Рейтинг: 0 / 0
Рациональный подход
    #33038025
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, сейчас буду разбираться :-)
...
Рейтинг: 0 / 0
Рациональный подход
    #33038248
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я либо чего-то не понял, но ф-ция у меня не работает :-( (иногда лепит два корабля вместе).
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
	int t, res;//t-кол-во кораблей, res - кол-во совпадений
	do{	
		res= 0 ;
		t= 0 ;
		Map(str);	//отчистка поля
		for(int i= 0 ; i< 10 ; i++){
			for(int j= 0 ; j< 10 ; j++){
				if(str[i][j]!=ship){
					t++;
					if(t<= 4 ){
						AutoShip(str,  1 );	//случайное построение 1 труб. корабля
					}				
				}
				if(check_1(i, j)){
				  res++;
				}
			}
		}		
	}while(res!= 4 );
Покажи, плз., как переделать ф-цию для кораблей >1 палубы .
...
Рейтинг: 0 / 0
Рациональный подход
    #33038323
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StalcerЯ либо чего-то не понял, но ф-ция у меня не работает :-( (иногда лепит два корабля вместе).
Покажи, плз., как переделать ф-цию для кораблей >1 палубы .

1) в моем коде есть небольшая ошибка, вместо ((dx > 0) надо поставить ((dx >= 0), для dy соответственно.

2) все, что делает эта функция, проверяет - есть ли в данной клетке однопалубный корабль - т.е. клетка заполнена, и вокруг нее нет других заполненных клеток. Эту функцию можно использовать, например, для поиска всех кораблей (что у меня и приведено в тесте). Но это не готовое решение для твоего случая, я же честно принался, что это только набросок :)

Алгоритм поиска кораблей длины (n) - пройтись по полю и для каждой точки определить является ли она началом корбаля длины n - т.е. надо проверить отрезок - (по горизонтали или по вертикали) размером n клеток.

Алгоритм поиска свободного места для установки корабля размером n - пройтись по полю и для клетки определить может ли она быть началом корабля размером n, т.е. проверить есть ли слева (внизу) от нее свободная линия, плюс свободная граница вокруг нее размером в 1 клетку (чтобы корабли не склеиваились).

Мне кажется ничего сложного... 2-3 цикла, плюс столько же проверок :-\

3) не знаю как рабоатет AutoShip, но подозреваю в чем глюк и почему корабли лепятся вместе - ты же сначала ставишь корабль в клетку, и только потом проверяешь стоило ли это делать :)

4) если нужен готовый код, то могу и написать, но только поздно вечером из дома, ибо сейчас на работе и так есть чем заняться
...
Рейтинг: 0 / 0
Рациональный подход
    #33038506
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за активную помощь.
AutoShip случайно выбирает координаты (ориент., если >1) и ставит корабль.
Я ставлю 4 корабля и проверяю если все четыре вокруг себя не имеют кораблей, значит можно показать на экран...
Если тебя это не сильно затруднит и будет время, помоги студенту с проверкой на корабли >1 плз.. :-)
...
Рейтинг: 0 / 0
Рациональный подход
    #33038510
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
после исправлений все равно лепит :-)
...
Рейтинг: 0 / 0
Рациональный подход
    #33038709
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как я уже говорил, у тебя плохая классификация ячеек. После постановки очередного корабля на игоровое поле, помимо установки признака "корабль" той ячейке, в который он установлен необходимо так же как-то "метить" окружающие корабль ячейки, которые уже не могут содержать другие корабли. Что это означает:

Например, мы случайным образом установили, что однопалубный корабль имеет координаты (2, 2). Так вот, после постановки корабля на игровое поле мы метим не только ячейку (2,2) (пусть 2), но и все 8-связные с ней ячейки (пусть 1). 0 отметим не занятые ячейки:

11100000
12100000
11100000
00000000

Теперь вернемся к твоей задаче, которая состоит в том, чтобы разместить n-палубный корабль. Что есть n-палубный корабль (пусть пока горизонтально ориентированный) - это прямоугольник (x-1, y-1) - (x + n, y + 1). Поэтому, чтобы определить можно ли разместить n-палубный корабль в точку (x, y) достаточно подсчитать сумму ячеек покрываемую этим прямоугольником и если она будет равна нулю, то (x,y) и есть искомая точка:

Код: plaintext
1.
2.
3.
4.
5.
6.
int sum =  0 ;
for(size_t r = y- 1 ; i <= y+ 1  )
   for(size_t c = x- 1 ; i <= x+n )
      sum += map[r][c];
if( sum ==  0 )
    // в позицию (x, y) можно установить n палубный корабль

Неприятность составляет проверка на граничные условия, но их можно легко избежать, если увеличить размерность игрового поля N на 2 - то есть по 1 с каждой стороны. В этом случае координаты игрового поля будут в точности принадлежать множеству [1, N] x [1, N].

Вот и все идеи. Теперь ты легко все реализуешь. Удачи.
...
Рейтинг: 0 / 0
Рациональный подход
    #33038797
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ответ разумный, конечно, за что и спасибо. Принцип понял, а вот синтаксис мне пока тяжело понять :-)
Приведи пример плз., если мне нужно поставить 3 двух трубных корабля, в случайные координаты x и y, поле 10x10.
...
Рейтинг: 0 / 0
Рациональный подход
    #33038942
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Stalcer

Извини, но пример ты как-нибудь сам.
...
Рейтинг: 0 / 0
Рациональный подход
    #33039433
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что такое size_t?
...
Рейтинг: 0 / 0
Рациональный подход
    #33039541
redskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stalcer...
Я ставлю 4 корабля и проверяю если все четыре вокруг себя не имеют кораблей, значит можно показать на экран...
Если тебя это не сильно затруднит и будет время, помоги студенту с проверкой на корабли >1 плз.. :-)

Меня то не затруднит, только сдавать ДЗ тебе все равно самому придецца :)

Код: plaintext
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.
#include <iostream>
#include <time.h>

const int N =  10 ;   // размер поля 
const int H =  4 ;    // макс. размер корабля
int str[N][N];      // игровое поле поле

#define RAND10 rand()/(RAND_MAX /  10 )
#define RAND2 rand()/(RAND_MAX /  2 )

// проверка свободна ли клетка и свободно ли пространство вокруг нее
bool Check(int x, int y)
{
	for(int i = x- 1 ; i <= (x+ 1 ); i++)
		for(int j = y- 1 ; j <= (y+ 1 ); j++)
			if((i >=  0 ) && (j >=  0 ) && (i < N) && (j < N))
				if (str[i][j] !=  0 ) 
					return false;
	return true;
}

// проверка доступности линии
// параметры:
// x, y  координаты верхнего левого угла
// L     длина линии 
// Dir   направление 
bool CheckLine(int x, int y, int L, int Dir /* 0 - горизонтальное, 1 - вертикальное*/)
{
	int dx = Dir ?  0  :  1 ;
	int dy = Dir ?  1  :  0 ;
	int x1 = x + L*dx;
	int y1 = y + L*dy;

	bool r = false;
	if( (x >=  0 ) && (y >=  0 ) && (x < N) && (y < N) && (x1 < N) && (y1 < N) )
	{
		r = true;
		for(int i =  0 ; i < L; i++)
			r = Check(x + i*dx, y + i*dy) && r;
	}
	return r;
}

// установка корабля
// x, y  координаты верхнего левого угла
// L     длина линии (кол-во палуб корабля)
// Dir   направление 
// возвращает true, если удалось поставить корабль, иначе false
bool SetLine(int x, int y, int L, int Dir)
{
	int dx = Dir ?  0  :  1 ;
	int dy = Dir ?  1  :  0 ;
	bool r = false;
	if(CheckLine(x, y, L, Dir))
	{
		for(int i =  0 ; i < L; i++)
			str[x + i*dx][y + i*dy] =  1 ;		 
		r = true;
	}
	return r;
}

// иницализаця игрового поля
// заполенение поля стандартным набором кораблей 
// 1 4хпалубный, 2 3хпалубных, 3 2хпалобных, 4 однопалубных
// вывод заполненного поля на экран
int main(int argc, char* argv[])
{
	srand(time( 0 ));

	for(int i =  0  ; i < N; i++)
		for(int j =  0 ; j < N; j++)
			str[i][j] =  0 ;

	for(int k = H; k >  0 ; k--)
		for(int i =  0 ; i < (H-k+ 1 ); i++)
			while(!SetLine(RAND10, RAND10, k, RAND2)) 0 ;

	for(int i =  0  ; i < N; i++)
	{
		for(int j =  0 ; j < N; j++)
			std::cout << str[i][j] << " ";
		std::cout << std::endl;
	}

	return  0 ;
}


Вот, примерно так.
Остальное сам :))
...
Рейтинг: 0 / 0
Рациональный подход
    #33040772
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибки!!!
Сейчас попробуем поюзать :-)
...
Рейтинг: 0 / 0
Рациональный подход
    #33040785
Stalcer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Супер!, есть же добрые люди то!
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Рациональный подход
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]