Sunday, July 5, 2009

Booleans from Aliases

I want to speak once again on Boolean variables. They are variables that are either true or false. They are very easy to use in if statements, among other things. You typically want to use them for things such as on or off, yes or no. Often you set them with an alias, and there is a very simple but often overlooked way of doing that.

For all the examples, assume we have this alias:
^(pause|unpause)$

What most people do is something like this, using an if statement:
if "%1" == "pause" then
pause = true
else
pause = false
end

While this does work, it overlooks one simple fact. We're actually converting '%1' to boolean twice. What do I mean? Well, look at what's between 'if' and 'then'.
"%1" == "pause"

What does that do? It returns true if '%1' is 'pause' and false if it isn't. Why, then, can't we just set the variable 'pause' to the results of that? The answer is that we can. Try this instead:
pause = "%1" == "pause"

That works! That will set pause to true if we do pause, false if we do unpause. There's only one slight problem. If we set the alias to ignore case, it won't match if we use uppercase letters anywhere. So with one modification, it's perfect.
pause = string.lower("%1") == "pause"

Perfect.


view the full post

Thursday, July 2, 2009

Boolean Trick

Lua variables take several forms. One of these is boolean, which is either true or false. Often, however, you want to use that boolean variable to determine what text you want to display. Normally you would use an if statement or a function, but thanks to how Lua works there is a much easier way.

I was using a boolean variable to keep track of whether or not the critcounter I'm working on was enabled or not. Well, I came to the part where I display the critcounter, and I wanted to show the status (enabled/disabled) in text, and color the text green or red. The typical way of doing this would be something like this, right?
if critcounter.enabled then
AnsiNote (ansicolor (10), ("enabled")
else
AnsiNote (ansicolor (9), ("disabled")
end -- if

Well, I got to thinking, that's five lines for something simple, let's shorten it some. So I pulled my usual and used a table. It looked like this.
local text = {["true"] = "enabled", ["false"] = "disabled"}
local color = {["true"] = 10, ["false"] = 9}
AnsiNote (ansicolor (color[tostring (critcounter.enabled)]), text[tostring (critcounter.enabled)])

Very nice, eh? Down to three lines. I moved on to another part. But something was nagging at me. See, logical operators are perfect for use with boolean. Logical 'and' shows if both are true, and logical 'or' shows if one is true. Well, that's part of the story. How they actually work is this. Logical 'and' returns the first item if it is false or nil, otherwise it returns the second. Logical 'or' returns the first item if it is not false or nil, otherwise it returns the second. It doesn't matter if they are boolean or numbers or text. So I went and rewrote that line to look like this.
AnsiNote (ansicolor (critcounter.enabled and 10 or 9),
(critcounter.enabled and "enabled" or "disabled"))

And voila! It worked! But why? Let's look at the number part.
critcounter.enabled and 10 or 9

What it's really doing is this. If critcounter.enabled is true, 'and' returns 10. So then we have this statement: '10 or 9'. The 'or' operator then sees 10 is not false or nil, and returns 10. If critcounter.enabled is false, 'and' returns false. So then we have this statement: 'false or 9'. The 'or' operator then sees that the left side is false, so it returns the right side. It does the exact same thing with the enabled and disabled text.


view the full post

Notepad++ and MUSHclient

You can use MUSHclient's built-in text editor for editing your script file and making plugins. While it is comparable to Notepad in Windows, it is very limited. Notepad++ is a much more powerful text editor, and can easily be integrated with MUSHclient.

About Notepad++. It has many features useful for editing your script file, including syntax highlighting, regular expressions for find/replace, drag and drop, and line bookmarking. You can get it at notepad-plus.sourceforge.net.

Once you have it installed, integrating it into MUSHclient is easy. Just go to file|world properties and click on the scripts tab at the bottom left. Uncheck 'use inbuilt notepad to edit scripts' and hit 'choose editor', then find where you installed Notepad++ and choose the program.

From there, whenever you do shift-ctrl-h or hit 'edit script' it will open your script file in Notepad++.


view the full post

Bank Withdrawal Taxes

Ever get frustrated with determining bank withdrawal taxes? Trying to figure out exactly how much to withdraw so you'll end up with the amount you want, no more or less? Well, a simple math operation can solve your problems for once and for all.

Basic math says if you do addition then subtract the same amount, you'll end up with the same number. Same goes for multiplication and division.

Let's look at the problem involved. We want to find out what a 0.5% tax would be. A tax of 0.5% is equal to 0.005. Just multiplying the number by 1.005 isn't exact, however, because it will take out taxes on that extra 0.005. It won't be much, but for larger numbers it's enough to throw it off slightly. What we really want is a number that when multiplied by 0.995 (1.000 - 0.005) will end up being the original amount we want. Remember what I said above? If you divide then multiply by the same number, you will end up getting your original number. So what you want to do, then, is divide the amount you want by 0.995. Since Achaea also discards any fraction, we'll want to do that as well. The function math.floor will discard any fractional part.

In MUSHclient, it looks like this (assuming %1 is what you want to get):
math.floor (%1 / 0.995)

Now, we have a minor problem. If you withdraw, it takes out a minimum tax of 1 gold. So we want to set a minimum of 1 gold more than what we're withdrawing. The function math.max is perfect for this, since it returns the larger of two options. We'll just make our math function one of the options, and one more than our withdrawal amount the other option. Thus we have this:
math.max (math.floor (%1 / 0.995), %1 + 1)

Try it, it works perfectly! Except of course for zero or negative numbers, but we have no use for them, so it doesn't matter.


view the full post