|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Sat Mar 04, 2006 9:36 pm
Generic Priority Queue |
Let me open with the simple statement that this script will not solve anything by itself. There are many interface steps that have to be preformed by other scripts you write. This is only a queue implementation and a question system to build low level data for the queue.
On that note, here is some of the interface things you have to do.
PQueueAdd command
PQueueDo
and also setting character state flags.
Code: |
#CLASS {PriorityQueue}
#ALIAS PQueueAdd {#IF (%numparam=0) {#ECHO Parameter required for PQueueAdd} {PQueueTemp3="";#LOOP %numparam {PQueueTemp=%db(@PQueueData,%param(%i));#IF (@PQueueTemp="") {#ECHO Did not find data for queue item %param(%i)} {PQueueTemp2=%word(@PQueueTemp,2,"R-");PQueueTemp2=%word(@PQueueTemp2,1,",");PQueueTemp=%replace(@PQueueTemp,%concat("R-",@PQueueTemp2),%concat("R-",%sort(@PQueueTemp2)));#ADDKEY PQueue {%param(%i)} {@PQueueTemp};PQueueTemp=%word(@PQueueTemp,2,"P-");PQueueTemp=%word(@PQueueTemp,1,",");PQueueTemp=%rightback(%concat("0000",@PQueueTemp),5);PQueueTemp3=%concat(@PQueueTemp3,"|",@PQueueTemp,"-",%param(%i))}};PQueueTemp3=%concat(@PQueueTemp3,"|",%db(@PQueue,"Priorities"));#DELITEM PQueueTemp3 {};PQueueTemp3=%sort(@PQueueTemp3);#ADDKEY PQueue {Priorities} {@PQueueTemp3}};#NOOP %-1}
#ALIAS PQueueDo {PQueueDTemp3=%eval(%numitems(@PQueue.Priorities)>0);#WHILE (@PQueueDTemp3) {PQueueDTemp=%word(%item(%db(@PQueue,"Priorities"),@PQueueDTemp3),2,"-");PQueueDTemp2=%word(%word(%db(@PQueue,@PQueueDTemp),2,"R-"),1,",");#IF (%regex(%concat("-",%replace(@PQueueDTemp2,"|","--"),"-"), %repeat(%concat("(-(?:",@PQueueFlags,")-)+"),%numitems(@PQueueDTemp2)))=0) {PQueueDTemp2="failed"} {PQueueDTemp2=""};#IF (@PQueueDTemp2="") {#NOOP Flags met requirements do this item;PQueueDTemp2=%word(%word(%db(@PQueue,@PQueueDTemp),2,"U-"),1,",");#WHILE (@PQueueDTemp2) {#DELITEM PQueueFlags {%pop(PQueueDTemp2)}};PQueueFlags=%sort(%concat(@PQueueFlags,"|",%word(%word(%db(@PQueue,@PQueueDTemp),2,"G-"),1,",")));#DELITEM PQueueFlags {};PQueueDTemp2=%db(@PQueueMapping,@PQueueDTemp);#IF (@PQueueDTemp2) {#EXEC {@PQueueDTemp2}} {#EXEC {@PQueueDTemp}};PQueueDTemp2=%word(%word(%db(@PQueue,@PQueueDTemp),2,"C-"),1);#DELNITEM PQueue.Priorities @PQueueDTemp3;#IF (@PQueueDTemp3>%numitems(@PQueue.Priorities)) {PQueueDTemp3=0};#IF (@PQueueDTemp2="1") {PQueueDTemp3=0}} {#ADD PQueueDTemp3 1;#IF (@PQueueDTemp3>%numitems(@PQueue.Priorities)) {PQueueDTemp3=0}}}}
#VAR PQueue {} {}
#VAR PQueueTemp {} {}
#VAR PQueueTemp2 {} {}
#VAR PQueueTemp3 {} {}
#VAR PQueueDTemp {} {}
#VAR PQueueDTemp2 {} {}
#VAR PQueueDTemp3 {} {}
#VAR PQueueFlags {} {}
#CLASS 0
#CLASS {PriorityQueue|PQCreator}
#ALIAS PQueueCreate {#IF (%yesno("Modify existing queue data?")) {PQueueCTemp=%word(%pick("p:Please choose entry to modify","o:1",%replace(%expanddb(%replace(@PQueueData,"|","/"),"|","="),","," ")),1,"=")} {PQueueCTemp=%replace(%prompt("","Name of new command?"),%char(34),"");#IF (@PQueueCTemp!="") {PQueueCTemp2=%regex(@PQueueCTemp,"[\-\|\ =\.\?\;\[\]\,\:\(\)\'\{\}/]");#WHILE (@PQueueCTemp2) {PQueueCTemp=%replace(%prompt("",%concat("Previous entry invalid(char '",%copy(@PQueueCTemp,@PQueueCTemp2,1),"'). Name of new command?")),%char(34),"");#IF (@PQueueCTemp!="") {PQueueCTemp2=%regex(@PQueueCTemp,"[\-\|\ =\.\?\;\[\]\,\:\(\)\'\{\}/]")} {PQueueCTemp2=0}}}};#IF (@PQueueCTemp) {PQueueCTemp2=%prompt(%word(%word(%db(@PQueueData,@PQueueCTemp),2,"P-"),1),%concat("Priority for command:",@PQueueCTemp,"?"));#IF (@PQueueCTemp2="") {PQueueCTemp2="1"};PQueueCTemp3=%concat("P-",@PQueueCTemp2);PQueueCTemp2=%pick(%concat("p:Requirement flags for command:",@PQueueCTemp),%expanddb(@PQFlagDef,"|"),"Other");#IF (%ismember("Other",@PQueueCTemp2)) {#DELITEM PQueueCTemp2 {Other};PQueueCTemp3=%concat(@PQueueCTemp3,",R-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {};PQueueNewFlag} {PQueueCTemp3=%concat(@PQueueCTemp3,",R-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {}};PQueueCTemp2=%pick(%concat("p:Uses flags for command:",@PQueueCTemp),%expanddb(@PQFlagDef,"|"),"Other");#IF (%ismember("Other",@PQueueCTemp2)) {#DELITEM PQueueCTemp2 {Other};PQueueCTemp3=%concat(@PQueueCTemp3,",U-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {};PQueueNewFlag} {PQueueCTemp3=%concat(@PQueueCTemp3,",U-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {}};PQueueCTemp2=%pick(%concat("p:Gives flags for command:",@PQueueCTemp),%expanddb(@PQFlagDef,"|"),"Other");#IF (%ismember("Other",@PQueueCTemp2)) {#DELITEM PQueueCTemp2 {Other};PQueueCTemp3=%concat(@PQueueCTemp3,",G-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {};PQueueNewFlag} {PQueueCTemp3=%concat(@PQueueCTemp3,",G-");#FORALL @PQueueCTemp2 {PQueueCTemp3=%concat(@PQueueCTemp3,%word("%i",2,"="),"|")};#DELITEM PQueueCTemp3 {}};#IF (%yesno(%concat("Await confirmation on command ",@PQueueCTemp,"?"))) {PQueueCTemp3=%concat(@PQueueCTemp3,",C-1")} {PQueueCTemp3=%concat(@PQueueCTemp3,",C-0")};#IF (%yesno(%concat("Add mapping for command ",@PQueueCTemp,"?"))) {PQueueCTemp2=%replace(%prompt("",%concat("Mapping value for '",@PQueueCTemp,"'?")),%char(34),"");#WHILE (%regex(@PQueueCTemp2,"[\-\\|\=\.\?\;\[\]\,\:\(\)\'\{\}/]")) {PQueueCTemp2=%replace(%prompt("",%concat("Previous entry invalid. Mapping value for '",@PQueueCTemp,"'?")),%char(34),"")};#IF (@PQueueCTemp2) {#ADDKEY PQueueMapping {@PQueueCTemp} {%expand(@PQueueCTemp2,1)}}};#ADDKEY PQueueData {@PQueueCTemp} {@PQueueCTemp3}}}
#ALIAS PQueueNewFlag {PQueueCTemp2=%replace(%prompt("","New flag short value?"),%char(34),"");#WHILE (@PQueueCTemp2) {#IF (%regex(@PQueueCTemp2,"[\-\|\ =\.\?\;\[\]\,\:\(\)\'\{\}/]")) {PQueueCTemp2=%replace(%prompt("","Previous entry invalid. New flag short value?"),%char(34),"")} {#IF (%ismember(@PQueueCTemp2,%expanddb(@PQFlagDef,"|","|"))) {PQueueCTemp2=%replace(%prompt("",%concat("'",@PQueueCTemp2,"' already used for '",%item(%expanddb(@PQFlagDef,"|","|"),%eval(%ismember(@PQueueCTemp2,%expanddb(@PQFlagDef,"|","|"))-1)),"'. New flag short value?")),%char(34),"")} {#IF (@PQueueCTemp2!="") {PQueueCTemp3=%concat(@PQueueCTemp3,"|",@PQueueCTemp2);PQueueCTemp2="";#WHILE (@PQueueCTemp2="") {PQueueCTemp2=%replace(%prompt("",%concat("Description of flag '",%item(@PQueueCTemp3,%numitems(@PQueueCTemp3)),"'?")),%char(34),"");#WHILE (%regex(@PQueueCTemp2,"[\-\\|\=\.\?\;\[\]\,\:\(\)\'\{\}/]")) {PQueueCTemp2=%replace(%prompt("",%concat("Description of flag '",%item(@PQueueCTemp3,%numitems(@PQueueCTemp3)),"'?")),%char(34),"")}};#ADDKEY PQFlagDef {@PQueueCTemp2} {%item(@PQueueCTemp3,%numitems(@PQueueCTemp3))}}}};PQueueCTemp2=%replace(%prompt("","New flag short value?"),%char(34),"")}}
#VAR PQueueCTemp {} {}
#VAR PQueueCTemp2 {} {}
#VAR PQueueCTemp3 {} {}
#CLASS 0
#CLASS {PriorityQueue|PQPersistentVars}
#VAR PQueueData {}
#VAR PQueueMapping {}
#VAR PQFlagDef {}
#CLASS 0 |
Here is some sample data I have been testing with for my MUD of choice.
#ADDKEY PQueueData {weathering} {P-100,R-x|A|S,U-,G-,C-0}
#ADDKEY PQueueData {vitality} {P-90,R-e|x|G|N|V|A|S,U-e|V,G-,C-0}
#ADDKEY PQueueData {scs} {P-110,R-e|x|A|S,U-x,G-l|r,C-0}
#ADDKEY PQueueData {sdk} {P-120,R-e|x|A|S,U-x,G-l|r,C-0}
#ADDKEY PQueueData {upc} P-121,R-e|A|S|l,U-l,G-,C-0}
#ADDKEY PQueueData {upc2} {P-122,R-e|A|S|r,U-r,G-,C-0}
#ADDKEY PQueueMapping {sdk} "sdk @target"
#ADDKEY PQueueMapping {upc} "upc @target"
#ADDKEY PQueueMapping {upc2} "upc @target"
#ADDKEY PQFlagDef {equilibrium=e|full balance=x|full health=G|full mana=N|awake=A|standing=S|left arm balance=l|right arm balance=r|vitality balance=V}
Now that allows my script to internally do:
PQueueAdd upc2 sdk upc
PQueueFlags="e|x|A|S"
Target="test"
PQueueDo
To recieive execution of:
sdk test
upc test
upc test
As with most scripts I post it is a work in progress. I wrote the confirmation flag into the data for various commands, but as of yet haven't decided how to make use of it or even when I would need it. All it does so far is stop the queue from sending further commands until the next call of PQueueDo. I guess I will just leave that one open to suggestions. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Sun Mar 05, 2006 8:43 pm |
Editted in 2 updates.
One was a correction to PQueueAdd. I noticed that when I hastily changed it around last night to support multiple parameter additions saving time on the %sort, that I had not shifted everything around the right way. It was causing severe multiple additions and a really nasty delay with adding. Having cleared that up it runs much better.
Next is a huge improvement. I finally figured out a good was to do a list union test with %regex. This allowed that the #WHILE loop that previously worked through the list and did a lot of variable thrashing has been replaced by a single messy %regex in a single #IF. Initial testing after kicking the queue up to 16 items showed the new method to be just about twice as fast as the old. I got a rather consistent 500ms using items that preform flag adjustments and command replacements. So that is a very sizeable improvment over the old which tested around 900ms for the same queue. I am sure I will a few more spots to squeeze out some speed, but the worst offender in the system has been dealt with. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
ZealousAnonymous Wanderer
Joined: 06 Jan 2006 Posts: 70
|
Posted: Mon Mar 06, 2006 10:02 pm |
Another amazing script, as usual. I'll try to make an objective post with ideas later.
|
|
|
|
Vitae Enchanter
Joined: 17 Jun 2005 Posts: 673 Location: New York
|
Posted: Tue Mar 07, 2006 3:35 am |
ummm, can ya actually tell me what the heck this is actually supposed to do?
Tho I'm willing to bet the real answer is, "If ya have to ask, then you don't need it" ";) |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Mar 07, 2006 10:59 am |
Well a queue is like a waiting line at a fast food restaraunt. Firsy come first served. The priority queue is like having someone monitoring that waiting line for the starving people, and telling them they can go first instead. My design also includes status flags, allowing another reasoning layer to skipping commands, kind of like giving that monitor guy the abiltity to see if a person waiting to buy food has enough money.
The way it all works is commands are preregistered either by hand or through the PQueueCreate alias, then as your script wants to do things it can use PQueueAdd to put the commands in the queue. PQueueDo then can be called to execute all the commands possible at that time by the priority sequence specified when the commands were registered. Anything that doesn't meet its flag requirements is skipped.
In the example test data I included 3 commands are used. 2 of them don't actually meet the flag requirements set for them at the time PQueueDo is called. They do qualify though because commands can use up a flag, and also give a flag. So the 'sdk' command uses up the flag 'x' which I called 'full balance', and then gives the flags 'l' and 'r'. This makes the upc and upc2 commands valid as they are tested later based on thier priority.
I hope this helps you to understand the purpose of the script. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Vitae Enchanter
Joined: 17 Jun 2005 Posts: 673 Location: New York
|
Posted: Tue Mar 07, 2006 4:34 pm |
"If ya have to ask, then you don't need it"
*snicker*
Or, I kinda see what you mean, and it's so far above me that I prolly won't use it :-)
But thanks for the explanation! |
|
|
|
Arminas Wizard
Joined: 11 Jul 2002 Posts: 1265 Location: USA
|
Posted: Thu Jan 03, 2008 6:16 pm |
Note: This information is a part of another post that I made in this thread before it was split and part of it was moved over to the CMud forums. Here is a link to that other thread.
For those of you that are intimidated by this script here is a bit more explanation.
The PQueue variable is in the following format.
Skill Name=Priority Number, Balance Requirements [string List], Uses these balances [and thus removes them] [string list], Gives these balances [string list], Keep this item as a priority until it is confirmed [0 or 1] <-<< This last one is not fully implemented and I suggest that you leave it as 0
Example
Vitality=P-90,R-A|e|G|N|S|V|x,U-e|V,G-,C-0
Skill Name: Vitality
Priority Number: 90
Balance Requirements: A|e|G|N|S|V|x
Uses these balances: e|V
Gives these Balances: None
Keep on list:0
Priorities=PriorityN-Skill
Priorities=00090-Vitality
The variable PQueueFlags is a string list that the PQueueDo alias checks for these requirements if a
requirement is not found in this list then the item is not performed and remains in the queue.
The variable PQFlagDef has a list of what each letter represents.
Key=vitality balance
Value=V
Key=awake
Value=A
etc.
The variable PQueueData holds the list of recognized skills and their info.
Key=vitality
Value=P-90,R-e|x|G|N|V|A|S,U-e|V,G-,C-0
key=sdk
Value=P-120,R-e|x|A|S,U-x,G-l|r,C-0
This should look familiar as it is almost the same format as the PQueue variable.
The only difference is that there is no Priorities key.
Finally the PQueueMapping variable.
Key=Skill Name
Value=Skill Long hand command
Example.
Key=sdk
Value=sdk @target |
|
_________________ Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram |
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|