Опубликован: 12.02.2014 | Доступ: свободный | Студентов: 925 / 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 залпа с разным числом "ветвей".
