Muller Jannie

About myself and everyone else.

Hexagon map – in c++

I’m definitely not a c++ programmer. I’m a SQL DBA.

However over the last couple of weeks (2) I figured I’d like to get into programming it. I learned c++ about 10 years ago when I studied and very basic c++. We never did comprehensive work on btrees or lists. So having a look at it after all of this time it’s not familiar.

The language itself interest me and after some recent activity from the news side, (the death of the C creator). It sparked a renewed interest in the language. I’ve read some of the material available on Bjarne’s website, the creator of c++. Honestly said I think he had a very nice agenda on how and why the language is what it is today.  His hopes and instruction on how to best learn the language and the intention of how it is to be used and learned is quite good. It’s the same as most of the parenting books you can read on teaching kids new things.

Since I’m keen to learn c++ I headed out to write something fun.

Here is what I did.

The idea was to create a game board of some sort. I didn’t feel like using an array, well not to get a basic square board. I did create on for a tic-tac-toe game but that was pretty straight forward. Then I decided to create a hexagon board. This was more tricky.

The first thing I had to figure out the number of hexagons around a single hexagon. Sure, easy as cake, 6 sides so 6 hexagons. But if you were to add another layer around that 6, how many do you have. I’m no math expert with formula and whatnot so I had to draw one or two iterations before I could figure out a pattern. I first tried to use the sides to calculate the new tiles. So 1 hexagon will have 6 sides. Then if you connect 6 to that will you have 36, nope. Because some of the side align to one another. For the hexagons above the center 2 sides will connect to the center and for the hexagons on the side 3 of the 6 sides will “connect” . So I broke the formula into two pieces. I calculate the number of hexagons above the center and multiply by 2 (for those below) and then I get the number of hexagons to the left of the center and calculate that by two in order to get the number on the right. Then I add 1 to get the center.

Once I had the formula I had to substitute a few values in order to build in a variable which I can modify which will deliver the proper results with the increase of the number of layers.

As example.

level 0 – 1 Hexagon.

level 1 – 6 (New hexagons) 1 (from previous level).

level 2 – 12 (New hexagons) 7 (from previous level).

The resulting code looks something like this

(2*(2*i-1) + (2*(1+i)));

i is the level variable. it seems to work.

Drawing a hexagon

//draw top
arboard[y-1][x-2] = ” “;
arboard[y-1][x-1] = “/”;
arboard[y-1][x] = ” “;
arboard[y-1][x+1] = “\\”;
arboard[y-1][x+2] = ” “;
//Draw middle
arboard[y][x-2] = “|”;
arboard[y][x-1] = ” “;
arboard[y][x] = “o”;
arboard[y][x+1] = ” “;
arboard[y][x+2] = “|”;
//draw bottom
arboard[y+1][x-2] = ” “;
arboard[y+1][x-1] = “\\”;
arboard[y+1][x] = ” “;
arboard[y+1][x+1] = “/”;
arboard[y+1][x+2] = ” “;

Now the draw bit is relative easy for a hexagon. I used the operators / \ for the top left and right, the pipe | for the side. I put a little 0 in the middle just for kicks. So you end up with a 3×3 square block. The corners of each block interlock with the next. That way you get a proper hexagon map that is neat and tidy.

I created a big array for each cell in order to have some sort of measure where to start plotting from. I am not adept enough to use any drawing functions the windows classes for c++. At this point I’m still getting to grips with classes and passing things between them and then of course some logic issues. There are tons of things which I normally take for granted and that you don’t get all kinds of overflows and addressing memory that doesn’t exist. It is fun though to have to consider these issues.

I have also managed to blue screen myself twice or locked my pc into some pc speaker sounding bleep. I believe this is a certain char which translates to a pc speaker output. I remember this from the turbo pascal days in school. I remember this faintly as I had more pressing matters on my mind which was totally non-academic.

So I haven’t achieved much, it took me day or so to get a basic program outline working with classes and drawing anywhere within bounds of the array without the program crashing. The idea was that once I could draw a hexagon I would draw more next and surrounding it with my formula. No problem, so what was next.

Where to draw.

So I know what I need to draw the hexagon but I had to work out a coordinate. Not to bad, it’s a 3×3 square of which the corners overlap. So I had to take some care that I don’t leave a space between the sides and leave my hexagon map with a bunch of potholes which by some creative means could be worked into the script as a hole for a hobbit to fall into. But I’d prefer a more solid world.

I could work out where to draw but it took me some time to put this into a way to logically program it. In order to draw all the hexagons I need to know how many hexagons we have. This is what I had the formula for. Now I need to figure out where to draw them. So for the 1 center hexagon this is easy. I first used a method to test if there is a “o” to the right of the pipe. If not then draw a hexagon. This works but the problem is the loop for the logic is irregular. This means it will work for the first iteration, well and for the second , it’s completely correct what the computer did. It drew infinite hexagons to the first of the right pipe, then the next and then next. It didn’t have a method in order to say “ok” now we have drawn this. Move onto the next connectable tile which is the / (if you go clockwise from the right | ). Then I eventually managed to move clockwise through all the sides of the hexagon. This worked really nice untill you need to add another layer around this structure such as this. 

The problem that happens here is that the coordinates suddenly becomes all messed up when you draw from the center. This is because each layer had to be calculated from the center out. I struggled quite a bit with this . Then I had a change of thought. Up to this point I was drawing the hexagons from the center out.

I believe this bias was created because when I drew the first hexagon. I started with the “o” and point x,y. The line above would be decreased in x and the lines below would see the x coordinate increase. This created the idea that I should draw from the inside out. This was a little too unpredictable and complex for my c++ skills.

Then came a bit of a breakthrough. By the way, you should have noticed by now that I initialized the array with X. The breakthrough was that I should draw the hexagon map from left to right top to bottom. This had a ton of advantages. First of all I could simply increase my y coordinate to move top to bottom. I can simply increase the x coordinate by half of the diameter of the 3×3 box. This would mean that my box corners would overlap nicely. Then I ran into the next issue, I was expecting it so luckily for me. The problem was that each new row needed to have an offset in order to line up the corners of the previous row. This was easy to do because I had already work in the line number variable for my line drawing loop. The drawing loop basically said while I have lines draw the tiles, the tiles was also in a loop saying that while I haven’t reached the number of tiles (which can be deduced from the formula) draw the tiles.

Something worth mentioning at this point is that I had a struggle in the design because I tried to do many things at once. I tried to draw , pick coordinates and refresh and get input all in the same time. I’ve read tons on how to structure programs and plan it out. I believe in other languages it’s easier to get away with but here you end up with a bunch of lines of code much like that of a marionette that has just done a triple back somersault with a flip and before you know if you don’t know which end goes where or does what. So I moved the draw, refresh and coords into their own methods or member functions or whichever you would like to call it.

Putting it all together.

I have a function to draw a single hexagon based on coordinates. This was pretty easy you just output to the screen yay. Note: Another issue;  I was burning to use recurring functions for some stuff just so I can tick it off my list. Mistake. It clouded my vision to be honest. I’ll write another  program for that.

Then I have the formulas for generating my coordinates. This was converted into a function which populates and array. It’s a two-dimensional dynamic array which the size is dependent on the number of the tiles that needs to be drawn on the screen. It generates the coordinates and it saves it in the array.

To make these to talk together I wrote another function. I’ve read a bit of cprogramming.com about the use of interfaces between classes and it’s functions. It recommends using this in order to prevent accessing functions directly in order to avoid major code changes down the line. I can relate to using a view in SQL server for this exact same reason. I don’t use select * in your code.  Thus I created a function that read the array and then setup the values in the array which will be drawn to the screen.

Lastly there is the drawing , or should I say refresh which just reads the array and does nothing else. It’s just a glorified print.

Note; Because of the drawing from left to right I had to take some precautions. This is due to the fact that if you start drawing at 0,0 and you have more hexagons that your second line (due to the offset) is out-of-bounds as it needs to expand almost into a pyramid. Since you have drawn at 0,0 on the screen there is no space to draw , well since there is no array there. To get around this I had to calculate the widest row. this was part of the formula to get the number of tiles so I just took it out of the equation.

The other note of using different functions to split, wait for it, functionality also comes in handy when trying to debug.

Conclusion.

I did what I wanted to do, draw a hexagon map. Currently the system has a fix source coordinates for the origin. If I modify this and allow for several maps to be drawn within the same canvas I could make all kinds of funky patterns.

Other notes;

I’m no expert of balance trees. But if a balanced tree has 2 nodes hi-lo and a hexagon has 6 nodes which also increases exponentially once you start adding layers. Balanced trees (gosh I keep on almost getting this wrong from Binary tree in SQL).  What I’m trying to get it is that in a lot of problem we use 2 dimensional solutions. Take compression for example. Dictionary compression is 2D , it reads from point to point and the crunch. If you can fold the data before you read it from point to point you should be able to get 3 dimensional patterns that can aid to compression. I will actually need to write something to be able to prove this point or test it.  Using 3D to look at data on disk can perhaps increase storage aswell but it will use additional CPU in order to calculate where to put data, then again something like this would run on firmware  and if you take how fast a firewall can process data. Compression should be a walk in the park.

This is thecode

Leave a comment

Information

This entry was posted on October 24, 2011 by in Awesome +1, Games and tagged , .