|
wilh Wanderer
Joined: 08 Feb 2001 Posts: 89 Location: USA
|
Posted: Sun Feb 09, 2003 9:19 pm
Potion Mixer Script |
Hey all,
I'd like to begin by saying that while what I'm asking isn't a huge project, it's probably not a small one either. So whoever decides to jump on this will need to spend a bit of time on it. Here's what I'm looking for:
1) On my mud, we can mix potions. Potions are mixed in a flask by putting a number of ingredients into the flask and typing "mix flask." The ingredients that swirl for a bit and possibly churn out a successful potion.
2) Unfortunately, finding out the ingredients to make the potions is tough. There are about 20 ingredients that I know of, more may be added. Each potion may have up to 5 ingredients (that's the most I know of, may be increased later). The ingredients may be five different things, four of one and one of another, or any combination. Consequently, you'll see there are many combinations to test. This is tedious work.
3) I would like a script that will test combinations given the ingredients that I have in my ingredient bag. I keep the flask in my inventory and just need to take the ingredients out of my sack, put them into the flask, mix flask, check results, rinse repeat.
Now for some more details.
a) The ingredients do not have unique identifiers. They have unique strings that I can recognize, but I must address them by 5.ingredient, etc.
b) When looking in my ingredient sack, I see something like this:
a bag (used) :
[2] a funky ingredient
some dead ingredient
a yellow died ingredient
[4] a smelly ingredient that smells awful
etc. So if I want to get the "some dead ingredient" out of the sack, I need to reference 3.ingredient. (The first 2 are "a funky ingredient")
So far my thinking went thusly (which isn't that far...):
A key to this problem is recognizing that some permutations are really the same. A B A is the same as A A B is the same as B A A, etc. So I needed a unique identifier that would explain the combination without dealing with which permutation is involved. What I came up with is this:
For ingredients A B C D E ... Z, I create a string with a single digit number in the place of each letter. Thus 1 0 0 0 0 ... 0 would be the combination that is 1 A and nothing else. 1 0 1 0 0 ... 0 would be 1 A, 1 C and nothing else. I hope that's clear.
From there, create a script that will create combinations that need to be tested. If we assume that nothing is initially know, we could start with all the one ingredient combinations, then the 2 ingredient combinations, etc. These strings could be stored in a variable called untested.
The test algorith grabs the first untested string and does the following:
1) checks to make sure that we have the ingredients necessary to perform the mix. If not, put the combination string in an untestable list for the time being.
2) If we can, grab the ingredients in the combination (and only the ingredients in the combination) and put them in the mixing flask. Mix.
3) If successful, we put the combination is a success list, otherwise in a failure list. Theoretically, there might be a different message that leaves us ambiguous. In that case put it back in the untested list.
4) Iterate accordingly.
I've started this several times, but keep getting bogged down. Perhaps my approach is flawed. Any ideas/suggestions would be greatly appreciated.
Wil
P.S. I'm already aware of the time it will take to iterate through all possibilities, so please don't remind me. ;)
Wil Hunt |
|
|
|
Emit Magician
Joined: 24 Feb 2001 Posts: 342 Location: USA
|
Posted: Sun Feb 09, 2003 10:18 pm |
Does the ingredient ratio change the outcome? i.e. does a mix of ingredients AAAAB equal a mix of ABBBB equal a mix of AABBB etc.?
I think a good solution is going to involve using a new database. You could make the name field as the name of a potion, and have text fields ing1 ing2 ing3 ing4 ing5.
when you make a new potion, add it to the database. I don't know if this would be easier than the string plan you had, but it seems like it would, since we have numerous nice database functions to help us loop through and etc.
so here are the steps i would use:
1) make the database and fields
2) get every ingredient you have in a string list
3) make a parallel string list to hold the depth of each ingredient
4) construct every viable 5 ingrediant permutation into a string list maybe store the name of each permu-string list in yet another string list or an array
5) go through the string lists of permutations in order, checking your database to see if you've tried it yet.
6) if not, mix the potion. you can get it out of the bag by finding the position of the name in the original string list, then getting the number from the depth list that is in the same position.
7) if it turns out to not be a potion, you can still record it in the database as BADPOTION1 or BADPOTION2 etc.
8) get a whole bunch of ingredients and repeat until your database explodes.
--
its been a while since i took discrete math, but it looks like your looking at upwards of 15000 combinations here, so have fun!
--------
moon.icebound.net:9000 |
|
|
|
wilh Wanderer
Joined: 08 Feb 2001 Posts: 89 Location: USA
|
Posted: Sun Feb 09, 2003 10:40 pm |
I'm not following you. Did I mention that my brain stopped working? ;)
Could you provide an example?
Wil
Wil Hunt |
|
|
|
LightBulb MASTER
Joined: 28 Nov 2000 Posts: 4817 Location: USA
|
Posted: Sun Feb 09, 2003 11:34 pm |
The database idea is a good one, Emit. It could actually keep track of almost everything except what ingredients are on hand and what the ingredient descriptions are.
Concept:
- Create a new database (Potions)
- Make fields for
- Combination - alpha
- Tested - Boolean (default false)
- Failed - Boolean (default false)
- Spell - alpha
- Generate a list of possible combinations and create a record for each one (see below)
- As you test combinations, change the "Tested" field to true
- When a combination produces a spell, put the spellname in the "Spell" field
- When a combination fails, change the "Failed" field to true
Combos scripts (I'm sure this can be improved on, but it'll only be needed once...)
#VAR letters {A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T}
#VAR descriptions {a funky ingredient|some dead ingredient|a yellow died ingredient|a smelly ingredient that smells awful|and 16 more}
#LOOP 1,20 {#NEW All|Potions Combination {%item( @letters, %i)}}
#LOOP 1,20 {#NEW All|Potions Combination {A%item( @letters, %i)}}
#LOOP 2,20 {#NEW All|Potions Combination {B%item( @letters, %i)}}
#LOOP 3,20 {#NEW All|Potions Combination {C%item( @letters, %i)}}
.
.
.
#LOOP 19,20 {#NEW All|Potions Combination {S%item( @letters, %i)}}
#NEW All|Potions Combination TT
That takes care of one and two ingredient combos. Three, four, and five ingredient combos will require nesting loops or more complex scripting. Try a search for "combination" or "combo", I've done similar scripts before and I'm sure others have also.
Feel free to alter or expand on the concept/script, I don't feel up to tackling the whole project.
LightBulb
Advanced Member |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Mon Feb 10, 2003 8:52 am |
An interesting problem. After a few hours with a decent amount of testing I have the alias to build a list of combos all set. Also included is capturing of the sac contents and placing it in a list.
To go any further I will need specific command to mix, rinse, get from sac, success and fail indicators, how and you want to record about successes, and how you want to record failures.
As the system I came up with records ingredient names to one list and then just uses numeric keys, a simple conversion routine could be done to spit out human readable mixing directions, but if the list with the names became damaged then all other stored data would become useless. It is a large trade off for speed and memory concerns.
As to memory since all untested combination are being stored in a single list, it could get quite bulky. For 4 distinct ingredients the list is up to 120 combinations, as new ingredients are added that size will double for pretty much each one. At an average of 13 bytes per combination it will take 100MB to store the list for 20 distinct ingredients. Using a database might be preferable, but etither way I know zMud can handle it.
So without further ado the script so far:
#CLASS {PotionMixer}
#ALIAS CreateCombos {#NOOP Combos are stored as a string of indexes;#NOOP each 3 characters in the string corresponds to;#NOOP to an ingredient. As new ingredients;#NOOP are encountered, the combo list will grow.;#NOOP This index storage is slower with a short;#NOOP ingredient list, but will be faster as;#NOOP ingredients are added.;#NOOP This alias creates all the untested combos;#NOOP for the most recently added ingredient.;#NOOP MaxIPerP hold the number of ingredients;#NOOP that can be used in a single potion.;#NOOP if this value is changed then CombosUntested;#NOOP will have to be completely rebuilt;ComboBI=%numitems(@IngredientNames);#LOOP 1,@MaxIPerP {#ADDITEM CombosUntested %concat(%i, %format("&2.0n", @ComboBI))};ComboBI=%concat("0 1","1",%format("&2.0n",%numitems(@IngredientNames)));ComboBI2=1;#NOOP This loop is for multiple ingredients;#WHILE (%eval(%copy(@ComboBI,2,2)<%numitems(@IngredientNames))) {#LOOP 1,%eval(@MaxIPerP-@ComboBI2) {ComboBI=%concat(%i,%copy(@ComboBI,2,2),%right(@ComboBI,3));#ADDITEM CombosUntested @ComboBI};#NOOP Check if we can just increase first ingredient index;#IF (%eval(%copy(@ComboBI,2,2)+1)=%eval(%copy(@ComboBI,5,2))) { #IF (%eval(@ComboBI2+1)<@MaxIPerP) {#NOOP Increased total fixed ingredients and that increase;#NOOP is on new ingredient, reset first ingredient;#ADD ComboBI2 1;ComboBI=%concat(%leftback(@ComboBI,3),%eval(%copy(@ComboBI,%eval(%len(@ComboBI)-2),1)+1),%rightback(@ComboBI,2));ComboBI=%concat("0 1",%right(@ComboBI,3))} {#NOOP Set new ingedient down to 1 and check what else to do;ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,%eval(%len(@ComboBI)-2),1));ComboBI=%concat(%leftback(@ComboBI,3),"1",%rightback(@ComboBI,2));ComboBI=%concat("0 1",%right(@ComboBI,3));ComboBI3=4;#WHILE (@ComboBI3<%eval(%len(@ComboBI)-2)) {#NOOP If we can increase amount of a middle ingredient then we will;#IF (%eval(@ComboBI2+1)<@MaxIPerP) {#ADD ComboBI2 1;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)+1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=99} {#NOOP Try to increase ingredient index;#IF (%eval(%copy(@ComboBI,%eval(@ComboBI3+1),2)+1)!=%eval(%copy(@ComboBI,%eval(@ComboBI3+4),2))) {ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,@ComboBI3,1));ComboBI=%insert(%concat("1",%format("&2.0n",%eval(%copy(@ComboBI,%eval(@ComboBI3+1),2)+1))),%delete(@ComboBI, @ComboBI3,3),@ComboBI3);ComboBI3=99} { #IF (@ComboBI3>4) { #IF (%eval(%copy(@ComboBI,%eval(@ComboBI3-3),1))>1) {#NOOP Move the middle values around a little more and we are done;#ADD ComboBI3 -3;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)-1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);#ADD ComboBI3 3;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)+1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=99} { #ADD ComboBI3 3}} { #ADD ComboBI3 3}}}};#IF (@ComboBI3=%eval(%len(@ComboBI)-2)) {#NOOP Set new ingredient down to 1 and add another ingredient;ComboBI2=%eval(@ComboBI2+2-%copy(@ComboBI,%eval(%len(@ComboBI)-2),1));ComboBI=%concat(%leftback(@ComboBI,3),"1",%rightback(@ComboBI,2));#IF (@ComboBI2>=@MaxIPerP) {#ADD ComboBI3 -3;#WHILE (@ComboBI3>1) { #IF (%eval(%copy(@ComboBI,@ComboBI3,1))>1) {#NOOP Take some away from middle ingredient to add another;ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,@ComboBI3,1));ComboBI=%insert("1",%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=0} { #ADD ComboBI3 -3}};#IF (@ComboBI3) { ComboBI="098 Addition of another ingredient would exceed Max"} {ComboBI=%concat("0 11",%format("&2.0n",2),%right(@ComboBI,3));#IF (%copy(@ComboBI,5,2)=%copy(@ComboBI,8,2)) { ComboBI="099 Add new results in duplicate ingedient"}}} {ComboBI=%concat("0 11",%format("&2.0n",2),%right(@ComboBI,3));#IF (%copy(@ComboBI,5,2)=%copy(@ComboBI,8,2)) { ComboBI="099 Add new results in duplicate ingedient"}}}}} {#NOOP Here we increase the ingredient in the build index;ComboBI=%concat("0",%format("&2.0n",%eval(%copy(@ComboBI,2,2)+1)),%right(@ComboBI,3))}}}
#ALIAS lsac {#T+ SacCapture;look bag}
#VAR IngredientNames {}
#VAR IngredientStock {}
#VAR CombosUntested {}
#VAR CombosTested {}
#VAR MaxIPerP {5}
#VAR ComboBI {} {}
#VAR ComboBI2 {} {}
#VAR ComboBI3 {} {}
#VAR IngredientBag {} {}
#VAR NewIngredients {}
#TRIGGER "SacCapture" {^a bag ~(used~) ~:} {IngredientBag=""} "" {disable}
#COND "SacCapture" {ingredient} {#ADDITEM IngredientBag %replace(%trigger,"[","")} {dur|param=1|disable}
#COND "SacCapture" {*} {#T- SacCapture;#SHOW Bag captured, updating Stock;#FORALL @IngredientBag {#IF (%pos("]",%i)) {ComboBI=%remove("]",%word(%i,1));ComboBI2=%trim(%remove(%word(%i,1),%i))} {ComboBI=1;ComboBI2=%i};ComboBI3=%ismember(@ComboBI2,@IngredientNames);#IF (@ComboBI3=0) {#ADDITEM NewIngredients {@ComboBI2};ComboBI3=%eval(%numitems(@NewIngredients)+%numitems(@IngredientNames))};#ADDITEM IngredientStock {%concat(@ComboBI," ",@ComboBI3)}};#IF (@NewIngredients) {#SHOW %numitems(@NewIngredients) new ingredients found, adding combos.;#WHILE (@NewIngredients) {#ADDITEM IngredientNames {%pop(NewIngredients)};CreateCombos}};#SHOW Stock detection complete.} {disable}
#CLASS 0 |
|
|
|
wilh Wanderer
Joined: 08 Feb 2001 Posts: 89 Location: USA
|
Posted: Tue Feb 11, 2003 7:45 am |
Thanks,
I think we're getting closer. I'm afraid I may have overgenerelized the case in my description. The ingredients when I look at them may not have the word "ingredient" in them, nor any other keyword. Though when I go to manipulate them, I can use the ingredient keyword to access them. I apologize for the confusion.
I'll keep looking through what you've come up with. I'm currently logged on as a different character on the mud now, so can't answer your other questions specifically. I can tell you, however, that I have those things already in place. So if you give me a script that is mixSuccessHandler or mixFailureHandler, etc., I can call them appropriately.
Thanks again for all your time.
Wil
Wil Hunt |
|
|
|
alptraum Newbie
Joined: 10 Feb 2003 Posts: 6 Location: Canada
|
Posted: Tue Feb 11, 2003 8:09 am |
whats the muds address with that your trying to build this script for, it definately sounds neat and i wouldn't mind seeing this in action. please post the address here or drop it my way in an email thanks alot.
|
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Feb 12, 2003 12:26 am |
Your post did not answer any of my questions.
About all it told me is that using the word ingredient for the conditional trigger is not good. This means that trigger will have to be tweaked with an appropiate word list if you don't want garbage to be caught.
I have done some further thinking on the math of the situation and arrived at the conclusion that for x distinct ingredients you will have (2^(x+2)-x-1)*5 combinations. For 26 ingredients that figures as 1342177150 combinations. So I would recommend that you keep new ingredients in a seperate bag. Only when you have finished testing all those currently in the list should you add a new ingredient to the mixer bag and build a new list.
As to actual script I can easily write something to automatically test combinations until you run out of ingredients. I can not write something to record successes until I know what you want to record about them.
I would recommend you simply not record anything about failures. The reason being that my initial estimate of memory usage was very short. For the 26 ingredients example above the actual memory usage to store the whole combination list would be about 18GB. That being considered the script that I posted likely has to be revised to put the created data directly into a file. I will need to know if you want to proceed in that direction. If you do then I will need to know how many maximum distinct ingredients to code for. If that number is under 16 I can get the file size down dramatically.
Which brings me to the next problem irregadless of whether the script directly writes to a file or the settings file is simply saved as normal; that problem is what is the format of the drive your writing to. If you are running Win 95, 98, or ME then it is definitely FAT32 and will not support a file over 4GB in size. If your running 2K or XP it may still be FAT32. So I will need to know if I have to overcome that as well. |
|
|
|
wilh Wanderer
Joined: 08 Feb 2001 Posts: 89 Location: USA
|
Posted: Thu Feb 13, 2003 12:13 am |
Vigilante,
In answer to a couple of your questions...
1) I'm using FAT32 on Win2K and XP Pro. I can give about 5GB to this problem if necessary.
2) There are 17 ingredients that I'm aware of in game play at the moment. There are at least 20 more that are referenced in the books and thus might be added later.
Further, at this time, only about 10-20 combinations will actually yield a successful result. Consequently, it might be better to avoid using discrete storage and instead break the problem into blocks that can be looked at individually. For example, if the same algorithm is used for generating the possibilities, we could generate a few hundred at a time, test them and store the false result for the whole group. Thus we could have false groups....
1-567 no result
568 success: blah blah potion
569 - 600 no result
601+ untested
etc. Presumably the algorithm would be able to start generating combinations at any point. This would greatly reduce the amount of memory required to do the problem.
I'm sure I didn't answer all your questions... I'll continue looking into it.
Wil
Wil Hunt |
|
|
|
Emit Magician
Joined: 24 Feb 2001 Posts: 342 Location: USA
|
Posted: Thu Feb 13, 2003 3:14 am |
well, as i said before, it has been a while since i took any sort of combinatorial math class, but i will go ahead and weigh in on the number of combinations (assuming 20 ingredients exist):
for potions with 1 ingredient there are 20 possibilities. For potions with 2 ingredients there are 20^2 possibilities. For potions with 3 ingredients, 20^3, and so on. Extending this on out we get
20+20^2+20^3+20^4+20^5=3368420
and this doesn't account for the fact that a potion of: AAB is equal to ABA
at 13 bytes per combo thats about 41 some odd MB
I hope that helps a little! I'm still interested to know if the ratio of the ingredients changes the outcome, i.e. does a mix of AAAAB yield the same as a mix of BBBBA?
--------
moon.icebound.net:9000 |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Thu Feb 13, 2003 6:21 am |
The blocking idea is a good one so I put that in. I started fleshing some prototypes out for the actual mixing. Cleaned up the bag capture trigger to detect all possible names, it now uses a blank line for end of sack contents, just tell me if that needs to be changed too. I also added a toggling guage button. It is something Zugg never meant to have doable so it is a little tweaky but seems stable.
To proceed further I would really like to have some hard mud text showing mix commands and results.
And since it is way past my weekday bed time:
#CLASS {PotionMixer}
#ALIAS CreateCombos {#NOOP Combos are stored as a string of indexes;#NOOP each 3 characters in the string corresponds to;#NOOP to an ingredient. As new ingredients;#NOOP are encountered, the combo list will grow.;#NOOP This index storage is slower with a short;#NOOP ingredient list, but will be faster as;#NOOP ingredients are added.;#NOOP This alias creates all the untested combos;#NOOP for the most recently added ingredient.;#NOOP MaxIPerP hold the number of ingredients;#NOOP that can be used in a single potion.;#NOOP if this value is changed then CombosUntested;#NOOP will have to be completely rebuilt.;#NOOP ComboBl holds current high and low for block.;#IF (%numparam=0) { #IF (@ComboBl="") {#SHOW Must have a combo block set or use numeric parameter to indicate size of first block.;ComboBI=0} { #IF (@CombosUntested!="") {#SHOW Untested combos still pending, please flush manually to generate next block.;ComboBI=0} { #IF (%item(@ComboBL,2)=%item(@ComboBL,3)) {#SHOW All Combos for current ingredients have been tested.;ComboBI=0} {ComboBL=%concat(%eval(%number(%item(@ComboBL,2))+1),"|",%min(%eval(%number(%item(@ComboBL,2))-%number(%item(@ComboBL,1))+1),%item(@ComboBL3)),"|",%item(@ComboBL3));ComboBI=1}}}} { #IF (@ComboBl!="") {#SHOW ComboBl indicates block pending please flush manually prior to generating new block.;ComboBI=0} { #IF (%number(%1)=%null) {#SHOW Please call with a number indicating how many combo to generate in first block.;ComboBI=0} {ComboBl=%concat("1|",%1);CalcMaxCombos;ComboBL=%additem(@ComboBL,%min(@ComboBI3,%item(@ComboBL,2)));ComboBI=1}}};#IF (@ComboBI) {ComboCnt=1;ComboBI=%numitems(@IngredientNames);#LOOP 1,@MaxIPerP { #IF ((@ComboCnt>=%number(%item(@ComboBl,1)))&(@ComboCnt<=%number(%item(@ComboBl,2)))) {#ADDITEM CombosUntested %concat(%i, %format("&2.0n", @ComboBI));#ADD ComboCnt 1} { #ADD ComboCnt 1}};ComboBI=%concat("0 1","1",%format("&2.0n",%numitems(@IngredientNames)));ComboBI2=1;#NOOP This loop is for multiple ingredients;#WHILE ((%eval(%copy(@ComboBI,2,2)<%numitems(@IngredientNames)))&(@ComboCnt<=%number(%item(@ComboBl,2)))) {#LOOP 1,%eval(@MaxIPerP-@ComboBI2) { #IF ((@ComboCnt>=%number(%item(@ComboBl,1)))&(@ComboCnt<=%number(%item(@ComboBl,2)))) {ComboBI=%concat(%i,%copy(@ComboBI,2,2),%right(@ComboBI,3));#ADDITEM CombosUntested @ComboBI;#ADD ComboCnt 1} { #ADD ComboCnt 1}};#NOOP Check if we can just increase first ingredient index;#IF (%eval(%copy(@ComboBI,2,2)+1)=%eval(%copy(@ComboBI,5,2))) { #IF (%eval(@ComboBI2+1)<@MaxIPerP) {#NOOP Increased total fixed ingredients and that increase;#NOOP is on new ingredient, reset first ingredient;#ADD ComboBI2 1;ComboBI=%concat(%leftback(@ComboBI,3),%eval(%copy(@ComboBI,%eval(%len(@ComboBI)-2),1)+1),%rightback(@ComboBI,2));ComboBI=%concat("0 1",%right(@ComboBI,3))} {#NOOP Set new ingedient down to 1 and check what else to do;ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,%eval(%len(@ComboBI)-2),1));ComboBI=%concat(%leftback(@ComboBI,3),"1",%rightback(@ComboBI,2));ComboBI=%concat("0 1",%right(@ComboBI,3));ComboBI3=4;#WHILE (@ComboBI3<%eval(%len(@ComboBI)-2)) {#NOOP If we can increase amount of a middle ingredient then we will;#IF (%eval(@ComboBI2+1)<@MaxIPerP) {#ADD ComboBI2 1;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)+1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=99} {#NOOP Try to increase ingredient index;#IF (%eval(%copy(@ComboBI,%eval(@ComboBI3+1),2)+1)!=%eval(%copy(@ComboBI,%eval(@ComboBI3+4),2))) {ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,@ComboBI3,1));ComboBI=%insert(%concat("1",%format("&2.0n",%eval(%copy(@ComboBI,%eval(@ComboBI3+1),2)+1))),%delete(@ComboBI, @ComboBI3,3),@ComboBI3);ComboBI3=99} { #IF (@ComboBI3>4) { #IF (%eval(%copy(@ComboBI,%eval(@ComboBI3-3),1))>1) {#NOOP Move the middle values around a little more and we are done;#ADD ComboBI3 -3;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)-1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);#ADD ComboBI3 3;ComboBI=%insert(%eval(%copy(@ComboBI,@ComboBI3,1)+1),%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=99} { #ADD ComboBI3 3}} { #ADD ComboBI3 3}}}};#IF (@ComboBI3=%eval(%len(@ComboBI)-2)) {#NOOP Set new ingredient down to 1 and add another ingredient;ComboBI2=%eval(@ComboBI2+2-%copy(@ComboBI,%eval(%len(@ComboBI)-2),1));ComboBI=%concat(%leftback(@ComboBI,3),"1",%rightback(@ComboBI,2));#IF (@ComboBI2>=@MaxIPerP) {#ADD ComboBI3 -3;#WHILE (@ComboBI3>1) { #IF (%eval(%copy(@ComboBI,@ComboBI3,1))>1) {#NOOP Take some away from middle ingredient to add another;ComboBI2=%eval(@ComboBI2+1-%copy(@ComboBI,@ComboBI3,1));ComboBI=%insert("1",%delete(@ComboBI,@ComboBI3,1),@ComboBI3);ComboBI3=0} { #ADD ComboBI3 -3}};#IF (@ComboBI3) { ComboBI="098 Addition of another ingredient would exceed Max"} {ComboBI=%concat("0 11",%format("&2.0n",2),%right(@ComboBI,3));#IF (%copy(@ComboBI,5,2)=%copy(@ComboBI,8,2)) { ComboBI="099 Add new results in duplicate ingedient"}}} {ComboBI=%concat("0 11",%format("&2.0n",2),%right(@ComboBI,3));#IF (%copy(@ComboBI,5,2)=%copy(@ComboBI,8,2)) { ComboBI="099 Add new results in duplicate ingedient"}}}}} {#NOOP Here we increase the ingredient in the build index;ComboBI=%concat("0",%format("&2.0n",%eval(%copy(@ComboBI,2,2)+1)),%right(@ComboBI,3))}}}}
#ALIAS CalcMaxCombos {ComboBI2=%numitems(@IngredientNames);ComboBI3=1;#WHILE (@ComboBI2) {ComboBI3=%eval(@ComboBI3*2);#ADD ComboBI2 -1};ComboBI3=%eval((@ComboBI3-1)*5)}
#ALIAS lsac {#T+ SacCapture;look bag}
#VAR IngredientNames {}
#VAR IngredientStock {3 1|1 4|1 1|4 2}
#VAR CombosUntested {}
#VAR MaxIPerP {5}
#VAR ComboBI {} {}
#VAR ComboBI2 {} {}
#VAR ComboBI3 {} {}
#VAR IngredientBag {} {}
#VAR NewIngredients {}
#VAR ComboBL {}
#VAR ComboCnt {} {}
#TRIGGER "SacCapture" {^a bag ~(used~) ~:} {IngredientBag=""} "" {disable}
#COND "SacCapture" {} {#IF (%line!="") { #ADDITEM IngredientBag %replace(%line,"[","")} {#STATE SacCapture 2;#SET SacCapture 2 1}} {looplines|param=99|disable}
#COND "SacCapture" {} {#ALARM {+1} {#T- SacCapture};#SHOW Bag captured, updating Stock;IngredientStock="";#FORALL @IngredientBag {#IF (%pos("]",%i)) {ComboBI=%remove("]",%word(%i,1));ComboBI2=%trim(%remove(%word(%i,1),%i))} {ComboBI=1;ComboBI2=%i};ComboBI3=%ismember(@ComboBI2,@IngredientNames);#IF (@ComboBI3=0) {ComboBI3=%ismember(@ComboBI2,@NewIngredients);#IF (@ComboBI3=0) {#ADDITEM NewIngredients {@ComboBI2};ComboBI3=%eval(%numitems(@NewIngredients)+%numitems(@IngredientNames))}};#ADDITEM IngredientStock {%concat(@ComboBI," ",@ComboBI3)}};#IF ((@NewIngredients!="")&(@ComboBl="")) {#SHOW %numitems(@NewIngredients) new ingredients found, adding combos.;#ADDITEM IngredientNames {%pop(NewIngredients)};CreateCombos 1000};#SHOW Stock detection complete. %if(@NewIngredients,New ingredients still pending)} {manual|disable}
#CLASS 0
#CLASS {PotionMixer|DoMixes} {disable}
#ALIAS GrabItems {#NOOP Issue get item commands, make triggers to confirm each grab}
#ALIAS SelectCombo {ComboBI=1;#WHILE (%item(@CombosUntested,@ComboBI)) {ComboSel=%item(@CombosUntested,@ComboBI);ComboIngredients=%repeat("|",%eval(%numitems(@IngredientNames)-1));ComboBI2=1;#WHILE (@ComboBI2<%len(@ComboSel)) {ComboIngredients=%replaceitem(%copy(@ComboSel,@ComboBI2,1),%number(%copy(@ComboSel,%eval(@ComboBI2+1),2)),@ComboIngredients);#ADD ComboBI2 3};ComboBI2=1;#WHILE (@ComboBI2) { #IF (%number(%item(@ComboIngredients,@ComboBI2))<=%number(%item(@IngredientMixer,@ComboBI2))) { #ADD ComboBI2} { ComboBI2=0}};#IF (@ComboBI2) {ComboBI=0} {ComboSel=""}}}
#ALIAS StartMixing {IngredientMixer=%repeat("|",%eval(%numitems(@IngredientStock)-1));#FORALL @IngredientStock { IngredientMixer=%replaceitem(%word(%i,1),%number(%word(%i,2)),@IngredientMixer)};SelectCombo;#IF (@ComboSel!="") {GrabItems;MixPotion} {#SHOW Could not find a combination testable with current ingredient stock.;EndMixing}}
#ALIAS EndMixing {#NOOP UpdateIngredientStock;MixerMode=0}
#ALIAS MixPotion {#NOOP Issue mix commands, activate triggers for success and fail}
#ALIAS SaveResult {#NOOP DeleteItem from untested}
#VAR IngredientMixer {} {}
#VAR ComboSel {} {}
#VAR ComboIngredients {} {}
#CLASS 0
#CLASS {PotionMixer|MixerButton} {enable}
#VAR MixerMode {0} {0}
#BUTTON 0 {Mixer} {#T+ DoMixes} {Mixing} {#T- DoMixes} {%eval(%number(%item(@ComboBL,2))%if(@MixerMode,"-%numitems(@CombosUntested)")} {MixerMode} {} {} {} {} {} {} {} {32880} {32832} {Gauge||12|%number(%item(@ComboBL,2))||9} {} "" {Explore|Inset} {} {MixButton}
#CLASS 0 |
|
|
|
|
|
|
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
|
|