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.

DarkBASIC Discussion / Randomized names

Author
Message
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 6th May 2012 21:27
I'm back, and I am working on something right now, but I need to randomize names, I've seen it done with data lines before, but I haven't used data lines before, and I need a bit of help.

-------------------------------------------------------------
BN2 Productions
20
Years of Service
User Offline
Joined: 22nd Jan 2004
Location:
Posted: 6th May 2012 21:48
I've never been a big fan of data lines myself. I prefer to just use an external file and load it all into an array. As far as generating the names, are you thinking of a (relatively) unique name generator or one that will randomly choose a name from a list of acceptable ones?

If Unique, a method I've seen work before is you have two "piles" of information. One is consonants and combinations of two consonants (Th, Ch, etc.). The other pile is comprised of vowels and combinations of vowels (ee, ie, etc.). You then have the program generate a random length of characters to choose and you grab a random character from each pile, alternating between the two (so consonant, vowel, consonant, vowel). You might need to play with the lists to get good values.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Fluffy Rabbit
User Banned
Posted: 6th May 2012 21:52 Edited at: 6th May 2012 21:57
LBFN
16
Years of Service
User Offline
Joined: 7th Apr 2007
Location: USA
Posted: 6th May 2012 22:06 Edited at: 6th May 2012 23:25
Converting Fluffy's code to use data statements:



So many games to code.......so little time.

Attachments

Login to view attachments
Fluffy Rabbit
User Banned
Posted: 6th May 2012 22:09
@LBFN-



// doesn't work in DBC



Too risky, there is overflow sometimes. Plus it will almost never equal 4.

Cool use of data statements, though.
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 6th May 2012 22:57
Overflow? There may be a repeat, but I don't see how it can overflow without a major bug in DBC.

Fluffy Rabbit
User Banned
Posted: 6th May 2012 23:08
@Pincho Paxton-

DarkBASIC's random number generator frequently returns values exceeding the given range, not to mention it doesn't have any round-to-nearest function.
LBFN
16
Years of Service
User Offline
Joined: 7th Apr 2007
Location: USA
Posted: 6th May 2012 23:22 Edited at: 6th May 2012 23:25
Quote: "// doesn't work in DBC"
You are correct, but I think darkzombies uses DBP, even though he is posting on the DarkBASIC forum.

Quote: "Too risky, there is overflow sometimes."

Haven't heard of that one.

Quote: "Plus it will almost never equal 4."

Not sure about that. Ran a quick test and the results show that 4 is picked around the same as the others.





So many games to code.......so little time.

Attachments

Login to view attachments
Fluffy Rabbit
User Banned
Posted: 6th May 2012 23:32
@LBFN-

Actually, that last bit of info is very useful. However, you should always remember to check random functions for overflow. You never know when an array might be accessed out of bounds, thus crashing your program.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 7th May 2012 00:02 Edited at: 7th May 2012 02:19
I made a very simple name generator a while back.



That's old code so I'll see if I can improve it.

edit:
I haven't found a simple better version yet but I've hit upon what I think are two break throughs in the algorithm: to analyse the previous two characters to produce the next character (before I was just analysing one previous character). I will also include a null character, which is used at the beginning and end of every word, now I don't need special conditions for the beginning and end of words because the null characters can do that for me.

WARNING: The above comment may contain sarcasm.
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 7th May 2012 14:26 Edited at: 7th May 2012 14:36
Quote: "@Pincho Paxton-

DarkBASIC's random number generator frequently returns values exceeding the given range, not to mention it doesn't have any round-to-nearest function. "


If rnd exceeded the range none of my programs would work. It has never exceeded the range in 8 years on 3 different computers. I think you have been misreading the return results by not including the zero returned. rnd(4) = 5 returned results. And DBPro uses the same method.

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 7th May 2012 15:16
Quote: "DarkBASIC's random number generator frequently returns values exceeding the given range"

I've never seen this happen either.

Also rnd() only returns up to a 15 bit unsigned integer (32767 is the max) so if you tried to do something like

value=rnd(100000) it would turn into
value=rnd(32767) and you would never get any values higher so I could see something failing in this case:

value=rnd(100000)
if value > 50000 then do something

It would never work.

Quote: "You never know when an array might be accessed out of bounds, thus crashing your program."

Some BASIC languages start their array indexes at 1 where DBC starts at 0. So I could see rnd() failing in another language when it returns zero and if one is used to that other language, it makes logical sense to assume that an index of zero would fail when accessing an array in DB.

Enjoy your day.
Fluffy Rabbit
User Banned
Posted: 7th May 2012 18:13
@Pincho-

How can I trust what you say when you primarily use DarkBASIC Pro? They are two completely different languages with their own rules.

@Latch-

rnd() has crashed my program in cases where I was calling it every frame. Perhaps it was my code, but I'd like to think it was rnd().
Pincho Paxton
21
Years of Service
User Offline
Joined: 8th Dec 2002
Location:
Posted: 7th May 2012 19:49 Edited at: 7th May 2012 19:50
I used DBC for 8 years before DB Pro. The programs I wrote would have crashed because I would have got a number out of my sprite range, so there was no rnd() overflow. And I called rnd() about 20 times per sync.

Fluffy Rabbit
User Banned
Posted: 7th May 2012 21:05
@Pincho-

Fine, you win. 20x/sync sounds like an awful lot. It must have been my code. Sorry if I sidetracked the thread.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 8th May 2012 01:36 Edited at: 8th May 2012 01:37
Coming back on topic, I was working on a game with IBOL a while ago based on the idea of an entirely procedurally generated universe populated by PG species, living on PG planets, flying PG spaceships.
I want to create a PG system that will create many distinct styles while providing many permutations within each style. This is important to create a feeling of culture and civilisation, rather than randomness.
With names you can tell where someone's family is from, you have Latin names such as Estevez and Garcia or English names like Smith or Roberts. How would I create such easily distinguishable "cultures" through PG methods?

WARNING: The above comment may contain sarcasm.
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 8th May 2012 02:36
Hmm, okay guys, this is confusing me, I use types in the game, and trying to think of a way to make this work is confusing me lol, can you see if you can get it to work?



BTW, the menu thing at the end isn't done lol.

-------------------------------------------------------------
BN2 Productions
20
Years of Service
User Offline
Joined: 22nd Jan 2004
Location:
Posted: 8th May 2012 04:07
@Obese
That would be a huge undertaking. As far as making obvious cultures, I would suggest a Lego type approach (Pieces have different attachment points) for the joints of ships/buildings and using a random number biased toward different styles (randomly assembled).

So when generating a new culture it could decide:
Large/Small Ships? (50/50)
Sharp features/Smooth? (50/50)
Box Shape/Spherical/Teardrop/etc?

And so on. Then, when building the ships/buildings, it randomly assembles them but it is more likely to choose, for instance, Spikes and such if Sharp features is a primary culture trait.

You would need an incredible library of parts if you wanted to make it work well, but on the other hand, your customization options for the player's stuff would be incredible as well.

Just a thought.

Great Quote:
"Time...LINE??? Time isn't made out of lines...it is made out of circles. That is why clocks are round!" -Caboose
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 8th May 2012 04:41
Never mind, I fixed it myself, i was just over-thinking it. But now I need a system to make sure it doesn't repeat a name (Because I'm generating 3 different names) I'm going to try to do it myself first, because if I always go straight for help I'll never learn, but I'll get back to you guys if I have trouble.

-------------------------------------------------------------
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 8th May 2012 06:58 Edited at: 8th May 2012 07:01
@DZ
You need to learn how to use FOR loops effectively, you write a block of code almost ideal for a FOR loop but then you copy and paste.
Here I have done some editing to your code so you can see what I mean. (I got rid of a lot of it and just left the important parts.)

Don't worry about the xoff and yoff, they use bit comparisons which isn't required to get the positioning like that, it's just the way that popped into my head.
If you find yourself repeating the same lines over and over then this means you need a loop of some kind. It can take time to learn how to fit things into the same loop that have slight differences (like the positioning in this example) but there is nearly always a way to do so.

There are great benefits to squeezing similar tasks into the same routine, it would be easy to add another enemy for example, we'd just increase the for loop by 1! It's also easy to change things, I decided to change the positioning of the first two lines and all I had to do was change one value and all the lines changed at once, but the player is displayed separately so it has to be changed as well (I didn't bother).

Another way to make changes easier (very important as one always wants to change things) is to store important values as variables. I usually have very few raw values in my code because if you decide to change something you need to go through and edit each instance! Like the 150 x offset you used for all the text, that's why I didn't change the player because I'd have to go through each one and change it. If you stored the 150 in a variable then you could change the variable and every instance would change too!

Some of your subroutines were suspect too: you had one that merely assigned four variables, that doesn't need a subroutine and only confuses the reader by sending them searching for your labels. It is good that you are trying to use subroutines but think about whether it is actually useful. I only make subroutines for two reasons: I want to do the same thing more than once in the program, a block is cluttering up the code and making it hard to read. In both cases the subroutine should be a clearly defined routine (it should do a specific job). There's no point in chucking one half of the program in one sub and the other half in another. You didn't do it as badly as a lot I have seen but it is something to consider.

I hope I've helped and if I sound cranky it's only because I believe you can do better.

WARNING: The above comment may contain sarcasm.
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 8th May 2012 08:10 Edited at: 8th May 2012 08:18
Ah no, I understand, the reason I didn't use the for loops is because I'm not good at math and theres no way I could've done what you did lol. BTW, what does
mean? I mean, what is the &&? I've never seen that before.

And can you explain this too?


what does the read do? This is basically my first time using data statements lol. Is the 'Read' the variable it places the data into or something? Then you make an array with the 6 names in it?

Thats what I gathered, but it's a bit confusing.

One last thing, I also finished the menu, I was having trouble with getting the ink down, so I probably did it a bit big, is there any way I can shrink it?



-------------------------------------------------------------
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 8th May 2012 19:13
Here is a simple way of adding more random names using interchangeable prefixes and suffixes:


WARNING: The above comment may contain sarcasm.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 8th May 2012 19:52
yoff = (e&&1)*centrey

This is the Y offset. We have three enemies and we want enemies one and three to be on the right of the screen while enemy two is on the left. The way I decided to do this (I will explain a more basic alternative after) was to use a bit comparison, since in binary the smallest bit (valued 1) is on for both one and three (01 and 11 respectively) but off for two (10). So the bits do the work for me, I just need to check if 1 is on for e and if so I know it's either equal to one or three. && is the AND operator and will return the value of all bits that are on in both values. I used the result of the comparison multiplied by centrey to position since if e equals 1 or 3 then yoff = 1*centrey = centrey but if e equals 2 then yoff = 0*centrey = 0, so yoff is only active when e equals 1 or 3.

The comparison for xoff is slightly different: xoff = ((e&&2)>0)*centrey
This compares e with the value 2, this time xoff is only active when e equals 2 or 3, since the second bit (value 2) is off for 1.
If I didn't have the >0 centrey would be multiplied by 2 when e = 2 or 3, since 2 is the value present in both numbers.
You can compare more than one bit at a time, for example 6&&39. The most common use of bit comparisons is to find whether a number is odd or even, since 1 is the only odd number in the binary system (x&&1).

Now the basic way to get a tabular format is to use two FOR loops: one for columns and the other for rows.

See how I got the cell number?

Quote: "Is the 'Read' the variable it places the data into or something? Then you make an array with the 6 names in it?"

Yes that is exactly it.

WARNING: The above comment may contain sarcasm.
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 9th May 2012 06:21
Still so confusing lol, but I get the point. I think I'll understand it better if I mess around with it.

-------------------------------------------------------------
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 9th May 2012 23:35 Edited at: 10th May 2012 02:22
Your menu is a good example for learning how to use FOR loops effectively. (edit: It's good for learning lots of things so I wrote lots! Better get some snacks or something, you're gonna be here a while!)
We have four options and the code for each looks quite similar, this hints that they might be able to be combined, but what exactly is different between them? and is there enough similarity to warrant combining them?

The ink commands and X positioning of the text is the same for each option.
The Y position is different, but the difference is incremental: each option's Y position is 50 greater than the previous. Incremental differences are perfect fodder for FOR loops because they are themselves incremental.

There is only one aspect of the code which is non-identical nor incremental: the string holding the option's name. We're going to need a trick to make something that is non-incremental (strings) behave incrementally, we do so by storing the strings in an array.

Arrays have numbered entities, each can store any value of the specified type; essentially allowing us to create any sequence of values without a logical pattern.


Before I give you the complete code I want to address a few rudimentary change to the original:

The text command is identical regardless of the outcome of the condition, therefore it should not be in the condition:

Notice how I have also replaced scrwid/2 with the constant centrex (which has a value of screen width()/2); repeating the same calculation is a waste of time, it's better to store the result in a variable. This may not affect a program this small but in a bigger FOR loop it can cause a noticeable delay. If you can spot the other two calculations that could be stored in variables I'd be very pleased!

If you didn't spot it you probably don't realise what rgb() does. I wont go into detail here but essentially it takes the three colour values, performs the necessary calculations on them, and returns a single value that represents the colour you asked for. If we store the returned values in variables we need only perform the calculations once!


So here's the full code:

The main loop is already a lot smaller and looks neater. I hope the FOR loop makes sense to you now, if not take a moment to examine it and experiment before moving on, then I will tackle the control and exit blocks.

Delays are never a good thing. You forced a delay to stop the cursor going haywire but we need a better way of taming the input that doesn't inhibit the user; we need to train our dog to stay rather than forcing everyone to keep the front door closed. Just like training a dog we are going to use the natural behaviour of the input to help us achieve our goal, not fight against it.

Key input is very simple, it returns a 1 while the key is pressed and a 0 when it is not. So how do we train it to only register once for each new key press? We need a system that deactivates the input after one iteration, then resets when the key is released. In other words we are defining two events: key press (input changing from 0 to 1) and key release (input changing from 1 to 0), how do we distinguish between these events? How do we know which is happening? Both events are changes so we need to store the old input value and compare it to the new value.

This might look a bit confusing at first but follow the loop around and you'll see that newkey is updated before the event check but oldkey is only updated afterwards. So oldkey is using the value of spacekey() from the previous loop.

The key press event is a positive change (0 + 1 = 1) and the release is a negative change (1 - 1 = 0), so detecting an increase in input reveals a key press while a decrease reveals a key release.

The great thing about this system is it resets itself! If we want to change options only on a key press we only need to test for when newkey > oldkey because newkey will have to return to 0 (which then gets passed to oldkey) before it can be greater again.

We want to use two keys, we could double the code and test the two inputs separately but I want to do something a bit cleverer. Since UP and DOWN move in opposite directions we can combine them and treat one as positive and the other as negative.

We have to write the condition slightly differently because now a decrease in input doesn't always indicate a key release: -1 would indicate that the upkey() is being held while downkey() is released. We have to think about which states are useful to us; 1 and -1 indicate down and up so they are useful, but 0 isn't because we don't want anything to happen on a 0. So let's start by removing 0 from the condition:

If you haven't seen the ! symbol before it simply means "not equal to" (I'm not sure if this is still used in DBP, if not use "<>"). This line ensures we ignore when the new input is 0 and only look for when it changes to 1 or -1. This exclusion has reduced the possible values of newin to two (1 or -1) inside the condition, and so we can perform a simple comparison as before:


Now let's insert that into the menu program:

(I changed SelectedItem to focus just because it's a shorter name.)

We're not quite finished with the control routine, let's take a closer look:

When you examine the code you will realise how we are patronising the computer. We are asking it to add 1 to focus when newin = 1 and subtract 1 when newin = -1, as if it is not capable of basic arithmetic!

Much better! Now you should be looking at the bounds checks below and rubbing your chin, they also have > and <, can they be combined as well? They could be but I can't find a way that doesn't introduce unnecessary calculations. Since we are trying to write neat and efficient programs, not show-off, we'll leave it how it is.

And so we come to the end of the menu, people are getting bored looking at options and want to be let out! Since we have no game to go to yet I've added a place-holder.

This works but I'd rather we change it to act on a key press. We've already done this earlier so if you don't know how to then you weren't paying attention! Okay, here it is:


Here's the finished program:

I was reminded how important it is to know where your sync and cls are: my "exit" text wasn't displaying because it came after the sync and before the cls, so it was being wiped before it had been displayed. This problem is why I like to keep sync and cls next to each other at the end of the loop.

I hope you've read all this and can understand my weird way of explaining things!

Challenge: play a sound when a key is pressed. Bonus: give the sound a higher pitch when moving up the menu and a lower pitch when moving down by using SET SOUND SPEED.

WARNING: The above comment may contain sarcasm.
Darkzombies
13
Years of Service
User Offline
Joined: 25th Dec 2010
Location: In multiple tabs, most likely youtube.
Posted: 10th May 2012 03:10
I understand it, but is it really neccessary to shorten


to



? I mean, in this case, I assume there are cases where this will shorten it alot.

Oh yeah, and after I saw the data statements I'm like OHHHHH!

Cause I didn't think of that :3

-------------------------------------------------------------
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 10th May 2012 03:31 Edited at: 10th May 2012 03:33
Quote: "is it really neccessary..."

Using a repeat loop causes the program to halt until the key is released. What if you wanted a dynamic menu with animation or a 3D scene in the background? All that would freeze when you held the key down. Now what about reading key presses for commands in game? It would be disastrous if the game froze every time you pressed a key.

Shortening isn't the goal, we want efficiency, it just happens that making things more efficient usually reduces the amount of code. My version is actually slightly longer if you cram them onto one line each

My version assigns two variables and does one comparison. The original assigns no variables and does one comparison, but it has a loop which could theoretically cycle infinitely! (If you could hold the key for that long.) Whereas the second has no such loop, therefore it is more efficient as it is doing fewer operations to achieve the same result.

WARNING: The above comment may contain sarcasm.

Login to post a reply

Server time is: 2024-03-28 20:24:36
Your offset time is: 2024-03-28 20:24:36