Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задание повышенной сложности про шахматного коня

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2

Открыть новую тему     Написать ответ в эту тему

krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Привет всем!  
Помогите доделать задачку:
Дана шахматная доска размером 8х8 и шахматный конь. Программа должна запросить у пользователя координаты клетки поля и поставить туда коня. Задача программы найти и вывести путь коня, при котором он обойдет все клетки доски, становясь в каждую клетку только один раз.  
 
На доске 5х5 доходил до 20 хода.
А как сделать чтоб до конца дошол.
А на 8х8 пока не делал.
Пробовал через рекурсию....
 
Пишу на С++.
Так что если есть предложения так пишите.
С удовольствием обговорю методы решения.  
Даже не так хочется решить, а хочется понять....  
 
________________________________
Подпись надо заработать. Wowik

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 21:55 19-03-2003 | Исправлено: Wowik, 03:30 25-03-2003
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ну как.. как.. рекурсией, ессно

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:49 19-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Дык то что через рекурсию я знаю...
Я не представляю как енто сделать.
программированием занимаюсь с декабря месяца

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 22:52 19-03-2003
Eugenne

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Задача эта есть в книге Дейтела "Как программировать на С++" (упраж к главе массивы - задача Эйлера путешествие коня). Кода там нет, но подробно описано как делать.
 
8 вариантов ходов конем. В первую очередь нужно обходить трудные клетки.
23444432
34666643
46888864
46888864
46888864
46888864
34666643
23444432
 
Ходить на клетку с меньшим числом доступности. ...

Всего записей: 2 | Зарегистр. 21-12-2002 | Отправлено: 22:54 19-03-2003
Cheery



.:МордератоР:.
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Ну смотри.. сколько у тебя максимум возможных ходов коня от любой позиции?
8
Перебираешь их по кругу, к примеру, и проверяешь, что:
а) место в пределах доски
б) еще не использовалось
если так, то идешь на него, и передаешь это место как первоначальное этой же функции . Если нет - рассматриваешь следующее место. А если такого нет, возвращаяешься выше (то есть на пред. ход)
и начинается все с самого начала.

----------
Away/DND

Всего записей: 52737 | Зарегистр. 04-04-2002 | Отправлено: 22:58 19-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
дык так я и пробовал сделать...
конечно может я что-то вообще не так делаю но все же гляньте код:
#include <iostream.h>
const int n=8,m=8;
int npol=0,vilet=0;
int cord[n][2];
int *hmicord;
void vibmest(int*,int*);
void printBoard(int[][n]);
void hod(int*,int*);
void  main()
{

int pole[n][n],currentRow=0,currentColumn=0,startRow=0, startColumn=0;

for(int a=0;a<n;a++)
{
for(int s=0;s<n;s++)
{
pole[a][s]=0;
}
}
cout<<"Vvedite nachalnie koordinati konya ";
cin>>startRow
>>startColumn;
pole[currentRow][currentColumn]=1;
printBoard(pole);




for(int i=1;i<n*n;i++)
{
hod(&startRow,&startColumn);
vibmest(&startRow,&startColumn);
// bool flag=true;
// hod(pole,moveNumber,horizontal,vertical,&currentRow,&currentColumn,&startRow,&startColumn,&flag);
pole[startRow][startColumn]=i+1;
// if(flag==false)
// {
// cout<<"Kon do konca ne dosol! A }|{alb! \n";
// break;
// }
// startRow=currentRow;
// startColumn=currentColumn;
printBoard(pole);
}
printBoard(pole);
cin>>startRow;
}

/*
void hod2(int pole[n][n],int moveNumber, int horizontal[m],int vertical[m],int *currentRw,int *currentCl,int *startR,int *startC,bool *flag)
{

*currentRw =*startR + horizontal[moveNumber];
*currentCl =*startC + vertical[moveNumber];
if(*currentRw<0||*currentRw>=n||*currentCl<0||*currentCl>=n)
hod(pole,moveNumber+1,horizontal,vertical,currentRw,currentCl,startR,startC,flag);
if(moveNumber==m)
moveNumber=0;
if(pole[*currentRw][*currentCl]!=0)
{
vilet++;
hod(pole,moveNumber+1,horizontal,vertical,currentRw,currentCl,startR,startC,flag);
}
if(vilet>=7)
*flag=false;
}
*/
void printBoard(int pboard[][n])
{
cout<<npol<<"________________\n";
for(int a=0;a<n;a++)
{
for(int s=0;s<n;s++)
{
if(pboard[a][s]<10)
cout<<pboard[a][s]<<" |";
else
cout<<pboard[a][s]<<"|";

}
cout<<"\n";
}
cout<<npol<<"________________\n";
npol++;
}
void hod(int *startR,int *startC)
{
int currentCl,currentRw,
horizontal[8]={2,1,-1,-2,-2,-1,1,2},
vertical[8]={-1,-2,-2,-1,1,2,2,1};
int count=0;
for(int c=0;c<m;c++)
{
currentRw =*startR + horizontal[c];
currentCl =*startC + vertical[c];
if(currentRw>=0&&currentCl>=0&&currentRw<=n&&currentCl<=n)
{
cord[count][1]=currentRw;
cord[count][2]=currentCl;
++count;
}
}
hmicord=&count;
}
void vibmest(int* moveRw,int *moveCl)
{
int *vibor=new int[*hmicord];
int prior[n][n]={{2,3,4,4,4,4,3,2},
{3,4,6,6,6,6,4,3},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{4,6,8,8,8,8,6,4},
{3,4,6,6,6,6,4,3},
{2,3,4,4,4,4,3,2}};
for(int co=0;co<=*hmicord;co++)
{
vibor[co]=prior[cord[co][1]][cord[co][2]];
cout<<vibor[co]<<"\n";
}
int min=vibor[0],number=0;

for(int cv=1;cv<*hmicord;cv++)
{
if(min>vibor[cv])
{
min=vibor[cv];
number=cv;
}
}
*moveRw=cord[number][1];
*moveCl=cord[number][2];
delete[] vibor;
}


Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 23:01 19-03-2003
Sleepwalker



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
плохо пробовал через рекурсию.
25 клеток расставляет за 329 ходов.  
64 - пока не знаю. Простой алгоритм рекурсивного перебора слишком долог.
 

Цитата:
// cout<<"Kon do konca ne dosol! A }|{alb! \n";



----------
...или я ничего не понимаю в этой жизни... или понимаю слишком хорошо...

Всего записей: 1957 | Зарегистр. 19-10-2002 | Отправлено: 07:21 20-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Тут 2 способа!
только один через рекурсию как коментарий.
Я не знаю как сделать чтоб в рекурсивном способе сделать анализ хода коня.

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 14:22 20-03-2003
developer_from_Volga



Junior Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Рекурсия очень долго будет работать, надо использовать поиск в ширину. Алгоритмы на графах проходил?

Всего записей: 44 | Зарегистр. 19-01-2003 | Отправлено: 08:41 21-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Нет!
Я читал в нете про графы, но ничего не понял
И там пример на паскале.

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 10:20 21-03-2003
JeanM

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
krol придется тебе приблизительно узнать паскакаль тогда :) Тебе ж чтоб в нете инфу нарыть нормальную, иногда английский приходится знать, да? Ну вот и здесь то же :)

Всего записей: 69 | Зарегистр. 22-02-2003 | Отправлено: 13:03 21-03-2003 | Исправлено: JeanM, 13:04 21-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Да в принципе с паскалем я знаком немного.  
Да и с англ. впиринципе нормально.
Вот тока времени мало....
Просто если я сделаю программку мне экзамен в академии автоматом будет.
А вообще кто-то про код может что-то сказать?
Это праильно записано?
int *vibor=new int[*hmicord];
 
А то так долго думает на этом месте.

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 14:11 21-03-2003
IntenT



Advanced Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
krol

Цитата:
int *vibor=new int[*hmicord];  

Смотря что ты этим имел в виду
Если нужен 2-мерный динамический массив, то его надо обьявить так:
 
int **vibor;
 
А потом инициализировать
 
*vibor =  new int[arr_length];
 
и дальше
 
for(i=0; i<arr_length; i++)
{
  vibor[i] = new int[arr_depth];
}
 
 
A eсли это просто одномерный массив - то так:
 
int *vibor[length];

Всего записей: 1584 | Зарегистр. 16-12-2001 | Отправлено: 17:16 21-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Не это надо одномерный динамический массив для хранения значений!

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 17:21 21-03-2003
FuzzyLogic



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Почитай тут...
http://forum.ru-board.com/topic.cgi?forum=33&topic=0873#1
если сильно надо могу написать на выходных как посвободнее буду

Всего записей: 1920 | Зарегистр. 27-07-2002 | Отправлено: 17:52 21-03-2003
krol



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
FuzzyLogic  
 
Я б был не против увидить готовый код, но мне самому интересно понятьь....
А ту что я написал не идет?
может просто подправить ее..

Всего записей: 18 | Зарегистр. 18-01-2003 | Отправлено: 18:22 21-03-2003
zam

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Типичная задача на применение эвристики...делать ход в ту клетку, откуда возможно наибольшее количество ходов. Как ни странно, в данной задаче это помогает.

Всего записей: 185 | Зарегистр. 19-01-2003 | Отправлено: 19:11 21-03-2003
snop



local root
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
krol
Это простейшая задачка по backtracking рекурсии

Код:
 
typedef int Matrix[N][M] ;
typedef int boolean ;
 
/*Функция проверки правильности клетки*/
boolean legal(Matrix mat ,int i, int j)
{
 return !( (i>=N||i<0) || (j>=M||j<0) || mat[i][j] );
}
 
/*Проход по доске*/
boolean fill_board(Matrix mat,int i,int j)
{
 int t;
 static int cnt = 0 ;
 static int d_row[] = {2,2,-2,-2,1,1,-1,-1} ;
 static int d_col[] = {1,-1,1,-1,2,-2,2,-2} ;
 
 mat[i][j] = ++cnt ;
 if(cnt==M*N) {                      /* Stopping condition */
 cnt = 0 ;
 return TRUE;  
 }
 for(t = 0 ;t < 8 ; ++t)                  /* All possible continuation */
if(legal(mat , i+d_row[t] , j+d_col[t]))
if(fill_board(mat , i+d_row[t] , j+d_col[t]))
return TRUE;
 
 mat[i][j] = 0 ;        /* We can't fill the remaining entries from this entry */
 cnt--;
 return FALSE;
}
 
 
 


----------
Русский Mambo уже здесь

Всего записей: 1591 | Зарегистр. 27-04-2002 | Отправлено: 19:26 21-03-2003 | Исправлено: snop, 19:29 21-03-2003
Sleepwalker



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
рекурсией все конечно очень просто... элементарно, я бы даже сказал... но скорость (
а количество вариантов просто ужасающее. даже если 1 Мвариант в секунду - это надолго... эвристику пока не пробовал, рекурсия тогда сильно усложняется.
попробую - выложу.

----------
...или я ничего не понимаю в этой жизни... или понимаю слишком хорошо...

Всего записей: 1957 | Зарегистр. 19-10-2002 | Отправлено: 02:30 22-03-2003
FuzzyLogic



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
В эвристике нет никакой рекурсии, там всё настолько просто что проще просто некуда

Всего записей: 1920 | Зарегистр. 27-07-2002 | Отправлено: 04:49 22-03-2003
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задание повышенной сложности про шахматного коня


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru