Опубликован: 12.02.2014 | Доступ: свободный | Студентов: 924 / 239 | Длительность: 11:22:00
Тема: Программирование
Специальности: Программист
Лекция 15:
Экспертная система. Логическая задача. Фейерверк
15.3. Новогодний фейерверк
В следующей программе моделируется фейерверк. Она представляет собой анимационную поздравительную открытку (рис. 15.1).
На фоне праздничного фейерверка появляются поздравительные надписи, выбранные случайным образом. Цвет надписей и цвет каждого элемента фейерверка также выбирается случайным образом. На каждую надпись приходится три залпа. Местоположение фейерверка и надписи выбирается случайным образом перед каждым залпом. Перед появлением или исчезновением каждого элемента фейерверка делается небольшая пауза. Поток залпов и поздравлений прекращается после щелчка левой кнопкой мыши в окне консоли.
open core, console, console_native, math, list, programControl constants % Congratulation-phrases for random choice phraseList : string* = [ "Счастливого Нового Года и Рождества!", "From Russia with love!", "Vivat Visual Prolog!", "We wish you a Merry Christmas and a happy New Year!", "Joyeux Noёl et bonne Annee!", "Frohe Weihnachten und ein gutes neues Jahr!", "Buon Natale e felice Anno Nuovo!", "Feliz Navidad y Prospero Ano Nuevo!", "Glaedelig Jul og Godt Nytar!", "Kurisumasu Omedeto!", "Natale hilareet Annum Faustum!" ]. % Symbols that will be randomly used for building a firework symbolList : string* = ["*", "+", "x"]. class facts xp : unsigned16 := 28. yp : unsigned16 := 37. phrase : string := "". n : positive := 3. class predicates ellipse: (integer Rx, integer Ry, integer XCent, integer YCent, string Symbol, positive Sleep). arc: (integer Rx, integer Ry, integer XCent, integer YCent, real PercentBeg, real PercentEnd, string Symb, positive Sleep). line: (coord P1, coord P2, string, positive Sleep). print: (string Symbol). stop: () determ. clauses print(Symbol):- setTextAttribute(math::random(7) + 9), write(Symbol). % drawing an ellipse with the center in (XCent; YCent) ellipse(Rx, Ry, XCent, YCent, Symbol, Sleep):- arc(Rx, Ry, XCent, YCent, 0, 1, Symbol, Sleep). % drawing an arc with the center in (XCent; YCent) arc(Rx, Ry, XCent, YCent, PercentBeg, PercEnd, Symb, Sleep):- X = std::downTo(round(PercEnd *31), round(PercentBeg *31)), Angle = (2 * pi) * (X / 32), XCur = round(XCent + Rx * cos(Angle)), YCur = round(YCent - Ry * sin(Angle)), setLocation(coord(XCur + 0, YCur + 0)), print(Symb), sleep(Sleep), fail; succeed(). % Drawing a vertical line line(coord(X, Y1), coord(X, Y2), Symbol, Sleep):- !, (Y = std::fromTo(Y1, Y2), setLocation(coord(X, Y)), print(Symbol), sleep(Sleep), fail; succeed()). % Drawing a non-vertical line line(coord(X1, Y1), coord(X2, Y2), Symbol, Sleep):- X = std::between(X1, X2), Y = round(Y1 + (X - X1) * (Y2 - Y1) / (X2 - X1)), setLocation(coord(X, Y + 0)), print(Symbol), sleep(Sleep), fail; succeed(). stop():- L = getEventQueue(), mouse(_, _, 1, _, 0) = getMember_nd(L), !. % Drawing a firework using random symbols from the list % and replacing the firework by that of blank spaces constants % Parametres for 7 branches of the firework startx : integer* = [42, 38, 42, 38, 41, 39, 39]. starty : integer* = [20, 20, 18, 18, 21, 21, 18]. vx : integer* = [7, -6, 4, -3, 5, -5, -2]. vy : integer* = [7, 7, 9, 9, 5, 5, 11]. class facts parametres : tuple{integer, integer, integer, integer}* := zip(startx, starty, vx, vy). class predicates printPoint: (real X0, real Xspeed, real T, real Y0, real Yspeed, real G, string Symbol). firework: (boolean IsDrawing, real X0, real Y0, real G, positive Sleep, string Symbol, positive SymbolListLength). getSymbol: (boolean IsDrawing, string Symbol, positive) -> string. clauses /* Calculation of the trajectory of a thrown object (symbol) for forming a firework line. The object is thrown at certain angle and falls with free-fall acceleration G */ printPoint(X0, Xspeed, T, Y0, Yspeed, G, Symbol):- X = round(X0 + XSpeed * T), Y = round(Y0 - (YSpeed * T - G * T ^ 2/2)), setLocation(coord(X + 0, Y + 0)), print(Symbol). firework(IsDrawing, Xc, Yc, G, Sleep, Symbol, N):- I = std::fromTo(0, 29), forAll(parametres, {(tuple(Cx, Cy, Vx, Vy)):- printPoint(Cx - Xc, Vx, I * 0.1, Cy + Yc, Vy, G, getSymbol(IsDrawing, Symbol, N))}), sleep(Sleep), fail; succeed(). getSymbol(true, _, N) = nth(random(N), symbolList):- !. getSymbol(_, Symbol, _) = Symbol. run():- FSleep = 15, setConsoleTitle("Happy New Year"), %A circle that will contain the characters ellipse(22, 11, 40, 12, "*", 0), vpi::alarm(2), % Three arc(7, 4, 40, 7, -0.25, 0.40, "$", FSleep), arc(9, 5, 40, 16, -0.43, 0.25, "$", FSleep), sleep(750), % Erasing 'three' % To erase something we replace it by the same figure % formed by blank spaces arc(7, 4, 40, 7, -0.25, 0.40, " ", FSleep), arc(9, 5, 40, 16, -0.43, 0.25, " ", FSleep), vpi::alarm(2), % Two arc(7, 4, 40, 7, -0.1, 0.50, "$", FSleep), line(coord(46, 9), coord(34, 18), "$", FSleep), line(coord(33, 19), coord(48, 19), "$", FSleep), sleep(750), % Erasing 'two' arc(7, 4, 40, 7, -0.1, 0.50, " ", FSleep), line(coord(46, 9), coord(34, 18), " ", FSleep), line(coord(33, 19), coord(48, 19), " ", FSleep), vpi::alarm(2), % One line(coord(33, 11), coord(43, 5), "$", FSleep), line(coord(43, 6), coord(43, 19), "$$", FSleep), sleep(750), % Erasing 'one' line(coord(33, 11), coord(43, 5), " ", FSleep), line(coord(43, 6), coord(43, 19), " ", FSleep), vpi::alarm(2), % Zero ellipse(11, 7, 40, 12, "$$", FSleep), sleep(200), % Erasing 'zero' ellipse(11, 7, 40, 12, " ", 0), % Erasing the initial circle ellipse(22, 11, 40, 12, " ", 0), LengthOfPhraseList = length(phraseList), LengthOfSymbolList = length(symbolList), vpi::alarm(3), I = varM::new(0), /* The cycle that draws fireworks and writes random congratulation-phrases in a random place */ std::repeat(), Xc = random(11), Yc = random(5), G = 4 + random(3), /* The first time a congratulation-phrase appears (all in all one phrase exists during three fireworks) */ if I:value = 0 then setLocation(coord(xp, yp)), phrase := nth(n, phraseList) end if, /* The last time the current phrase appears; it is replaced by a string of blank spaces. Then new random location is chosen and a new congratulation-phrase is written */ if I:value mod 3 = 0, I:value > 0 then setLocation(coord(xp, yp)), write(string::create(55, " ")), phrase := nth(n, phraseList), xp :=random(getConsoleWidth() - string::length(phrase)), yp := random(30), setLocation(coord(xp, yp)), write(phrase) % Not the first or the last time the current phrase appears else setLocation(coord(xp, yp)), write(phrase) end if, I:value := I:value + 1, n := random(LengthOfPhraseList), % Drawing a firework firework(true, Xc, Yc, G, 30, "", LengthOfSymbolList), % Erasing the firework firework(false, Xc, Yc, G, 3, " ", 0), stop(), !, _ = readLine(); succeed().Пример 15.4. Поздравительная открытка
В упражнениях 6 – 9 требуется написать программу, которая решает логическую задачу.
Упражнения
- Реализуйте такой вывод в экспертной системе, чтобы система начинала с опроса сведений о признаках животного, и при наличии необходимого набора признаков у какого-либо животного, сразу выдавала бы заключение.
- Создайте экспертную систему по определению видов растений.
- Создайте экспертную систему по выбору места летнего отдыха.
- Создайте экспертную систему по выбору книг для отпуска.
- Создайте экспертную систему по выбору направления обучения для абитуриента.
- Мартовский Заяц заявил, что муку украл Болванщик. Что сказали Болванщик и Соня, записано не было. Однако выяснилось, что муку украл лишь один из этих троих и что только он сказал правду. Кто украл муку?
- Мартовский Заяц сообщил, что масло украл Болванщик. Болванщик сказал, что яйца украла Соня. Соня сказала, что она украла молоко. Каждый из них украл что-то одно. Выяснилось, что тот, кто украл масло, говорил правду, а тот, кто украл яйца, лгал. Кто что украл?
- Тройка думает, что Туз не в своем уме. Четверка думает, что Тройка и Двойка обе не могут быть не в своем уме. Пятерка думает, что Туз и Четверка либо оба не в своем уме, либо оба в здравом рассудке. Шестерка думает, что Туз и Двойка оба в здравом уме. Семерка думает, что Пятерка не в своем уме. Валет Червей думает, что Шестерка и Семерка не обе не в своем уме. В своем ли уме Валет Червей?
- На одном международном конгрессе встретились четыре делегата из разных стран. Каждый из них владел двумя языками из четырех — английским, французским, немецким и итальянским. Оказалось, что не было такого языка, на котором они могли говорить вчетвером, и был только один язык, на котором могли говорить трое из них. Никто из делегатов не владеет французским и немецким языками одновременно. Хотя физик не говорит по-английски, он может служить переводчиком, если математик и биолог захотят поговорить друг с другом. Биолог говорит по-немецки и может говорить с химиком, хотя тот не знает ни одного немецкого слова. Физик, математик и химик не могут беседовать втроем на одном языке. Какими двумя языками владеет каждый из этих делегатов ?
- Измените программу "Фейерверк" (листинг 15.4) так, чтобы почти одновременно производилось по 2-3 залпа с разным числом "ветвей".