helpful code tricks

This is a moderated forum that collects tutorials, guides, and references for creating Transcendence extensions and scripts.
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

Well digdug wanted me to post about dirty variables and I thought we could turn it into a thread with many nice little tricks to help you with code.

but first dirty variables

Have you ever wanted data that you could change already in the space object when it was created (kind of like a default for the data) and InitialData wasn't working as you hoped. Then you can use a dirty variable system. On the space object xml put a static data for the default. Then make two helper functions for it one to set one to get.
The set one would store whatever data that was passed in in that object (both global and per object versions work but both the variable and the dirty tracker need to be on the same level) and set a variable keeping track of the variable being dirty to true.
The get one would return the static data if the dirty tracker is nil and the normal data if it is true. This is safe across saves.


loops are meant to be broken

Lets say you want to iterate (walk through) looking for something and stop when you find it. Enum will just apply a function to everything on the list so that is not what we want. Enumwhile would work but for this lets try something else (you will not always be in a list).

Lets go with the basic loop and put for its condition (gr countOfList i) (countOfList is just how many elements the list has and i was set to 0 before the loop). With item you would inspect each element of the list and it would keep looping until it found it. When it finds it and does what you want it to do with it set i to countOfList that way the loop will end at the bottom of the loop.


Did you find these informative? Any questions on them? Do you want more (do you want them to stay basic or get more advanced)? Do you have some of your own you want to share?
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

Code: Select all

(for i 0 (subtract countList 1)
		(block (pT aList)
			(setq doReplace (item checkList i))
			(setq pT (item doReplace 0))
			(if (eq nodeID pT)
				(block Nil
					(lnkReplace checkList i newInfo)
					(setq getFlagged (cat " is now " (item flagInfo 0) ))
					(sysSetData "Sys26" "activeArray" checkList)
					(setq i (subtract countList 1))
				)
				
			)
		)
	)
I just wrote something using exactly the break (for method you describe!

This is a (for that looks through a list of lists until it finds a list with an item in first position that matches a search string - it uses the count of the list of list -1 to keep track of it's place on the list, and if it finds an entry that matches, it pops the i variable to the max to end the (for after updating that specific list with a new item.

It changes the colors of the flag icons for the viewer, too!
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

sorry Periculi but that code doesn't do what you think it does

the for function can not be broken

Code: Select all

(for i 0 10
	(block nil
		(dbgoutput (cat "number " i))
		(setq i 10)
	)
)
Will give you in the console

number 0
number 1
number 2
number 3
number 4
number 5
number 6
number 7
number 8
number 9
number 10
10

so as you can see the for loop was not broken
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

hmm... well I guess it doesn't matter.

I think you should present a working example of what you are talking about.
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

ask and you will receive

Code: Select all

(setq test (lambda Nil
	(block (counter)
		(setq counter 0)
		(loop (leq counter 10)
			(block nil
				(dbgoutput (cat "number " counter))
				(setq counter (add counter 1))
				(if (gr counter 5)
					;break the loop
					(setq counter 11)
				)
			)
		)

	)

))
that will display on the console (when test is run)

number 0
number 1
number 2
number 3
number 4
number 5
11

returning a value from a function

often when making a function you want it to return something. Often it would just return what the last function it runs returns, but sometimes you don't want that due to cleaning up or checking. A easy way is just store the thing in a variable and when you get to the end of the function just put down the variable and it will return that. Here is an example.

Code: Select all

(setq test (lambda nil
	(block (tester)
		(setq tester 5)
		
		;now we do whatever clean up or checking
		
		(if (gr tester 2)
			(dbgoutput "Success")
			(dbgoutput "Error")
		)
		
		;now we put down the the variable so we can return it
		
		tester
	)
))
would display on the console

Success
5
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

Thanks!

Nice samples and I am glad you corrected me on the (for -it could have created some issues for me down the road.
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

constructing lists

The three main ways of making a list are
simply putting the list in code, for example '(a b c)
using the list function, for example (list a b c)
using append or functions like it, for example (append 'a 'b 'c)

These ways you can make any list you want.
Here is some sample code

Code: Select all

(setq test (lambda Nil
	(block (funList)
		(setq funList nil)

		(setq funList (append 'a funList))

		;now funList is the list (a)

		(setq funList (append funList 'b))

		;now funList is the list (a b)

		(setq funList (append funList funList))

		;now funList is (a b a b)

		(setq funList (list 'a 'b 'c 'd))

		;now funList is the list (a b c d)

		(setq funList (list funList))

		;now funList is the list ((a b c d))

		(setq funList (append funList funList))

		;now funList is the list ((a b c d) (a b c d))
	)

))
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

Hmm.. I need to set up a way to control a loop. The loop is intended to cycle through a list of systems with gate links- it needs to following the links until it gets done with the map list and then end.

The list would look something like

(list "NodeID" "Link1" "Link2")
(list "NodeIDofLink1")
(list "NodeIDofLink2" "Link3")
(list "NodeIDofLink3")

So it encounters that list, it knows it is processing the NodeID, so it must remove a counter from that- but it finds that it must do 2 more systems...

The one I built isn't going any further than the first list.

It's a little big to paste in here too.

So how can set up a controlled loop cycle that uses the information in the list (or the amount of the list items) to control the loop to stop it or keep it running?
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

hmm how about you build a separate data structure depending on what order you want it processed. Do you want a first in first out behavior or a last in first out or both would work for you. (and if you know about this stuff yes I am suggesting you make a separate stack or queue so you can push/pop as needed in the loop without worrying about items or enum being by value)
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

I need it to trace the route of the links by what they were defined as.

say a predetermination is being made:

A is chosen from A or B
D is chosen from D E F

A links to C
B links to C

C links to [DEF] and [AB]
D links to C
E links to C
F links to C

(setq itemsToDo 1)

(loop (gr itemsToDo 0)

(list A C)
(list B C)
(list C D)
(list D C)
(list E C)
(list F C)

the path I want to trace is A - C - D

The total activated links is only 3.

How can I control the loop to mark the start (A or B) on a new list, get the linked item (C) from the starting point look up the item on the list, process it and mark it on the new list, look up the final link (DEF) and add it to the list then end?

I can't define how many links there are in advance, this changes every time the list is being made.

I can't define how many iterations will be needed because it depends on the link choices made.

So, the process needs to manage this on it's own. And it can only do each item once, no double entries!

I have made a few stacks actually- an activated list and a done list. The process reads the list it is currently at (A for the Start) adds any links to the activated list (start is added in prior to the loop), then puts itself on the done list, removes itself from the activated list and passes the torch to the next cycle.. where the loop has been either dying or going infinite.. ugh
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

(sorry so late was a busy day)

so let me ask a few questions

are (list a b) and (list b a) equivalent?
how do you want the output to look? it seems you want two things a single path the (a b c) and a branching path (d e f) or is that just an issue with input and you don't worry about that with output?

do you want just a single path (kind of like a simplified depth first search)? Do you want that same path to be chosen every time? Or do you want to convert the simple lists into a more complex format to do various things to it (tests and stuff)?
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

(list a b) and (list b a) are not the same at all.

in the list i am dealing with, the first item is the origin node, the next items are the linked nodes.

I want to trace the star network that was activated from a big list of potential links.

The way I see doing it is to get the starting node, see what links it got, go look those up, see what links they got, and so on-

However, linked nodes have the original node listed- like A -> B, B -> A & C. A goes to B, B goes back to A and also to C.

A could have gone to D, E or F, let's say, but it actually went to B.

You see?
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

sounds like you want to do a depth (maybe breadth but I will describe depth) first search (not visiting nodes you already did)

define linkList to be the list of all the links in the format
(node1 node2 ...)
define node as (nameOfNode visitedFlag linkedNodeNameList)
define linkedNodeNameList as just a list of all the names the owner node links to

(I defined them this way so its easier for me to make the recursive function I don't care the format you use)

have a recursive function

first mark this node visited
then go through the list and for every link call this function if that node hasn't been visited
do anything you need for book keeping (I am not sure what you want to do but here is where to do it)

and that's it :D if all the nodes are not accessible from the origin node then all the nodes will not have been visited so you can check for that after this has been called plus you have the book keeping code to do whatever you need to do at every node accessible from the origin node.

converting from your format to this one is easily done with code or just have it start this way
Crying is not a proper retort!
User avatar
Periculi
Fleet Officer
Fleet Officer
Posts: 1282
Joined: Sat Oct 13, 2007 7:48 pm
Location: Necroposting in a forum near you

Now explain how <OnAttackedByPlayer> works, genius. :P

No, seriously, check out my thread- or just go play around with the tag and see if you can figure out how to get it to do things.
User avatar
Betelgeuse
Fleet Officer
Fleet Officer
Posts: 1920
Joined: Sun Mar 05, 2006 6:31 am

hmm now that I think about it doing book keeping before you call the recursive functions might make put it in an easier to read format (depending on how you want to do book keeping or if you even want to do that)
Crying is not a proper retort!
Post Reply