ID:1819981
 
Randomized Ground Cover

I'd like to share a really basic snippet to help new users randomize their ground cover like grass and dirt.

What it looks like before randomization

What you get is a really dull looking ground cover and yes I know this is using black and brown. It's an example.




What it looks like after randomization

Here's the same example with variation in the brightness which gives the impression of hills and crests. This doesn't look like flat ground anymore. Also the arrangement of dots is randomized for each icon. I did this on MS-Paint using the spray can tool.

You may personally want more states or more/less variation in brightness.




What code is used for this?

This code gives each turf object the ability to be randomized. Chosen turf will automatically be randomized when they are created on the map.
turf
icon = 'Turf.dmi'
var
randomize = FALSE
randomStates = 0 // How many icons you've made

proc
randomizeIcon()
icon_state = "[name] [rand(0,randomStates)]"

New()
..()
if(randomize == TRUE)
randomizeIcon()


This code shows what would need to be set to work with the following icons.
turf/Ground

Rock
icon_state = "Rock"
randomize = TRUE
randomStates = 3




END
Thank you for reading my snippit.
Looks good :)
Zecronious wrote:
 turf
icon = 'Turf.dmi'
var
randomize = 0 // 0 = OFF, 1 = ON
states = 0 // How many icons you've made

proc
randomizeIcon()
icon_state = "[name] [rand(0,states)]"

New()
..()
if(randomize == 1)
randomizeIcon()


Given the randomize var is used as a switch, if(randomize) would suffice.
In response to Lige
Lige wrote:
Given the randomize var is used as a switch, if(randomize) would suffice.

So lets imagine that was used instead. What you would be allowing people to do is this:

turf/Ground

Rock
icon_state = "Rock"
randomize = 1
states = 3

Grass
icon_state = "Rock"
randomize = 3
states = 3


Grass has randomize 3 and Rock has randomize 1. Does this mean something different? Is grass being randomized differently?

Doing what you said would possibly make things look ambiguous. For the sake of writing more readable code, lets keep things consistent and clear.
In response to Zecronious
Zecronious wrote:
Lige wrote:
Given the randomize var is used as a switch, if(randomize) would suffice.

So lets imagine that was used instead. What you would be allowing people to do is this:

 turf/Ground

Rock
icon_state = "Rock"
randomize = 1
states = 3

Grass
icon_state = "Rock"
randomize = 3
states = 3


Grass has randomize 3 and Rock has randomize 1. Does this mean something different? Is grass being randomized differently?

Doing what you said would possibly make things look ambiguous. For the sake of writing more readable code, lets keep things consistent and clear.

That's assuming people would assign those values. You clearly express that randomize is a boolean - 0 is false; any other value is true. It's pretty much just faster to check if there is no value or has a value, instead of checking for an explicit value.

Why not just:
turf
icon = 'Turf.dmi'
var
states = 0 // How many icons you've made

proc
randomizeIcon()
icon_state = "[name] [rand(0,states)]"

New()
..()
if(states)
randomizeIcon()

Rock
icon_state = "Rock"
states = 3
In response to Super Saiyan X
SSX Wrote:
That's assuming people would assign those values.

SSX, if no one would ever assign those states then what's the point in allowing them?

SSX Wrote:
It's pretty much just faster to check if there is no value or has a value, instead of checking for an explicit value.

Are you sure about that? The statement: if(randomize) is actually equivalent to the statement if(randomize != 0).

We're dealing with elementary operations here and there is for all practical purposes no speed difference between elementary operations. In time complexity analysis elementary operations such as most binary operations (except for modulus) are considered to have a constant time complexity.

SSX Wrote:
Why not just:
if(states)

Again, clarity. If you read an object's definition and it has 'states = 3'.. What does that mean? What does it do? It would be far more clear to define it as either being randomized or not.

You might want to argue that it would take up less space in memory per object if you only had states but what you would be missing is that memory space is not at a premium these days. We have a vast amount of memory available and we can afford to add extra clarity to our code.

In response to Zecronious
Zecronious wrote:
Again, clarity. If you read an object's definition and it has 'states = 3'.. What does that mean? What does it do? It would be far more clear to define it as either being randomized or not.

You could always explain it in your initial post. You're making it seem like it's far more complicated than it actually is.

You might want to argue that it would take up less space in memory per object if you only had states but what you would be missing is that memory space is not at a premium these days. We have a vast amount of memory available and we can afford to add extra clarity to our code.

Regardless of how small the memory difference is, you're still adding unnecessary fluff.

Zecronious wrote:
Randomized Ground Cover

I'd like to share a really basic snippet to help new users [...]

If you really want to help new users, you should avoid providing snippets that add unnecessary fluff. If that means explaining things further, they can handle it. Those who can't, especially over something so basic, are more than likely looking to be fed -- not taught to feed themselves.
In response to Lige
Lige, what you're saying is that I should write code that isn't readable by itself and instead requires an external explanation like a manual to use.

Do you realise how self defeating that is and how much that goes against good programming practice?

Code should be easy to understand, comments should be minimal and external explanations should be at a minimum or non existent because the code should be self explanatory.

unnecessary fluff
I would like to also address what you said here because I think this is the core of our difference in opinion. You think that my attempts to make my code more readable without impacting it's performance in any significant way is unnecessary.

I would disagree and say that anything I can do to make my code more readable and maintainable without taking too much time is completely necessary and fundamental to writing good code.
If you want clarity, document your code.

Even in your example, there's no way to know what states and randomize have to do with each other; that's why you have that comment right next to them.

var/states = 3 //selects between rand(1, states); set to 0 to disable randomization



You already have a value that declares how the possible variations; why have a value that decides if those variations should even be used?

Have an on/off switch, and then another value which is effectively pointless if the switch isn't on.
I think that there are probably better ways to handle this, but regardless the snippet gave me an idea or two. Whether or not it is received with love from everyone, I appreciate you sharing it.

It brings to mind a question, though. Is there a way in DM to figure out the length of a file? For example, say that I have three icon_states in an icon file-- Are there any procedures that would allow one to figure out how many icon states there are within that file?

If not, what kind of code might one use to figure it out?

(Random thing that comes to mind: I prefer using TRUE or FALSE for booleans-- It tends to save any confusion/headache from occurring. But it is also okay that you did not. :p)
In response to Aero Sye
Aero Sye wrote:
It brings to mind a question, though. Is there a way in DM to figure out the length of a file? For example, say that I have three icon_states in an icon file-- Are there any procedures that would allow one to figure out how many icon states there are within that file?

If not, what kind of code might one use to figure it out?

There are two built-in functions to retrieve a list of icon_states from an icon.

icon.IconStates() (from an /icon object)
icon_states(icon) (from an icon file, or object)

They both return a list of the icon_states as strings. You can then use the list.len variable, or length() function to get the length of the list.
In response to Super Saiyan X
Super Saiyan X wrote:
If you want clarity, document your code.

Even in your example, there's no way to know what states and randomize have to do with each other; that's why you have that comment right next to them.

> var/states = 3 //selects between rand(1, states); set to 0 to disable randomization

You already have a value that declares how the possible variations; why have a value that decides if those variations should even be used?

Have an on/off switch, and then another value which is effectively pointless if the switch isn't on.

Okay I understand what you're saying. Your style is to reduce code and increase documentation (comments).

What I'm saying is that I believe it's friendly to other people reading my code if I write the code so well that I don't have to give lengthy comments. Your comment there is very long and seems unnecessary if the code was just written a little more clearly.

You said that randomization and states seem to be unrelated. That's a pretty good point and got me thinking. The way that I make sure people know they're related is that I keep them together when writing an object definition. My understanding is that if you're using this snippit in your project then you have some grasp of what it does and you got that grasp by reading the easy to understand code.
In response to Super Saiyan X
I see. That's useful, then. Thanks!
In response to Aero Sye
Aero Sye wrote:
I think that there are probably better ways to handle this, but regardless the snippet gave me an idea or two. Whether or not it is received with love from everyone, I appreciate you sharing it.

Thank you very much, I'm glad to be of assistance.

(Random thing that comes to mind: I prefer using TRUE or FALSE for booleans-- It tends to save any confusion/headache from occurring. But it is also okay that you did not. :p)

I agree and I as well pray for the day that they get added to the language. I could use a #define to add it myself but it makes it more difficult to share code with other people when you have to either go through the defines yourself or include your definitions in your snipit.
I actually recall them working.. Maybe I'm getting it mixed up with Python, but I am pretty sure I used them quite recently. Try with all caps and no caps and with the first letters capitalized-- I'm nearly certain you'll find that one of those works.
In response to Zecronious
Zecronious wrote:
Aero Sye wrote:
I think that there are probably better ways to handle this, but regardless the snippet gave me an idea or two. Whether or not it is received with love from everyone, I appreciate you sharing it.

Thank you very much, I'm glad to be of assistance.

(Random thing that comes to mind: I prefer using TRUE or FALSE for booleans-- It tends to save any confusion/headache from occurring. But it is also okay that you did not. :p)

I agree and I as well pray for the day that they get added to the language. I could use a #define to add it myself but it makes it more difficult to share code with other people when you have to either go through the defines yourself or include your definitions in your snipit.


Er. TRUE and FALSE are pre-defined in the stddef. You can use them without defining them yourself.
In response to Aero Sye
In all the time I've been here I've not known of them being built into the language. Maybe they got added but I'm not aware if they did.
In response to Zecronious
Zecronious wrote:
In all the time I've been here I've not known of them being built into the language. Maybe they got added but I'm not aware if they did.

Here's the entire contents of the stddef.dm:

ID:1820598
In response to Super Saiyan X
How that evaded me for so long I will never know. Thanks, I'll start using that now.
Update:

Now uses TRUE/FALSE.
Now uses randomStates instead of states to be more clear.
Page: 1 2