Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Array/hash tag help

  1. #11
    Join Date
    Jul 2008
    Posts
    128
    Thanks
    0
    Thanked 17 Times in 16 Posts

    Default

    I assumed that lootarray was an object property, which it isn't.

    Remember that values stored in localStorage are always strings and shouldn't be numerically compared or added.

  2. #12
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    You may be over thinking this with logging to the console, the console may be part of the problem. In any case, this works (must be live):

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript">
    var lootedItem, maxLikelihood = 0;
    
    var loot = {
    	silver	: 3,
    	bronze	: 3,
    	copper	: 3,
    	platinum: 1,
    	iron	: 5,
    	stone	: 5
    };
    
    var playerLoot = {
    	silver	: 0,
    	bronze	: 0,
    	copper	: 0,
    	platinum: 0,
    	iron	: 0,
    	stone	: 0
    };
    
    var lootArray = [];
    
    for (var p in loot){
    	if(loot.hasOwnProperty(p)){
    		lootArray.push(p);
    		maxLikelihood = Math.max(maxLikelihood, loot[p]);
    	}
    }
    
    function addLoot(){
    	lootArray.sort(function(){return 0.5 - Math.random();});
    	lootedItem = Math.random() * maxLikelihood;
    	for(var i = 0; i < lootArray.length; ++i){
    		if(loot[lootArray[i]] > lootedItem){
    			lootedItem = lootArray[i];
    			break;
    		}
    	}
    	playerLoot[lootedItem] = +playerLoot[lootedItem] + 1;
    	allLoot();
    	storeIt();
    }
    
    function allLoot(){
    	var r = ['Player Loot\n'];
    	for(var p in playerLoot){
    		if(playerLoot.hasOwnProperty(p)){
    			r.push(p + (p.length < 8? '\t : ' : ' : ') + playerLoot[p]);
    		}
    	}
    	document.getElementById('allloot').firstChild.nodeValue = r.join('\n');
    }
    
    function storeIt(){
    	for(var i = 0; i < lootArray.length; ++i){
    		localStorage.setItem(lootArray[i], playerLoot[lootArray[i]]);
    	}
    }
    
    function retrieveIt(){
    	var key;
    	for(var i = 0; i < localStorage.length; ++i){
    		key = localStorage.key(i);
    		if(playerLoot.hasOwnProperty(key)){
    			playerLoot[key] = localStorage.getItem(key);
    		}
    	}
    }
    
    function resetPlayer(){
    	var key;
    	for(var i = 0; i < lootArray.length; ++i){
    		key = lootArray[i];
    		playerLoot[key] = 0;
    		localStorage.removeItem(key);
    	}
    	allLoot();
    }
    </script>
    <style type="text/css">
    pre {
    	font-family: consolas, monospace;
    }
    </style>
    </head>
    <body>
    <input type="button" value="add" onclick="addLoot();"><br>
    <input type="button" value="reset" onclick="resetPlayer();">
    <pre id="allloot">&nbsp;</pre>
    <script type="text/javascript">
    retrieveIt();
    allLoot();
    </script>
    </body>
    </html>
    Once the player accumulates points for any of the ores, they cannot be removed by refresh. You can remove them with the resetPlayer() function (reset button).

    Oh and putting a number into localStorage will automatically type convert it to a string. As a result, it must be type converted back to a number to perform addition on it. I have done so in the above page:

    Code:
    function addLoot(){
    	lootArray.sort(function(){return 0.5 - Math.random();});
    	lootedItem = Math.random() * maxLikelihood;
    	for(var i = 0; i < lootArray.length; ++i){
    		if(loot[lootArray[i]] > lootedItem){
    			lootedItem = lootArray[i];
    			break;
    		}
    	}
    	playerLoot[lootedItem] = +playerLoot[lootedItem] + 1;
    	allLoot();
    	storeIt();
    }
    Preceding a string or number value with a + sign and no space converts it back to a number if it's a string and makes no change if it was already a number. And contrary to what one might think, though it wouldn't come into play here, it doesn't change a negative into a positive value.

    Note: This version adds only one point each time and sorts through the loot randomly while assigning the probability of a random ore on the basis of its number in the loot Object. Higher numbers will be picked on average more frequently. In a small sample size this might not always be the case.
    Last edited by jscheuer1; 12-21-2011 at 03:18 AM. Reason: code improvements and add - Oh and putting a number . . . etc.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. The Following User Says Thank You to jscheuer1 For This Useful Post:

    lmbarns (12-20-2011)

  4. #13
    Join Date
    Dec 2011
    Posts
    34
    Thanks
    8
    Thanked 0 Times in 0 Posts

    Default

    Ugh, thank you so much John. Honestly you need to make games, you could pump them out in no time......

    Was it because I was testing locally that it didn't work? The code you just posted doesnt work locally but works beautifully the second I uploaded it(per your instructions) to my bluehost account.........

    I had that happen when I was doing stuff with ajax where I spent hours trying to get it to work locally with IE only to find out it requires it to be uploaded.

    Guess uploading elsewhere should be a first step in my troubleshooting workflow........

    edit:: also I'm still digesting this, the pre tag is pretty cool too, I always used span to change text but I think pre is probably a lot better.
    Last edited by lmbarns; 12-20-2011 at 10:53 PM.

  5. #14
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    There are a number of things that can trip you up testing locally as opposed to live. I had mentioned that about localStorage back in post #7 in this thread:

    Quote Originally Posted by jscheuer1 View Post
    Now, localStorage only works if the page is live.
    AJAX, bookmarks, certain types of javascript in iframe and frames are other things in that category. But those all vary by browser. I don't believe any browser does localStorage unless the page is live.

    The pre tag can be useful because its text is pre-formatted (renders all tabs, spaces and line breaks). But that's up to the coder/designer. In this case the same information could be presented in a table. And this is one of those instances where a table is appropriate.

    It just seemed easier here to use a pre tag.

    I had thought to annotate the addLoot() function with comments a little:

    Code:
    function addLoot(){
    	lootArray.sort(function(){return 0.5 - Math.random();}); // shuffle lootArray so it will be looped through in a random fashion each time
    	lootedItem = Math.random() * maxLikelihood; // set a random threshold each time for which items might qualify
    	for(var i = 0; i < lootArray.length; ++i){
    		if(loot[lootArray[i]] > lootedItem){ // at the first item encountered in the shuffled array that breaks the random threshold
    			lootedItem = lootArray[i]; // set that as the item to increment and
    			break; // exit the loop
    		}
    	}
    	playerLoot[lootedItem] = +playerLoot[lootedItem] + 1; // increment that item
    	allLoot(); // update the report
    	storeIt(); // update the storage
    }
    Last edited by jscheuer1; 12-21-2011 at 10:05 AM. Reason: English usage
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. #15
    Join Date
    Dec 2011
    Posts
    34
    Thanks
    8
    Thanked 0 Times in 0 Posts

    Default

    I had this going so well and hit another roadblock that seems like it should be way simpler than I'm making it.

    I made several other arrays following this format and they're amazing. I made a main, giant loot table, then can generate random calls from ranges within the table for different groups of items. It was all going perfectly, when you kill a monster you get a looted item from the relative type...warrior drops warrior items, mage drops magic items, ranger drops ranger items, etc the mine gives you random selection of ores, and finally, when you enter a "trading zone" I update a div that draws entries from all these different arrays, with buttons to buy/sell

    For some reason up until this point, it's been letting me just access the item of the array like this: playerLoot[lootArray[1]]-=1; to subtract 1 from that entry in the array.
    Example:
    Code:
    function sellIt(what){	
    	if(what==0){ //arrows
    		if(playerItems[itemArray[4]] > 9) {
    			playerItems[itemArray[4]]-=10;  //arrows
    			playerLoot[lootArray[7]]+=25; //gold coins			
    		}
    			else {alert("You dont have one of those!");}
    	}
    	else if(what==1){ //bandages
    		if(playerItems[itemArray[7]] > 9) {
    			playerItems[itemArray[7]]-=10;  //bandages
    			playerLoot[lootArray[7]]+=50; //gold coins
    		}
    			else {alert("You dont have one of those!");}
             }  //ETC CONTINUED MANY TIMES FOR MANY ITEMS
    }
    console.log(typeof(playerLoot[lootArray[7]])); //returns number at first
    }
    Elsewhere I was using playerLoot[lootArray[7]]+=parseInt(Math.random() *25); to add gold to it when I killed a monster.

    If I start a game, run around killing monsters, it increments that number just fine, if I go to the vendor and start a transaction I can buy/sell items from a couple different arrays, but the second I click addLoot() to add some ingots to the array, it converts the array entries to string. Then when I try to add/subract, instead of 2+2=4 it's 22...

    In the trade div, i have a button that runs sellIt(what); which decrements that particular ingot entry from the array, and increments the array entry for gold_coins.

    So I need to know if there is an easy way to access the array entries as numbers, like some command like parseInt(array[i]); which didn't work when I tried, or some other voodoo to access these entries????

    I tried a few things so far...adding additional variables to use as a setter/getter but it didn't work. I would do something like:

    Code:
    var gold_coin;
    function addSomeGold() {
    gold_coin = playerLoot[lootArray[7]];
    gold_coin+=10;
    playerLoot[lootArray[7]=gold_coin;
    }
    Doesn't work in the console I used typeof to see what it has and when you first log in it's type number, and you can buy/sell things from different arrays but the second you run the addLoot() function for the array that has the ingots and gold_coin entry, it converts to "string"

    Seems there should be an easy way to convert back to number????

    edit:: Also tried/currently trying
    Code:
    Number(playerLoot[lootArray[7]]);
    Number('playerLoot[lootArray[7]]');
    playerLoot[Number(lootArray[7])];
    playerLoot[Number('lootArray[7]')];
    parseFloat('playerLoot[lootArray[7]]')
    //etc combinations
    All still strings....
    Last edited by lmbarns; 01-01-2012 at 07:40 AM.

  7. #16
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    If you know it's a number, albeit represented as a string, the easiest way to ensure it's treated as a number is to precede it by a + sign. So for:

    Code:
    playerLoot[lootArray[7]]+=parseInt(Math.random() *25)
    You already know that parseInt(Math.random() *25) is a true number. So, if there is a problem with playerLoot[lootArray[7]], like if it was retrieved from localStorage, which would have made it a string, you can do:

    Code:
    playerLoot[lootArray[7]] = +playerLoot[lootArray[7]] + parseInt(Math.random() *25);
    Or for:

    Code:
    var gold_coin;
    function addSomeGold() {
    gold_coin = playerLoot[lootArray[7]];
    gold_coin+=10;
    playerLoot[lootArray[7]=gold_coin;
    }
    You could do:

    Code:
    var gold_coin;
    function addSomeGold() {
    gold_coin = +playerLoot[lootArray[7]];
    gold_coin+=10;
    playerLoot[lootArray[7]=gold_coin;
    }
    But, if that's the only place that string is creeping in - retrieving from localStorage, you could leave the rest of the code alone and nip that part in the bud by converting back to a number when retrieving:

    Code:
    function retrieveIt(){
    	var key;
    	for(var i = 0; i < localStorage.length; ++i){
    		key = localStorage.key(i);
    		if(playerLoot.hasOwnProperty(key)){
    			playerLoot[key] = +localStorage.getItem(key);
    		}
    	}
    }
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  8. The Following User Says Thank You to jscheuer1 For This Useful Post:

    lmbarns (01-01-2012)

  9. #17
    Join Date
    Dec 2011
    Posts
    34
    Thanks
    8
    Thanked 0 Times in 0 Posts

    Default

    Thank you for such a quick response. Happy new year.

    Exactly what I was looking for. Never seen the "+" used after the = other than to concatenate(sp?) things together or increment stuff.

  10. #18
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,164
    Thanks
    265
    Thanked 690 Times in 678 Posts

    Default

    You could also use a mathematical formula that doesn't change the value:
    var=var+0;
    var=var*1;

    But I think that just signing the number (as John suggested) is slightly faster to process.
    Daniel - Freelance Web Design | <?php?> | <html>| espa˝ol | Deutsch | italiano | portuguŕs | catalÓ | un peu de franšais | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

Bookmarks

Posting Permissions

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