Добавлен , опубликован

Lua-программирование для чайников

Содержание:
Их здесь всего не четыре, как учили в школе, а шесть:
+ сложение
-  вычитание
*  умножение
/ деление
% (остаток от деления)
^ (возведение в степень) 
Примеры:
a = 1 + 2;
b = (1 * 3) / 10;
c = 2 - 2;
d = 10 % 1;
e = 5 ^ 5;
Для более корректных вычислений можно применять скобки.
чтобы проверить, можно print в онлайн-редакторе
print(a) --печатает 3
print(b) --печатает 0.3
print(c) --печатает 0
print(d) --печатает остаток от деления mod: 0
print(e) --печатает 3125.0

Остаток от деления

это скока отстаётся. возвращает целое число после деления. Возвращает всегда положительное число. Пример, было 5 яблок, поровну раздали Пете и Маше по 2 яблока. 1 яблоко осталось лишним, которое и является остатком. Логически мы бы могли разрезать яблоко пополам, но в логике это целое число, и иногда это не нужна.
Примеры, применения остатка от деления:
  1. как определить является ли число чётным или не чётным? Логично предположить, что если число делится на 2, то оно является четным. Определить четность можно по остатку от деления. Это сделать можно через mod или %, % можно по-другому заменить и на функцию из математической библиотеки луа math.fmod(сс,2).
Пример
if math.fmod(сс,2)~=0 then
  print("Нечетное")
else 
  print("Четное")
end
  1. Нормирование. Цикличный интервал. Пример, возьмем круг, который оперируется в градусах (для понимания беру в градусах). Полный круг это 360°. Пример, в математике всегда любили нормировать большие числа, пример: 346765° - это какой угол?
print(math.fmod(346765,360)) --это угол 85°
print(math.fmod(720,360)) --это угол 0°
Иногда нормирование помогает обрабатывать циклично индексы табличных массивов. Пример:
tt = {}
tt[1] = 'Первый'
tt[2] = 'Второй'
tt[3] = 'Третий'
tt[4] = 'Четвертый'
tt[5] = 'Пятый'
Представим задачу, есть 5 точек многоугольника. Найдена точка 2, и циклом должны пройти от 2 до 2. Условие выхода цикла если из 2 точки вернется в 2 (2 => 3 => 4 => 5 => 1 => 2). До этого пришлось бы писать проверку
if index > 4 then
	return 1 --или 0, если нумерация идет от 0. В луа идет от 1, поэтому возвращаю 1
end
Для упрощения можно с помощью остатка отделения доставать индексы из массива.
tt = {}
--теперь изменил нумерацию от 1
tt[1] = 'Первый'
tt[2] = 'Второй'
tt[3] = 'Третий'
tt[4] = 'Четвертый'
tt[5] = 'Пятый'
--#tt - это длина таблицы
print('count: '..#tt) --печатает 'count: 5'
print(0 % #tt) --вернет 0
print(1 % #tt) --вернет 1
print(2 % #tt) --вернет 2
print(3 % #tt) --вернет 3
print(4 % #tt) --вернет 4
print(5 % #tt) --вернет 0 => недостаток в том, что если это был язык C, то это было бы нормально. Но в нашем случае, в индексе 0 ничего не указано, тк нумерация идет не с нуля.

--А если я хочу, чтобы цикл пошел в обратную с шагом -1, то что будет?
print(-1 % #tt) --вернет 4
print(-2 % #tt) --вернет 3
print(-3 % #tt) --вернет 2
print(-4 % #tt) --вернет 1
print(-5 % #tt) --вернет 0 => здесь тот же недостаток, что и выше
Решение с нулевым индексом тут простое, либо в индекс нуль копируем значение из индекса 1, или заводим функцию
--возвращает индекс массива. сбрасывает к началу, если превышает
--остаток от деления % не помогает, тк нумерация идет от 1, а не с 0
function index(x,max)
	if x> 0 or x< 0 then
		x=x % max
		if x== 0 then return max end
	end
	return x
end

tt = {}
--теперь изменил нумерацию от 1
tt[1] = 'Первый'
tt[2] = 'Второй'
tt[3] = 'Третий'
tt[4] = 'Четвертый'
tt[5] = 'Пятый'
--#tt - это длина таблицы.Но означает не кол-во яеек в таблице, а до первого nil. в 6-ой ячейке это nil
print('count: '..#tt) --печатает 'count: 5'
print(index(0,#tt)) --вернет 0

print('----')
print(index(1,#tt)) --вернет 1
print(index(2,#tt)) --вернет 2
print(index(3,#tt)) --вернет 3
print(index(4,#tt)) --вернет 4
print(index(5,#tt)) --вернет 5
print('----')
--А если я хочу, чтобы цикл пошел в обратную с шагом -1, то что будет?
print(index(-1,#tt)) --вернет 4
print(index(-2,#tt)) --вернет 3
print(index(-3,#tt)) --вернет 2
print(index(-4,#tt)) --вернет 1
print(index(-5,#tt)) --вернет 5
пример цикл от -10 до 10
--возвращает индекс массива. сбрасывает к началу, если превышает
--остаток от деления % не помогает, тк нумерация идет от 1, а не с 0
function index(x,max)
	if x> 0 or x< 0 then
		x=x % max
		if x== 0 then return max end
	end
	return x
end

tt = {}
--теперь изменил нумерацию от 1
tt[1] = 'Один'
tt[2] = 'Два'
tt[3] = 'Три'
tt[4] = 'Четыре'
tt[5] = 'Пять'
--#tt - это длина таблицы.Но означает не кол-во яеек в таблице, а до первого nil. в 6-ой ячейке это nil
print('count: '..#tt) --печатает 'count: 5'

for a=-2*#tt,#tt*2 do
    if a ~= 0 then
        print(a..') '..tt[index(a,#tt)])
    else
        print('------')
    end
end
печатает выше как:
count: 5
-10) Пять
-9) Один
-8) Два
-7) Три
-6) Четыре
-5) Пять
-4) Один
-3) Два
-2) Три
-1) Четыре
------
1) Один
2) Два
3) Три
4) Четыре
5) Пять
6) Один
7) Два
8) Три
9) Четыре
10) Пять
  1. дроби. В lua есть разные способы добыть дробь. Есть специальные нативки. Пример, math.modf. Об этой функц рассмотрим на след уроках. Но остаток от деления тоже может достать дробь. Можно проверить целое ли число получилось или дробь по остатку от деления на единицу, хотя мб погрешности в сравнении, но это аналогично math.modf получается.
local a = 5.4 % 1
print(a) --печатает 0.4

local b = 6.7 % 1
print(b) --печатает 0.7
заметка: в рефордже знак % приводит к вылету из редактора карты при тестовом запуске или сохранения. Даже, если убрать строку, где есть знак %, под комменты. пример:
--local b = a % size 
все равно вылетает. в варкрафте рекомендуется заменить на %% или на math.fmod
пример:
local b = a %% size 
--или
local b = math.fmod(a,size)

`
ОЖИДАНИЕ РЕКЛАМЫ...