Разбор полётов на примере r5636

 
+
-
edit
 

Balancer

администратор
★★★★★

Changeset 5636 – L2J Fortress

Changeset 5636
View differences
inlineside by side
Show
lines around each change
Show the changes in full context


// Дальше —
trac.balancer.ru
 


Увидел и упал :D

system-time-day-of-week dup 1 = 7 = +

1. Для логического ИЛИ у нас используется слово OR.
2. Смотрим, что у нас на стеке:
system-time-day-of-week ( — day )
dup ( day — day day )
1 = ( day day — day day==1? )
7 = ( day day==1? — day {day==1}==7? )
и теперь мы это безобразие складываем. Ужас.

Вот как должно быть:
system-time-day-of-week ( — day )
dup ( day — day day )
1 = ( day day — day day==1? )
swap ( day day — day==1? day )
7 = ( day day==1? — day==1? day==7? )
or ( day==1? day==7? — day==1||day==7 )

А, вообще, лучше возвращать день в виде "понедельник"==1, "воскресенье"==7, что и было сделано в r5658:
code forth
  1. : system-time-day-of-week  ( -- день_недели[1..7] )
  2.   7 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
  3.   1- ?dup unless 7 then
  4. ;


Надеюсь, понятно, как 1==воскресенье, 2==понедельник... 7==суббота, превращаются в более привычные цифры по формуле:
день := день - 1

если день == 0, то день := 7.

unless - это почти то же самое, что not if

Дальше:
code forth
  1.   ( ... ) if
  2.     true boolean
  3.   else
  4.     false boolean
  5.   then


1. boolean можно вынести за пределы условия и писать только раз: if true else false then boolean

2. А чему равно if true else false then? Да нет операции, вообще-то :D

3. Наконец, зачем тут boolean? Мы же не в Java-метод объект Boolean передаём.

В итоге весь этот if-блок просто... выкидывается.

code text
  1. : system-time-isNight
  2.   system-time-hour dup 12 <= 22 >= + if
  3.     system-time-is-offday not if
  4.         true boolean
  5.       else
  6.         false boolean
  7.     else
  8.       false boolean
  9.   then
  10. ;


Вообще красота. На два if'а - один then. Мне даже как-то в голову не пришло сделать проверку на такую ошибку на этапе компиляции. Надо будет сделать.

А что по сути? Та же ошибка с + вместо OR и отсутствие swap между сравнениями.

Дальше. Вложение if'ов - ни что иное, как логическое И. В итоге от всего этого слова у нас остаётся:
code forth
  1. : system-time-isNight  ( -- скидки? )
  2.   system-time-hour dup 12 <= swap 22 >= or
  3.   system-time-is-offday not and
  4. ;


В принципе, это выражение можно даже ещё чуть-чуть упростить, вспомнив слово
WITHIN ( число левая_граница правая_граница -- входит? )
(нужно помнить, что левая граница берётся включительно, правая - исключительно).

Т.е.:
code forth
  1. : system-time-isNight  ( -- скидки? )
  2.   system-time-hour 11 21 within \ если это день
  3.   system-time-is-offday or      \ или выходной
  4.   not                           \ скидок нет
  5. ;
 
+
-
edit
 

Balancer

администратор
★★★★★
Маленький довесок:
code forth
  1. : gatekeeper-jump (( x y z amount objectId1 objectId2 -- ))
  2.     self "AlikeDead" p? if "You not teleport in death mode" show exit then
  3.     system-time-isNight if amount 2 / to amount then
  4.     amount adena? nip unless "You have not adena!" show exit then
  5.     objectId1 id>obj objectId2 id>obj dist 300 > if "Too far" show exit then
  6.     amount adena_pay
  7.     x y z jump
  8. ;


Вот так будет покрасивее:

code forth
  1. : gatekeeper-jump (( x y z adena objectId1 objectId2 -- ))
  2.     self "AlikeDead" p? if "You not teleport in death mode" show exit then
  3.     adena system-time-isNight if 2 / then adena? not if drop "You have not adena!" . exit then drop
  4.     objectId1 id>obj objectId2 id>obj dist 300 > if "Too far" . exit then
  5.     adena system-time-isNight if 2 / then adena_pay
  6.     x y z jump
  7. ;


гы... сделать, что ли, так?
code forth
  1. : gatekeeper-jump (( x y z оплата obj1 obj2 -- ))
  2.     я AlikeDead? если "You not teleport in death mode" вывести выйти тогда
  3.     скидки? если оплата пополам в оплата тогда
  4.     оплата деньги-есть? если-нет "You have not adena!" вывести выйти тогда
  5.     obj1 id>obj obj2 id>obj расстояние 300 > есди "Too far" вывести выйти тогда
  6.     оплата заплатить
  7.     x y z прыгнуть
  8. ;


;)
 
+
-
edit
 

Balancer

администратор
★★★★★
Что-то я развеселился :) (этот пример - оттестирован)
code text
  1. module: время
  2. : час
  3.   11 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
  4. ;
  5.  
  6. : день_недели  ( -- день_недели[1..7] )
  7.   7 "java.util.Calendar" class "getInstance" 0 jget "get" { int.class } jget
  8.   1- ?dup unless 7 then
  9. ;
  10.  
  11. "включает?" alias within
  12. "или" alias or
  13. "нет" alias not
  14.  
  15. : выходной?   день_недели 6 >= ;
  16. : день?       час 11 21 включает? ;
  17. : скидки?     выходной? день? или   нет ;
  18. ;module


:)
 
+
-
edit
 
Ну если бы где-то было хотябы подобие документации... А так понятно каждый пишет как знает, изобретая свои конструкции.
Пытаясь понять рекурсию, следи за тем, чтобы она не поняла тебя первой...  
+
-
edit
 

Balancer

администратор
★★★★★
По Форту в сети масса литературы. forth.org.ru в руки :)

Всё, что касается стека и вычислений, обычно умещается в первой главе и у нас работает также, как и в любом другом Форте. Разница со стандартным Фортом начинается только там, где появляются адреса. У нас вместо них - ссылки на объекты.
 
+
-
edit
 

Balancer

администратор
★★★★★
Кроме того, некоторые напрочь отказываются рассматривать вопросы тестирования. А Форт тут - рулит как нигде. Цепляешься к живому серверу телнетом, и возишься с операциями на стеке по одной, просматривая результат по .s. Что может быть проще? :D
code text
  1. # telnet localhost 1904
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. Welcome To The L2J Telnet Session.
  6. Please Insert Your Password!
  7. Password: ****
  8. Password Correct!
  9. [L2J]
  10. system-time-day-of-week
  11. .s
  12. Stack: 7
  13. dup .s
  14. Stack: 7 7
  15. 1 = .s
  16. Stack: 7 0
  17. 7 = .s
  18. Stack: 7 0
  19. + .s
  20. Stack: 7


Неужели тут так трудно заметить, что что-то в Датском королевстве не то? :D
 
+
-
edit
 
Имеется в виду список возможных команд :)
?dup unless within - никогда о таких не слышал...
Пытаясь понять рекурсию, следи за тем, чтобы она не поняла тебя первой...  
AD Реклама Google — средство выживания форумов :)
+
-
edit
 

Balancer

администратор
★★★★★
?dup - это стандартная команда Форта. У нас на Wiki даже описана: http://la2.balancer.ru/wiki/index.php/Dup Правда, с ошибкой (поправил).

unless - это калька с Перла. Используется уже очень давно и в куче примеров, в т.ч. на этом форуме.

within - стандартное слово.
 

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru