Learning

http://timaster.googlepages.com/GameofLife.exe
http://timaster.googlepages.com/GoLpref.ini
Put these two in the same folder.
Open the .exe, then open the .ini.
The .exe will output a pretty pattern!
Now, an explanation of how this works.
Every time you hit space, the game pauses.
Every time you hit enter, the game reads the .ini. So what you may do is change the pattern on the screen as it goes.

Now here’s how the game works:
Each row of pixels is a bunch of numbers from 5 to 0. The game logic reads everything that isn’t a 0 as a 1. The higher numbers exist only for pretty colors.
So, in a 1/0 environment, we start with (for example):
010010100
There are certain rules that define how the next line is printed.
111 → 1#1
101 → 1#1
110 → 1#0
100 → 1#0
010 → 0#0
000 → 0#0
This is the setup for all the rules.
The game looks at every combination of 3 numbers, and depending on the rules set, it writes the middle number of the next line. The game, however, does not differentiate between 100 and 001 (it doesn’t care what side the 1 is on).
If the rule for 101 is is 1, then 101 results in a 1 printed on the next line.
Let’s set the default rules, and see what happens to the previous line.
111 → 0
101 → 0
110 → 0
100 → 1
010 → 0
000 → 0
Now, 010010100 obviously has edges, but we’ll treat it as a circle. The leftmost 0 has a 0 to the left of it.
According to this, 010010100 becomes 101100010
The first numbers is in a 001, so it writes a 1. The next is 010, so it writes a 0. Then 100 is a 1, etc.

If that makes sense, you can start messing with the game!

Here’s a list of all the possible values for each field, what they mean, and when to use them:

x, y: These are the screen dimensions, but these (unlike everything else in the .ini) are only read when you start the game. If you want to change the resolution, close the game before you change these values.
fullscreen: Changes whether the game is fullscreen or not. I recommend setting x and y to your desktop resolution values if you do this in fullscreen.

all: Defines the starting values of all the squares. Preset values are
all0/all1 - The value of every pixel in the initial row is 0 or 1, for all0 and all1 respectively.
rand - Each value is defined anywhere from 0 to randWeight - 1, rounded up. More info under randWeight. Using this option while the program is running will oftentimes result in a single wacky-looking row of pixels. Yes, this is supposed to happen, don’t worry.
alt - The first pixel is 0, the next is 1, the next is 0, etc.
none - Don’t change anything. Useful if you want to modify the rules in the middle of a pattern without resetting the pattern. Do NOT leave it as none when you start the program, though, it will crash. Always start with one of the other options.
randWeight: Changes the chance that the initial row of a randomly initiated pattern is colored. A randWeight of 1 to 0 will result in all initial pixels being 0s. If you want only a few scattered pixels to be 1s, make randWeight 1.05 or so. If you want only a few pixels to be 0s, make randWeight really high. A randWeight of 2 will result in approximately 50/50 distrubution of 0s and 1s in the initial row.
howManySingle: The next few lines are allocated for if you want to set specific pixels. howManySingle tells the game how many specific pixels you want to set.
resetStatic: If you have set static pixels earlier, this will clear them all, and let them be overwritten.
setSingleI#: The location of the pixel you want to set.
setSingleVal#: The value of the pixel you want to set.
setSingleStatic#: Whether or not the pixel you have set is static. If it is static, it will NOT CHANGE until you reset all static pixels, or write a non-static single pixel to the same location later.

rule###: For rule111, setting a value of 1 will mean 111 → 1 as described above. Remember, rule110=0 means that 110 → 0 AND 011 → 0. This is also where you set the colors. Anything that isn’t a 0 is a 1, in terms of rules, so write in any number from 1 to 5 as a 1 to color things a bit.
color#: Every value is output as a color. The default colors are black, white, red, green, blue, yellow, in that order. Change these to whatever you like, they do not affect the actual game logic in any way at all, but sometimes yield prettier results.
Use the formula R*(256^0)+G*(256^1)+B*(256^2) where R, G, and B are numbers from 0 to 255 to get colors.

PLEASE NOTE:
You must save the .ini each time you change something, before you go back to the game screen and hit enter. If you hit enter, and nothing happens, chances are you forgot to save.
Other things to keep in mind are that howManySingle should be 0 whenever you’re planning on not changing anything. Reset its value to 0 every time you use it, so you don’t forget. Same goes for resetStatic. It’s also a good idea to reset all to none every time, so you don’t accidentally reset the whole pattern.

Also, the previous post with 1s and 0s is a list of all of the good 1/0 patterns. Everything else stabilizes or loops within a few pixels.
Read it as:
000100
is
111 → 0
101 → 0
110 → 0
100 → 1
010 → 0
000 → 0
And stuff.
If you don’t get anything, please ask me to explain. I suck at explanation <3

Shit, I miscalculated white in the .ini. Link updated.

Different rule settings lead to very interesting designs :astonished: . Here are some cool ones I’ve found so far: (in the order of 111, 101, 110, 100, 010, 000)
0 3 4 5 2 0
0 3 0 5 2 0
2 0 0 0 0 1
2 1 0 2 1 0

Just try sticking in other numbers for 1 in the list Tim posted earlier.

I haven’t even tried changing the colors yet.

Troid and I spent a while dicking around with pointers in C++ today. If you’re interested, go grab a copy of dev-cpp (FREE! http://www.bloodshed.net/devcpp.html) and join in the fun!

I’d like to type up a full explanation of the way RAM works when you’re coding a C/C++ program, which I’ll probably do tomorrow. Until then, I present you with a program that allows you to edit, bit by bit (yes, bit, like 1/0), any data type in C++, and observe what happens to the output! Doubles are confusing and weird, but datatypes like int are quite simple. Simplest is an “unsigned short int”, so we’ll work with that for now. A short int is 2 bytes (varies by compiler) that hold an integer value, as opposed to a regular int, or more properly, a “long int”, which is 4 bytes (in visual studio), and “unsigned” means it cannot be negative. The first bit in a signed int is responsible for negative/positive values, and because of the way binary works, an unsigned int (short or long) is twice as big, but can’t be negative. Anyway, here’s the code:

[code]#include
using namespace std;

unsigned char bin2dec(const char *bin);

int main()
{
unsigned char *pointer;

pointer = new unsigned char[8];

pointer[0] = bin2dec("01000001");
pointer[1] = bin2dec("00000000");
pointer[2] = bin2dec("00000000");
pointer[3] = bin2dec("00000000");
pointer[4] = bin2dec("00000000");
pointer[5] = bin2dec("00000000");
pointer[6] = bin2dec("00000000");
pointer[7] = bin2dec("00000000");

// add more pointers here if need be

unsigned short int *variable;
variable = (unsigned short int*)&pointer[0];

cout << sizeof(variable) << '\n' << *variable;

cin.get();
return 0;

}

unsigned char bin2dec(const char *bin)
{
unsigned char result = 0;
for(;bin;bin++)
 result=result
2+(*bin-‘0’);
return result;
}[/code]
All you have to do is fill the 0s with whatever you like. Each line of 0s is a single byte. The output of the program is the number of bytes in the variable, and the variable itself (should be 65 on most computers right now, and PLEASE PLEASE tell me your operating system and compiler if it’s not). Editing bytes past the size of the variable is pointless, for what should be obvious reasons. So right now, if the size of the variable is 2 (which I think it is on all compilers), edit pointer[0] and pointer[1].

Uhhh, yeah, so have fun, and as always, please ask if there’s anything I didn’t explain fully enough.

EDIT: Oh yeah, credit to some dude on google for the binary to decimal converter. It’s heavily modified, but the basic idea is his, so yay at him. All of the other code is mine, and the idea is mine and troid’s collaborative effort.

EDIT2: Oh yeah2, if you know a bit about C++, you might be asking “what the bloody hell is an unsigned char?”. The answer is simple: Characters in C++ are just 1 byte integers, with an extra bit on the end that doesn’t mean anything. How is this possible? The ASCII table, of course! A signed char will return wonky values if the last bit has a 1 in it. By unsigning the char, I can use it exactly as I would an integer, and there’s no other integer datatype of 1 byte, so unsigned char is very very convenient. DO let me know if your compiler doesn’t support this, though! It’s a strange thing to do, so it might give you warnings along the lines of “What the hell are you thinking?”.

So I was bored yesterday, and made a program that draws a sine wave in the RAM usage monitor in the Windows task manager (or any RAM monitor, if it works properly). I put the finishing touches in today, and because I think it’s a totally nifty idea, I uploaded it.

  1. Open your task manager (ctrl+shift+esc).
  2. Hit the “Performance” tab.
  3. Download and run this.
  4. Wait a few minutes for the graph to form!

Credit to Troid92 for helping me work out a couple of weirdnesses.

CAUTION: This uses a ton of RAM. About .4 GBs worth of it. If you don’t have that much RAM available, your computer will slow down MASSIVELY as soon as you run the program.

Source code available on request in case someone thinks it’s a keylogger.

that is amazing tim.

.4GB of ram is what I eat for breakfast, however.

I have twice that free, and am playing crysis.

So now I’m learning how to code for SNES, in 65816 assembly.
I don’t think anyone here actually wants to get involved, but I’m so fascinated by the differences between assembly and higher level languages that I think I’m going to post a brief overview of the coolness.
DISCLAIMER: I don’t know shit. If I’m wrong, D: and :[. I’m working under the assumption that none of you will ever write a single line of assembly in your lives, so any inaccuracies in what I say don’t really matter.
Anyway, yeah, let’s… commence.

The first and fascinatingest thing ever is that the code of assembly seems to translate directly into binary. You can code it in binary if you so prefer. An example line of code looks like this:

MOV AL, 61h

This SAME code looks like this in machine code:

10110000 01100001

(note: this isn’t an SNES command, it’s for intel processors)

In contrast, C++ has no 1 to 1 correspondence between code and language. What’s so cool about this? ALL compiled binaries (that you know and love by the name of .exe) can be written in machine code without any loss of data. Pretty darn awesome! (It also means writing compilers for machine code is stupidly easy…)

The next point is the obvious point that it’s very low level, meaning that when you do something, you are actually doing it. In a high-level language like TrueBASIC, when you assign a variable, you are actually cutting out an enormous chunk of memory, jamming numbers in there, making a separate piece of memory that holds the variable’s name, making a variable that stores the location of the variable, and suchlike.
In C++, a medium-level language, when you assign a variable, you are requesting memory, assigning a value to an address, an address to an address, and tying an address to a name.
In assembly, you don’t even have variables. You just have addresses and values. You can request memory. You can assign assign a value to an address. You can assign an address to an address. You can form a variable using the separate commands for doing those.
Anywho!
On to the way it works.

Most all of the basics revolve around 3 things:

  1. There are certain memory addresses that are responsible for stuff. For instance, the memory address at the 8448th location (commonly known as $2100, where $ means hexadecimal) is responsible for turning drawing on or off, as well as brightness. So all you have to do is write something there, and the computer automatically interprets it as meaning whatever it’s supposed to mean.
  2. There are 3 “registers”, which I can’t really describe, except as variables. Basically, they are your only 3 variables. EVERYTHING has to be done through them. For instance, you can’t write a number to an address. You can write a number to a register, and you can write a register to an address.

lda #%00001111 sta $2100
The first line writes the binary value 00001111 to register A (the only register that can store values - the other two, X and Y, store addresses), and the second one writes the value in register A to $2100. These two lines turn the screen on and set it to max brightness. So, to reinforce the point, I’m not writing 00001111 directly to $2100, I’m writing it to A, and then writing A to $2100.
3) The code is stored in a linear order on the hard drive. The processor literally just reads it from the beginning to the end. Since the only looping and if statementing methods involve goto/label structures, this makes everything makes substantially more sense than in a higher level language. The code can easily be seen as a series of 1’s and 0’s and a jumping cursor flying over and reading it. Very very VERY logical and precise.

There you have it. The awesomeness of assembly. Super nifty, amirite?

I think there’s an emacs command for that.

  1. rofl
  2. I just realized PAIN:
    High level languages give errors if you mess anything up at all, even the minorest thing.
    Assembly frickin’ NEVER gives errors (it’s really hard to mess up lines of 3 letters and a number syntactically) but NEVER functions the way you want it to either. With great power comes great responsibility…

With great power, comes OH CRAP I WIPED MY RAM AGAIN

Precisely :confused:

By the way, your description of assembly was good. (I took an “introduction to microprocessors” college class a few semesters ago that taught me quite a bit about assembly and the inner workings of processors. I even got to program a processor by typing hexadecimal data on a little keypad.)

So I made my first multithreaded program in response to the horsedickery in the Processors topic.

And I must say, WOWZA. Without a pause in my code, moving a pixel 0.00000001 pixels a cycle throws it off the screen before I even draw to the screen. Without multithreading, it took a good minute at .0001 pixels a second. That’s 10 thousand times faster!
Here’s why:
For those of you who don’t already know wtf multithreading is, it allows you to run different parts of a program independently of one another, each at its own pace. They still compete for processor time, but only as much as they compete with other processes. One doesn’t strictly wait for the other (unless you tell it to for some reason).
In the case of this program, I have two threads, one of which is responsible for calculations in real-time, and the other of which is responsible for displaying the results on the screen, which is ZOUNDS AND GADDLES more time-consuming than calculation, so if we do one calculation per every draw to the screen, we end up calculating ZOUNDS AND GADDLES slower. With multithreading, you can have one part go at the speed of your calculations, and the other at the speed of your drawing.

ZZZZZZZZZZZZZZOOM.

So it’s been a while, but I’m writing a program now that should be vaguely interesting to some here, since it’s gonna be doing some… drumroll
RAYTRACING.

In this case, the raytracing involved is astoundingly simple, since it involves a spherical light source of radius a centered at location (xl,yl,zl), a mirrored sphere of radius b centered at location (xs,ys,zs), and an observer of size 0 at infinity.

Raytracing, as you probably know, just means that instead of assuming some things about the way light works, we actually take some light waves (not ALL light waves) and calculate the path they take through space.
At this point I should inform you I lied to you - I’m not going to be looking at light waves (lines of light), I’m going to be looking at clumps of light waves that I know are reflecting off of one point on the sphere (cones of light). There’s a good reason for this assumption though. The thing is that since I’m infinitely far away, infinitely zoomed in, and infinitely small, it’s pretty hard to find light that actually intersects me (light that I can see). If a cone of light is pointed in my general direction, however, I know that I can see some of that light. Here’s a picture of what I mean:

Even though the observer is infinitely small and infinitely far away, some of that light is going to reach him.
All I have to do to calculate if any given cone of light is reaching the observer is make sure that the sides of the cone pass on either side of the observer.

TOMORROW (or whenever I get around to it):
What cones of light are we talking about?

EDIT:
I didn’t sleep, so here’s the update where I talk about why the hell I think cones of light are relevant.
Let’s draw our system in two dimensions - a circular light source, a bigass shiny circle, and an infinitely small observer infinitely far away.

The result we’re looking for in the original problem is a 2D image - a 2D projection of the 3D sphere and the light reflected off of it. In this 2D case, our projection will be 1D. We want to form a 1D projection of the side of the 2D circle. The width of the circle is about 80 pixels, so what we’re really looking to draw is 80 pixels of varying brightness.

To me it seems the most logical way to calculate the brightness of each pixels, is to take another shortcut. Instead of tracking rays or cones of light emanating from the light source until we find one hitting the sphere at a point visible to the observer, we’ll instead take a point visible to the observer (one of the 80 pixels), then check to see if there’s any light shining on it at all, and finally we’ll draw a cone of light from the source to the point on the circle in question. There’s one tricky bit here - converting from a pixel to a point on a circle. This, actually, is the sole reason I chose to fix the observer infinitely far from the circle. This way, each pixel corresponds to a line in space, and all the lines are parallel and of equal width (1 pixel). Here’s how that looks:

Each of the black/white lines is a pixel in 1D space, and a point on the circle in 2D space. With that knowledge, all it takes is some basic trigonometry to translate each pixel into a point on the circle.
Finally, we’ve advanced far enough to answer the initial question.
Q: What cones?
A: Each cone of light consisting of every ray emitted from the source and reflected off of the 80 points on the circle we’re testing.

The angle of the cone reflected is the same as the angle of the incoming cone. The size of the cones are the same too.
We now know how to do all three steps involved in this raytracing system, at least in 2D space.
Step 1: Pick a pixel on the 1D projection of the circle and convert it into a point in 2D space on the circumference of the circle.
Step 2: Find the cone of light emanating from the source and hitting the point in question, and reflect it into space.
Step 3: See if the reflected cone is visible by the observer.
If the cone is visible, we can shade the original pixel in the color of the light source!

That actually ended up covering all of the logic behind what I’m doing. I won’t bother posting the math, because I’ll post my code when I’m done if anyone wants to dig the math out, but maybe I’ll make a post explaining the medium I’m working in (facebook graffiti) so that my code can be better understood when I do post it. I’ll also probably post an explanation of how this is expanded to 3D space, even though it’s really the same shit.

PS The light involved here is perfectly reflected. If light is perfectly scattered (like on a sheet of paper - you’ll never shine a light on paper and be unable to see it from a certain angle), then all you have to do is make the reflected cone infinitely wide… spherical, to be precise. The ‘reflected’ light goes in all directions. If you want to mix degrees of reflection and scattering, just make the reflected cone larger by whatever amount. The closer the size of the reflected cone to the size of the incident cone, the more reflective the surface will appear.

PPS I haven’t slept in 24 hours, please please please forgive me if I said anything stupid or wrong or overlooked something. I’m really tired. Goodnight!

So I ran the first successful build of the code today and it um… didn’t do anything.
Please stand by >_>

mayhaps you need to molest it for awhile?
its usually works for me

Incidentally, with your multithreading thing, the fastest speed increase you could get is (number of cores) * original speed. Did you not use a Semaphore or a Critical Section object to prevent the multiple threads from writing to the same variable at the same time? Because not using one of those can really screw up multi-threaded programs. :stuck_out_tongue:

Sure, sure, really old post, but what do I care? It’s in this topic! <.<

The way I had the program set up, the speed increase was 1/10000 for the slower of two functions, and 10000 for the function that already took almost no time. Basically, the way I had it set up originally was a loop of two functions:

core1[ slow_function() fast_function() ] core2 [ ]
and then I put each function in each own thread:

core1[ slow_function() ] core2[ fast_function() ]
What you’re describing is if I’d gone from

core1[ slow_function() fast_function() ] core2 [ ]
to

core1[ slow_function() fast_function() ] core2 [ slow_function() fast_function() ]
The point is that the fast function is no longer limited by how slow the slow function is. So it can go as fast as it likes… and it happened to be about ten thousand times faster than the slow function. Yay!

I forgot to mention, of course, that I’m not doing 10,000 times as much processing (that would be what increased by 2 times). But I am running a function 10,000 times faster.

And to answer your question, no, I did not use a critical whatever, because I didn’t write to the one variable the two threads shared at all in one of them, so there was no risk of doing that.