Elsewhere there are things that we all miss, yet it takes just one to notice...

Perfect Maze now working

After a thorough going over of the code, I’ve managed to get this one working. Although painfully slow, at least it works. In the future I will be looking at other algorithms which are much faster. I only remembered this one from a long time ago so I just thought I’d have a go on my own without any help with implementing it.

// File: generate.agc
// Created: 19-09-21

/*
	Attempting to generate a maze using a decent algorithm.
	Unfortunately this particular algorith is painfully slow,
	but for the time being, it does work.
*/

type MAZE
	seed as integer
	wid as integer
	hgt as integer
	maze as integer[0,0]
endtype

function maze_get_odd_random(max as integer)
	val = random(0, ((max - 2) / 2)) * 2 + 1
endfunction val

function maze_not_visited(obj ref as MAZE, xpos, ypos)
	val = obj.maze[ypos, xpos]
endfunction val

/*
	The width and height have to be even numbers.
	NB: In AGK this means 0 to width (as even) for example
		NOT 0 to width - 1
*/

function maze_gen(obj ref as MAZE, wid as integer, hgt as integer, seed as integer)
	obj.seed = seed
	
	SetRandomSeed(seed)
	
	obj.wid = wid
	obj.hgt = hgt

	/*
		Wierd way of assigning a multidimensional array
		Assign the first dimensions length
		And then assign the length of each separate part
		ie.
		a[0].length = 5 (giving a[0,4])
		is not the same as
		a[1].length = 10 (which gives a[1,9])
		
		Also, AGK arrays end with the value assigned.
		ie. length is 10 so the array goes from 0 to 10
		instead of 0 to 9.
	*/
	
	obj.maze.length = hgt

	for c = 0 to hgt
		obj.maze[c].length = wid
		
		for x = 0 to wid
			obj.maze[c, x] = 1
		next
	next c
	
	/*
		If I remember correctly, I choose a random cell.
		But, it has to be, erm, ODD or EVEN???
		I will find out...
		
		It has to be odd.
	*/
	
	currentx = maze_get_odd_random(wid)
	currenty = maze_get_odd_random(hgt)
	
	// set position to 0
	
	obj.maze[currenty, currentx] = 0
	
	done = 0
	
	repeat
		
		// iterations to run through (might increase)
		for route = 0 to 63
			
			/*
				Basically direction is UP, DOWN, LEFT or RIGHT
			*/
			
			direction = random(0, 3)
			
			select direction
				case 0:
					if currenty - 2 > 0
						if maze_not_visited(obj, currentx, currenty - 2)
							obj.maze[currenty - 2, currentx] = 0 // clear path
							obj.maze[currenty - 1, currentx] = 0 // between
						endif
						dec currenty, 2
					endif
				endcase
				
				case 1:
					if currenty + 2 < hgt
						if maze_not_visited(obj, currentx, currenty + 2)
							obj.maze[currenty + 2, currentx] = 0
							obj.maze[currenty + 1, currentx] = 0
						endif
						inc currenty, 2
					endif
				endcase
				
				case 2:
					if currentx - 2 > 0
						if maze_not_visited(obj, currentx - 2, currenty)
							obj.maze[currenty, currentx - 2] = 0
							obj.maze[currenty, currentx - 1] = 0
						endif
						dec currentx, 2
					endif
				endcase
				
				case 3:
					if currentx + 2 < wid
						if maze_not_visited(obj, currentx + 2, currenty)
							obj.maze[currenty, currentx + 2] = 0
							obj.maze[currenty, currentx + 1] = 0
						endif
						inc currentx, 2
					endif
				endcase
			endselect
		next
		
		/*
			Print this mazes iteration (just for testing)
		*/
		
		Print( ScreenFPS() )
		maze_print(obj)
		print("Calculating...")
		sync()
		
		/*
			Check if maze is done (the silly bit)
		*/
		
		done = 0
		
		for h = 1 to hgt - 1 step 2
			for w = 1 to wid - 1 step 2
				if obj.maze[h, w] = 1
					done = 1
					exit // quick exit if not done
				endif
			next
			if done = 1 then exit
		next
		
	until done = 0
	
endfunction obj

function maze_print(obj ref as MAZE)
	print (obj.wid)
	print (obj.hgt)
	//print (random(0, 2) - 1) // HUH
	
	for h = 0 to obj.hgt
		s as string = ""
		for w = 0 to obj.wid
			if obj.maze[h, w] = 1 then s = s + "#" else s = s + " "
		next
		print (s)
	next
endfunction

Hmm… Almost…

// File: generate.agc
// Created: 19-09-21

/*
	Attempting to generate a maze using a decent algorithm
*/

type MAZE
	seed as integer
	wid as integer
	hgt as integer
	maze as integer[0,0]
endtype

function maze_get_odd_random(max as integer)
	val = random(0, max / 2) + 1
endfunction val

function maze_not_visited(obj as MAZE, xpos, ypos)
	val = obj.maze[ypos, xpos]
endfunction val

/*
	The width and height have to be even numbers.
	NB: In AGK this means 0 to width (as even) for example
		NOT 0 to width - 1
*/

function maze_gen(obj ref as MAZE, wid as integer, hgt as integer, seed as integer)
	obj.seed = seed
	
	//SetRandomSeed(seed)
	
	obj.wid = wid
	obj.hgt = hgt

	/*
		Wierd way of assigning a multidimensional array
		Assign the first dimensions length
		And then assign the length of each separate part
		ie.
		a[0].length = 5 (giving a[0,4])
		is not the same as
		a[1].length = 10 (which gives a[1,9])
		
		Also, AGK arrays end with the value assigned.
		ie. length is 10 so the array goes from 0 to 10
		instead of 0 to 9.
	*/
	
	obj.maze.length = hgt

	for c = 0 to hgt
		obj.maze[c].length = wid
		
		for x = 0 to wid
			obj.maze[c, x] = 1
		next
	next c
	
	/*
		If I remember correctly, I choose a random cell.
		But, it has to be, erm, ODD or EVEN???
		I will find out...
		
		It has to be odd.
	*/
	
	currentx = maze_get_odd_random(wid)
	currenty = maze_get_odd_random(hgt)
	
	// set position to 0
	
	obj.maze[currenty, currentx] = 0
	
	done = 0
	
	repeat
		
		// iterations to run through (might increase)
		for route = 0 to 3
			
			/*
				Basically direction is UP, DOWN, LEFT or RIGHT
			*/
			
			direction = random(0, 3)
			
			select direction
				case 0:
					if maze_not_visited(obj, currentx, currenty - 2) and currenty - 2 > 0
						obj.maze[currenty - 2, currentx] = 0 // clear path
						obj.maze[currenty - 1, currentx] = 0 // between
						currenty = currenty - 2
					endif
				endcase
				
				case 1:
					if maze_not_visited(obj, currentx, currenty + 2) and currenty +2 < hgt
						obj.maze[currenty + 2, currentx] = 0
						obj.maze[currenty + 1, currentx] = 0
						currenty = currenty + 2
					endif
				endcase
				
				case 2:
					if maze_not_visited(obj, currentx - 2, currenty) and currentx - 2 > 0
						obj.maze[currenty - 2, currentx] = 0
						obj.maze[currenty - 1, currentx] = 0
						currentx = currentx - 2
					endif
				endcase
				
				case 3:
					if maze_not_visited(obj, currentx + 2, currenty) and currentx + 2 < wid
						obj.maze[currenty, currentx + 2] = 0
						obj.maze[currenty, currentx + 1] = 0
						currentx = currentx + 2
					endif
				endcase
			endselect
		next
		
		/*
			Check if maze is done (the silly bit)
		*/
		
		for h = 1 to hgt - 1 step 2
			for w = 1 to wid - 1 step 2
				if obj.maze[h, w] = 1
					done = 1
					exit // quick exit if not done
				endif
			next
			if done = 1 then exit
		next
		
	until done = 0
	
endfunction obj

function maze_print(obj ref as MAZE)
	print (obj.wid)
	print (obj.hgt)
	print (random(0, 2) - 1) // HUH
	
	for h = 0 to obj.hgt
		s as string = ""
		for w = 0 to obj.wid
			if obj.maze[h, w] = 1 then s = s + "#" else s = s + " "
		next
		print (s)
	next
endfunction

Not quite working… Need a nap… Not well…

A Perfect Maze

So I got an algorithm done last week that produced a perfect maze. Unfortunately though, I wiped my 2 x 1Tb SSD’s on my PC and didn’t back up the code.

So I am starting again.

(I’m not too good by the way, so I am documenting this)

I didn’t want a recursive algorithm because I think that on low end architecture this would be bad for memory usage. This meant that the algorithm would possibly be slower. For a 40 by 40 maze it would still be instant, even though there was a silly check in there.

Here goes. (back soon with some snippets)

I’m using AGK and will port everything to C.

Back to these C++ tuples

Okay, now that Christmas and New Year is finally over and I’ve got pockets like a white eared elephant, I decided to have another blast at these tuple things because they were doing my head in.

All along I’ve been thinking that a class/struct would be much better. In most cases I would be right, but then I thought, “Hang on, this is C++. Let me check if I can return a tuple from a function.”

Hey, turns out I could.

#include <cstdlib>
#include <iostream>
#include <tuple>

using namespace std;

auto get_tuple(string name) {
    return make_tuple(name, 1);
}

int main(int argc, char** argv) {
    auto t3 = get_tuple("FOO");
    auto t4 = get_tuple("BAR");
    
    cout << get<0>(t3) << endl << get<0>(t4) << endl;
    
    return 0;
}

And voila, just like that I can now return multiple values from a function.

The one thing you have to be careful of is the setup. A typo mistake or a type mistake can and will cost hours of debugging so be wary of things like this:

    auto t1 = std::make_tuple("foo", 1, 2);
    auto t2 = std::make_tuple("bar", 1.0, 2);

Now even if I added to the first tuple “foo”, 1f, 2, this would not match the second as the second tuple uses a double value. A pain for debugging.

Just the fact you can return multiple values of data without having to define a complete struct or class is actually quite a nice addition.

I have done some research into tuples now and found that these use cases are good, but for larger data, it is so much better even to still use a struct/class because with the above examples you still are having to use index values to access the data items. Where as a struct/class, the data items are named.

Although this however can be overcome by using enums, larger tuples are very likely better off being converted to a struct/class.

Even after 35+ years of programming I’m still learning.

Time to move onto something else… Bigger…

csnorwood.com

It was tough to accept the change from my old website (wlgfx) to this new one (csnorwood), but I couldn’t ignore the benefits.

Yes, this is going to affect the search engines for some time but I’m used to that. I can still slowly build stuff in the meantime while the web crawlers do there stuff.

It’s highly unlikely that the the old web address is even going to link back to this new one, but what the hell. Time to move onward and upwards.

Rewrite from Java to C++

Okay, so my server is currently running on Java and makes use of DataOutputStream and DataInputStream. And whilst I’m on a rewrite, I need to wrap those into C++.

Which I thought might be a tad difficult…

It turns out that Linux automatically handles UTF-8 strings out of the box, so sending and receiving string is of no consequence. Which was one of my main worries before I looked into everything else which slowed down the transition. Java’s DataOutputStream writes it UTF-16 strings as UTF-8 strings over the wire. That’s that problem solved.

The other problem was wrapping the socket connection. Sorted. Easily done by returning the error status on every call and handling the active status of the socket.

The last problem was wrapping the Java functions for sending a Long, Int, Byte, String, etc… These need to be in network byte order, which is not little endian. I’m just going through that now.

Oh yeah, encryption using a Cryptographic Secure Pseudo Random Number Generator. Done and implemented to match perfectly the Java version… For now.

So hopefully soon, I’ll be able to test run this wrapper ready for a production run.

Amazing feeling

“I feel almost like a god!”

To have my own software running in the cloud and being able to serve its purpose, ‘feels good’.

Yes, I’ve had one of those moments of personal successful achievements accomplished.

Or something like that.

‘Project’ updates

Maybe things have plodded along at a gentle pace recently, but that’s also a good thing because it give me a chance to reflect back and get things back into perspective. Which I have done.

A few weeks ago I was ready to plough ahead with this. And then as I get stopped in my tracks, or more so, slowed down, I start to find a few more faults, cracks, bugs, etc. All fixed now.

Anyway, the server has now moved onto a VPS somewhere in the cloud which means better bandwidth speed than running from home. I’m still testing out the VPS and getting myself familiar with using it. Everything is via terminal so my previous Linux knowledge is becoming extremely useful here. Commands such as ‘rsync’ to copy files from my PC to the server for example. Now I need to create a way of restarting the server on demand.

The Java TCP server still has its minor issues, but it just works. Any problems I face I can just restart it and everything just carries on. Once it is securely setup on the VPS then I can leave it alone and work on the C++ server upgrade coding.

I won’t talk about the many other things that have happened around this project in the recent weeks apart from to say that it will be big. Fair enough, now I’m starting to feel the pressure is on me to come up with the C++ server code. Which I might actually continue with tomorrow after I figure out how to get my server software to automatically start on the VPS.

Everything will come to light, … in time.

“Follow your passion, not your paycheck. The money will come eventually.”

Just some random updates

The ‘project’ has slowed a bit because of content and artwork which I will be jumping on over these next few days.

Server updates are now being reconsidered because I read last night that non-blocking IO can also be done in Java. I can quickly setup stuff in Java than I can in C++ which means Java has that slight advantage being a language. It may end up being 10-15% slower overall, but it just does stuff. And development is much faster.

However, saying that, I’ve still to test out the non-blocking IO in Java. So time will tell on that score.

If it works then the previous devices commands will be ported over so they will carry on running. The current server is running Java so why not.

If it doesn’t, then it will be back to the fd_set and select() in C which was coming on very nicely until the distraction.

Video editing has been done mainly with Blender. Recently though, I tried Adobe Premiere CS2 and at first glance it looked like it could really do the job. First off, it doesn’t import 99% of video clips and other file formats. I think the only two things that it has going for it is the titling and the rendering of the work area for faster previewing.

Now, Openshot, may not have the best interface, but it just works. Titling is a pain using an external editor. And it also renders the video in memory as you’re going along for faster playback.

With using Openshot, I can create 95% of what I need it for. All titling can be done externally which can be a pain, but more than doable. I just drag n drop the exported PNG’s. I only need to figure out a faster way of setting key frames for animations.

My head is exploding at the moment. I’ve got the ‘project’ to think about, the ‘projects’ server updates, learning new API’s, protocols, etc, blah, as well as trying to do this all in ‘my’ time.

My time now is extremely valuable to me. I’m spending most of it on working on my ‘project’. There are people that know about it, and others I won’t tell because those that know would gladly give up their ‘time’ for me.

This project is actually going to be a huge thing for me. There are only a few involved in it. I was going to involve another but fate stepped in perfectly because of this ‘time’ issue. So it’s carrying on as it was meant to. It is a lot of mental work but it’s will be worth it.

Posts navigation

1 2 3 4 5 6 7
Scroll to top