complex maths thing

Posted by Humiliation on Fri 13 Apr 2007 11:58 PM — 23 posts, 87,083 views.

#0
could someone help me with an alias/script i'm writing?

basically i want it to go:
@var1 ÷ (@var1 + @var2 + @var3 + @var4) x 300= @Avar1

Then the same for Var 2 3 and 4 and avar 2 3 and 4 respectively.

Thanks a bunch
Amended on Sat 14 Apr 2007 04:37 AM by Humiliation
USA #1
That really depends on what you want the alias to be phrased as, what the variables are, how they are stored, and how many of them you want.

The easy way if you will always have 4 variables and you are just triggering on "foo * * * *" would be this:

temp = 300 / ( "%1" + "%2" + "%3" + "%4" )
print( "%1" * temp )
print( "%2" * temp )
print( "%3" * temp )
print( "%4" * temp )
#2
How do you do it so instead of just printing it it puts it in a variable? I want to then use those variables.

And just to make it even more complicated i forgot to add after multiplying it by 300 if it is above 75 we minus 75 from it then minus that number from 75 and if it is below we minus it from 75 then add 75. And then round it to the nearest whole number. If that makes sense...

And thanks for the response
Amended on Sat 14 Apr 2007 05:27 AM by Humiliation
USA #3
The variables part is easy.
temp = "%1" * foo
SetVariable("var1", temp )

It's retrieved later with GetVariable( "var1" )

Quote:
And just to make it even more complicated i forgot to add after multiplying it by 300 if it is above 75 we minus 75 from it then minus that number from 75 and if it is below we minus it from 75 then add 75. And then round it to the nearest whole number. If that makes sense...

It might make sense if I tried to pull it apart more than I'm willing to do in the middle of the night after a few drinks. But the easier thing to do is to show you if statements. Scripting with Lua is very easy, and there are some nice tutorials here: http://lua-users.org/wiki/TutorialDirectory

if temp > 75 then
  temp = 75 - temp
else
  temp = 75 - temp + 75
end
temp = math.floor(temp + 5)

I think that's roughly what you were getting at. I'm still really confused about the 75 bit. The actual math you can probably handle after reading the tutorial. I can't seem to find a round function, so I just rounded down after adding a half.
Australia Forum Administrator #4
Quote:

temp = math.floor(temp + 5)


He means to add 0.5 - but that is quite a good way of rounding:


temp = math.floor(temp + 0.5)



Quote:

if it is below we minus it from 75 then add 75

...

temp = 75 - temp + 75


Yes, this looks a bit strange. It is identical mathematically to:


temp = 150 - temp

Australia Forum Administrator #5
This actually raises an interesting point. How do you round negative numbers? For example, does -1.5 round to -2 or -1?

This simple function actually rounds it to -1:


function round (x)
  return math.floor (x + 0.5)
end -- round


This slightly more complex round function rounds to the nearest number with "upwards" being to the absolute value.


function round (x)
  if x >= 0 then
    return math.floor (x + 0.5)
  else 
    return math.ceil (x - 0.5)
  end
end -- round


It might be a moot point, especially if your numbers are always positive, but it is an interesting question.

The second function rounds -1.5 to -2.
#6
Thank you so very much. I'm actually really impressed at how powerful lua - and mushclient - is.

Thanks again
USA #7
you should be impressed. this client rules.
#8
uhh got this error

[string "Alias: "]:2: attempt to perform arithmetic on global `foo' (a nil value)
stack traceback:
[string "Alias: "]:2: in main chunk
the alias is
<aliases>
<alias
match="foo * * * *"
enabled="y"
expand_variables="y"
send_to="12"
sequence="100"
>
<send>temp = 300 / ( "%1" + "%2" + "%3" + "%4" )
temp = "%1" * foo
SetVariable("var1", temp )
temp = "%2" * foo
SetVariable("var2", temp )
temp = "%3" * foo
SetVariable("var3", temp )
temp = "%4" * foo
SetVariable("var4", temp )
</send>
</alias>
</aliases>

If you could give me thw hole thing in one block it would make things easier for me. Thanks again
#9
Thank you so very much. I'm actually really impressed at how powerful lua - and mushclient - is.

Thanks again
USA #10
copy/paste an example from your mud of what you are trying to alias.
#11
i cleared it all up but its super messy. that's beside the point but. Now var1 2 and 3 are getting negatives (which shouldn't be happening). Here it is...

<aliases>
  <alias
   match="foo"
   enabled="y"
   expand_variables="y"
   send_to="12"
   sequence="100"
  >
  <send>temp = 300 / ( "@offensive_skill" + "@daring_skill" + "@attack_skill" + "@Aim_skill" )
temp = "@offensive_skill" * temp
if temp &gt; 75 then
  temp = 75 - temp
else
  temp = 150 - temp
end
temp = math.floor(temp + 0.5)

SetVariable("var1", temp )
temp = 300 / ( "@offensive_skill" + "@daring_skill" + "@attack_skill" + "@Aim_skill" )
temp = "@daring_skill" * temp
if temp &gt; 75 then
  temp = 75 - temp
else
  temp = 150 - temp
end
temp = math.floor(temp + 0.5)

SetVariable("var2", temp )
temp = 300 / ( "@offensive_skill" + "@daring_skill" + "@attack_skill" + "@Aim_skill" )
temp = "@attack_skill" * temp
if temp &gt; 75 then
  temp = 75 - temp
else
  temp = 150 - temp
end
temp = math.floor(temp + 0.5)

SetVariable("var3", temp )
temp = 300 / ( "@offensive_skill" + "@daring_skill" + "@attack_skill" + "@Aim_skill" )
temp = "@aim_skill" * temp
if temp &gt; 75 then
  temp = 75 - temp
else
  temp = 150 - temp
end
temp = math.floor(temp + 0.5)

SetVariable("var4", temp )
</send>
  </alias>
</aliases>


@offensive_skill = 41
@daring_skill = 35
@attack_skill = 37
@aim_skill = 20

The results i got were
@var1 = -17
@var2 = -4
@var3 = -8
@var4 = 105
Amended on Sat 14 Apr 2007 10:16 AM by Humiliation
USA #12
Also.

I, as well, just started to learn LUA(2weeks so far) and here's some tips that I found helped me out...

Get familiar with regular expresions(regex). I printed out 2 pages worth of regex symbols and taped them to my wall. What used to be weird symbols and strange-looking words now start to make sense. The sooner you take to memory these things the faster you'll learn -> the faster you'll understand.

Be very specific with asking about what you want. Give exact examples of the output from your mud and what you want to do. In the last 2 weeks of my posting here on the forums 90% of the replies I got were from Nick and Shaun. They aren't here all the time so make sure you phrase your questions as simple as possible so that anyone else who happens to peruse your thread might want to help out.

Hope this helps, and good luck.

cheers
Australia Forum Administrator #13
Quote:

Now var1 2 and 3 are getting negatives (which shouldn't be happening). Here it is...

...

temp = "@offensive_skill" * temp
if temp > 75 then
temp = 75 - temp
else
temp = 150 - temp
end




First, I wouldn't put "@offensive_skill" in quotes. It's a number, right? So if offensive_skill is 41, then you are saying:

temp = "41" * temp

You don't really multiply strings, you multiply numbers, so it should read:

temp = 41 * temp

I think Lua has converted it to a number for you, but you should be more precise with your use of strings and numbers.

Amended on Sat 14 Apr 2007 10:50 AM by Nick Gammon
Australia Forum Administrator #14
As for the negative problem, printing intermediate results can help. I substituted your numbers to see what would happen:


temp = 300 / ( "41" + "35" + "37" + "20" )
print (temp)    --> 2.2556390977444
temp = "41" * temp
print (temp)    --> 92.481203007519
if temp > 75 then
  temp = 75 - temp  --> 75 - 92.481203007519 = -17.481203007519
else
  temp = 150 - temp
end
print (temp)   --> -17.481203007519
temp = math.floor(temp + 0.5)
print (temp)   --> -17


It is doing what you told it to, the question is, what do you really want it to do?
#15
SORTED. A couple of the signs were were wrong (> instead of < - instead of +). works like a dream now
#16
Part of your problem is that Shaun Biggs in his first post skipped over some of your explanation when he was writing the code :(

Quote:
And just to make it even more complicated i forgot to add after multiplying it by 300 if it is above 75 we minus 75 from it then minus that number from 75 and if it is below we minus it from 75 then add 75. And then round it to the nearest whole number. If that makes sense...


Ok, breaking this up into pseudo-code:


temp1 is our number after multiplying by 300

if temp1 > 75:
  temp2 = temp1 - 75
  temp3 = 75 - temp2

if temp1 < 75:
  temp2 = 75 - temp1
  temp3 = temp2 + 75

tempf = round(temp3)

Note that in the case of temp1 == 75, nothing is done.

If we examine the maths a bit more, it turns out that if temp1 > 75 then temp3 = 75 - (temp1 - 75) => temp3 = 75 - temp1 + 75 => temp3 = 150 - temp1.

We already know the temp1 < 75 case devolves to temp3 = 150 - temp1 from one of the earlier posts, so out pseudocode should actually be:

temp1 is our number after multiplying by 300
tempf = round(150 - temp1)


HTH.
USA #17
ok, now that I've had a bit of time to think about this and I don't have any alcohol in my system...

vars = { var1="%1", var2="%2", var3="%3", var4="%4" }
divisor = 300 / ( "%1" + "%2" + "%3" + "%4" )
for i,v in pairs(vars) do
  temp = v * divisor
  if temp > 75 then
    temp = (temp - 75) - 75
  else
    if temp < 75 then
      temp = (75 - temp ) + 75
    end
  end
  if temp < 0 then
    temp = math.ceil( temp - 0.5 )
  else
    temp = math.floor( temp + 0.5 )
  end
  SetVariable( i, temp )
end -- loop


The main issue with the actual math is that how you tried stating what the logic is just is way too ambiguous. Seems like one of those things that are easier to think about than to explain. The best way to start explaining in this situation is to break it down into smaller chunks instead of trying to get the whole process out in one statement with no punctuation. Also breaking it down into sections that you can easily refer back to would help.
Quote:
And just to make it even more complicated i forgot to add after multiplying it by 300 if it is above 75 we minus 75 from it then minus that number from 75 and if it is below we minus it from 75 then add 75. And then round it to the nearest whole number. If that makes sense...

Could be easier to read in this format:
1) sum = sum of v1,v2,v3, and v4
2) temp = var / sum * 300
3) if temp at stage 2 is ___ then temp should be temp - 75 etc.
USA #18
This thread does remind of a question I had earlier. Is there a nice easy way to get Lua to have a table of all the wildcards in an alias or trigger without having to pass it to a script in the world file? That would make a few of my scripts a bit easier to deal with.
Australia Forum Administrator #19
Check out GetTriggerWildcard. I'm not sure you can tell how many wildcards there are, short of working your way through the list (1, 2, 3 etc.) until it returns an empty string.

http://www.gammon.com.au/scripts/doc.php?function=GetTriggerWildcard
#20
Quote:
if temp > 75 then
  temp = (temp - 75) - 75
else

If we simplify this we get temp = temp - 150. Since temp can presumably be 76, we end up with a negative again.

Seriously, the if checks are redundant. temp = 150 - temp is what he's looking for based on the explanation he gave.

It helps if you replace the word "minus" with "subtract" as appropriate in the explanation, ie: if it is above 75 we subtract 75 from it (temp) then subtract that number (temp - 75) from 75 (75 - (temp - 75) = 150 - temp) and if it is below ( if temp < 75) we subtract it from 75 (75 - temp) then add 75 ((75 - temp) + 75 = 150 - temp).

Humiliation, how did you come up with this math in the first place?
USA #21
I'm pretty sure I get the basic idea about what the math is supposed to do. I just don't know where the difference between how Humiliation has in in his head and how we have it in our head is. I think it's supposed to change the value to be closer to 75 than it originally is, similar to how tiered damage reduction works after a certain cap in a diku mud.

if damage > 80 then
damage = ( (damage - 80) * 0.75 ) + 80

or something similar to that effect. That way the higher damage is reduced a bit to cut back on everyone one hitting each other, and you still have the higher damage doing more damage as it increases.
Amended on Sun 15 Apr 2007 09:04 AM by Shaun Biggs
#22
Except that the larger the individual skill numbers are, the smaller the resultant number is.

temp = 300 * (0.5 - (skill / sum_skills))

Which means either that "high skill" is actually represented by a small number OR the result number is actually something he wants to minimize (chance to miss?).

Since it is relativized (by the / sum_skills), having all your skills equal will get the same end results irrespective of the actual skill values. AND if any one skill makes up more than half of the total skills (ie 40, 10, 10, 10) it will go negative again.