Psychose-a-Matic -- one-stop NPC psychiatric management

Bale

Minion
Another weakness: It won't detect an item in the closet unless the player has checked the preference to auto-satisfy with the closet. I'd recommend you add closet_amount() also.
 
Oh dear. I feel very, VERY sorry for you.
I read this and my heart sank... I should have written that down?
Code:
> count flick

flickering pixel (7)
I assumed I saved the hardest for last, so if one shines as "hardest" then I may not have it so bad... luckily:
If you were running mafia at the time you could probably get that info out of the session log. If that still seems daunting, more help can be offered such as how to text search multiple files.
I always use mafia, so I can hopefully dig that out (how old is this content again?) with some regex and patience.

EDIT:
Code:
 findstr "flickering" almighty_sapling_2013*.txt
is very very helpful.
 
Last edited:

Theraze

Active member
Also useful:
findstr /i /c:"some text" *files-to-search*.txt

The /i makes it case insensitive, in case the capitalization doesn't match your memory or you don't have a good example in front of you. the /c:"something" looks for the phrase something rather than just the words... if you want the phrase "flickering pixel", you have to use /c:"flickering pixel" to find the phrase instead of just looking for the word flickering or the word pixel.
 

zarqon

Well-known member
You are far too kind, m00g!

By the way, if anyone has any good quotes about mental unwellness, I'm not averse to suggestions. Particularly from TPTB, KoL forumites, or other known figures in KoL land. Or ones that you make up yourself! INFAMY IS YOURS FOR THE TAKING
 

EdFox

Member
I got my Byte! WHOO!:D

A minor change request: The quote pushes the active jar--if one is up--to the right. Longer quotes will push it right out of the frame on my small laptop. I think a CRLF or newline or whatever will fix it, just put the jar slightly below the quote.

This game is probably the best OCD test there is. Unless one is *really* obsessive-compulsive, I doubt they'll stay past the first ascension.
 

Veracity

Developer
Staff member
I love this script. I have a couple of improvements:

1) When you have an active jar, it shows it, but it is off to the right. It needs to be centered with style='clear:both' (this is the same bug that EdFox, right above me, reported).
2) You do a lot of page.append( stringX+stringY). Personally, I think it is clearer - and definitely uses less temporary memory - to do
page.append( stringX); page.append( stringY );

I attach a version of the script with both mods.
 

Attachments

  • relay_Psychose-a-Matic.ash
    10.5 KB · Views: 58

zarqon

Well-known member
r11 Update

  • Only list Truthsayer ingredients as rewards if you haven't made Truthsayer yet.
  • After getting your Jick-sword, add a link next to it to pop up the description so you can see which enchantments you were lucky or unlucky enough to get.
  • Add a framework for per-jar detailed progress/information depending on which jar you have active. For now the only extra info is quick links to set goals for a target effect in the Pretentious Artist's Psychoses.
I tried the "clear: both" fix, but I realized when doing this that I'd originally written it that way, but removed it to conserve vertical space. As more and more info shows up to the left of the imagemap, this should be less of a problem. There's probably a way to make it positioned more consistently -- perhaps by somehow forcing the quote to wrap around -- but I haven't figured that out yet.

Also, expanded a few of the append(a+b)'s to append(a); append(b)'s, but not very many of them, I'm afraid. I generally find it easier to read concatenated strings, but that's mainly an issue of taste.

Is there any way I can find out which flickering pixel tracking property goes with which test? If so, I'll be able to add some very helpful info for that jar.
 

Bale

Minion
Following copy/paste is from FlickerCommand.java:

Code:
	public static final String[][] PIXELS =
	{
		{
			"flickeringPixel1",
			"Anger",
			"Stupid Pipes",
			"25 hot resistance",
		},
		{
			"flickeringPixel2",
			"Anger",
			"You're Freaking Kidding Me",
			"500 buffed Muscle/Mysticality/Moxie",
		},
		{
			"flickeringPixel3",
			"Fear",
			"Snakes",
			"300 buffed Moxie",
		},
		{
			"flickeringPixel4",
			"Fear",
			"So... Many... Skulls...",
			"25 spooky resistance",
		},
		{
			"flickeringPixel5",
			"Doubt",
			"A Stupid Dummy",
			"+300 bonus damage",
		},
		{
			"flickeringPixel6",
			"Doubt",
			"Slings and Arrows",
			"1000 HP",
		},
		{
			"flickeringPixel7",
			"Regret",
			"This Is Your Life",
			"1000 MP",
		},
		{
			"flickeringPixel8",
			"Regret",
			"The Wall of Wailing",
			"60 prismatic damage",
		},
	};
 

Veracity

Developer
Staff member
Also, expanded a few of the append(a+b)'s to append(a); append(b)'s, but not very many of them, I'm afraid. I generally find it easier to read concatenated strings, but that's mainly an issue of taste.
Just want to make sure you understand the internal difference between appending to an existing buffer and appending the result of string concatenation into an existing buffer.

Code:
buffer page;
page.append( "a" );
page.append( "b" );
page.append( "c" );
string a = page.to_string();
String a is now is "abc".

Code:
buffer page;
page.append( "a" + "b" + "c" );
string a = page.to_string();
String a is now is "abc".

Sweet! No difference, right? Well, let me rewrite that second one to show you what's actually happening.

Code:
buffer page;
buffer tempb1;
tempb1.append( "a" );
tempb1.append( "b" );
string temps1 = tempb1.to_string();
buff tempb2;
tempb2.append( temps1 );
tempb2.append( "c" );
string temps2 = tempb2.to_string();
page.append( temps2 );
string a = page.to_string();
As I said, no difference in end result, but two extra buffers and two extra strings end up being allocated and garbage collected.

By all means - write the code that is "clearest" to you. But, as you say, that is a matter of taste. To me, if I am building up a buffer, the "clearest" code successively adds strings to that buffer. To you, it is "clearest" to build up substrings in implicitly allocated temporary buffers via string concatenation and append the result into the visible buffer.

Suit yourself.
 

Veracity

Developer
Staff member
You are welcome. Note that Mafia code is Java and Java optimizes string concatenation in a way that the ASH compiler does not. For example:

Code:
String a = "a" + "b" + "c";
compiles into something like this:

Code:
String a;
{
    StringBuilder temp = new StringBuilder();
    temp.append( "a" );
    temp.append( "b" );
    temp.append( "c" );
    a = temp.toString();
}
In other words, there is still a temporary buffer allocated (and garbage collected), but a single one is used to collect all of the strings that are being concatenated. Therefore:

Code:
System.out.println( "a = " + a + " b = " + b );
will similarly use a single buffer to accumulate the argument. That's efficient enough. Now, you have undoubtedly seen lots of places in KoLmafia where we explicitly allocate a StringBuilder and then construct a string in it. We could get the same effect by using a single big string concatenation, but if there are lots of calculations along the way to decide what goes into the string, you end up with a big messy assignment loaded with ternary conditionals and such and its just a lot cleaner to make the StringBuilder explicit.

ASH's compiler does not optimize. If you have a + b + c, it will generate code to call "+" on two operands at a time - and "+" for a pair of strings does Java string concatenation - it allocates a temporary StringBuilder to concatenate the strings and then a temporary String to hold the result. That is what I showed in my example. It would not be unreasonable for ASH to optimize string concatenation in general, so that

Code:
print( "a = " + a + " b = " + b );
would use a single temporary buffer to build up the string, just like Java.

However, my statement still stands that if you are already loading up a buffer - like every relay script does when it generates the page HTML - you may as well append into the existing buffer, rather than having all sorts of temporary buffers and strings be allocated - and garbage collected - along the way.

But that is just MY "taste" or "style". YMMV.
 

Veracity

Developer
Staff member
And with revision 13526, your preferred "style" is less inefficient. Again, compare:

Code:
buffer page;
page.append( "a" );
page.append( "b" );
page.append( "c" );
string a = page.to_string();
to:

Code:
buffer page;
page.append( "a" + "b" + "c" );
string a = page.to_string();
With the backend optimization I just committed, the second one now does this:

Code:
buffer page;
buffer tempb1;
tempb1.append( "a" );
tempb1.append( "b" );
tempb1.append( "c" );
string temps1 = tempb1.to_string();
page.append( temps2 );
string a = page.to_string();
So, you are now down to 1 extra temporary buffer and one extra temporary string for each string concatenation you do, no matter how many substrings comprise it.
 

zarqon

Well-known member
Thank you very, very much Veracity.

I had always felt my preference for concatenation to be one of my shameful secrets that I tried to avoid mentioning, but now that Veracity has made it much more efficient on the backend, I can come out of the closet and explain why I felt that concatenation was grammatically -- not executively -- more efficient. I was conflicted about two different forms of efficiency, and it made me uneasy. And as you probably all know by now, I'm more of a linguist than a programmer, and efficiency of language use, rather than efficiency of parsing that language, was the more important form of efficiency to me.

So, keep in mind this is not a defense of my (objectively inferior-performing) preference. This is a confession, the reasons why my grammarian's soul was torn and couldn't see the light.

  1. Avoiding repeated commands. I have an aversion to repeated commands. They're basically the reason for control structures to exist. So when I see a whole bunch of page.append()'s in a row, my instinct is to immediately consolidate them into a single command. Never mind that said consolidation was actually much less efficient to run, the repeated commands on the screen made my fingers itch to join them all together with a few innocuous-seeming plus signs. My brain would remind my fingers that those little plus signs are actually less efficient to run, but ofttimes before I knew it they'd already done it.

  2. Distributive property. f(a) + f(b) + f(c) is equivalent to f(a + b + c). I find the second, non-distributed form clearer. I suppose this overlaps a bit with the previous reason.

  3. Not splitting atoms. In relay scripts, we are quite often writing HTML markup to a buffer, with much of the content being static, merely plugging in values as needed using variables. Say I want to write the variable someint to the buffer:

    page.append(someint);

    Sweet. Oh wait, I want to italicize it. Whether I use <i> tags or styleable <span> tags, I now need to put one string on each side of the variable. I could use three append commands:

    page.append("<i>");
    page.append(someint);
    page.append("</i>");


    But I find that vertical arrangement hard to read, especially given that the italicized someint is one atom of content. Code that writes code has always been tricky grammatically. How much should the structure of the code your code is writing structure the code you're writing? Ha. I find grouping that related content together easier to read:

    page.append("<i>"+someint+"</i>");

    Western civilization has been reading left-to-right for centuries, and as a product of said civilization, this arrangement is much easier for me to follow. I feel the same about businesses that for some reason feel that it's OK to have words on their sign with vertically stacked letters. We ought to have grown out of that in the 1800s.

  4. Use fewer characters. This is of course churlish and stupid, but there are still some dinosaurs for whom a small filesize and linecount is a point of pride, and when a single plus sign can replace a semicolon, newline, some whitespace, a variable name, and another command call, it can be hard to consider the extra milliseconds shaved off the execution time as being worth all those characters. Completely childish reason of course, but when added to the above three it sometimes gave me that extra excuse that my lazy fingers and linguist brain were looking for.

I have long wished for a way to reconcile my loyalties to these conflicting types of efficiency. No matter which way I wrote the code I was betraying a principle. I felt guilty and shamed to be writing inefficient code deliberately, but I knew that I could never accept full-on append() repetition for the above reasons. I am exceedingly grateful that Veracity, in her wisdom, has seen fit to mostly reconcile these principles, that I may once again face the world with head held high as both grammarian and scripter. Thank you.
 

fronobulax

Developer
Staff member
What a post. Thank you.

In the early days of Java and portable devices (so we're talking at least 15 to 20 years ago) I wrote some code that was used to send and receive binary, bit encoded messages. The spec was complex and conditional (if the current bit is one then the next 5 bits will be the op code) and conceptually what made the code understandable and easy to check against the spec was to build a string with zeros and ones and then convert that representation to bits. So the code was littered with x = x + "1" Needless to say that was inefficient. The usual strategy of making a working program and then making it fast failed spectacularly because the folks who wanted to implement in C++ managed to torpedo attempts to profile the Java or hand optimize it to remove a couple hundred string concatenations so the Java implementation was deemed a failure, all because I was drawn to the clarity of overloading the plus sign to concatenate.
 

Veracity

Developer
Staff member
I tried the "clear: both" fix, but I realized when doing this that I'd originally written it that way, but removed it to conserve vertical space. As more and more info shows up to the left of the imagemap, this should be less of a problem. There's probably a way to make it positioned more consistently -- perhaps by somehow forcing the quote to wrap around -- but I haven't figured that out yet.
Yeah, well, OK, this is a major problem for me.

Everywhere else within the KoL interface, if there are a lot of lines of output, I am given a vertical scrollbar. I have to use that in the charpane, in chat, and in the mainpane, in order to see all the output.

So, running your script, I am perfectly willing - in fact, I expect it - to have a vertical scrollbar, if the quote + the jar + the info below the jar use "too much vertical space".

However, with the code as written, you feel that it is important to save one line of vertical space - what the quote would take by itself - and, in order to do that, you put the jar on the same line as the quote.

As a result, unprecedented in my KoL experience, I am given a horizontal scrollbar, which I need to use to bring the jar into mouse-click range in the main frame.

It is completely and utterly unimportant to me to save one line of vertical space in exchange for being forced to use a horizontal scrollbar.

I am probably unable to make you understand why this is an actual UI issue - even though you have two bug reports from people begging you for a fix - so, I will continue to use my clear:both fix to this bug in your script.

As is apparent from your later response, you will not change from your less efficient and harder to read (in my opinion; obviously your opinion differs) method of concatenating into a string buffer you already have available to you, so I shrug and abandon that, but the UI bug that I provided a fix for is still a major, visible, degrades-my-experience, issue to me. Therefore, here is a version of your script which fixes only that bug.

Thanks.
 

Attachments

  • relay_Psychose-a-Matic.ash
    11.1 KB · Views: 20
Last edited:

zarqon

Well-known member
I agree that the horizontal scrollbar is unforgivable. My understanding (having either not seen or remembered EdFox's comment) was that the jar was merely appearing off-center rather than actually extending off-window.

I'll add the clear:both to the next update, in addition to flickering pixel progress spoilers. Eventually I'll want the jar to force the text on the left to wrap, but that's going to have to wait. Unfortunately, TPTB have completely worn me out with all their updates lately and most of my scripting energy is spent just trying to keep my scripts afloat, rather than add anything new to them.
 
Top