• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Need Help with VJASS script

Status
Not open for further replies.
Level 13
Joined
May 24, 2005
Messages
601
Hey there,

So I have a vjass library that throws an error but due to my absense and blackout I cannot handle to fix it on my own.

Here is the code:

JASS:
library Pool
//******************************************************************************
//* BY: Rising_Dusk
//*
//* This script gives the user access to general integer pools. A pool is a data
//* structure that allows you to give entries to it a weight. This weight
//* essentially scales how likely certain random accesses to the pool will be
//* returned by the internal .getRandomInt method. Pools can be useful in any
//* number of ways, such as item drops, randomizing enemy encounters, randomly
//* selecting rects weighted by area, and so forth.
//*
//* Modified by Moco [2013-04-12]:
//*   - Fixed a critical issue with the RemoveInt function not properly updating the hashtable
//*   - Added a flush method to clear the whole pool
//*
//******************************************************************************
//*
//* Example usage:
//*    local intpool ip = intpool.create()
//*    call ip.addInt(1, 1.0)
//*    call ip.addInt(2, 0.5)
//*    call ip.getRandomInt()
//*    call ip.getChance(2)
//*    call ip.getWeight(2)
//*    call ip.removeInt(1)
//*
//* You will first need to create an intpool as shown above. Once you've done
//* that, you may use the .addInt method to add an entry to the pool with a
//* specific weight. The example above adds 2 integers, one twice as likely to
//* be randomly selected as the other. That means for the above example, the
//* .getRandomInt method will 66% of the time return 1 and 33% of the time
//* return 2. If you want to remove an entry from an intpool, the .removeInt
//* method is what you will want to use. If you would like to update an entry's
//* weight after already adding it, simply use .addInt again with the new
//* weight.
//*
//* The .getChance and .getWeight methods are there for convenience. If you are
//* interested in the exact chance of the intpool returning a specific entry,
//* then you should use .getChance to obtain the decimal chance out of 1. If you
//* want to know the weight input for a specific entry, .getWeight will return
//* that for you.
//*
//* When adding an entry to the intpool with .addInt, the actual magnitude of
//* the weight doesn't matter. What matters is its magnitude relative to the
//* magnitudes of all other entries in the intpool. This means that it is ok to
//* use very large or very small weights and is done at the user's discretion.
//*
//* It is worth noting that if you use .getRandomInt on an intpool with no
//* entries, the function will return INTPOOL_NO_ENTRIES, which is about as
//* random an integer as possible so as to avoid people accidentally using it.
//*
globals
    //These constants can be changed
    private constant integer MAX_INSTANCES         = 8191
    private constant integer MAX_ENTRIES           = 256
            constant integer INTPOOL_NO_ENTRIES    = 0x672819
          
    //Don't change the following global declaration
    private hashtable ht = InitHashtable()
endglobals

struct intpool[MAX_INSTANCES]
    private integer Cnt         = 0
    private real    WeightTotal = 0.
    private integer array Entries[MAX_ENTRIES]
    private real    array Weights[MAX_ENTRIES]
    private string name = " " // pool name for debug
  
    method getWeight takes integer entry returns real
        return Weights[LoadInteger(ht, integer(this), entry)]
    endmethod
  
    method getChance takes integer entry returns real
        if WeightTotal > 0. then
            return Weights[LoadInteger(ht, integer(this), entry)]/WeightTotal
        endif
        return 0.
    endmethod

  
method addInt takes integer entry, real weight returns nothing
local integer in = LoadInteger(ht, integer(this), entry)



if .Cnt == MAX_ENTRIES then
//Can't hold any more entries
debug call BJDebugMsg(SCOPE_PREFIX+"Error: .addEntry has reached MAX_ENTRIES")
endif



if weight <= 0 then

//Zero or negative weights make no sense
debug call BJDebugMsg(SCOPE_PREFIX+"Error: .addEntry can't take zero or negative weights (" +.name+")")

endif

eif in > 0 then

//Update old entry
set .WeightTotal = .WeightTotal - .Weights[in] + weight
set .Weights[in] = weight
//    debug call BJDebugMsg(SCOPE_PREFIX+"Pool updated existing entry: "+I2S(entry))

//else

//Make a new entry
set .Cnt           = .Cnt + 1
call SaveInteger(ht, integer(this), entry, .Cnt)
set .Entries[.Cnt] = entry
set .Weights[.Cnt] = weight
set .WeightTotal   = .WeightTotal + weight
//   debug call BJDebugMsg(SCOPE_PREFIX+"Pool New Entry: "+I2S(entry))
endif

// debug call BJDebugMsg("Pool added value: "+I2S(entry)+" with weight: "+R2S(weight))
endmethod
  
  
  
  
  
method flush takes nothing returns nothing
local integer c = 0
call FlushChildHashtable(ht, integer(this))
        loop
            exitwhen c > Cnt
            set .Entries[.Cnt] = 0
            set .Weights[.Cnt] = 0
            set c = c + 1
        endloop
        set .WeightTotal = 0
        set .Cnt         = 0
    endmethod
  
    method showEntries takes nothing returns nothing
        local integer c = 1
        call BJDebugMsg(" Pool count: "+I2S(Cnt))
        loop
            exitwhen c > Cnt
            call BJDebugMsg("Pool entry #"+I2S(c)+ ": "+I2S(.Entries[c]))
            set c = c + 1
        endloop
    endmethod
  
    method removeInt takes integer entry returns nothing
        local integer in = LoadInteger(ht, integer(this), entry)
        if in > 0 then
            call RemoveSavedInteger(ht, integer(this), entry)
          
            //Remove its entry in the arrays
            set .WeightTotal = .WeightTotal - .Weights[in]
          
            if in != .Cnt then         
                set .Entries[in] = .Entries[.Cnt]
                set .Weights[in] = .Weights[.Cnt]
                call SaveInteger(ht, integer(this), .Entries[in], in)
            endif
            set .Entries[.Cnt] = 0
            set .Weights[.Cnt] = 0
            set .Cnt         = .Cnt - 1
          
            if .Cnt == 0 then
                call this.flush()
            endif
        debug else
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: .removeEntry entry doesn't exist")
        endif
    endmethod
  
    method getRandomInt takes nothing returns integer
        local real    r = GetRandomReal(0, .WeightTotal)
        local integer c = 0
        if .WeightTotal <= 0. then
            debug call BJDebugMsg(SCOPE_PREFIX+"Error: intpool has no entries (" +.name+")")
            return INTPOOL_NO_ENTRIES
        endif
        set r = GetRandomReal(0, .WeightTotal) // Double Random
        loop
            set r = r - .Weights[c]
            exitwhen r <= 0
            set c = c + 1
        endloop
        return .Entries[c]
    endmethod
  
    method setName takes string name returns nothing
        set this.name = name
    endmethod
  
endstruct
endlibrary
 
Last edited by a moderator:
Status
Not open for further replies.
Back
Top