Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Приложение. Текст программы

Читайте также:
  1. D. Программы использования
  2. I «Волевые* метапрограммы_________________________ 161
  3. II. Модульное структурирование содержания образовательной программы
  4. II. Проблема текста (что это такое и как её определить).
  5. II. Требования к структуре образовательной программы дошкольного образования и ее объему
  6. II. Требования к структуре образовательной программы дошкольного образования и ее объему
  7. II. Требования к структуре основной общеобразовательной программы дошкольного образования

 

uses Crt, Graph;

const

N = 50; {размерность матрицы - шаблона кроссворда}

menu:array[1..3] of string[15]=('Данные','Тест','Выход'); {верхняя строка меню}

menuup:array[1..2]of string[15]=('Из файла','Диалог'); {меню Данные}

type

masWord = record {структура элемента массива слов}

number:integer; {номер слова}

word: string[25]; {слово}

pr: boolean {признак занятости слова}

end;

masKWord = record {структура элемента массива кроссворда}

ch: char; {символ}

numberWord: integer {номер слова, из которого взят символ}

end;

mas = array[1..N, 1..N] of masKWord; {заполненный кроссворд}

ListWord = record {список слов массива}

InI, InJ: integer; {координаты начала слова}

Dlina: integer; {длина}

Horizont: boolean; {ориентация слова (по горизонтали или по вертикали)}

end;

ref = ^z; {список использованных слов}

z = record {структура элемента списка использованных слов}

next: ref;

NumberWord: integer;

end;

var

f: text; {входной файл}

words: array[1..100] of masWord; {массив слов}

kword: array[1..N, 1..N] of integer; {шаблон кроссворда}

krword: mas; {кроссворд}

List: array [1..N*N] of ListWord; {список слов кроссворда}

k, kolWord: integer; {количество слов}

top: ref; {список использованных слов}

 

{процедура инициализации верхней строки меню}

Procedure InitMenu;

var

i: integer;

begin

window(1,1,80,25); {заливка экрана}

TextBackGround(Blue);

ClrScr;

gotoxy(1,1);

TextBackGround(LightGray); {верхняя строка серого цвета}

ClrEol;

TextColor(Black);

For i:=1 to 3 do {вывод трех пунктов меню}

begin

gotoxy((i-1)*30+2,1);

write(menu[i]);

end;

end;

 

{чтение данных из файла}

function InitFile:boolean;

var

s:string; {строка}

i, j: integer; {переменные для заполнения массива шаблона}

ch:char; {для чтения из файла}

p: boolean;{признак корректности файла}

 

procedure InitError; {вывод сообщения об ошибке}

begin

window(25,12,55,14); {формирование окна}

TextBackGround(Red); {вывод сообщения об ошибке символами красного цвета}

ClrScr;

write('Структура файла некорректна!');

repeat until keypressed;

InitMenu; {инициализация верхней строки меню}

end;

 

procedure WriteError; {вывод сообщения об ошибке}

begin

window(25,12,55,14); {формирование окна}

TextBackGround(Red); {вывод сообщения об ошибке символами красного цвета}

ClrScr;

write('Файл не найден! Повторите ввод имени файла!');

repeat until keypressed;

InitMenu; {инициализация верхней строки меню}

end;

 

begin

repeat

window(30,10,50,12); {ввод имени файла в окно}

TextBackGround(LightGray);

ClrScr;

gotoxy(1,1);

p:=true;

write('Введите имя фала');

gotoxy(1,2);

readln(s); {чтение строки - имени файла}

{$I-}

Assign(f,s); {открыть файл для чтения}

Reset(f);

if IOResult<>0 {если возникла ошибка при открытии файла}

then

begin

p:=false; {если возникла ошибка при открытии}

WriteError; {вывод сообщения}

end;

{$I+}

until p;

{$I-}

readln(f,k); {чтение из файла размерности шаблона кроссворда}

if (k<1) or (k>50) then p:=false; {проверка корректности размера массива шаблона}

if p then

begin

for i:=1 to k do {чтение из файла шаблона кроссворда}

for j:=1 to k do

begin

read(f,ch);

if ch='_' then

kword[i,j]:=0

else if ch='#' then

kword[i,j]:=1

else p:=false;

if j=k then readln(f);

end;

i:=1;

while not eof(f) do {чтение из файла слов для формирования кроссворда}

begin

readln(f,words[i].word);

words[i].Number:=i;

words[i].pr:=false;

inc(i)

end;

KolWord:=i-1;

{$I+}

end;

if (IOResult<>0) or not p then

begin

InitError;

InitFile:=false

end

else InitFile:=true; {проверка корректности входного файла}

end;

 

{ввод шаблона кроссворда и слов для формирования кроссворда в режиме диалога}

Procedure InitDialog;

var

i: integer;

begin

{заглушка}

end;

 

{вывод выпадающего меню}

Function InitMenuUp:boolean;

var

i, iold: integer;

p: boolean;

c: char;

begin

window(1,3,16,5); {вывод окна выпадающего меню}

TextBackGround(LightGray);

ClrScr;

TextColor(Black);

For i:=1 to 2 do {вывод пунктов меню}

begin

gotoxy(2,i);

write(menuUp[i]);

end;

i:=1;

iold:=1;

p:=false;

repeat {организация движения маркера по пунктам}

TextBackGround(LightGray);

gotoxy(2,iold);

write(menuUp[iold]);

TextBackGround(Green);

gotoxy(2,i);

write(menuUp[i]);

c:=readkey;

while c=#0 do c:=readkey;

case c of

#80: begin iold:=i; if i<2 then inc(i) else i:=1 end; {перемещение маркера вниз}

#72: begin iold:=i; if i>1 then dec(i) else i:=2 end; {перемещение маркера вверх}

#13: begin iold:=i; {выбор пункта}

p:=true; {начальные данные введены}

case i of

1: if not InitFile then begin p:=false; c:=#27 end; {если в результате

чтения данных из файла произошел сбой, то начальные данные не

введены}

2:InitDialog; {ввод данных в режиме диалога}

end;

end;

end;

until p or (c=#27); {возврат к верхней строке меню, если данные введены или Esc}

window(1,1,80,25);

InitmenuUp:=p; {функция возвращает true, если начальные данные введены, false в противном случае}

InitMenu; {инициализация верхней строки меню}

end;

 

{добавление в стек номеров использованных слов}

procedure pop(var top:ref; a:integer);

var

q:ref;

begin

new(q);

q^.next:=top;

top:=q;

top^.NumberWord:=a;

end;

 

{извлечение из стека номеров использованных слов}

function push(var top:ref):integer;

var

q:ref;

begin

if top<>nil then

begin

push:=top^.NumberWord;

q:=top;

top:=top^.next;

dispose(q);

end;

end;

{проверка возможности создания кроссворда на основе заданного шаблона с использование заданного набора слов}

Procedure Test;

type

r = record {количество слов заданной длины}

kolKrWord, kolWord: integer; {количество слов в кроссворде и в списке}

end;

var

i, j, len,num:integer;{вспомогательные переменные}

w: boolean; {признак ошибки}

dlw: array[1..N] of r; {массив количества слов (номер элемента - длина слова)}

{вывод сообщения о невозможности составить кроссворд}

Procedure PrintError;

begin

window(25,12,55,15); {вывод сообщения в окно}

TextBackGround(Red);

ClrScr;

writeln('По заданному множеству слов и');

writeln('матрице кроссворда не возможно');

writeln('составить кроссворд!');

repeat until keypressed; {ожидание нажатия клавиши}

InitMenu; {инициализация верхней строки меню}

end;

 

{вывод кроссворда}

Procedure PrintRez;

var i,j: integer; {вспомогательные переменные}

begin

TextBackGround(Blue);{установка цвета фона}

TextColor(Yellow);

clrscr;

Gotoxy(27,1);

writeln('Вариант кроссворда');

for i:=1 to k do {вывод кроссворда}

for j:=1 to k do

if j<>k then

if krword[i,j].ch<>'#' then

write(krword[i,j].ch)

else write('#')

else if krword[i,j].ch<>'#' then

writeln(krword[i,j].ch)

else writeln('#');

gotoxy(1,25); {вывод подсказки}

TextBackGround(LightGray);

ClrEol;

TextColor(Black);

write('Для выхода в главное меню нажмите Esc');

repeat until keypressed; {ожидание нажатия клавиши}

end;

 

{проверка, можно ли вписать слова в шаблон}

function testword:boolean;

var i,j,l,z:integer;

p:boolean;

 

{выбор из списка слов слова подходящей длины и не занятого, функция возвращает номер слова в списке}

function newword(i:integer;l:integer):integer; {i - с какого по счету слова в списке начинать поиск, l - длина искомого слова}

var

j:integer;

p: boolean;

begin

j:=i; {от какого номера начинать поиск}

p:=true;{слово не найдено}

while (j<=kolword) and p do {пока не прошли весь список и не нашли слово}

if (length(words[j].word)=l) and not words[j].pr then{если длина слова поджходит }

p:=false {слово найдено}

else inc(j); {иначе ищем дальше}

if p then newword:=0 {если прошли по всему списку и не нашли, функция возвращает 0}

else newword:=j; {иначе номер найденного слова}

end;

 

begin

i:=1;{подбор слова} j:=0;

while (i<=num) and(i>0) do {подбор для всех слов шаблона}

begin

j:=newword(1+j,List[i].dlina);{ищем слово подходящей длины, j используется как смещение }

if j<>0 then {если в списке слов такое нашлось}

begin

pop(top,j);{помещаем его номер в стек}

p:=true; {читаем, что слово можно вписать в кроссворд}

words[j].pr:=true; {помечаем, что слово занято}

if (krword[List[i].InI,List[i].InJ].NumberWord=0) or {если нет пересечения с уже вписанным словом данного символа}

(krword[List[i].InI,List[i].InJ].ch=words[j].word[1]) then {или пересечение есть, но символы совпадают}

begin

krword[List[i].InI,List[i].InJ].ch:=words[j].word[1]; {вписываем символ в клетку кроссворда}

if krword[List[i].InI,List[i].InJ].NumberWord=0 then {если пересечения нет}

krword[List[i].InI,List[i].InJ].NumberWord:=j; {помечаем номер слова, из которого взят символ}

l:=1; {номер вписанного символа слова}

while (list[i].dlina>l) and p do {пока не все символы слова вписаны и не произошла ошибка}

begin

if List[i].Horizont then {если слово необходимо вписать по горизонтали}

if (krword[List[i].InI,List[i].InJ+l].NumberWord=0)or {если клетка кроссворда свободна}

(krword[List[i].InI,List[i].InJ+l].ch=words[j].word[1+l]) then {или занята, но символы совпадают}

begin {вписываем символ и вписываем, если необходимо, номер слова}

krword[List[i].InI,List[i].InJ+l].ch:=words[j].word[1+l];

if krword[List[i].InI,List[i].InJ+l].NumberWord=0 then

krword[List[i].InI,List[i].InJ+l].NumberWord:=j;

end

else p:=false {если клетка занята, и символы не совпадают, произошла ошибка}

else {если необходимо вписать слово по вертикали}

if (krword[List[i].InI+l,List[i].InJ].NumberWord=0)or

(krword[List[i].InI+l,List[i].InJ].ch=words[j].word[1+l]) then

begin

krword[List[i].InI+l,List[i].InJ].ch:=words[j].word[1+l];

if krword[List[i].InI+l,List[i].InJ].NumberWord=0 then

krword[List[i].InI+l,List[i].InJ].NumberWord:=j

end

else p:=false; {произошла ошибка при вписывании слова}

inc(l); {переход к следующему символу слова}

end

end

else p:=false; {первый символ слова невозможно вписать в кроссворд}

if p then begin inc(i); j:=0 end; {если слово успешно вписано

в кроссворд, переходим к следующему пустому слову кроссворда}

if not p then {если попытка вписать слово не удалась}

begin

j:=push(top); {извлекаем номер слова из стека}

words[j].pr:=false; {помечаем слово как свободное}

for l:=1 to k do {в кроссворде помечаем клетки занятые символами слова как свободные}

for z:=1 to k do

if krword[l,z].numberWord=j then

krword[l,z].numberWord:=0;

l:=0; {нет вписанных символов слова}

end

end

else {если не нашли слова подходящей длины}

begin

j:=push(top); {извлекаем из стека номер последнего успешно вписанного слова}

{j используется как смещение при поиске следующего подходящего слова}

words[j].pr:=false; {помечаем слово как свободное}

for l:=1 to k do {помечаем клетки кроссворда, в которые было вписано слово как свободные}

for z:=1 to k do

if krword[l,z].numberWord=j then

krword[l,z].numberWord:=0;

i:=i-1; {уменьшаем количество вписанных слов на 1}

l:=0;

end;

end;

if i=num+1 then testword:=true else testword:=false {если все клетки кроссворда заполнены, функция возвращает true}

end;

 

begin

num:=0; {количество слов в шаблоне - ноль}

for i:=1 to k do {проход по строкам шаблона для поиска слов}

begin

w:=false; {слово не найдено}

len:=0; {длина слова - ноль}

for j:=1 to k do {идем по строке}

begin

if (kword[i,j]=0) and not w then {если в ячейке - начало слова}

begin

num:=num+1; {количество слов увеличиваем на 1}

List[num].InI:=i; {в список слов шаблона заносим координаты начала слова}

List[num].InJ:=j; {номер строки и номер столбца}

List[num].Horizont:=true;{ориентация по горизонтали}

w:=true; {признак слова}

end;

if kword[i,j]=0 then len:=len+1;{если признак слова true, длина слова увеличивается на 1}

if (kword[i,j]=1) and w then {если слово закончилось}

begin

if len>1 then {и длина слова больше 1}

List[num].Dlina:=len {заносим длину слова в список слов}

else num:=num-1; {если длина слова равна 1, извлекаем слово из списка слов}

len:=0; {длина слова 0}

w:=false; {слово не найдено}

end

end;

if w then if len>1 then list[num].dlina:=len else num:=num-1 {заносим последнее слово шаблона}

end;

 

for j:=1 to k do {проходим по столбцам с целью поиска слов}

begin

 

w:=false;

len:=0;

for i:=1 to k do

begin

if (kword[i,j]=0) and not w then

begin

w:=true;

num:=num+1;

List[num].InI:=i;

List[num].InJ:=j;

List[num].Horizont:=false;

end;

if kword[i,j]=0 then len:=len+1;

if (kword[i,j]=1) and w then

begin

if len>1 then

List[num].Dlina:=len

else num:=num-1;

len:=0;

w:=false;

 

end

end;

if w then if len>1 then list[num].dlina:=len else num:=num-1

end;

{инициализация массива кроссворда}

for i:=1 to k do

for j:=1 to k do

begin

krword[i,j].ch:='#';

krword[i,j].numberWord:=0;

end;

{инициализация массива количества слов заданной длины}

for i:=1 to k do

begin

dlw[i].kolkrWord:=0;

dlw[i].kolWord:=0;

end;

{подсчет количества слов заданной длина}

for i:=1 to k do

begin

for j:=1 to num do {в шаблоне}

if list[j].dlina=i then

dlw[i].kolkrWord:=dlw[i].kolkrWord+1;

for j:=1 to kolWord do {в списке слов}

if length(words[j].word)=i then

dlw[i].kolWord:=dlw[i].kolWord+1;

end;

{проверка соответствия количества слов по длине}

w:=true;

for i:=1 to k do

if dlw[i].kolKrWord>dlw[i].kolWord then {в списке слов заданной длины должно быть не меньше, чем требуется по шаблону}

w:=false;

{если слов не хватает, вывод сообщения, иначе пробуем вписать слова в шаблон}

if not w then printError

else if testWord then

printrez

else printError;

{инициализация меню}

InitMenu;

end;

{процедура инициализации экрана, верхней строки меню и организации работы с меню}

Procedure Init;

var

i,iold: integer;{координаты маркера}

c: char; {последний считанных символ}

p: boolean; {признак ввода входных данных}

{процедура вывода сообщения об ошибке при попытке

вызова процедуры нахождения варианта построения кроссворда

при незаданных начальных условиях}

procedure TestError;

var

c:char;

begin

window(25,12,55,14); {вывод в окно символами красного цвета}

TextBackGround(Red);

ClrScr;

write('Не заданы входные данные!');

repeat until keypressed;

c:=readkey;

 

InitMenu;

end;

 

begin

InitMenu; {вывод верхней строки меню}

p:=false; {начальные данные для построения кроссворда не заданы}

i:=1;{маркер установлен на первый пункт меню}

iold:=1; {перемещений маркера не было}

repeat

TextBackGround(LightGray); {перемещение маркера с позиции iold на позицию i}

gotoxy((iold-1)*30+2,1);

write(menu[iold]);

TextBackGround(Green);

gotoxy((i-1)*30+2,1);

write(menu[i]);

c:=readkey;

while c=#0 do c:=readkey; {ожидание нажатия клавиши}

case c of

#77: begin iold:=i; if i<3 then inc(i) else i:=1 end; {перемещение маркера вправо}

#75: begin iold:=i; if i>1 then dec(i) else i:=3 end; {перемещение маркера влево}

#13: begin iold:=i; {выбран пункт меню}

case i of

1: p:=InitMenuUp; {Выбран пункт ДАННЫЕ, вызываем процедуру вывода выпадающего меню}

2: if p then begin Test; p:=false end {выбран пункт ТЕСТ, если начальные данные заданы,

вызываем процедуру поиска варианта кроссворда}

else TestError; {если не заданы, выводим сообщение}

end;

end;

 

end;

until (i=3) and (c=#13); {выход из программы при выборе пункта ВЫХОД}

end;

 

Begin

Init; {Запуск процедуры инициализации}

window(1,1,80,25);{восстановление параметров экрана}

TextBackGround(Black);

ClrScr;

TextColor(white);

End.


Дата добавления: 2015-12-08; просмотров: 58 | Нарушение авторских прав



mybiblioteka.su - 2015-2024 год. (0.072 сек.)