| 02-06-2011, 02:37 AM | #1 |
Very simple base script that handles the creation of and conversion between bases. JASS:library Base /* v1.0.0.2 ************************************************************************************* * * A script used for base conversion where integers are represented as strings in * another base. * ************************************************************************************ * * struct Base extends array * * static method operator [] takes string base returns Base * * method convertToString takes integer i returns string * method convertToInteger takes string i returns integer * * method ord takes string c returns integer * method char takes integer i returns string * *************************************************************************************/ /************************************************************************************* * * Code * *************************************************************************************/ globals private hashtable t = InitHashtable() private integer c = 0 private integer array s endglobals struct Base extends array static method operator [] takes string base returns thistype local integer value = StringHash(base) local thistype this = LoadInteger(t, 0, value) local string char if (this == 0) then set c = c + 1 set this = c call SaveInteger(t, 0, value, this) set value = StringLength(base) set s[this] = value loop set value = value - 1 set char = SubString(base, value, value+1) if (char == StringCase(char, true)) then call SaveInteger(t, this, StringHash(char), value) else if (char == "/") then call SaveInteger(t, this, StringHash(char), value) else call SaveInteger(t, this, -StringHash(char), value) endif endif call SaveStr(t, -this, value, char) exitwhen value == 0 endloop endif return this endmethod method convertToString takes integer i returns string local integer k = s[this] local string n = "" loop exitwhen i < k set n = LoadStr(t, -this, i-i/k*k) + n set i = i/k endloop return LoadStr(t, -this, i) + n endmethod method convertToInteger takes string i returns integer local integer n = 0 local integer p = StringLength(i) local integer l = 0 local integer k = s[this] local string char loop exitwhen p == 0 set p = p - 1 set l = l + 1 set char = SubString(i, l-1, l) if (char == StringCase(char, true)) then set n = n+LoadInteger(t, this, StringHash(char))*R2I(Pow(k, p)) else if (char == "/") then set n = n+LoadInteger(t, this, StringHash(char))*R2I(Pow(k, p)) else set n = n+LoadInteger(t, this, -StringHash(char))*R2I(Pow(k, p)) endif endif endloop return n endmethod method ord takes string c returns integer if (c == StringCase(c, true)) then return LoadInteger(t, this, StringHash(c)) endif if (c == "/") then return LoadInteger(t, this, StringHash(c)) endif return LoadInteger(t, this, -StringHash(c)) endmethod method char takes integer i returns string return LoadStr(t, -this, i) endmethod method operator size takes nothing returns integer return s[this] endmethod endstruct endlibrary |
| 02-18-2011, 03:39 AM | #2 |
Updated this as apparently StringHash("d") == StringHash("D") ... will now work, but had to add this bs if (c == StringCase(c, true)) then. |
| 02-18-2011, 08:53 AM | #3 |
heres another one: StringHash("/")==StringHash("\\") |
| 02-21-2011, 08:02 PM | #4 |
Fixed ;|. wc3c is finally back up, lol. |
| 02-27-2011, 06:22 PM | #5 |
|
| 03-05-2011, 09:11 PM | #6 | |
->The ord and char methods need more descriptive names ord and char is the way it's done. Those are the names if you program in the majority of languages. When you say ord, you are talking about the -ordinal value of a character. When you say char, you are talking about the symbolic representation of that value.->Are they even needed? They seem to do the same thing as ConvertToInteger and convertToString, only for single character strings. ord/char faster as they perform less operations->The library should detect and report user errors, at least in debug mode, for example if a user uses a character that is not present in the given base or if a base contains the same character more than once. new one does that to a degree->Never mind, forgot that Table can only store integers. New one uses a Table script written by Bribe and this will never use the Table script written by Vexorian as it doesn't have the necessary features.The updates also use an Ascii library, which will probably never end up getting sent here and probably would never be approved anyways since the Ascii library is only used for Char and Ord functionality in wc3, which has extremely limited uses. I'll link the two required libraries as well as the updated script for your convenience so that you can review whether it is worth it or not. I'll also link some of the dependent libraries that use this. Bribe's Table http://www.hiveworkshop.com/forums/j...-table-188084/ Ascii http://www.hiveworkshop.com/forums/1858865-post11.html Updated Base (quite a bit better) http://www.hiveworkshop.com/forums/j...t-base-188814/ BigInt http://www.hiveworkshop.com/forums/j...bigint-188973/ Scrambler http://www.hiveworkshop.com/forums/j...ambler-189766/ Knuth Checksum http://www.hiveworkshop.com/forums/1846246-post343.html Encoder http://www.hiveworkshop.com/forums/s...-0-0-a-189883/ And Encoder is superior to the save/load system here by a small amount. Encoder 2.0.0.0 will be vastly superior to it though. So yea, up to you guys. Bribe's table does have an add on that makes it backwards compatible with vex's table and it's already being widely accepted (especially with the backwards compatibility add on). The reason Encoder 1.0.0.0 is slightly superior to PipeDream's- 1. Takes ranges rather than maximums (shifts values around to minimize their sizes) 2. Can save negative values 3. If the checksum is greater than the first value on the code, it will add checksum rather than the first value. The first value in a code does not have to be multiplied in, so you want the biggest value first. 4. More customizable and better security options with as strong a security as you want (to prevent code modification). Stronger security means a bigger code, but the point is that it puts the user in control. 5. Not coupled with a big int library The reason Encoder 2.0.0.0 will be vastly superior 1. Links ranges together for saving objects*. This solves the problem of saving something like item charges, which can be different for each item. Rather than having something like a max of 300 for all items, each item's specific max charge can be saved with that item. It also makes the API a bit more intuitive =). Quote:
Base is the first script in a large series of scripts that make up Encoder, so it's your call whether it is worth it or not. I don't know about you, but I like smaller save/load codes =P, and there is certainly no comparison between Encoder 2.0.0.0 and any other save/load system ever created for wc3. It's your call. I know that wc3c operates differently from TH and THW. It's just that wc3c is starting to kind of fall behind in the latest in vJASS resources, for example, the lua suite at THW and TH. |
| 03-06-2011, 06:25 PM | #7 |
As you know, a library may only require already approved resources in order to qualify for approval itself. This is not necessarily a problem in this case as the code that is currently posted in the first post without the extra requirements seems quite acceptable. The only thing that I request before approving it is that you add the warning debug messages for faulty inputs in debug mode:
|
| 03-06-2011, 07:58 PM | #8 |
Hm... the debug messages on this version are a pain compared to the one using Ascii, mind if I get Bribe to submit his Ascii first? Actually, the thing was a collaboration between us 2 (he didn't change it much from the one at th), so I'll just submit it here and say by Bribe and nes or something, give me a bit. We can then look back at this script after we look at the Ascii one. tx. edit Got the Base update ready to go with tons of debug stuff, so I can update this to that when Ascii and Bibe's Table are approved. Had to fix a few mistakes by Bribe on Ascii >.>, spent an hour trying to figure out why the initialization order was wrong and realized Bribe made the onInit public... >.> Contacting Bribe about submitting Table here. It has backwards compatibility to the other one, so it should be ok =). Here it is JASS:library Base /* v1.0.2.0 ************************************************************************************* * * A script used for base conversion where integers are represented as strings in * another base. * ************************************************************************************* * */uses/* * * */ Ascii /* wc3c.net/showthread.php?t=110153 * */ Table /* hiveworkshop.com/forums/jass-functions-413/snippet-new-table-188084/ * ************************************************************************************ * * struct Base extends array * * static method operator [] takes string base returns Base * * method convertToString takes integer i returns string * method convertToInteger takes string i returns integer * * method ord takes string c returns integer * method char takes integer i returns string * *************************************************************************************/ /************************************************************************************* * * Code * *************************************************************************************/ globals private Table gt = 0 //stacks of strings with same hashes private integer array n //next node pointer for gt stack private string array b //base of string private Table array t //base character table private integer c = 0 //base instance count private integer array s //base size endglobals private module Init private static method onInit takes nothing returns nothing set gt = Table.create() endmethod endmodule struct Base extends array debug private static boolean array a //is allocated static method operator [] takes string base returns thistype local integer value //string hash value local string char //iterated character local integer i = 0 //this local integer v //stack of hashes local integer dv //copy of v debug if (StringLength(base) > 1) then set value = StringHash(base) //first get the hash set i = gt[value] //get first node of hash table set v = i //copy if (i != 0) then //if stack exists, then loop through loop exitwhen i == 0 or b[i] == base set i = n[i] endloop endif //if this still doesn't exist, create it if (i == 0) then //allocate set c = c + 1 set i = c set dv = v debug set a[i] = true set t[i] = Table.create() //character table set b[i] = base //base string //value is now used for iterating through the base string set value = StringLength(base) set s[i] = value loop set value = value - 1 set char = SubString(base, value, value+1) set v = Char2Ascii(char) //if the character already exists, stop //and deallocate (invalid base) debug if (t[i].has(v)) then debug call t[i].destroy() //destroy character table debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CREATION ERROR: " + char + " MULTIPLY DEFINED") debug set c = c - 1 debug set a[i] = false debug return 0 //character doesn't exist debug else set t[i][v] = value set t[i].string[-value] = char debug endif exitwhen value == 0 endloop //if dv is 0, then allocate dv if (dv == 0) then set gt[value] = i //otherwise add i to hash stack else set n[i] = n[dv] set n[dv] = i endif endif return i debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CREATION ERROR: " + base + " IS INVALID") debug return 0 endmethod method convertToString takes integer i returns string local integer k = s[this] local string n = "" debug if (a[this]) then debug if (i >= 0) then loop exitwhen i < k set n = t[this].string[-(i-i/k*k)] + n set i = i/k endloop return t[this].string[-i] + n debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CONVERSION ERROR: " + I2S(i) + " IS OUT OF BOUNDS") debug return null debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CONVERSION ERROR: " + I2S(this) + " IS NOT ALLOCATED") debug return null endmethod method convertToInteger takes string i returns integer local integer n = 0 local integer p = StringLength(i) local integer l = 0 local integer k = s[this] local string char debug if (a[this]) then loop exitwhen p == 0 set p = p - 1 set l = l + 1 set char = SubString(i, l-1, l) debug if (t[this].has(Char2Ascii(char))) then set n = n + t[this][Char2Ascii(char)]*R2I(Pow(k,p)) debug else debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CONVERSION ERROR: " + char + " IS OUT OF BOUNDS") debug return 0 debug endif endloop return n debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CONVERSION ERROR: " + I2S(this) + " IS NOT ALLOCATED") debug return 0 endmethod method ord takes string c returns integer debug if (a[this]) then debug if (StringLength(c) > 1 or c == "" or c == null or not (t[this].has(Char2Ascii(c)))) then debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE ORD ERROR: " + c + " IS OUT OF BOUNDS") debug return 0 debug endif return t[this][Char2Ascii(c)] debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE ORD ERROR: " + I2S(this) + " IS NOT ALLOCATED") debug return 0 endmethod method char takes integer i returns string debug if (a[this]) then debug if (i < s[this] and i >= 0) then return t[this].string[-i] debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CHAR ERROR: " + I2S(i) + " IS OUT OF BOUNDS") debug return null debug endif debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "BASE CHAR ERROR: " + I2S(this) + " IS NOT ALLOCATED") debug return null endmethod method operator size takes nothing returns integer return s[this] endmethod implement Init endstruct endlibrary |
