Moving Values From an Array to HashTable then back

This forum is currently in read-only mode.
From the Asset Store
Helping streamers give their viewers more excitement.
  • This is for the purpose of saving and loading using my tile based map editor.

    I would only like to have one file per save. I need to save a bunch of values from global variables, and the contents of (at least) one array.

    To do this I need to move all of the array to a HashTable before saving the file, then upon loading I need to reverse the process, overwriting the array with the contents of the HashTable (excluding global variables obviously.)

    *Edited, thread re titled, and post rewritten for clarity. Keep this in mind if the next post or two seem redundant!

  • I've also discovered that you can only save one array or one hashtable to a file at a time.

    I guess I could use the INI object to store my variables, but I would rather everything be stored in one file.

    I'll have to try and make some sort of loop that stores the contents of my array into the hashtable while saving, and empties it back into the array on loading.

  • Try loading the file through an expression like apppath + "myfile.dat".

  • Thanks for your response!

    The file actually loads fine. It's just that it can't store more than one of these objects at a time. It either stores the contents of a hashtable, or the contents of an array.

  • Ah, I misunderstood the problem. But I?m not sure I?m getting it now either ;)

    The description of your loading/saving is a bit misleading. Are you using arrays and/or hashtables?

    You can only load one file per instance of either object, probably what you are doing is overwriting the first set when loading the second.

    Workaround to unify both tables would be to have two hashtable objects loading the two files, then you could do a "for each key" on the second object and insert it to the first.

  • You're right, sorry about that! I didn't initially realize what the problem was because it was manifesting in a strange way.

    I've re-titled this thread and rewritten my first post to try and clear things up.

    So I need to figure out how to create keys in a HashTable for each element in my array, and give it a name indicative of the position in the array. (ie: x10, y52)

    My first thought would be to use:

    For Each Element -> HashTable: Insert key Array.CurrentX with value Array.CurrentValue

    This does nothing. I also tried creating a loop and using Loopindex instead, which also didn't work.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Been away for quite a while, and it seems that the CC help section has more people needing help, than people willing to spend a few seconds to help...

    To help with your specific example:

    For Each Element -> HashTable: Insert key Array.CurrentX with value Array.CurrentValue

    This won't work because the key of a hashtable entry has to be a string. Construct doesn't autoconvert to a string here (I guess it simply was forgotten). So by simply adding str() it will work:

    +For Each Element

    -> HashTable: Insert key str(Array.CurrentX) with value Array.CurrentValue

    But why making it so complicated? Who cares if the savegame consists of one file or a folder with several files? The gamer won't! In fact, if you have a look at today's games, they often have a complex tree-structure, with a folder named after the game slot or profile name or whatever and lots of files and sub-folders, containing other files and sub-folders. And why not? It doesn't make a difference in the gameplay-experience <img src="smileys/smiley2.gif" border="0" align="middle" />

  • AH! I had read on the Wiki that hashtables could only store strings, but I had stored numbers in them before so I just assumed that this was old news. I think I had determined that with input from a textbox, which must default to being a string even if it is a number?

    This makes sense now.

    As for your point about why I care I'm not too sure if it's rhetoric or not so I'll answer:

    This isn't a game, it's a map editor! So I expect myself and whoever else uses it to move files around. As I make maps they pile up pretty fast. If I were to split the file out of wanting to take the easier route I would end up having to make 3 files each per map (not including the optional tileset save file)... so it just starts to get kinda messy.

    And I could use folders, but I think it is just easier if I want to share a map with someone to just send one map file.

    The second thing is that while I'm mostly making this for me (maybe a couple of friends, and I plan to share it on the forum) I'd rather not have to code for an exception if one of the files is missing. Just easier, once I hit the bug squashing phase I'm going to have my hands pretty full anyways.

    You make a great point about spending more time helping people too. I find when I look (and I do whenever I'm on here) I don't have anything to contribute to questions about physics, or controller issues, or AI. This will change when I'm done this map editor and actually focusing on making games, but in the meantime I am constantly amazed at the frequency that you and Jayjay and R0j0hound help people.

    If I haven't said it before, thank you so much.

  • AH! I had read on the Wiki that hashtables could only store strings, but I had stored numbers in them before so I just assumed that this was old news. I think I had determined that with input from a textbox, which must default to being a string even if it is a number? hope to not confuse more than helping, but you are talking about storing. And the value to store can be of any type. It is just the key that has to be a string.

    -> Insert key "1" with value 2

    the key "1" is created with the value number 2, accessible as HashTable("1")

    -> Insert key "1" with value "2"

    the key "1" is created with the value string 2, accessible as HashTable("1")

    -> Insert key 1 with value 2

    no key is created, because 1 is a number, not a string.

    And a textbox indeed only knows strings, but CC is helpful enough ro autoconvert for you.

    -> Set Text to str(1)

    -> Set Text to "1"

    -> Set Text to 1

    all three examples lead to the same result: A textbox with the text/value "1" (string)

    As for your point about why I care I'm not too sure if it's rhetoric or not so I'll answer:

    This isn't a game, it's a map editor! So I expect myself and whoever else uses it to move files around. As I make maps they pile up pretty fast. If I were to split the file out of wanting to take the easier route I would end up having to make 3 files each per map (not including the optional tileset save file)... so it just starts to get kinda messy.

    And I could use folders, but I think it is just easier if I want to share a map with someone to just send one map file.

    The second thing is that while I'm mostly making this for me (maybe a couple of friends, and I plan to share it on the forum) I'd rather not have to code for an exception if one of the files is missing. Just easier, once I hit the bug squashing phase I'm going to have my hands pretty full anyways.I see. Apart from the possibility of compressing such folders in an archive before sharing it, I think you have an argument with the exception code. The one-file-route should be easier to maintain.

    If you are heading for one final file containing the map structure with all its levels and the like, you may want to develop a naming convention for the keys. Something like

    "countL" (number of levels)

    "01_tiles" (the tileset of level 01)

    "01_countM" (number of maps of level 01)

    "01_01" (map 01 of level 01)

    could easily be retrieved again. And instead of storing one key per array value, I would convert the array to a string and store the array in one key. In the example above the key "01_01" would contain a string with all the array data of map 01 of level 01. I made an example cap showing how this can be achieved: array2hashtable.rar

    You make a great point about spending more time helping people too. I find when I look (and I do whenever I'm on here) I don't have anything to contribute to questions about physics, or controller issues, or AI. This will change when I'm done this map editor and actually focusing on making games, but in the meantime I am constantly amazed at the frequency that you and Jayjay and R0j0hound help people.

    If I haven't said it before, thank you so much. hope I didn't offend you, because my words weren't addressed at you but at the people that didn't help although they could have. I was just a bit disappointed coming back here after two month just to see, that so many questions are unanswered for weeks. There are so many talented developer out there, and even those who got help themselves don't contribute. It's not the way a community works: If most of the people are only leeching then the system breaks. And that would be very sad...

    Please don't think that I meant you, it was just the first thread that I answered in <img src="smileys/smiley1.gif" border="0" align="middle">

  • Yay! another veteran is back helping on this forum. I was confused as to where everybody went.

    I didn't help because I just never use hash tables. They just seem like less functional arrays to me..

  • Wow! That's a lot to process.

    So I've got it. A HashTable has to have a KEY that is a string, but it doesn't matter whether the value is a string or integer. Thanks for the lucid explanation.

    Your example is fantastic. I'd never actually considered storing multiple levels within a map. I think I will probably use that idea eventually, but it's going to wait until I finish the basic version of this (random map generation would be something I'd love to put in later too.)

    I have one concern. One of the things I've been quite happy with in this project is the possibility of making a map as big as 1000x1000. I once tried storing all of the paths to texture files in a global variable, and it crashed construct after about 40 of them (they were pretty convoluted to be fair c:\users\documents\dropbox\construct projects... etc..) Anyways, I can't find anything on a hard limit for global variables, would you happen to know what it is?

    In the meantime this is much simpler than the method I was using, which took me two new files to figure out and a bunch of messy notes on a pad of paper!

    and don't worry, I didn't take offense. Just seems like a lot of work helping out everyone, and I'm eager to be able to do the same.

  • I don't know of any limit besides RAM. But I also use globals only sparely. Most of the data is stored in arrays, hashtables and dedicated sprites (invisible ones, that never appear on screen, only their PVs are used). It is much easier to work with and less vulnerable.

    1 million values per map? Be careful then to not convert them from the string to the array in only one tick, like in my example. Setting up such a huge array will take minutes, and if you do it in one tick the app is known to the system as "not responding", which might irritate users. Instead, use a routine that shows the progress while only converting a smaller part of the array, until done.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)