Помощь - Поиск - Пользователи - Календарь
Полная версия: Шахматный конь
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Cheburashka
В общем задача заключается в том, чтобы по введённому месту на доске (e1, h3, c6) программа выводила все возможные ходы конём. То есть если мы введём a1, то программа должна вывести следующие значения - b3, c2.

Помогите мне понять как построить алгоритм решения задачи. (как Вы понимаете,что на доске клетка а1 находится в нижнем левом углу. А h8 находится в верхнем правом углу)
Krjuger
Ну как идея.
Смотри что нам дает положение коня,это цифра и буква,первое ограничение,не вылезаем за алфавит,второе по цифрам.Какое дальше ограничение,если буква меняется на 1(с А на Б например),то число может либо увеличиться,либо уменьшитьсяна 2,и проверяеш,если при уменьшении ты вылитаеш за граници дозволенного(напимер был а1,по алфавину влево ты уйти не можеш,следовательно только на Б,либо С,но мы для условности берем пока что Б,значит ты из А1 можеш уйти либо в Б3 либо в Б-1,но б-1 это вылет за доску,поэтому остается Б3,а вообще суть задачи заключается в том,чтобы ограничить грамотно поле и разрешить только 2 варианта либо на 2 по алфавиту в +- и на 1 по числам,либо на 2 по числам и на 1 по алфавиту,дальше проверка границ.
А вообще можно все поле запихнуть в массив,дальше перебрать все движения коня(ну то что я гворил про движение) и потом просто проверять на принадлежность массиву,если принадлежит,то печать,если нет то увы.Код писать не стану,а то обругают еще...)))

Как проверить,ну ты ставиш допустим,чтобы числовая переменная была от 1 до 10 вроде(уж не помню давно не играл) ну и алфавит обьвляеш множеством.
Cheburashka
То есть доску можно описать следующим образом:

Var a:array[1..8,a..h] of char;
...
...
For i:=8 downto 1 do
For j:=a to h do
a[i,j]:=j+i;


Я не очень разбираюсь в таких выражениях, и я не уверен что может быть вот это [1..8,a..h] и вот это a[i,j]:=j+i;

Но ведь что-то подобное можно сделать?
volvo
Цитата
я не уверен что может быть вот это [1..8,a..h]
Это - нет, а вот это:
[1..8,'a'..'h'] - вполне... Хотя, можно и первый вариант реализовать... В FAQ-е был? Про шахматные задачи читал, чтоб велосипед-то не изобретать?
Cheburashka
Сейчас взгляну... Но как я понял ход мыслей у меня правильный? smile.gif
Krjuger
Ну если ты захотел через массив реализовывать,то первый шаг ты сделал правильно.
Цитата

Хотя, можно и первый вариант реализовать

Это через аски чтоли?вроде как буквы там подрят расположены.И еще
Цитата

[1..8,'a'..'h']

Ну если он берет "of char",разве не ['1'..'8','a'..'h'] должно быть?Или я что то путаю.
Cheburashka
volvo, Что-то я не очень там могу найти это))
Krjuger, всё возможно... Только я с типом char очень мало работал))) Так что могу наделать сотни ошибок.
Krjuger
Ну я больше к volvo обращался,чем к тебе,ведь это его вариант был.
А вот тебе конкретная ссылка на этом же форуме,я хз можно ли их тут размещать.
Переборные Алгоритмы
Cheburashka
Ну то что там записано, это для меня чуть-чуть трудновато... Причём я многово ещё не знаю... Так сказать изучаю азы программирования...

Ну вернёмся к задаче)
Значит таким образом записать шахматное поле можно?
Var a:array['1'..'8','a'..'h'] of char;
...
...
For i:='8' downto '1' do
For j:='a' to 'h' do
a[i,j]:=j+i;



Меня смущает данная надпись - a[i,j]:=j+i;
Krjuger
Ну эта запись ты понимаеш что говорит?ну смотри как пример a[a,1] это самый первый элемент в массиве и ты ему присваиваеш значение этого поля.то есть у тебя получается элемент с координатами а,1 развен а1,кстати тогда у тебя должно быть не of char(char это только 1 элемент а у тебя их 2) a of string[2].
Да кстати поменяй тогда,в описании массива сначала буквы потом цифры иначе будет 1а
Cheburashka
В таком случае можно осуществить такую запись?
Var a:array[1..8,'a'..'h'] of string;
Krjuger
Можно, но string[2] будет достаточно,зачем тебе выделать лишную память,если у тебя вполне конкретные цели.,а вообще вот так будет лучше.

...
...
For i:='8' downto '1' do begin
For j:='a' to 'h' do begin
a[i,j]:=j+i;
write(a[i,j]);
end;
writeln;
end;

печать на экран чисто формальна,чтобы ты наглядно понял,что значит та строчка.
volvo
Цитата
Ну если он берет "of char",разве не ['1'..'8','a'..'h'] должно быть?
А какая разница Of "что"? Of показывает, что будет храниться в массиве, тип его элементов. Тип индекса - дело другое... Тем и хорош Паскаль, что позволяет в качестве индекса использовать любой перечислимый тип...

{ Хочу - так: }
Var a:array['1'..'8','a'..'h'] of char;

{ или так: }
Var a:array[1 .. 8, 'a' .. 'h'] of char;

{ ну, можно и так: }
Const
a = 'a';
h = 'h';
Var a:array[1 .. 8, a .. h] of char;


Цитата
Меня смущает данная надпись - a[i,j]:=j+i;
Правильно смущает... Чтобы это стало возможно, надо сделать
Var a:array['1'..'8','a'..'h'] of String[2];
, в один Char строку не засунешь...
Cheburashka
Krjuger, нет нельзя потому что вся доска сделана именно таким видом:
Изображение
Krjuger
Тема слишком горяча,даже пост отредактировать низя blink.gif .Насчет ответа мне, спс,запомню,хотя роли не играет.Понимаеш,как ты запихнет туда поле,роли не играет,разница будет в том что у тебя получаться перевернутые шахматы(как будто смотриш на ходы противника),а если оно привильно,то на результат это не повлияет,тебе же надо вывести значение поля.
Cheburashka
Ну да значения! Но что бы данные значения вывести нужно знать как они находятся на поле. Тут всё таки желательно учитывать в каком положении находится доска шахмат.
Krjuger
Покрути монитор и будет тебе счастье,только не выкрути совсем))))))Если бы ты собираться графику подключать и все это визуаально оформлять,то да,а так у тебя в виде результата только числа.
Хотя в общем это пустой треп))))Делай своим вариантом он эстетичнее)
volvo
А теперь - внимание: вопрос на засыпку. Зачем заполнять матрицу идентификатором клетки, если этот же идентификатор в любую секунду можно по индексам получить, может мне кто-нибудь объяснить? Что это мне даст? В матрице надо хранить не обозначение клетки, а признак того, может ли в определенную клетку попасть конь или нет...
Krjuger
А это уже другой вопрос,у нас не спрашивали,надо ли это или нет,а спрашивали,что это делает)))))и что то мне подсказывает,что это человек взял либо из какого нить фака,либо из чьей нить задачи.
Cheburashka
Ну так после того как мы нашли данную клетку, как нам переобозначить число в букву? (если только не глупым перебором 1-а 2-b)
volvo
Цитата
у нас не спрашивали,надо ли это или нет
dry.gif А тебе что, сообразительности не хватает, сказать человеку, что это ему не надо? Что ж ты сам-то ждешь КОРРЕКТНЫХ ответов, а даешь какие???

+ я все-таки настоятельно рекомендую топикстартеру просмотреть в FAQ-е алгоритмы Варнсдорфа (и тот, что перед ним) еще раз, он содержит бОльшую часть решения... Разберись с ними, если что непонятно - задавай вопросы, а не "просто чтобы спросить..."
Cheburashka
Ну хорошо. Посмотрю потом поинтересуюсь)
Krjuger
Эм а зачем тебе число в букву преобразовывать,я тебе сказал 2 схемы по котрым может двигаться конь,ты просто проверяеш,есть ли элемент в твем массиве,если есть то тру,если нету то фолс,и потом все тру печатаеш.

volvo, ему даже ссылку скинул на них,но человек ответил,что слишком сложно для него.

Насчет того что нужно это или нет
Цитата

тебе что, сообразительности не хватает, сказать человеку, что это ему не надо?

Ну для начала,используя его способ тоже можно решить,просто это менее рационально,но уж лучше сделать задачу,хоть как нибудь(ну чтоб правильно работала),а уж потом пытаться оптимизировать.Я думаю через ООП,эту задачу можно решить более красиво,и коротко,но человек врятли пока что в этом разбереться,плюс твой совет предполагает,что у нас массив будет хранить булеву переменную чтоли?Мож для человека это сложно7 ты не задумывался?
Client
for x2:=x1-2 to x1+2 do
for y2:=y1-2 to y1+2 do
if ((abs(x1-x2)=1) and (abs(y1-y2)=2) or
(abs(x1-x2)=2) and (abs(y1-y2)=1)) and
(x1 in [1..8]) and (y1 in [1..8])
then writeln(x2,y2)
X1,Y1-первоначальная клетка, X2,Y2-возможный переход (как в системе координат).
Cheburashka
Хм как бы то ни было странно но задача решается с данным алгоритмом!
Но я всё таки попытаюсь её доделать своим способом. Так как в данном случае программа выводт только но мера ячеек, а не букву и цифру.
Krjuger
Вот тебе человек щас предложил именно то,что я говорил,только вариантом банального перебора.тебе надо лиш немного изменть его процедуру,просто он делает с числами,то каждая буква в аски код переводится числом и вроде функция возвращения числа называется ord(x);,поправьте,если ошибаюсь.
Cheburashka
В общем либо сегодня либо послезавтра, я это попытаюсь решить до конца)
Cheburashka
Ха! Всё сделал)) Проверил все 64 теста))) олностью работает)))
program N_5;
var i,j,q,w,ibr,cod:integer;
s:string;
a:array[1..8,1..8] of integer;
Begin
Read (S);
case s[1] of
'a':s[1]:='1';
'b':s[1]:='2';
'c':s[1]:='3';
'd':s[1]:='4';
'e':s[1]:='5';
'f':s[1]:='6';
'g':s[1]:='7';
'h':s[1]:='8';
End;
Val(s,ibr,cod);
q:=ibr div 10;
w:=ibr mod 10;
For i:=q-2 to q+2 do
For j:=w-2 to w+2 do
If ((abs(q-i)=1) and (abs(w-j)=2)) or
((abs(q-i)=2) and (abs(w-j)=1)) and
((q>=1) and (q<=8)) and ((w>=1) and (w<=8)) then
If ((i>0) and (j>0)) and ((i<=8) and (j<=8)) then Begin
case i of
1:Write('a');
2:Write('b');
3:Write('c');
4:Write('d');
5:Write('e');
6:Write('f');
7:Write('g');
8:Write('h');
End;
Writeln (j);
End;
End.

Правда мне тут пришлось переводить цифры в буквы, буквы в цифры)) Но зато я её сделал)) cool.gif
Krjuger
Тебер дебагер вводиш свои переменные и смотриш посторочно что в них записывается на каждой строке,и когда увидеш что число в переменной вышло за рамки дозволенного смотриш почему так произошло.короче с дебагером учись работать.Скорее всего у тебя проблемы с проверкой на принадлежность массиву.
Cheburashka
Спасибо, но я уже разобрался))
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.