Author Topic: Видимость переменных или как выходить из цикла.  (Read 1750 times)

0 Members and 2 Guests are viewing this topic.

Gabba

  • Зашел в гости
  • *
  • Posts: 9
    • View Profile
Добра этому дому.
Вот такой код:
[spoiler]

Code: (clickermann) [Select]
while(1)

logwrite("cyc1")
keypress(75)

while(1)
getscreen
$l = pxlxor(1023, 1008, 1045, 1010)
if($l ! 5921370)
keypress(76)
WAIT(2)
goto(lDone)
end_if
WAITMS(30)
end_cyc
lDone:
logwrite("lDone")

getscreen
$Q = pxlxor (850,1006, 852, 1008)
$E = pxlxor (897, 1012, 899, 1014)
$R = pxlxor (935, 1006, 937, 1008)
logwrite($Q)               //  3552822
logwrite($E)               //  2960685
logwrite($R)               //  2763306

if( ($Q ! 3552822) & ($E ! 2960685) & ($R ! 2763306) )    // åñëè áóòûëü
logwrite("QER")
QERsub()
end_if

$check = 0
while($check = 0)
logwrite("cyc2 ", $check)

getscreen
$Q = pxlxor (850,1006, 852, 1008)
$E = pxlxor (897, 1012, 899, 1014)
$R = pxlxor (935, 1006, 937, 1008)
logwrite($Q)               //  3552822
logwrite($E)               //  2960685
logwrite($R)               //  2763306

if($Q ! 3552822)
logwrite("Q")
Qsub()
logwrite("Qen")
getscreen
$1 = pxlxor (908, 940, 910, 942)
logwrite($1)
if($1 ! 5658198)
logwrite("1")
keypress(76)
$check = 1
goto(Ret)
end_if
else
if($E ! 2960685)
logwrite("E")
Esub()
logwrite("Een")
getscreen
$1 = pxlxor (908, 940, 910, 942)
logwrite($1)
if($1 ! 5658198)
logwrite("1")
keypress(76)
$check = 1
goto(Ret)
end_if
else
if($R ! 2763306)
logwrite("R")
Rsub()
logwrite("Ren")
getscreen
$1 = pxlxor (908, 940, 910, 942)
logwrite($1)
if($1 ! 5658198)
logwrite("1")
keypress(76)
$check = 1
goto(Ret)
end_if
end_if
end_if
end_if
WAITMS(30)
Ret:
logwrite("yeah ", $check)
end_cyc          
logwrite("nope")
end_cyc
[/spoiler]

Выдает лог:
23:09:07 cyc1
23:09:29 lDone
23:09:29 3552822
23:09:29 2960685
23:09:29 7551502
23:09:30 cyc2 0
23:09:30 3552822
23:09:30 2960685
23:09:30 7551502
23:09:30 R
23:09:30 Rfu
23:09:31 Rlabel
23:09:31 Ren
23:09:32 5658198
23:09:32 yeah 1
23:09:33 nope

Видно, что программа заходит в "R-условие", Rfu  и Rlabel печатаются внутри функции Rsub, затем проверяется условие, что некторорая кнопка "1" горит (если 56..., то тусклая), кнопка оказывается тусклой, внутрь условной конструкции не заходит, доходит до конца цикла, при этом, $check с помощью какой-то магии оказался 1.
Почему? У меня есть только одна гипотеза: интерпретатор переприсваивает $check значение даже если не заходит в условие. Но это очень странный подход. В чем моя ошибка?

P.S
Вообще, грустно без привычных сердцу "return", "continue" и "break"  (
« Last Edit: April 27, 2017, 11:40:08 PM by Gabba »

Gabba

  • Зашел в гости
  • *
  • Posts: 9
    • View Profile
"Я был слеп, учитель" :D
Уже поднял глаза свои к шапке форума.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
запомни раз и на всегда, выпрыгивать из цикла на метку ЗАПРЕЩЕНО!!! возможно в твоем случае это и не приведет каким либо ошибкам, но всеже...
 для чего условие для цикла? правильно:
Code: (clickermann) [Select]
getscreen
$l = pxlxor(1023, 1008, 1045, 1010)
while($l = 5921370)
   getscreen
   $l = pxlxor(1023, 1008, 1045, 1010)
   WAITMS(30)
end_cyc
keypress(76)
WAIT(2)
logwrite("lDone")

и твои прыжки на метку Ret: не имеют смысла, убирай. $check становится единицей в подпрограмме Rsub(), как и написал kiril выше.


чуточку подправил.
« Last Edit: April 28, 2017, 12:04:34 AM by dramster »

Gabba

  • Зашел в гости
  • *
  • Posts: 9
    • View Profile
Ох...
А и вправду, Q, R и E -sub построены на цикле, который тоже вырубается по $check.
Однако, это же отдельные методы, я думал, что тамошний чек - это совсем другой чек, служебная переменная, которая "сгорает" после того, как метод возвратит что-либо.

Эх, говорила мне мама: "Не используй одинаковые счетчики, сынок..."

[бухтеж]
Воот были бы return и break, такой фигни не было бы
[/бухтеж]

Да, я знаю, что goto - плохой стиль, но здесь очень непривычные для меня механизмы организации выполнения и для не особо важного куска кода на 100 строк есть большой соблазн заняться спортивным костылированием). Я вообще на этот инструмент (восхитительный по своей мощи, кстати, автору глубокий поклон) пришел только из-за встроенной возможности обращения напрямую к порту ps/2. Ни на моих родных языках с использованием dll winAPI, ни тем более, на ассемблере (*перекрестился*) такое быстро и легко не напишешь.

Благодарю за помощь, тему можно закрывать, удалять, или что здесь принято делать с решенными.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Воот были бы return и break, такой фигни не было бы
break и continue просили уже не однократно. Не созрел автор. Или, скорее, недостаточно мотивации.


Однако, это же отдельные методы, я думал, что тамошний чек - это совсем другой чек, служебная переменная, которая "сгорает" после того, как метод возвратит что-либо.
Чек, это не служебная переменная, это простая переменная. И все (почти) переменные глобальные.
И методов в CM нет, только подпрограммы. А всё так потому, что ориентированность на лёгкость освоения и написания. Хотя нет. Как раз ориентированность на лёгкость освоения не даёт вводить множество конструкций которые есть в других языках. Это даёт шанс новичкам не утонуть в количестве операторов и инструкций... на простых скриптах. Но это же и усложняет написание сложных и приводит к костылестроению и разрастанию кода.

Кстати, в твоём примере как раз всё нормально. Непонятно, почему ты не применил в первом цикле такое же решение, какое применил во втором while($check =...

И самый внешний бесконечный цикл не нужен. В кликере он по умолчанию есть. Весь код прокручивается по кругу если не остановить специально.