Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers DBPro Corner / Looping without interupting

Author
Message
Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 5th Nov 2011 15:15
Im am wondering about an alternative to looping something while already in a loop, as this stops the game flow even in something as fast as text based stuff.

For example if i want to randomise a number and then make sure that the number it randomised isnt a certain number i could do:

a = 4
Repeat
b = RND (9) + 1
Until NOT (b=a)

So therefore keep going until b is not 4. Now as there is only a one in 10 chance that it will do this most of the time it wont even loop, it will just break straight out, but it still interupts the game cycle, if i have lots of things happening there is a distinct pause in the process. How can this be if it goes out of the loop straight away is beyond me but most of the time it more than likely wont need to loop more than twice to ensure it wont pick 4 in this case. Now this isnt a huge loop with lots of things to check through, just a small 1 line loop that is merely randomising a number, nothing special. Yet it still interputs. I imagine a very complex loop with more complex lines happening would cause havoc on a 3d game where a pause in the game would be critical.

So what are the alternatives to doing this without creating more loops. I had a little play around but the best i came up with is too presumptuous and relied on a few nested if statements checking against a "is it the same, if so rnd again" principle. Well although it would be rare 4 could happen 20 times in a row so just putting a few if statements nested together just wont cut it.
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Nov 2011 15:47
For this specific example, you just need to think outside the box a little.

You are attempting to choose 1 of 9 numbers and retrying when you choose the previously used number.

Instead, what you should actually be doing is choosing 1 of 8 numbers (that's the number of items you want to choose from, not the actual numbers), then map your chosen number into your valid ranges.

Using your example of 4 being out of bounds, you have a range of 8 numbers to choose from: 1 to 3, 5 to 9. If you pick a number from 1 to 8 and the result is from 1 to 3, then that maps directly into the first range. If the result is from 4 to 8, then that maps to the 5 to 9 range simply by adding 1 to your result.

Here's how you do that:


You can exclude two numbers from your range simply by extending the idea a little:


That last piece of code will work correctly no matter the values in a and b, even if they are the same values. If they are guaranteed to not be the same, simply remove the code 'a <> b and'.

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 5th Nov 2011 16:16
I did actually think of that at first. But say for example i have 100 different numbers all picking numbers themselves, writing the ranges for each one of those numbers ould be a pain. I was wondering if there were other alternatives, or would that above code be expanded to fit easily. Its a daft simple question but i tried a few alternatives and my heads just not coming up with the goods
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Nov 2011 16:54 Edited at: 5th Nov 2011 20:01
There are many ways to skin this cat.

Here's an array based version:


The numbers in the array 'Numbers' are the numbers I want to choose from - I've populated that with the numbers 1 to 10 in this example.
In the loop, I initially have 10 items to choose from (held in the variable 'Top', which actually represents 0 to 9 in the array). So I pick one and display it. Then the picked item is swapped with the last item in the array, and the number of further items to choose from reduced by 1. Repeat until you have chosen the number of items you need to.

Simply reset the 'Top' to the array size to reset the list of items to choose from - there's no need to re-sort the array.

[EDIT - Quick code fix]

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 5th Nov 2011 18:41
That looks great Ian. It gave me an excuse to install your utils aswell. 2 things then.
1) I cant quite work out what its doing exactly. After getting it to run (the array was out of bounds, needed a -1) i ran it and then tried to follow it. Why is the constant Number_to_choose there, i cant find out where it gets used, is that suppose to be the number not to use. Also is i basically picking a number from 1 to 9 then swapping that number with whatever the last number in the array is after printing it?

2) Have you got any tutorials regarding your utils. There are so many commands - most i have no idea what use they could have. I am not the experimental type so i dont learn by doing, i learn by learning then doing, then i can finally experiment. When i look at commands if i dont know where they are used or what they are for i just wont use them out of fear, and because of this i suspect i am going to miss out on some great methods for doing things that these utils allow. I know there is so much useful stuff in there but i have no idea how to use them or what to do with them. I know there are help files but like the help files in dbpro it is too brief for someone as new as me. Are there tutorials which show you certain things that can be done and how the utils fit in with the snippets? I would really like that.
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 5th Nov 2011 21:20 Edited at: 5th Nov 2011 21:22
Yes, I edited my code after you took your copy. Plus I've edited again to put the NUMBER_TO_CHOOSE where I meant to put it.

Quote: "I cant quite work out what its doing exactly"

You are picking an entry in the array. That entry has the number chosen in.

Perhaps it'll be easier to visualise in this way. Imagine you have two arrays of numbers:
TO_CHOOSE: 1 2 3 4 5 6 7 8 9 10
CHOSEN: <empty>

So item 0 of the TO_CHOOSE array has a value of 1 stored in it, item 1 has 2 in it etc.

I randomly pick a number from 0 to 9 - I get a 5. That's item 5 from the array, which has a value of 6. We remove it from the TO_CHOOSE array, and move it to the CHOSEN list:
TO_CHOOSE: 1 2 3 4 5 7 8 9 10
CHOSEN: 6

Now I need to pick another number from the TO_CHOOSE array - I have one less item in there this time, so I need a random number from 0 to 8. I get a 7. That's item 7 from the array, which has a value of 9. We remove it from the TO_CHOOSE array, and move it to the CHOSEN list:
TO_CHOOSE: 1 2 3 4 5 7 8 10
CHOSEN: 6 9

Again that's reduced the size of the TO_CHOOSE array, so the next random selection will be from 0 to 7. Repeat until you have your set of numbers.

Ok, now back to my particular implementation. Rather than have two separate arrays, I use a single array and separate it into 2 (note the pipe symbol - that's the separation between the TO_CHOOSE section of the array, and the CHOSEN section, with Top being the placement of that separation):
Numbers: 1 2 3 4 5 6 7 8 9 10 |

Picking item 5, with it's value of 6. Item 5 is swapped with the Top item:
Numbers: 1 2 3 4 5 10 7 8 9 6 |

Then reduce Top by 1:
Numbers: 1 2 3 4 5 10 7 8 9 | 6

Now pick item 7, with it's value of 8 (swap with the Top item, then reduce Top by 1):
Numbers: 1 2 3 4 5 10 7 9 | 8 6

Now pick item 3, with it's value of 4 (swap with the Top item, then reduce Top by 1):
Numbers: 1 2 3 9 5 10 7 | 4 8 6

Again, repeat until you have your set of numbers.

Quote: "Are there tutorials which show you certain things that can be done and how the utils fit in with the snippets?"

I suffer from the same problem that Lee does - the interesting stuff is in writing the code, not so much in help files and examples

I do have a largish set of examples, but they are not commented, and largely disorganised - I've uploaded them temporarily here:
[url]http://www.matrix1.demon.co.uk/Matrix1Util Examples 20111105.zip[/url]

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 5th Nov 2011 21:50
Ian thats brilliant. I understand things better when there is some sort of visualisation (or a picture) involved. I know exactly whats is going on now. that will work perfectly. Thank you very much. I really need to learn more concepts and methods for messing around with arrays but have never come across much decent easy to understand things. This works perfectly though, thanks again.

Quote: "I suffer from the same problem that Lee does - the interesting stuff is in writing the code, not so much in help files and examples"


I fully understand and appreciate this. I can imagine after putting in a lot of hard work and time more than anything to make things like this sometimes the last thing you want to do is the help files etc. I had a look through many of the commands (and there are so many) but as i said before, most i wouldnt know if i had a use for them or not. I will take a look at that link though at some point in the future and at least i have the utils so that better ways of doing what i am after can be reccomended to me and i will learn then one command at a time.

At the end of the day i am just grateful that people like you are out there trying to make something thats already pretty damn good, even better.
Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 6th Nov 2011 18:45 Edited at: 6th Nov 2011 20:21
Damn. Ian im sorry i thought i had it but when i tried out the theory myself it just isnt quite doing it.
The way i understood it was that it populates an empty array with a random selection of the main array (in this case 1 -6). It should only need to do this twice in this case as it can only be one number and it will be either that number or the next one.
So pick a number from the array (lets say it picks 3), delete 3 from the array and pick another number (cant pick 3 now as its not an option so it picks 6) As its doing this its populating an empty array with the number 3 in position 1 and 6 in position 2.
A quick IF statement checks if "the number im looking for = the first number in the array", if it does use the next number, if it doesnt use that number.
Its just not as neat as i thought it would be. Perhaps someone could steer me in the right direction. As i managed this without the swap array command and i dont know why it means i think ive misunderstood the theory behind what you were trying to explain, and now looking at it im not sure if your describing 2 different methods or the same one. Sorry about this.

zenassem
21
Years of Service
User Offline
Joined: 10th Mar 2003
Location: Long Island, NY
Posted: 6th Nov 2011 20:31 Edited at: 6th Nov 2011 20:49
edit
After reading the entire thread, I see that IanM suggested exactly what I just typed. Now I have to figure out what problem you are having with it.

The only part I don't get is why you need to check your chosen set of numbers. Why would you populate the chosen array with a number you don't want? I would eliminate putting numbers I don't want into to the set initially. Am I missing something?

====
I will preface that I have to read this entire thread to see what solution IanM gave. Without reading it, my initial solution would be to have an array that stores all numbers available in the set.

Now with that there are a couple of takes on what to do next. Here is the simplest I could think of. Get a Random number that corresponds to an index of the array 0,1,2,3,4,5... MaxElements in the array. When a given index is chosen get the value from that index. Now swap that index with the last element index. Now generate a Random number from 0 (the first element) to MaxElements -1 (. In this way you will never choose the same value twice. To reset the array, no shuffling is required. Just set the random number range to include all elements (MaxElements) in the array.

Only one array is required. You never have to check if a value has already occurred because inherently you can't ever get the same value (assuming your original set had all unique values to begin with). Every time a number is chosen it moves to the end of the array, and that value is "never chosen again" (unless you chose to by resetting MaxElements to it's original value) becuase your random range won't pick that index if MaxElements is reduced by 1.

Your signature has been erased by a mod please reduce it to 600 x 120.
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 6th Nov 2011 21:05
I have no idea what you are trying to do with that code.

One glaring problem is that you are confusing the random number you picked as the final result, when instead you should simply use it as an index to the array that contains the number you are choosing.

I think it'd be easier if you actually explained what you are trying to accomplish rather than posting what you think the solution is and asking me to get it to work.

What are ALL the rules to choosing these numbers, how often are they chosen etc? It might be that once you have a concrete set of rules written down, you may see the solution for yourself.

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 6th Nov 2011 21:27
Quote: "I have no idea what you are trying to do with that code.
"

Neither do i.

No really, what i am trying to do in its simplest form is make something that is a UDT array, not pick its own number.
So i set up 6 people for example. They all number 1 - 6.
Eventually at some point person 4 is going to decide he wants to kick the crap out of someone. That person cant be himself, that would just be daft. So he has to pick a number that isnt him.
The way i did it initially wasnt good enough as it went into a loop and that paused the game for a split second, something which i do not want.
What i did was put it in a repeat until loop.
Pick a random number and keep repeating it until person(a).number is NOT the random number that is chosen. When this occurs that number will be the sufficient choice.

Now using that array in my last bit of code my idea was much more simple than moving bits of the array around everywhere, im not sure why i would do that.
Basically if i can get it to randomise 2 numbers then the first one should be enough, if it matches the person number then use the second number instead. Only problem with this is it could pick 4 twice. Now using what i thought you were telling me was to pick a random number out of the array then populate an array with it.
Then delete that number from the array so in no way shape or form will that number be duplicated.
So now i have one array with two completely different numbers.
Now the above formula works. Is the first element in the aarray equal to person(a).number? Yes then pick the second because it wont be, if it isnt then pick the first element of that array.
Thats what i thought anyway, but i am having trouble in general with it because i think i have the idea nailed down but the implimentation isnt right.

I think i got the impression of this from the

Array1(10) 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Array2((2) 0,0 (or empty i suppose, just use array insert at bottom to fill it)
Pick a random number, delete from array (it picks 8)
Array1(9) 1, 2, 3, 4, 5, 6, 7, 9, 10
Array2(2) 8, 0
Pick another number from the above (it picks 5)
Array1(8), 1, 2, 3, 4, 6, 7, 9, 10
Array2(2), 8, 5

Now is the person(a).number equal to the first element? Yes then use the second, no then use the first.

Is this what you were trying to say?
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 6th Nov 2011 21:41 Edited at: 6th Nov 2011 21:41
I haven't read every word of this thread so forgive me if I repeat something or miss the point. As IanM said there are many ways to skin this cat. So taking the immediate problem in the first post (random numbers one) I wrote up a way to get a different random number and avoiding a loop to do it. I hope it is well commented enough.


IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 6th Nov 2011 22:40
Then we're back to the original code I posted:


The only reason to get into the whole array thing is either so that you can pick multiple random numbers and not get any repeats, or so that you can control the frequency of picked numbers precisely.

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 6th Nov 2011 22:42
Yeah i think for the purpose i was after i was severely over complicating the code. This will work more than fine. I was just trying to learn what was going on above. I will bookmark this page though and return to it if the need takes it.

Many thanks for the help.
Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 7th Nov 2011 20:19
I just thought of something. I am going to have to expand on the array idea. Because the numbers that i want it to choose from will not always be 1 - 6.

For example if a faction (lets say 2) gets wiped out and faction 1 decided to attack and it picks 1 then inc 1 isnt going to be right, nor will it if it picks 2. So i do need to use that option after all. Basically generate a pool of numbers out of whats available (all the factions have a number unless they die then they get put as 0 and data is cleared, or at least thats how im trying to do it.)
So i will want to do an array of numbers more like 1, 2, 4, 5 or something then pick a random number from there. If its 5 for example and 5 is the attacking faction (which cant work because its itself) then i also cant inc 5 because there is no 6, so ill check if im at the end of the array or something and dec instead? I think that will be ok.

Ill get back to the drawing board on that one. I got some good ideas though.
Grog Grueslayer
Valued Member
18
Years of Service
User Offline
Joined: 30th May 2005
Playing: Green Hell
Posted: 7th Nov 2011 23:17
Sounds like you need to add a switch to the faction UDT so you can use it to quickly turn on a faction number that's being attacked already.

Turn off all faction switches
Randomly pick a faction to attack other than itself
Check faction UDT switch to see if it's off and turn switch on

IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 8th Nov 2011 19:41
Something like this:


You'll have to work out how you want the FactionList array to be populated - I simply filled in with consecutive numbers, but it could be driven from another array that holds your faction details.

Somarl
13
Years of Service
User Offline
Joined: 11th Feb 2011
Location: UK
Posted: 8th Nov 2011 23:35
That is one hell of a peice of code Ian. Just playing around with it and seeing whats going on. Its certainly making me think differently about arrays and some of the programming in general.
What i have written so far i can already think of different ways to do it neater and better, though im not going to change those bits just yet, i will hold them up here at some point for scrutiny so i can learn more ways of doing everything i have currently done.
Agent
19
Years of Service
User Offline
Joined: 7th Sep 2004
Location: Sydney, Australia
Posted: 10th Nov 2011 21:55 Edited at: 10th Nov 2011 22:08
I have another way.

If your faction names and info are stored in a UDT array (or several independent non-UDT arrays), you can run a loop through all of them and count how many are still alive. Then determine a random number between 1 and this count. Run through the loop of all factions again, counting the live ones as you go, and when you hit your random number, set the final decision variable to this index and abort the loop.




If you want to choose two factions to fight one another, and be sure that we don't choose the same faction twice, you repeat the code almost identically, excluding the choice we just made from the possibilities. Here's the total code for this scenario:




And for the finale, save coding space by making the whole thing into a function that allows for an optional exclusion from the list of alive factions, like so:




That will be your final solution.

enderleit
16
Years of Service
User Offline
Joined: 30th May 2007
Location: Denmark
Posted: 12th Nov 2011 18:55
There should be a button so you could become a "fan" of IanM.

Login to post a reply

Server time is: 2024-05-20 03:47:32
Your offset time is: 2024-05-20 03:47:32