What's new

-Średni Kr?tsze odpowiedniki w lua

Grimekk

memsoria.pl
Joined
Oct 9, 2011
Messages
609
Reaction score
56
Poradnik poni?ej jest po prostu list? skrypt?w kt?re mog? by? zoptymalizowane po przez ich skr?cenie. Nie b?d? t?umaczy? dzia?ania ka?dego z kod?w, bo zaj??oby to po prostu wieczno??. Je?li ju? wiesz czego szukasz to powiniene? wiedzie? jak to dzia?a. Zaczynajmy.


Zamiast pisania tej instrukcji w ten spos?b:
[lua]
//zle
x = 7
if x < 10 then
x = 10
end[/lua]
Mo?na to zrobi? w ten:
[lua]
//dobrze
x = 7
x = math.max(x, 10)[/lua]

Tak samo zreszt? z tym:
[lua]
//zle
x = 23
if x > 20 then
x = 20
end[/lua]
[lua]//dobrze
x = 23
x = math.min(x, 20)[/lua]

A je?eli chcia?by? oba z??czy?, to nie piszemy tego:
[lua]
//zle
x = 23
if x < 10 then
x = 10
elseif x > 20 then
x = 20
end[/lua]
Tylko to:
[lua]
//dobrze
x = 23
x = math.min(math.max(x, 10), 20)[/lua]
Lub:
[lua]
//dobrze
x = 23
x = math.max(math.min(x, 20), 10)[/lua]
Funkcja math.min zwraca nam najni?sz? warto??, za? math.max najwy?sz?.


Nast?pna optymalizacja mo?e nast?pi? w tym skrypcie:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 100
b = 50
xybz = x + y + b + 110
else
y = 30
b = 50
xybz = x + y + b + 20
end[/lua]
Mo?e by? on skr?cony do:
[lua]
//dobrze
y = 100
b = 50
if x == 10 then
z = 35
elseif x == 20 then
z = 110
else
y = 30
z = 20
end
xybz = x + y + b + z[/lua]


Kolejnym b??dnym kodem b?dzie to:
[lua]
//zle
if x == 10 then
y = 100
b = 50
xybz = x + y + b + 35
elseif x == 20 then
y = 40
b = 78
xybz = x + y + b + 76
elseif x == 30 then
y = 80
b = 50
xybz = x + y + b + 45
elseif x == 40 then
y = 100
b = 666
xybz = x + y + b + 144
elseif x == 50 then
y = 33
b = 45
xybz = x + y + b + 12[/lua]
Wersja poprawna:
[lua]
//dobrze
function numbers(x, y, b, z)
return (x + y + b + z)
end

if x == 10 then
xybz = numbers(x, 100, 50, 35)
elseif x == 20 then
xybz = numbers(x, 40, 78, 76)
elseif x == 30 then
xybz = numbers(x, 80, 50, 45)
elseif x == 40 then
xybz = numbers(x, 100, 666, 144)
elseif x == 50 then
xybz = numbers(x, 33, 45, 12)
else
xybz = numbers(x, 100, 100, 20)
end[/lua]
Lub jeszcze kr?cej:
[lua]
//dobrze
results = {
[10] = {100, 50, 35},
[20] = {40, 78, 76},
[30] = {80, 50, 45},
[40] = {100, 666, 144},
[50] = {33, 45, 12},
default = {100, 100, 20}
}
result = results[x] or results.default
xybz = x + result[1] + result[2] + result[3][/lua]


A zamiast tego:
[lua]
//zle
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Rat", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Troll", pos)
doSummonCreature("Orc", pos)[/lua]
Mo?emy po prostu doda? p?tle. Skrypt wtedy b?dzie wygl?da? nast?puj?co:
[lua]
//dobrze
local summons = {["Rat"] = 3, ["Troll"] = 2, ["Orc"] = 1}
for k, v in pairs(summons) do
for i=1, v do
doSummonCreature(k, pos)
end
end[/lua]


Tutaj kolejny za d?ugi skrypt kt?ry b?dzie nam dawa? addony:
[lua]
//zle
sexAddons = {
{[136]=142, [147]=150, [155]=158, [252]=252},
{[128]=134, [143]=146, [151]=154, [251]=251}
}
local addons = sexAddons[getPlayerSex(cid)+1]
if (addons ~= nil) then
for k, v in pairs(addons) do
for i=k, v do
doPlayerAddOutfit(player, i, addonType[1])
end
end
end[/lua]
A w tej sytuacji wystarczy zrobi? tylko to!:
[lua]
//dobrze
numbers = {
[10] = 30,
[55] = 65,
[80] = 140
}
for start, stop in pairs(numbers) do
for number=start, stop do
print(number)
end
end[/lua]

Jednym z kolejnych b??d?w podczas pisania kodu jest dodawanie nil'a - a jest on po prostu zb?dny. Mo?na to zobaczy? na przyk?adzie poni?ej:
[lua]//zle
function doSomething(x)
if x == nil then
x = 1
end
return x
end[/lua]
[lua]
//dobrze
function doSomething(x)
return x or 1
end[/lua]
Co tu si? sta?o? Solucja problemu jest bardzo prosta. Je?eli x = nil, lub false to po prostu bierze nast?pn? warto??.
Jeszcze wi?ksze skr?cenie:
[lua]
//dobrze
x = 5
y = 10
z = x or y or 5[/lua]
Tu za? skrypt najpierw sprawdza czy x = nil. Je?eli tak, to p??niej sprawdza czy y = nil. Teraz gdy oba = nil, to skrypt po prostu zamienia z w 5.
Kolejny przyk?ad kt?ry nigdy nie zwr?ci nil'a:
[lua]
//dobrze
function sum(a, b)
return (a or 0) + (b or 0)
end[/lua]
W praktyce to wygl?da tak:
[lua]print(sum(5, 10))
print(sum(5, nil))
print(sum(nil, 10))
print(sum(5))[/lua]
Powy?szy skrypt zwr?ci nam to:
Code:
15
5
10
5
A je?li chcesz wiadomo?? kt?ra wysy?a error to zamiast tego:
[lua]
//zle
if x == nil then
if y == nil then
print("Error, all values are nil!")
else
z = y
end
else
z = x
end[/lua]
Wpisz to:
[lua]
//prawie dobrze
z = x or y or print("Error, all values are nil")[/lua]
Teraz, gdy x = nil, z zamieni si? w y, a je?eli y = nil to silnik wy?le wiadomo?? "Error, all values are nil", ale z zamieni si? w nil. Co zatem zrobi? aby wys?a? wiadomo?? i nada? z warto???
Sp?jrz:
[lua]
//dobrze
z = x or y or print("Error, all values are nil") or 0[/lua]
Dzi?ki dodaniu "or 0", silnik wy?le wiadomo?? i z = 0!

Tutaj mamy kolejny przyk?ad u?ywania "or":
[lua]
//zle
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
if vocations[param] ~= nil then
vocation = vocations[param]
else
vocation = "Unknown"
end
end[/lua]
Poprawnie:
[lua]
//dobrze
function onSay(cid, words, param)
param = tonumber(param)
vocations = {"Sorcerer", "Druid", "Paladin", "Knight", "Master Sorcerer", "Elder Druid", "Royal Paladin", "Elite Knight"}
vocation = vocations[param] or "Unknown"
end[/lua]

Je?eli chcesz sprawdzi? czy kilka zmiennych razem = nil, robisz to w ten spos?b:
[lua]
//zle
if x and y and z then
pos = {x=x, y=y, z=z}
end[/lua]
a przecie? to samo mo?na zrobi? o tak:
[lua]
//dobrze
(a and b) or (c and d) or e[/lua]
"(a and b)" zwraca b je?li nie jest nil'em.

Czyli to:
[lua]
//dobrze
result = (a and b) or (c and d) or e[/lua]
To to samo co to:
[lua]
//zle
if a then
result = b
elseif c then
result = d
else
result = e
end[/lua]

Gdy u?ywasz tonumber zapewne piszesz skrypty w ten spos?b:
[lua]function position(x, y, z, stackpos)
if ((x and y and z) and type(tonumber(x..y..z)) == 'number') then
pos = {x=x, y=y, z=z}
if (stackpos and type(stackpos) == 'number') then
pos.stackpos = stackpos
end
return pos
end
return false
end[/lua]
Jak wida? to:
[lua]
//zle
type(tonumber(x) == 'number' and type(tonumber(y) == 'number' and type(tonumber(z) == 'number'[/lua]
To po prostu inna wersja tego:
[lua]
//dobrze
type(tonumber(x..y..z)) == 'number'[/lua]
Jak to si? sta?o? Przyk?ad:
[lua]x = "134"
y = "abc"
z = "7"
print(tonumber(x))
print(tonumber(y))
print(tonumber(z))
print(tonumber(x..y..z))[/lua]
Rezultatem tego skryptu b?dzie:
Code:
134
nil
7
nil
Dlaczego? Bo tonumber tylko akceptuje znaki numeryczne. Wi?c je?li u?ywasz tonumber do tekstu, nawet je?li posiada on gdzie? numer to skrypt i tak zwr?ci nil.


Zamiast tego d?ugiego skryptu:
[lua]
//zle
if (x > z) then
r = x
else
r = z
end [/lua]
Mo?na napisa? to:
[lua]
//dobrze
r = (x > z and x) or z[/lua]
Co to jest? Tak jak m?wi?em, gdy wpisujesz co? typu "1 and 2 and 3" to zwr?ci nam ostatni? warto??, w tym wypadku 3. Dlatego te? pisz? "x > z", bo gdy warunek si? spe?ni to skrypt doda te? "and x", co zamienia ostatni? warto?? w x przy okazji transformuj?c r tak?e w x. Ale gdy "x > z" wychodzi false, to skrypt przejdzie do "or z" co zmienia r w z.
Kolejny przyk?ad:
[lua]
//zle
if (type(x) == "number" and type(y) == "number") then
r = math.max(x, y)
else
r = 0
end[/lua]
[lua]
//dobrze
r = (type(x) == "number" and type(y) == "number" and math.max(x, y)) or 0[/lua]
Lub troch? bardziej zaawansowanie:
[lua]
//zle
if (type(x) == "number" and type(y) == "number") then
r = math.max(x, y)
elseif (type(x) == "number") then
r = x
elseif (type(y) == "number") then
r = y
else
r = 0
end[/lua]
Mo?na skrypt przetransformowa? w to:
[lua]
//zle
r = (type(x) == "number" and type(y) == "number" and math.max(x, y)) or (type(x) == "number" and x) or (type(y) == "number" and y) or 0[/lua]
Jak wida? da?em tu przypis "//zle", a to dlatego, ?e kod jest przynajmniej dla mnie nieczytelny i nie polecam u?ywania tej metody, chocia? sama wiedza nt. takiej techniki si? Wam przyda.


Poradnik pisany z pomoc? tutoriala z otland'u. Zabraniam jego kopiowania na inne strony - zosta? on napisany dla www.tibia.net.pl.
 

Restles

Senior User
Joined
Aug 31, 2012
Messages
616
Reaction score
51
Odp: Kr?tsze odpowiedniki w lua

fakt :)
 
Last edited:

Placek

Blue Waffle
Joined
Sep 30, 2008
Messages
6,793
Reaction score
672
Age
9
Odp: Kr?tsze odpowiedniki w lua

@up
Nie chce ci sie czytac a linijke dalej jest jeszcze bardziej poprawiona wersja, wiec...
@top
Czy ja wiem czy sie to tu komus przyda. Wiekszosc ludzi ktorzy pisza, pisze slabo, bo z programowaniem doczynienia nie ma zadnego. Ci co troche lepiej ogarniaja, ale wciaz slabo i tylko w tej tematyce, a nie ogolnie, oleja ten temat, beda woleli robic po swojemu bo sie przyzwyczaili i im tak latwiej. A ci ktorzy ogarniaja temat, albo juz smai optymalizuja kod tymi sposobami, albo wezma sie za ten poradnik, co z kolei i tak jest bez sensu bo juz lepiej jakikolwiek sensowny jezyk ogarnac niz powtarzac i udoskonalac to glupie lua ;P
Przegladnalem tylko na szybko kody zeby zobaczyc o czym to w ogole jest i stwierdzam co stwierdzilem.
 

Dubler

Lua Factory =)
Joined
Apr 8, 2009
Messages
1,874
Reaction score
112
Odp: Kr?tsze odpowiedniki w lua

Poradnik dla bardzo pocz?tkuj?cych i robi?cych podstawowe b??dy, ale zawsze si? mo?e przyda? bo takich os?b jest mrowie. Z u?ywaniem math.max/min zamiast instrukcji warunkowej bym polemizowa?, po pierwszych przyk?adach nawet nie czyta?em co jest dalej.
 
Top