Среда, 18 Декабря 2024, 07:19

Приветствую Вас Гость

Меню сайта
Категории каталога
Создание игр [358]
Статьи об общих понятиях связанных с созданием игр.
Программирование [84]
Гайды по программированию на разных ЯП.
Движки и Гейммейкеры [149]
Статьи о программах для создания игр, уроки и описания.
Софт [44]
Различные программы, в том числе в помощь игроделам.
2D-графика [14]
Уроки по рисованию, растр, пиксель-арт, создание спрайтов и пр.
3D-графика [17]
Уроки по моделированию, ландшафт, модели, текстурирование и пр.
Моддинг игр [5]
Модификация компьютерных игр, создание дополнений, перевод, хакинг.
Игры [169]
Статьи об играх, в том числе и сделанных на гейммейкерах.
Разное [133]
Статьи, которые не вошли в определённые разделы.
Наш опрос
Игры какого типа вы предпочитаете делать?
Всего ответов: 16686
Главная » Статьи » Программирование

Lua для всей семьи. Урок 2: условные ветвления и логика
Содержание:
1. Урок 1: установка и первые программы

=== Урок №2 ===

Всё, что мы могли написать до настоящего момента - это последовательность инструкций, которые прямолинейно исполняются интерпретатором. Для того, чтобы сделать процесс исполнения программы более нелинейным - например, пропускать некоторые фрагменты кода при определённых условиях - существует управляющая конструкция if. Описывается подобным образом:

Код

if <условие> then
  <инструкции>
end


Условием может быть любое логическое выражение: то есть, утверждение, которое может быть либо ложным, либо истинным. Если условие истинно, то инструкции между then и end исполняются, если нет - пропускаются. Например:

Код

if x > 0 then
  print("x is positive")
end


Читать этот код следует как: "если значение переменной х больше, чем 0, то вывести на экран: х - положительный". Соответственно, если х меньше либо равно нулю, то ничего выведено не будет, инструкция просто проигнорируется. Выражение x > 0 возвращает одно из двух значений логического типа: true (истина) или false (ложь). Вообще, что делает оператор ">": он берёт значения слева и справа и проверяет, больше ли значение слева чем значение справа, и возвращает true в случае, если это так, и false в случае, если это не так. Можно даже попробовать вывести на экран результат сравнения:

Код

print(2 > 3, 3 > 2)
-- Выводит:
-- false true


Существуют и другие операторы сравнения: "<" - меньше, ">=" - больше либо равно, "<=" - меньше либо равно, "~=" - не равно, "==" - строго равно. Они работают именно так, как человек как минимум с пятью классами образования мог ожидать:

Код

print( 0 < 1, 1 < 10, 10 < 5 )
-- Выводит:
-- true true false

print( 1 <= 1, 4 >= 3, (99-98.9) ~= 0, 58 == 85 )
-- true true true false
-- Не путайте операторы "=" и "=="!
-- "=" используется для присваивания переменным значений
-- "==" используется для __сравнения__ двух значений


Таким образом, вы можете использовать все эти операции сравнения в условии if:

Код

-- cmp9to10.lua--

if 9 ~= 10 then
  print("9 doesn't equal 10!")
end
-- Выведет: 9 doesn't equal 10!

if 9 == 10 then  
  print("2 equals 10!")
end
-- Ничего не выведет, и это правильно


Два раза сравнивать два числа? Перебор! Пример, приведённый выше, можно переписать:

Код

-- smartcmp9to10.lua--

if 9 ~= 10 then
  print("9 doesn't equal 10!")
else
  print("2 equals 10!")
end
-- Выведет: 9 doesn't equal 10!


Структура if-else позволяет не просто проигнорировать кусок кода, а выбрать для исполнения одну из двух последовательностей инструкций. Пример читается: "Если девять не равно десяти, то вывести: 9 не равно 10, иначе - вывести: 9 равно десяти". Удобно, да? Теперь можно расширить самый верхний пример:

Код

if x > 0 then
  print("x is positive")
else
  print("x is negative")
end


Красота, да и только! Теперь мы можем написать очень умную программу, которая определяет знак числа. Задайте переменной x различные значения (т.е. допишите наl if'ом что-то вроде x = <ваше_любимое_число>) и посмотрите, как программа на них реагирует.

Что? Вы написали 0, и программа вывела: x is negative? С каких это пор у нуля есть знак? Наша программа не выдерживает критики, и если бы мы писали её за деньги какому-нибудь клиенту, он бы потребовал выплатить компенсацию. Так как платить мы не хотим, стоит добавить дополнительную проверку с помощью инструкции elseif. Вроде того:

Код

if x > 0 then
  print('x is positive')
elseif x < 0 then
  print('x is negative')
else
  print('x is zero')
end


elseif всегда принимает дополнительное условие для проверки, в отличие от else, который всегда стоит один-одинёшенек. Фрагмент выше читается: "если значение х больше нуля, вывести: х - положительный. Если же х меньше нуля, то вывести: х - отрицательный. А уж ежели ни то, ни другое, то вывести: х равен нулю".

Веток elseif вы можете написать сколько угодно. Взгляните, например, на эту внушающую ужас постройку:

Код

if x == 1 then
  print('one')
elseif x == 2 then
  print('two')
elseif x == 3 then
  print('three')
elseif x == 4 then
  print('four')
elseif x == 5 then
  print('five')
elseif x == 6 then
  print('six')
elseif x == 7 then
  print('seven')
elseif x == 8 then
  print('eight')
elseif x == 9 then
  print('nine')
elseif x == 0 then
  print('zero')
end
-- Здесь ветка else опущена


Что твой небоскрёб! Кстати, заметили? Я в последних двух примерах заключил параметры для print'ов в одинарные кавычки. Это не ошибка, так тоже можно записывать строковые литералы в Lua. "STRING" это же самое, что и 'STRING'. Различия вы узнаете в более поздних уроках, а пока проверьте:

Код

print('STRING' == "STRING")
-- Выведет true.
-- О сравнении строк вы также узнаете позднее.


А что если мы решаем задачу с интервалами? Что если нам нужно проверить, укладывается ли переменная в какой-то предел? Например, играть в настольную игру Cluedo могут от двух до шести человек. Допустим, в переменной players хранится число игроков (надеемся, положительное целое), которые хотят играть. Как мы проверим, сможет ли состояться игра при заданном числе желающих? Один вариант так и напрашивается:

Код

if players >=2 then
  if players <=6 then
  print("Ok, you can play!")
  end
end


На первый взгляд, сносное решение, но, если подумать, не очень гибкое. И громоздкое, к тому же. Хотелось бы оставить один if вместо двух. И мы можем так сделать с помощью логического оператора and:

Код

if players >= 2 and players <= 6 then
  print 'Ok, you can play!'
else
  print 'No way, buddies!'
end


Читается: "если количество игроков больше либо равно двум и меньше либо равно шести, то играть можно, иначе играть нельзя."

Заметьте, что написать 2 <= players <= 6 не получится, хотя в школе и учили, что так правильно. Не получится потому, что интерпретатор сперва сравнит 2 и players. Если players равняется, например, 3, то тогда сравнение даст значение true, после чего выражение выродится в true <= 6. Можете сказать, что больше: шесть или истина? Не знаю, как вы, а Lua не может.

Суть работы оператора and состоит в том, что он берёт два операнда (два значения: слева и справа) и возвращает true, если оба они истинные, или false, если хотя бы один из них ложный. and - не единственный логический оператор, у него есть друзья: or и not. Работа каждого из них пояснена ниже:

Код

-- and возвращает true, если и первый, и второй операнды истинны
-- также известен как: "и", конъюнкция, логическое умножение
true and true -> true
true and false -> false
false and true -> false
false and false -> false

-- or возвращает true, если хотя бы один из операндов истинен
-- (или левый, или правый, или оба сразу)
-- также известен как: "или", дизъюнкция, логическое сложение
true or true -> true
true or false -> true
false or true -> true
false or false -> false

-- not принимает только один операнд и инвертирует его
-- также известен как: "не", инверсия
not true -> false -- ложь - не истина!
not false -> true -- истина - не ложь!


С использованием операторов or и not пример с игроками в Cluedo можно переписать так:
Код

if not (players < 2 or players > 6) then
  print 'Ok, you can play!'
else
  print 'No way, buddies!'
end

И работать он будет точно так же. Только читается по-другому: "если количество игроков не меньше двух и не больше шести, то играть можно, иначе играть нельзя."

Кстати, true и false - такие же обычные значения, как числа и строки, их можно присваивать переменным! Переменные, имеющие логическое значение true или false, на программистском жаргоне часто называются флагами, наподобие флажков на американских почтовых ящиках. Флажок поднят (true) - почта пришла, флажок опущен (false) - почты нет.

В программах флаги используют подобным образом:

Код

-- mailbox.lua --
flag = true

if flag then
  print "You've got mail"
end


Заметьте, что сравнивать flag с true необязательно: его значение уже имеет логический тип.

Как вы догадались, из логических переменных и логических операторов тоже можно строить выражения, большие и не очень.

Код

humans_are_mortal = true
socrates_is_a_human = true
socrates_is_mortal = humans_are_mortal and socrates_is_mortal

-- Выясняем, смертен ли Сократ.
-- Заметьте, что здесь if-else записан несколько по-другому,
-- но на его работу это не влияет.
if socrates_is_mortal then print("Socrates is mortal")
else print("Socrates is immortal") end

jack = (1 >= 0)
frost = true or jack
madness = (jack and not frost) or not (frost and not jack) and true
-- Попробуйте посмотреть, что из этого выйдет, сами!


Как в прошлый раз, в конце урока мы вспоминаем про nil. Никогда не забывайте про nil! Очень много ходовых приёмов программирования на Lua основано на махинациях с этим значением.

Во-первых, если не считать одно исключение, в контексте логических операций nil трактуется как false. Таким образом:

Код

-- nillogics.lua --

print(true and nil)
-- Выведет false

print(true or nil)
-- Выведет true

print(not nil)
-- Выведет true

existent = true
print(nonexistent or existent)
-- Выведет true

-- Однако !!
print(nil and nil, nil or nil)
-- Выведет nil nil
-- Если оба операнда and или or равны nil, то и результат равен nil


Во-вторых, нелогическое значение в условии if трактуется как истинное, если оно не равно nil, и как ложное, если оно равно nil.

Код

-- nillogics2.lua --

value1 = "OK"
value2 = 1.6180339887
value3 = nil

if value1 then
  print "This works."
end

if value2 then
  print "This works, too."
end

if value3 then
  print "This doen't work."
end

if value4 then -- Не забывайте: несуществующая переменная имеет значение nil
  print "Neither does this."
end

-- Этот фрагмент может вызвать недоумение программистов на С,
-- но он совершенно корректен, так как 0 не равен nil.
if 0 then
  print "And this does work."
end


nillogics2.lua выведет: This works. This works, too. And this does work. Таким манером мы можем, например, избежать выполнения операций над неинициализированными (равными nil) значениями, поскольку такие операции могут "положить" программу. Держите это в голове, в будущем это знание нам пригодится.

Резюме:
1. Мы узнали, как создавать условные ветвления в программе на Lua.
2. Узнали, какие есть операторы сравнения, логические операторы, какие выражения мы можем с ними написать и где их использовать.
3. Узнали о новой ипостаси значения nil как аналога значения false. Поняли, что nil всё ещё гораздо глубже, чем мы думали.


Как и в прошлый раз, вот несколько упражнений для желающих упражняться.
1. Существует действительная переменная p (то есть, её значение - число, которое может быть целым или дробным, положительным, отрицательным или равным нулю). С помощью управляющей конструкции if напишите программу, которая проверяет, является ли значение p корректным значением вероятности: оно должно попадать в интервал [0, 1].
2. Создайте программу, которая реализует операцию "исключающее или". В начале у вас должно быть объявлено две переменные с логическим значением: a и b, в конце вы должны получить переменную с, равную true, если лишь одна из переменных a и b равна true, и false в любом другом случае. Удачи!
Категория: Программирование | Добавил: -l33t-h4xx- (09 Января 2014) | Автор: Андрей Липовалов
Просмотров: 23328 | Комментарии: 5 | Рейтинг: 4.8/60 |
Теги: LUA, Условные ветвления, для всей семьи, для начинающих, логика, Урок 2, скриптинг, Lua-скрипт, Урок
Дополнительные опции:
Также если вы считаете, что данный материал мог быть интересен и полезен кому-то из ваших друзей, то вы бы могли посоветовать его, отправив сообщение на e-mail друга:

Игровые объявления и предложения:
Если вас заинтересовал материал «Lua для всей семьи. Урок 2: условные ветвления и логика», и вы бы хотели прочесть что-то на эту же тему, то вы можете воспользоваться списком схожих материалов ниже. Данный список сформирован автоматически по тематическим меткам раздела. Предлагаются такие схожие материалы: Если вы ведёте свой блог, микроблог, либо участвуете в какой-то популярной социальной сети, то вы можете быстро поделиться данной заметкой со своими друзьями и посетителями.

Всего комментариев: 5
+1-
5 GromsNN   (14 Декабря 2023 16:17) [Материал]
Урок 2 задание 2 не искл или, а равносильность, эквивалентность, логическое тождество (a and b) or (not a and not b)

+1-
4 GromsNN   (13 Декабря 2023 16:13) [Материал]
Вопрос почему "socrates_is_mortal = humans_are_mortal and socrates_is_mortal" может вместо 3-ей переменной socrates_is_a_human ?

+2-
2 donalduck   (14 Октября 2023 21:39) [Материал]
donalduckv etom godu 30 let - LUA ))
The Lua Workshop 2023 will be held on 17 October 2023 at PUC-Rio in Rio de Janeiro.

The main theme of this workshop is to commemorate 30 years of Lua.

+1-
3 Linka   (23 Октября 2023 21:35) [Материал]
LinkaНу и что?

+2-
1 donalduck   (20 Июня 2022 03:59) [Материал]
donalduckgood ;)

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск по сайту
10 случ. движков
  • FIFE
  • RPG Maker MV
  • Ignifuga
  • HiAsm
  • Orx
  • M.U.G.E.N
  • Blitz3D
  • Danmakufu
  • Unreal Engine 5
  • DreamSDK
  • Друзья сайта
    Игровой форум GFAQ.ru Перевод консольных игр
    Все права сохранены. GcUp.ru © 2008-2024 Рейтинг