[pascal] Японские кроссворды

Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Здравствуйте, уважаемые участники форума! Меня к вам привело следующее задание:

Тема : «Программирование графики в Турбо Паскале. Программа для решения
японских головоломок»

Содержание задания: Составить программу для решения японских головоло-мок. Программа должна уметь предложить пользователю головоломку на выбор (не менее 15), проверить правильность её решения; позволять созда-вать собственные рисунки для головоломок и запоминать их в файле.

Под японской головоломкой понимается японский кроссворд.

Как решить простейший японский кроссворд:

В японских головоломках, в отличие от других кроссвордов, зашифрованы не слова, а изображения. Задача - восстановить картинку по числам, которые проставлены слева от строк и над колонками. Числа показывают, сколько групп черных клеток находится в соответствующей строке или колонке и сколько слитных черных клеток содержит каждая группа. Например, набор чисел 4 и 4 означает, что в этом ряду есть две группы: первая - из четырех и вторая - из четырех черных клеток. Группы разделены как минимум одной пустой клеткой. Пустые клетки могут быть и по краям рядов. Необходимо определить размещение групп клеток.

Прикрепляю картинку с примером.

Дело в том, что я графику в паскале почти не знаю :confused:

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

Фрагмент следующий:

program japanese_crossword;
uses crt, graph;
const r=11;
var p: 0..1; a,b: array[0..r,0..r] of 0..1;
i,j,n,k1,k2,ss,x,y,gm,gd:integer; c:char;
begin
detectgraph(i,j); initgraph(i,j,'c:/bp/bgi');
begin
gm:=vgahi; setgraphmode(gm); setlinestyle(0,0,1); setcolor(4);
for i:=0 to r-1 do
begin
line(20+i*20,20,20+i*20,r*20);
line(20,20+i*20,r*20,20+i*20);
end;
x:=10; y:=10;
repeat
c:=readkey; if c=#0 then c:=readkey;
case c of
#72 : begin
setcolor(0); circle(x,y,2); y:=y-20; setcolor(15); circle(x,y,2);
end;

#80 : begin
setcolor(0); circle(x,y,2); y:=y+20; setcolor(15); circle(x,y,2);
end;

#75 : begin
setcolor(0); circle(x,y,2); x:=x-20; setcolor(15); circle(x,y,2);
end;

#77 : begin
setcolor(0); circle(x,y,2); x:=x+20; setcolor(15); circle(x,y,2);
end;

#13 : begin
floodfill(x,y,4); a[(x-5) div 10,(y-5) div 10]:=1;
b[(x-5) div 10,(y-5) div 10]:=1;
end;

#32 : begin
setfillstyle(1,5); bar(x-9,y-9,x+9,y+9);
a[(x-5) div 10,(y-5) div 10]:=0;
b[(x-5) div 10,(y-5) div 10]:=0;
setfillstyle(1,15);
end;
end; {case}
until c=#27;
setcolor(0); circle(x,y,2);
end;
end.

Надеюсь, что мое задание вас заинтересует. Помогите, чем сможете. Заранее благодарю.
Вложения
car.gif
car.gif (2.91 КБ) 351 просмотр
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

const r=11;
var p: 0..1; a,b: array[0..r,0..r] of 0..1;
Ну, во-первых, для переменных, имеющих значения "истина" или "ложь" (включено-выключено) есть тип boolean. А во-вторых, кто мешает сделать массив [0..r,0..p] of boolean, где p - тоже какая-нибудь константа?
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Программа будет не маленькая, советую:
- Обозначить определенные действия через процедуры и функции - это значительно упростит программирование в целом.
- Ввести тип данных рабочего поля примерно таким:

Код: Выделить всё

TJapanField = record
        Width : Byte;
        Height : Byte;
        Field : Array[1..256, 1..256] of byte;
end;
впоследствии можно передавать это поле (целиком или ссылку) в процедуры и функции, например, прорисовки на экране всего поля

Код: Выделить всё

procedure DrawField(var F: TJapanField);
begin
ClearViewPort;
line(20+i*20,.........
.....
end;
Процедуры сохранения в файл оформляются таким же способом.
Рабочее поле состоит из данных, типа byte. Это связано с тем, что
- Кол-во цветов в кроссворде может быть более 2-ух
- Помимо неизвестных клеток есть еще помеченные как пустые
Можно задать следующие условные обозначения:
бит 0 - известная/неизвестная клетка
все остальные биты кодируют цвет, т.е. в простейшем случае из двух цветов
00000000 - пустая неизвестная клетка
00000001 - пустая известная
00000010 - клетка заполнена цветом 1, но нам не известна
00000011 - клетка заполнена и разгадана и т.д. если цветов более 2-ух
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Somewhere, все проще, чем ты думаешь. Дело в том, что кроссворд 2-х цветный (извини, забыл упомянуть). Как лучше рассуждать в таком случае?
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):Somewhere, все проще, чем ты думаешь. Дело в том, что кроссворд 2-х цветный (извини, забыл упомянуть). Как лучше рассуждать в таком случае?
Точно так же, так как флаг открытой/неоткрытой клетки все равно остается. Типа Boolean будет недостаточно.
Думаю, сейчас стоит сделать сначала каркас. Т.е. описать все типы, сделать заготовки процедур и функций. После этого постепенно добавлять по небольшой возможности.
It's a long way to the top if you wanna rock'n'roll
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Программа предназначена для того, чтобы пользователь сам решал японские кроссворды, или чтобы она решала? Если сам, то у клетки может быть три состояния: неизвестно что, гарантированно пустая клетка и гарантированно полная. Тогда вместо байта можно использовать перечисляемый тип 0..2
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

&quot писал(а):
Программа предназначена для того, чтобы пользователь сам решал японские кроссворды, или чтобы она решала? Если сам, то у клетки может быть три состояния: неизвестно что, гарантированно пустая клетка и гарантированно полная. Тогда вместо байта можно использовать перечисляемый тип 0..2
Для того, чтобы пользователь решал кроссворд - он должен уже заранее существовать. Значит 4-е состояния
- пустая/неизв.
- заполнен./неизв.
- пустая/изв.
- заполнен./неизв.
It's a long way to the top if you wanna rock'n'roll
Хыиуду
Сообщения: 2442
Зарегистрирован: 06 мар 2005, 21:03
Откуда: Москва
Контактная информация:

Вначале он существует в виде совокупности цифр. Это не "Сапер", где мина либо есть, либо нет. Программа может проверить корректность закрашивания, но изначально она не знает, какая клетка закрашена, а какая нет.
Искусство программирования - заставить компьютер делать все то, что вам делать лень.
Для "спасибо" есть кнопка "Спасибо" в виде звездочки внизу под ником автора поста.
Аватара пользователя
somewhere
Сообщения: 1858
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

Ну хорошо, вот мы пишем процедуру проверки решения, в плане реализации мы должны оставить 4-е значения для поля. Как нам потом сравнивать решение пользователя и компа. Если поле юзера и программы объединить, то должно быть 4.
It's a long way to the top if you wanna rock'n'roll
Аватара пользователя
Alex_Burn
Сообщения: 147
Зарегистрирован: 13 апр 2007, 17:49
Контактная информация:

Программа не должна уметь решать кроссворды, она лишь должна предложить кроссворд пользователю.
;)
Я вообще-то предполагал состояния клеток задавать в программе (естественно, для каждого кроссворда эти состояния будут свои), записывать эти состояния в файл. А потом, после того, как пользователь решит кроссворд, прочитать данные из файла и сравнить с тем, что получилось у пользователя.

На мой взгляд, в таком случае у клеток должно быть 2 состояния:

закрашена/незакрашена

Я вообще-то начинающий. Может я ошибаюсь?.. :confused:
Ответить