Программа для создания кросвордов - Lazarus[Delphi]-версия. ([Обсуждение программы и кода])

Полезные советы и программы от пользователей нашего форума.

Модератор: Модераторы разделов

Ответить
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

Здравствуйте!

Вот и созрел четвёртый проект для глаз общественности. Пока выпущено 2-е бетаверсии. В них я попытался исправиться с комментариями кода. Комментирую сразу, возможно есть лишнее.

Он представляет собой Клёст-кроссворд переписанный на Lazarus так же, не используя ничего нестандартного, во избежании плохой межплатформенной переносимости. Носит кодовое название OpenKlest. Смысл его заключается в создании открытого стандарта файла кроссвордов для всех компиляторов, независимо от платформы или языка.

Версия 0.1.1 - есть функция отгадывания кроссворда в формате OpenKlest 1.0(экспортируют Клёст-кроссворд 0.2.9, 0.3.7). Пока только латиница :rolleyes:
Скрин:
Изображение

Ссылка на SourceForge.net. Код под GNU GPL v2 - OpenSource.

Описание формата OpenKlest 1.0:
Это двоичный формат файла кроссворда, разработанный так, чтобы было максимально просто сделать его поддержку в других языках программирования, отличных от C++. Он экспортируется средствами чистого C++, без расширяющих возможностей библиотеки Qt.
---
//Версия файла
char cFileBegin[14] = "OpenKlest-1.0~";

//Количество строк кроссворда
uint uiRowCount;

//Количество столбцов кроссворда
uint uiColumnCount;

//Ширина(Высота) ячейки
uint uiRowHeight;

// Если ячейка чёрная
;QChar qcCell = 'b';

// Если ячейка белая
;QChar qcCell = 'w';

// Цикл от uiRowCount до uiColumnCount
ushort usCell = qcCell.unicode() + 1;

//Количество слов
uint uiWordCount;

//Координата строки расположения слова в сетке кроссворда;
//Цикл от 0 до uiWordCount
ushort usWordRow;

//Координата столбца расположения слова в сетке кроссворда;
//Цикл от 0 до uiWordCount
ushort usWordColumn;

// Если слово вертикальное
;QChar qcDirection = 'v';

// Если слово горизонтальное
;QChar qcDirection = 'h';

//Направление слова в сетке кроссворда;
//Цикл от 0 до uiWordCount
ushort usWordDirection = qcDirection.unicode();

//Длина слова в сетке кроссворда;
//Цикл от 0 до uiWordCount
ushort usWordLength;

//Слово
;string sWord;

//Цикл от 0 до uiWordCount
char cWord[sWord.length()];

//Длина вопроса; Цикл от 0 до uiWordCount
ushort usQuestionLength;

//Вопрос
;string sQuestion;

//Цикл от 0 до uiWordCount
char cQuestion[sQuestion.length()];

//Метка конца файла
char cFileEnd[10] = "~OpenKlest";
Как Вам словесное описание и сам формат? Что нужно добавить или изменить? Жду комментариев.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение RasenHerz »

Описание формата OpenKlest 1.0:

Больше похоже на какой-то бред состоящий из кусков кода на C++ и комментариев, а не на описание формата хранения данных. Загуглите <любой_формат> specification.
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

RasenHerz писал(а):
05.11.2011 22:22
Описание формата OpenKlest 1.0:

Больше похоже на какой-то бред состоящий из кусков кода на C++ и комментариев, а не на описание формата хранения данных. Загуглите <любой_формат> specification.
Как я думаю, оно просто неполное и не содержит стройной картины и уточняющей информации.
Вот пример описания формата Across lite v1:
Creating Across puzzles using Across Lite
...
Older TEXT version (prior to v2) // = 1.0 :)
...
<ACROSS PUZZLE>
<TITLE>
...puzzle title/theme here in a single line... (or leave a blank line)
<AUTHOR>
...puzzle author/editor here in a single line... (or leave a blank line)
<COPYRIGHT>
...puzzle copyright notice here in a single line. A © will be automatically added at the
beginning... (or leave a blank line)
<SIZE>
...grid size as No. of columns x No. of rows (e.g., 15x15). Must provide this information. x
must be lower case.
<GRID>
...Use one line for each row in the grid. Enter solution letter or period(.) for black
...
Поэтому не надо так критично ;)
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение RasenHerz »

Вот пример описания формата Across lite v1:

И как я понимаю он не бинарный в отличие от вашего. За пример описания бинарной структуры можно взять документацию для тега ID3: http://www.id3.org/Developer_Information .

P.S. я не совсем понял зачем вы изобретаете велосипед, если можно взять спеку от того же Across lite v1
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

RasenHerz писал(а):
06.11.2011 13:33
Вот пример описания формата Across lite v1:

И как я понимаю он не бинарный в отличие от вашего. За пример описания бинарной структуры можно взять документацию для тега ID3: http://www.id3.org/Developer_Information .

P.S. я не совсем понял зачем вы изобретаете велосипед, если можно взять спеку от того же Across lite v1 //Доформулируйте вопрос с примером ;)
Это невнимательный вброс был. Я понял. В описании формата Across Lite v1 -
кусков кода на C++ и комментариев
- да, да, куски кода и комментарии. В описании тега ID3 есть байты и принимаемые значения списком. В моём формате - указаны типы данных(ex. ushort) - это значит, принимает все значения диапазона. Просто и компактно но, если будет необходимость разжевать для остальных, я возможно это сделаю.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение /dev/random »

1) Начнём с мелочей. Абсолютно нечитаемый стиль написания "спецификации", в результате чего её можно трактовать двояко. Например, отсутствует описание того, где заканчиваются тела упомянутых в комментариях "циклов".
2) Это C++? Если да, то в нём отсутствуют такие типы, как uint (есть unsigned int), ushort (есть unsigned short) и, тем более, QChar. Полагаю, что вы имели в виду типы из библиотеки Qt? Почему же вы тогда написали, что файл экспортируется без её использования?
3) QChar объявлен в Qt как пользовательский класс. Что должно быть в файле? Его бинарное представление? Оно мало того, что в разных компиляторах может получаться разным, так ещё и разработчики Qt без проблем могут изменить его в очередной версии.
4) string - это стандартный класс, но бинарное представление для него стандартом не определено.
5) Даже для типов int/long/short не определены ни бинарное представление, ни даже размер. Они могут меняться от системы к системе, от компилятора к компилятору, от архитектуры процессора к архитектуре процессора.

Таким образом получаем, что ваша "спецификация" вообще не описывает, что должны представлять из себя эти поля. Более того, если вы точно так же реализовали свой формат и в программе, то даже просто после обновления системы, не говоря уже о переносе файла на чужой компьютер, вы уже не сможете быть уверены, что он откроется.
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

/dev/random, благодарю!
Описание формата OpenKlest 1.0:
Это двоичный формат файла кроссворда, разработанный так, чтобы было максимально просто сделать его поддержку в других языках программирования, отличных от C++. Он экспортируется средствами чистого C++, без расширяющих возможностей библиотеки Qt.
---
//Версия файла
cFileBegin array[14] of char := 'OpenKlest-1.0~';
//Количество строк кроссворда
lwRowCount: Longword;
//Количество столбцов кроссворда
lwColumnCount: Longword;
//Ширина(Высота) ячейки
lwRowHeight: Longword;
// Если ячейка чёрная
;(wcCell: WideChar) wcCell = 'b';
// Если ячейка белая
;(wcCell: WideChar) wcCell = 'w';
// Цикл от 0 до lwRowCount
//Вложенный цикл от 0 до lwColumnCount
wCell: Word := Word(wcCell) + 1;
//Количество слов
lwWordCount: Longword;
//Координата строки расположения слова в сетке кроссворда;
//Цикл от 0 до lwWordCount
wWordRow: Word;
//Координата столбца расположения слова в сетке кроссворда;
//Цикл от 0 до lwWordCount
wWordColumn: Word;
// Если слово вертикальное
;(wcDirection: WideChar) wcDirection = 'v';
// Если слово горизонтальное
;(wcDirection: WideChar) wcDirection = 'h';
//Направление слова в сетке кроссворда;
//Цикл от 0 до lwWordCount
wWordDirection: Word := Word(wcDirection);
//Длина слова в сетке кроссворда;
//Цикл от 0 до lwWordCount
wWordLength: Word;
//Слово
;sWord: string;
//Цикл от 0 до lwWordCount
cWord: array[Length(sWord)] of char;
//Длина вопроса;
//Цикл от 0 до lwWordCount
wQuestionLength: Word;
//Вопрос
;sQuestion: string;
//Цикл от 0 до lwWordCount
cQuestion: array[Length(sQuestion)] of char;
//Метка конца файла
cFileEnd: array[10] of char := '~OpenKlest';
Пока такой вариант - потом буду дорабатывать, со словесным указанием занимаемой памяти и диапазона принимаемых значений. :rolleyes:
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение RasenHerz »

xwicked писал(а):
07.11.2011 10:20
Пока такой вариант - потом буду дорабатывать, со словесным указанием занимаемой памяти и диапазона принимаемых значений. :rolleyes:

Опять же, это не спецификация, это псевдокод описывающий считывание этого файла. И к примеру, у меня сразу возникает вопрос что такое к примеру Word и Longword и какова их длина? Если Word это машинное слово, то что такое LongWord и почему не указана длина этих типов. Кроме того, что такое WideChar, какова его длина для UTF-8 и UTF-16 строк? Возможно я повторюсь, но так же неясно где заканчиваются циклы описанные в псевдокоде.
Спасибо сказали:
aumit
Сообщения: 28

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение aumit »

Makefile написал бы, или bash скрипт для сборки.
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

aumit писал(а):
07.11.2011 23:14
Makefile написал бы, или bash скрипт для сборки.
Это чтобы из консоли запускать сборку, не трогая Lazarus IDE?
Спасибо сказали:
Ism
Сообщения: 1261
Статус: Никто, по сути быдло

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение Ism »

Зачем, если есть lazbuild

http://wiki.lazarus.freepascal.org/lazbuild
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

Здравствуйте!

В новой версии есть улучшения работы и интерфейса. TBitBtn

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

tbExit: TBitBtn;//Кнопка панели "Выход из программы"
заменён на TSpeedButton

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

tbExit: TSpeedButton;
Убрано раздражающее мерцание, вызванное неправильной и двойной перерисовкой сетки кроссворда. До:

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

    bmCell := TBitmap.Create();//Создание цветной ячейки
    bmCell.SetSize(GridOpenKlest.DefaultColWidth - 1,
                   GridOpenKlest.DefaultColWidth - 1);
    bmCell.Canvas.Brush.Style := bsSolid;
    bmCell.Canvas.Brush.Color := cl3DLight;//Установка цвета фона сетки кроссворда в ячейке
    bmCell.Canvas.FillRect(0,0, GridOpenKlest.DefaultColWidth - 1,
                           GridOpenKlest.DefaultColWidth - 1);

        //Если прошлое направление слова было горизонтальным, то
        if LastGWL = 'h' then
            begin
                for i := LastCFCW to LastCFCW + LastLW - 1 do
                    begin
                        //Очистка выделенного слова в стеке кроссворда от зелёного(clLime) цвета
                        //Замена на cl3DLight
                        GridOpenKlest.Canvas.CopyRect(GridOpenKlest.CellRect(
                            i, LastRFCW), bmCell.Canvas, Rect(0,0,
                            bmCell.Height, bmCell.Width));
                    end;
            end;

        //Если прошлое направление слова было вертикальным, то
        if LastGWL = 'v' then
            begin
                for i := LastRFCW to LastRFCW + LastLW - 1 do
                    begin
                        //Очистка выделенного слова в стеке кроссворда от зелёного(clLime) цвета
                        //Замена на cl3DLight
                        GridOpenKlest.Canvas.CopyRect(GridOpenKlest.CellRect(
                            LastCFCW, i), bmCell.Canvas, Rect(0,0,
                            bmCell.Height, bmCell.Width));
                    end;
            end;

    GridOpenKlest.Repaint;//Перерисовка таблицы кроссворда, чтобы введённый в ячейках текст не был стёрт
После:

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

GridOpenKlest.Repaint;//Очистка сетки от зелёного
Дополнительные изменения:
- Устранена ошибка неправильного отображения текста в списке вопросов;
- Добавлена поддержка Windows-тем, используя файл *.manifest;
- Оптимизирована часть кода;
- Добавлена возможность выбора слова из сетки кроссворда;
- Добавлены ссылки программы в разделе "Автор", окна "О программе" на сайт SourceForge.net: Основная ссылка, Bug-трекер и Git;
Скачать
Спасибо сказали:
Аватара пользователя
xwicked
Сообщения: 115
ОС: GNU / Linux Debian 7 amd64
Контактная информация:

Re: Программа для создания кросвордов - Lazarus[Delphi]-версия.

Сообщение xwicked »

Здравствуйте!
Чуть изменил формат уже 1.1 и подправил описание:
Описание формата OpenKlest 1.1:

Это двоичный формат файла кроссворда, разработанный так, чтобы было максимально просто сделать его поддержку в других языках программирования, отличных от C++. Он экспортируется средствами чистого C++, без расширяющих возможностей библиотеки Qt.

Чтение файла начинается c 14-ти байт типа Char('OpenKlest-1.1~'), где 1.1 - это версия формата. 1 символ Char = 1 символу AnsiChar = знаковое 1 байт.
Далее идёт язык кроссворда логического типа, boolean, 1 байт.
Далее количество строк сетки кроссворда, LongWord, беззнаковое 4 байта.
Далее количество столбцов сетки кроссворда, LongWord, беззнаковое 4 байта.
Затем размер ячейки сетки кроссворда, LongWord, беззнаковое 4 байта.
Затем значение цвета ячейки, Word, беззнаковое 2 байта. От него отнимается цифра 1. Чтение происходит в 2-х циклах:
Основной от 0 до количества строк, вложенный цикл от 0 до количества столбцов.
Затем количество слов, LongWord, беззнаковое 4 байта.
Потом чтение координат первых букв слов(строки), Word, беззнаковое 2 байта. Цикл от 0 до количества слов.
Потом чтение координат первых букв слов(столбцы), Word, беззнаковое 2 байта. Цикл от 0 до количества слов.
Потом чтение направлений слов, Word, беззнаковое 2 байта. Цикл от 0 до количества слов.
Следующим будет чтение длин слов, Word, беззнаковое 2 байта. Цикл от 0 до количества слов.
Следующим будет чтение слов-ответов, состоящих из набора unicode-симоволов, типа Word, беззнаковое 2 байта. Основной цикл от 0 до количества слов, вложенный от 0 до количества букв текущего слова.
Следующим будет чтение длин вопросов, Word, беззнаковое 2 байта. Цикл от 0 до количества слов.
Далее идёт чтение предложений-вопросов, состоящих из набора unicode-симоволов, типа Word, беззнаковое 2 байта. Основной цикл от 0 до количества слов, вложенный от 0 до количества букв текущего вопроса.
Ну и в конце загружается флаг конца файла ('~OpenKlest'), 10 байт типа Char. 1 символ Char = 1 символу AnsiChar = знаковое 1 байт.

Обращаю внимание на то, что в ОС Оффтопик русский текст, записываемый в строку AnsiString, записывает Wide(unicode)-символы по одному байту в Ansi-букву. Чтобы это исправить я сделал так:

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

    //Для Оффтопика
//s: String;

        {if gWordLine = 'h' then
            begin
                for i := ColumnFirstCellWord to ColumnFirstCellWord + LengthWord - 1 do
                    begin
//Если язык русский
                        if bLanguageWords = true then
                           begin
                               s := sTemp[j - 1] + sTemp[j];//Собираю их вместе :)
                               GridOpenKlest.Cells[i, RowFirstCellWord] := s;//Загрузка слова в сетку
                               j := j + 2;
                           end
                        else
                        begin
                             GridOpenKlest.Cells[i, RowFirstCellWord] := sTemp[j];//Загрузка слова в сетку
                             Inc(j);
                        end;
                    end;
            end;

Есть ещё это:

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

                            //Для Оффтопика
//Если язык русский
                            {if bLanguageWords = true then
                                begin
                                     slQuestionT.Add(AnsiToUtf8(sTemp));//Wide(!)-символы преобразую из Ansi(!) в Wide :)
                                     ListQuestions.Items.Add(AnsiToUtf8(sTemp));
                                end
                            else
                            begin
                                slQuestionT.Add(sTemp);
                                ListQuestions.Items.Add(sTemp);
                            end;}
Скачать новую версию 1.0.0
Изменения:
- Добавлен перевод интерфейса игры на русский язык;
- Добавлена поддержка Unicode в кроссворде;
- Добавлена проверка версии файла кроссворда. Тем самым устранена фатальная ошибка;
- Добавлена справка;
- Добавлена возможность ввода ника;
- Добавлены новые кнопки на стандартную панель инструментов;
- Добавлена возможность проверки правильности разгадывания кроссворда;
- Добавлена статистика игроков;
- В строку состояния добавлены новые элементы;
- Добавлены подсказки для элементов интерфейса;
- Добавлен диалог, позволяющий продолжить разгадывание, при случайной попытке выхода из игры;
Спасибо сказали:
Ответить