Page 2 of 8 FirstFirst 1 2 3 4 ... LastLast
Results 11 to 20 of 80

Thread: Rethinking Candy

  1. #11
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    Yeah, -1 for "not a candy" is good.

    Also, CandyDatabase will have 4 item sets:

    tier0Candy - every "candy"
    tier1Candy - every "candy1"
    tier2Candy - every "candy1" and "candy2"
    tier3Candy - every "candy2"

    As well as a "canonical name array" built from tier2Candy, which can be used for "fuzzy matching" of all candy items.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  2. #12
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    Actually, given that:

    string ITEM.candy_tier -> "none", "unspaded", "simple", "complex"
    int EFFECT.candy_tier -> 0, 1, 2, 3 -> "not usable for synthesis", "tier 1 synthesis", "tier 2 synthesis", "tier 3 synthesis"
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  3. #13
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,163

    Default

    string ITEM.candy_tier -> "none", "unspaded", "simple", "complex"
    Originally Posted by Veracity View Post
    I'd prefer to keep the proxy record as an int. -1, 0, 1, 2. Because I find integers easier to work with, but I could adapt if you really prefer strings.
    If people like my scripts, please send me stuffed Hodgmen.
    Universal Recovery, OCD Inventory Control, CounterChecker, newLife, ChIT.


  4. #14
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    I don't feel strongly, but I'm wondering how your program would use the item's "candy tier" rather than the effect's "candy tier".

    If you use candy_tier() to get an array of candidates, you are passing in an effect's "candy_tier".
    If you use candy_synthesis_pairing() to get an array of candidates, you are passing in an effect (in effect, an effect "candy_tier") and a candy.

    I guess if you are writing a script to manipulate raw items before the phase 3 ASH functions come in, you might prefer a number in the item's candy_tier. But, once phase 3 is done, why will you need to look at that proxy field in the item?
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  5. #15
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,163

    Default

    I agree that any script is more likely to use the functions rather than checking raw item data. I'll probably never use the proxy record, but if I was to use the proxy record, the integer would be easier.

  6. #16

    Default

    If no script is going to use candy_tier, then maybe it doesn't need to exist?

  7. #17
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    Good point.

    If a skill has a "candy tier" and items do not and the candy_tier( int tier ) method exists to return a set of items that can be used to get you that "tier" of effect, seems like scripts are being directed to use the tools that are available to make their life easy.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  8. #18
    Minion Bale's Avatar
    Join Date
    Jun 2008
    Posts
    13,163

    Default

    Yay! No redundant proxy record needed!

  9. #19
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    OK, here is the updated phase 1-5 development plan. I'll probably start on it tomorrow.
    Phases 1-3 should be straightforward.
    Phase 4 is GUI work - my non-forte - including things I haven't done before.
    Phase 5 requires a little research, although Ezandora's script is inspiring; simply choosing the cheapest total mall price for the two required candies will probably end up being really cheap, modulo major mall manipulation.

    And the "synthesize" command and SynthesizeRequest have to remember that doing this uses a spleen...

    ******Phase 1******

    Candy data.

    - tag "candy" items in items.txt as:

    candy - unspaded
    candy1 - "simple" candy
    candy2 - "complex candy

    lost did this. Thank you!

    - when ItemDatabase parses items.txt, for any of the above, it calls CandyDatabase to register it.

    CandyDatabase has four Sets of itemIds:

    Set<Integer> tier0Candy - all "unspaded" candies
    Set<Integer> tier1Candy - all "simple" candies
    Set<Integer> tier2Candy - all "simple" and "complex" candies
    Set<Integer> tier3Candy - all "complex" candies

    CandyDatabase also has:

    String [] canonicalNames

    which is a sorted array of canonical names of everything in tier2Candy, which is what is needed to add a CANDY_MATCH filter to persistence/ItemFinder for fuzzy matching candy.

    - ASH $item proxy:

    boolean ITEM.candy -> true if any candy

    Effect data.

    - ASH $effect proxy:

    int EFFECT.candy_tier -> 0, 1, 2, 3

    0 = not a candy synthesis effect
    1 = simple, simple
    2 = simple, complex
    3 = complex, complex

    - "checkcandy" command

    Simply lists everything in CandyDatabase.tier0Candy

    - "checkitems" command

    When we see that the description says an item is a candy, allow "candy", "candy1" or "candy2".
    ItemDatabase generates the "item line" for candy with candy, candy1, candy2, as appropriate

    - "test newitem" (and hence ItemDatabase.registerItem)

    For candy items, enter into CandyDatabase

    The above has all the "data" we will need and exposes some of it to ASH

    ******Phase 2******

    Using the skill.

    - SynthesizeRequest does what is necessary to cast the skill and handle inventory.

    - CLI commands in SynthesizeCommand:

    These use fuzzy matching on "candy" items via ItemFinder's CANDY_MATCH filter.

    synthesize CANDY1, CANDY2

    "acquires" CANDY1 and CANDY2 and uses the skill, if acquisition succeeds

    synthesize? CANDY1, CANDY2

    tells you which effect this combination of candy will produce
    and
    for each of CANDY1, CANDY2:
    -- how many are "easily accessible" (no mall or clan)
    -- mall price
    -- simulated result of "acquire": fail, use, pull from storage, take from closet, buy, whatever
    and
    result of attempting skill:
    FAIL - you cannot acquire (at least) one candy
    SUCCEED - and total "value" of the two ingredients, even if you use one or both from what you already own.

    - ASH functions in RuntimeLibrary:

    boolean candy_synthesis( item candy1, item candy2 )

    Does retrieve_item() on candy1 and candy2, casts the skill, and returns true - or false, if failed to retrieve. The equivalent of the "synthesize" command.

    effect candy_synthesis_result( item candy1, item candy2 )

    The "simulated" result of doing the above - either the resulting effect, if it would succeed, or $effect[ none ] if retrieval would fail

    This phase will allow people to use Ezandora's tool to explore options and then make it so via KoLmafia.

    ******Phase 3******

    ASH support in RuntimeLibrary using internal functions in CandyDatabase:

    item [int] candy_for_tier( int tier )

    Returns an array of all candy in tier 1, 2, or 3 (or 0, if you want to spade). Note that "tier 1" is all "simple" candies and "tier 3" is all "complex" candies.
    This will be ordered randomly.

    You could do the following:

    item [int] candy = candy_for_tier( 1 );
    sort candy by -available_amount( value );
    ... to sort by high-to-low "easily available count"
    sort candy by mall_price( value );
    ... to sort by low-to-high "mall price"

    item [int] candy_synthesis_pairing( effect eff, item candy1 )

    Returns an array of all candy that will synthesize with candy1 to produce eff. The array can be empty if you ask for a tier 1 effect and give it a complex candy or ask for a tier 3 effect and give it a simple candy.

    This is probably all the ASH support needed to write a smart script which will get you the desired effect "cheaply".

    ******Phase 4******

    A panel in the Item Manager to let you do this.

    At the top:

    3 rows of 5 buttons each: the Tier 1, Tier 2, and Tier 3 effects:

    Beneath:

    Two (blank) text panes: Candy A and Candy B

    At the Right:

    (Disable) "Synthesize!" button

    Candy A
    Have:
    Cost:

    Candy B:
    Have:
    Cost:

    When you press one of the 15 Effect buttons, it highlights.
    The Candy A pane fills with a table of candies, populated based on the Effect tier
    Each row has three columns:
    Name
    Count
    Cost

    As is usual for such tables in KoLmafia, click on the column head to sort on that column

    If you press another Effect button, the previous one unhighlights (and the table clears) and the new one highlights and replaces the Candy A table.

    If you select a candy in the Candy A table, the Candy B table fills with a table of all candies that will synthesize with the selected candy to produce the desired effect. As expected, you can sort on the three columns there, two. Additionally, the Have and Cost fields in the right for Candy A will have numbers.

    If you select a different candy in Candy A, the Candy B table and the Candy A data in the right change appropriately.

    If you select a candy in Candy B, the Candy B values in the right are filled in and the Synthesize! button is enabled.
    If you deselect the candy, the values are cleared and the button is disabled.

    If you click on the Synthesize! button, it acquires Candy A and Candy B and synthesizes the desired effect.

    ******Phase 5******

    Allow automatic generation of the effect, as requested:

    CLI command:

    synthesize EFFECT
    synthesize? EFFECT

    Use an algorithm to calculate the "cheapest" two candies to use to get the desired effect. And yes, some people will want to consider "candy in inventory" to be worth 0 and some will want to consider it to be worth the mall price. Same old controversy.

    (Ezandora's script uses only candies in inventory if in Ronin or Hardcore and always buys from the mall otherwise. That's not a bad model.)

    If we add "synthesize EFFECT" to the various effects in statuseffects.txt:

    - "up EFFECT" uses that command
    - Therefore, up arrows in the charpane will work
    - You can put it in a mood
    - You can use it with the maximizer

    All of the above will have to be taught that it takes a spleen...

    ******
    Last edited by Veracity; 12-29-2016 at 11:17 PM.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

  10. #20
    Developer Veracity's Avatar
    Join Date
    Mar 2006
    Location
    The Unseelie Court
    Posts
    10,832

    Default

    Revision 17612 does Phase 1 and half of Phase 3.

    1) When we parse items.txt, "candy", "candy1", and "candy2" items are registered with CandyDatabase, which has data structures and methods that are useful elsewhere.

    2) Items have a string candy_type proxy record field:

    Code:
    > ash $item[ cool whip ].candy_type
    
    Returned: none
    
    > ash $item[ hard rock candy ].candy_type
    
    Returned: unspaded
    
    > ash $item[ Angry Farmer candy ].candy_type
    
    Returned: simple
    
    > ash $item[ sugar sheet ].candy_type
    
    Returned: complex
    3) Effects have an int candy_tier proxy record field:

    Code:
    > ash $effect[ Synthesis: Greed ].candy_tier
    
    Returned: 3
    
    > ash $effect[ Synthesis: Pungent ].candy_tier
    
    Returned: 1
    
    > ash $effect[ Synthesis: Smart ].candy_tier
    
    Returned: 2
    
    > ash $effect[ Got Milk ].candy_tier
    
    Returned: 0
    4) ASH now has a function to return all the candy in a tier:

    item [int] candy_for_tier( int tier )

    Code:
    > ash candy_for_tier( 0 )
    
    Returned: aggregate string [1]
    0 => hard rock candy
    
    > ash candy_for_tier( 1 ).count()
    
    Returned: 66
    
    > ash candy_for_tier( 2 ).count()
    
    Returned: 214
    
    > ash candy_for_tier( 3 ).count()
    
    Returned: 148
    Note that this is not convenient to check if a given candy is in a tier; you can't say "candy_for_tier( 1 ) contains $item[ Angry Farmer candy ]", for example. Instead, you'd say "$item[ Angry Farmer candy ].candy_type == "simple"". This is an array that you can use with "sort by" to order by mall price, quantity on hand, or what have you.

    5) The "checkcandy" command will list all unspaded candy (with no argument) or will tell you the candy type of the specified candies. (That last was primarily to be able to test the CANDY_MATCH filter):

    Code:
    > checkcandy
    
    ***Unspaded candy: hard rock candy
    
    > checkcandy angry farmer candy, sugar sheet
    
    Angry Farmer candy: simple
    sugar sheet: complex
    
    > checkcandy cool whip
    
    [cool whip] is not candy.
    6) The "item string" generated by ItemDatabase now correctly includes "candy", "candy1", or "candy2", as appropriate.
    Ph'nglui mglw'nafh Cthulhu
    R'lyeh wgah-nagl fhtagn.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •