generating/creating hexagon grid in C - c

So i m trying to make hexagonal grid in C for a game. I am really dumb founded on where to start on it. ANyone have any ideas.
EDIT: I need about 15-20 hexagons in a grip shape all joined,something like a game board. for a game i m working on. Sorry for not being clear

Absolutely. Despite their odd shape, hexagons can still be contained in your usual multidimensional array, for future use (I assume you'll want to put things in your hexagons). As for drawing them, it's simple. Sum of angles = (6 - 2) * 180 = 4 * 180 = 720. One angle is 720 / 6 = 120 degrees. Calculate first the leftmost angle's Y position, which is equal to √(hexagonSide - hexagonWidth * hexagonWidth). I'm sure you can figure out hexagonWidth, right? Okay, now the X position relative to the last one will be 0. You'll need to offset the Y position by half the height of the hexagon before it, up or down depending on whether row * col is even or odd. Since you know the hexagon's width you have the coordinates of the opposite angle. Rotate by 120° and repeat.
Before I continue, is this supposed to be in the console? Or is it real graphics?

So let's get this straight, the game will be played on the console? Right, well now you will need to set up your data structures, the most obvious is with nodes.
The nodes
Each hexagon is a node with six edges.
typedef struct Node {
void *object; /* Pointer to object */
Node *node_array; /* Pointer to node_array with 'node_count' nodes */
int node_count; /* size of node_array */
} Node;
How to initialize and connect the node structure
Imagine the following hexagon:
/\
| |
\/
It has the following edges, NORTHEAST, EAST, SOUTHEAST, SOUTHWEST, WEST and NORTHWEST. Next observe how they will be arranged (10, 11 and 12 were represented in Hex so that they can fit in one space):
// 0 1 2 3
// 4 5 6 7 8
// 9 A B C
So 0 will link to 5 through it's SOUTHEAST link, and 4 through it's SOUTHWEST link. Also notice how the rows alternate between odd and even numbers of elements. Let's call {0, 1, 2, 3} row[0], and {4, 5, 6, 7, 8} row[1]. And let's call this a 5x3 hexmap. The easiest way to create this array is with malloc(sizeof(Node) * width * height).
Connecting the nodes
First of all let me point out that every even row (0, 2, 4, ...) will have width-1 elements. But there's more, each element (x, y) on this row will link to the following element in your array:
(x+1, y-1) - NORTHEAST
(x+1, y) - EAST
(x+1, y+1) - SOUTHEAST
(x, y+1) - SOUTHWEST
(x-1, y) - WEST
(x, y-1) - NORTHWEST
Elements on the other rows, such as {4, 5, 6, 7, 8} will have width elements, where element (x, y) links to the following:
(x, y-1) - NORTHEAST
(x+1, y) - EAST
(x, y+1) - SOUTHEAST
(x-1, y+1) - SOUTHWEST
(x-1, y) - WEST
(x-1, y-1) - NORTHWEST
When trying to link (x1,y1) with (x2, y2), ensure that 0 <= x < width and 0 <= y < height.
Remember ...
Your array contains one unused element at the end of every two rows (row[0], row[2], etc.). Also you might want to provide them all with some sort of label or index so that you can refer the player to them. You could label them as (x,y) pairs, or numerically by their index, it's all up to you. The (x, y) pair is very easy for you since that will map directly to the array they are stored in.

Related

Calculating Displacement based on the compass direction

I need some help with programming the calculation of displacement. Given the distance the object has moved in the XY plane, and the yaw (heading) of the object, I'd like to calculate the displacement of the object. For example, the object moved 5m North and 2m East.
The data I have is the distance it travels in the XY plane (X distance and Y distance) and the heading of the device which is determined by the direction of X. I know how to calculate it on paper but I am having trouble to program it.
I've attached two examples that shows how I obtained the calculations. The black dot is the displacement of the object. In the 1st example, the X-distance travelled is 3 meters while the Y-distance is 4 meters and the heading of the X-axis is 70°. After calculating, I managed to get that it has travelled 2.733m South and 4.187m East. In example 2, it travel, the X-distance is -5m and the Y-distance is -12m, the heading is 160°. I calculated that the object travels 8.80m North and 9.566m East.
Example 1
Example 2
Assume you have your XY pane rotated by some angle Zp and have a 2D movement vector within that pane, let's say its direction rotated by Zv – what is total rotation of the vector, relative to the global orientation? Zp + Zv...
So all you need to do is applying the rotation Zp to the movement vector within XY-pane, i. e. apply a rotation matrix to the vector. This matrix for a rotation by z looks like:
cos(z) -sin(z)
sin(z) cos(z)
With our data above:
north = cos(Zp) * x - sin(Zp) * y
east = sin(Zp) * x + cos(Zp) * y
which gives, with your first sample data applied:
north = cos(70°) * 3 - sin(70°) * 4 ~ -2.7327
east = sin(70°) * 3 + cos(70°) * 4 ~ 4.1872
north = cos(160°) * -5 - sin(160°) * -12 ~ 8.8027
east = sin(160°) * -5 + cos(160°) * -12 ~ 9.5662
Corresponding pretty much to the values you calculated (note: negative movement to north is positive movement towards south...).
What you are doing is a conversion from polar to Cartesian coordinates. https://en.wikipedia.org/wiki/Polar_coordinate_system#Converting_between_polar_and_Cartesian_coordinates
If your Cartesian coordinates are not aligned to the polar axis, just compensate by adding the rotation angle to the polar argument.

Finding sum of many sub matrices in a big matrix?

For a 2D matrix A, we want to find the sum of the submatrix from (x1,y1) to (x2, y2) coordinates.
I came across this explanation of finding the submatrix sums, and I can follow the logic of the solution until the last part where they perform the following computation:
sum[x2][y2] + sum[x1][y1] - sum[x1][y2] - sum[x2][y1]
The idea is that they compute a matrix where each point represent the sum of the matrix, with all of which with reference to the original x1,y1 being (0,0). Then using some geometry method, they get the sums for a certain sub array. What I don't get is the geometry part. How does it come into play? I will draw the array for the sake of completeness.
Assume we have A as such:
1 2 3
4 5 6
7 8 9
For example, assume after finding the matrix sums we have the following:
1 3 6
5 12 21
12 27 45
Assume that I want to find the sum of the sub array starting from (1,1) to (2,2) where (0,0) is the origin at the sum 10. Then according to the formula, we have the sum
A[2][2] + A[1][1] - A[1][2] - A[2][1]
which gives 12 + 45 - 27 - 21 = 9.
Which isn't really the correct answer, 28?
Is there something wrong with this answer?
After calculating the sums you mentioned, sum[x][y] will represent the sum of the rectangle from (0,0) to (x,y).
Now we want to calculate the sum of the subarray from (x1,y1) to (x2,y2). We start with sum[x2][y2]. we need to subtract sum[x1-1][y2] and sum[x2][y1-1] since they don't belong to the required rectangle. However, notice that the red rectangle was subtracted twice, so we add sum[x1-1][y1-1]

C Programming - Checking all valid solutions of a game board

Ok so I'm to create a code in C which outputs all the possible solutions of a board. The board is a nxn board with a row looking like this(3x3): AA BA BB.
The objective of the game is to visit every position in the board by only going vertically or horizontally across the board. Also, you can only go to the next position if the first or second letter is the same so I can go from AA to BA but not from AA to BB and you can only visit each position once. The starting position is always the upper left corner or the 00 position.
Anyway, I thought of an algorithm where the computer starts at 00 and checks the next valid position, let's say 01. Then the computer checks all possible solutions using the chain of 00 and 01 as starting positions. When there's no more, the computer checks a new chain lets say 00, 10 and so on. How do you know not to repeat the previous solutions? I was thinking something with recursion. Are there more efficient path-finding algorithms other than mine?
Re: How do you know not to repeat the previous solutions?
A part of the depth first search algorithm involves marking the visited nodes so as not to visit them twice. This can be done in various ways: spare bits on the nodes themselves, initialized before every search, or a dynamic set data structure external to the graph being searched.
The problem is related to Gray code, by the way, which is a way of arranging the codes of a binary word so that only one bit changes between successive codes. E.g. 000 001 011 010 110 100 101 111.
What this means is that in your board, you can navigate to a neighboring square if and only if it is a two bit Gray code successor or predecessor.
But Gray code forms a sequence. So the problem is isomorphic to one in which there is a simple numbering from 0 to 3, and you are allowed from N to a N+1 successor or N-1 predecessor.
This can help you think about the problem.
Here's a very inefficient solution in Python. You should be able to follow along. I didn't want to just give away the answer in your own language :P
class Finder:
def __init__(self, board, n, x, y):
self.board = board
self.n = n
# Create a copy of the board.
self.copy = []
for i in range(n):
row = []
self.copy += [row]
for j in range(n):
row += [False]
# The best move sequence (longest).
self.best = []
# The current move sequence.
self.move = []
self.find(x, y)
def valid_move(self,x1, y1, x2, y2):
# Don't move off the board!
if x2 < 0 or x2 > self.n - 1 or y2 < 0 or y2 > self.n - 1:
return False
# Don't go somewhere we've gone before!
if self.copy[y2][x2]:
return False
# See if this is a valid move.
a = self.board[y1][x1]
b = self.board[y2][x2]
return a[0] == b[0] or \
a[0] == b[1] or \
a[1] == b[0] or \
a[1] == b[1]
def find(self,x, y):
self.move += [(x, y, board[y][x])]
self.copy[y][x] = True
# If this is the best path, then create a copy.
if len(self.move) > len(self.best):
self.best = list(self.move)
# Short-circuit if the optimal route is found.
if len(self.best) == self.n * self.n:
return
newX = x - 1
newY = y
if self.valid_move(x, y, newX, newY):
self.find(newX, newY)
newX = x
newY = y - 1
if self.valid_move(x, y, newX, newY):
self.find(newX, newY)
newX = x + 1
newY = y
if self.valid_move(x, y, newX, newY):
self.find(newX, newY)
newX = x
newY = y + 1
if self.valid_move(x, y, newX, newY):
self.find(newX, newY)
# Clean up by removing the last move.
self.move = self.move[:-1]
self.copy[y][x] = False
# The board
board = \
[["AB", "XX", "DE"],
["BB", "FE", "DD"],
["BC", "CC", "CD"],
]
# The size of the board.
n = 3
# Find!!
finder = Finder(board, n, 0, 0)
for row in board:
print(row)
# Print empty line.
print()
for move in finder.best:
print(move)
Here's the output:
['AB', 'XX', 'DE']
['BB', 'FE', 'DD']
['BC', 'CC', 'CD']
(0, 0, 'AB')
(0, 1, 'BB')
(0, 2, 'BC')
(1, 2, 'CC')
(2, 2, 'CD')
(2, 1, 'DD')
(2, 0, 'DE')

Ordering of a 2D array

I am trying to solve a problem on 2D arrays and need little help. The problem goes like this:
Suppose we have a 2D array A of size nxn comprising of unique elements. The need to rearrange the elements of A as follows. Let A11, A12, A21, A22 be four mutually disjoint subarrays of A, each of size n/2 x n/2. Then A11 < A12 < A21 < A22. If each of these subarrays is recursively split into four equal-sized sub-arrays, then also the property holds.
User input: n, N (≥ n2). n is a power of 2
I have tried many things but nothing seems to work.
You need to create a function which will convert an index between 0 and n*n-1 to coordinates in your array according to the ordering in question. Then you just run some usual 1D sorting algorithm, on an array of size n*n, jth element of which is substituted using that function. It solves the problem.
Update: the mapping function maps numbers in this matrix to their coordinates:
0 1 4 5
2 3 6 7
8 9 12 13
10 11 14 15
Piggybacking somewhat on the answer of unkulunkulu I think you could approach it as follows:
Take all the values in your matrix (2D) and put them in a simple array (1D). Then take this array and sort the values from lowest to highest.
Now what you need to do is fill the matrix again but in such a way that it conforms to the rules you have specified. If you have a look at a Z-order space filling curve in 2D, you will find that if you fill you matrix in this order (with the sorted elements), that the resulting matrix has your desired properties.
Now actually coding this would be up to you.
The book numerical recipes chapter 21.8 http://www.nrbook.com/nr3/ gives an analytic expression to calculate an index into the 2D array given the coordinates of a quadtree.
Here is another straight forward approach that I tried, but I don't like it as much:
(defun quad-pos (pos)
"POS is a list of letters that indicate the position in a 2x2 matrix [a,b; c,d]."
(let ((x 0)
(y 0)
(s 1))
(dolist (e pos)
(setf s (/ s 2))
(ecase e
('a )
('b (incf x s))
('c (incf y s))
('d (incf x s) (incf y s))))
(values x y)))
#+nil
(quad-pos '(a)) ;=> 0, 0
#+nil
(quad-pos '(a b c)) ;=> 1/4, 1/8
#+nil
(quad-pos '(d d d d)) ;=> 15/16, 15/16

Dynamic programming - Largest square block

I need to find the largest square of 1's in a giant file full of 1's and 0's. I know i have to use dynamic programming. I am storing it in a 2D array. Any help with the algorithm to find the largest square would be great, thanks!
example input:
1 0 1 0 1 0
1 0 1 1 1 1
0 1 1 1 1 1
0 0 1 1 1 1
1 1 1 1 1 1
answer:
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
My code so far:
int Square (Sq[int x][int y]) {
if (Sq[x][y]) == 0) {
return 0;
}
else {
return 1+MIN( Sq(X-1,Y), Sq(X,Y-1), Sq(X-1,Y-1) );
}
}
(assuming values already entered into the array)
int main() {
int Sq[5][6]; //5,6 = bottom right conner
int X = Square(Sq[5][6]);
}
How do I go on from there?
Here is a sketch of the solution:
For each of the cells we will keep a counter of how big a square can be made using that cell as top left. Clearly all cells with 0 will have 0 as the count.
Start iterating from bottom right cell and go to bottom left, then go to one row up and repeat.
At each scan do this:
If the cell has 0 assign count=0
If the cell has 1 and is an edge cell (bottom or right edge only), assign count=1
For all other cells, check the count of the cell on its right, right-below, and below. Take the min of them and add 1 and assign that to the count. Keep a global max_count variable to keep track of the max count so far.
At the end of traversing the matrix, max_count will have the desired value.
Complexity is no more that the cost of traversal of the matrix.
This is how the matrix will look like after the traversal. Values in parentheses are the counts, i.e. biggest square that can be made using the cell as top left.
1(1) 0(0) 1(1) 0(0) 1(1) 0(0)
1(1) 0(0) 1(4) 1(3) 1(2) 1(1)
0(0) 1(1) 1(3) 1(3) 1(2) 1(1)
0(0) 0(0) 1(2) 1(2) 1(2) 1(1)
1(1) 1(1) 1(1) 1(1) 1(1) 1(1)
Implementation in Python
def max_size(mat, ZERO=0):
"""Find the largest square of ZERO's in the matrix `mat`."""
nrows, ncols = len(mat), (len(mat[0]) if mat else 0)
if not (nrows and ncols): return 0 # empty matrix or rows
counts = [[0]*ncols for _ in xrange(nrows)]
for i in reversed(xrange(nrows)): # for each row
assert len(mat[i]) == ncols # matrix must be rectangular
for j in reversed(xrange(ncols)): # for each element in the row
if mat[i][j] != ZERO:
counts[i][j] = (1 + min(
counts[i][j+1], # east
counts[i+1][j], # south
counts[i+1][j+1] # south-east
)) if i < (nrows - 1) and j < (ncols - 1) else 1 # edges
return max(c for rows in counts for c in rows)
LSBRA(X,Y) means "Largest Square with Bottom-Right At X,Y"
Pseudocode:
LSBRA(X,Y):
if (x,y) == 0:
0
else:
1+MIN( LSBRA(X-1,Y), LSBRA(X,Y-1), LSBRA(X-1,Y-1) )
(For edge cells, you can skip the MIN part and just return 1 if (x,y) is not 0.)
Work diagonally through the grid in "waves", like the following:
0 1 2 3 4
+----------
0 | 1 2 3 4 5
1 | 2 3 4 5 6
2 | 3 4 5 6 7
3 | 4 5 6 7 8
or alternatively, work through left-to-right, top-to-bottom, as long as you fill in edge cells.
0 1 2 3 4
+----------
0 | 1 2 3 4 5
1 | 6 7 8 9 .
2 | . . . . .
3 | . . . . .
That way you'll never run into a computation where you haven't previously computed the necessary data - so all of the LSBRA() "calls" are actually just table lookups of your previous computation results (hence the dynamic programming aspect).
Why it works
In order to have a square with a bottom-right at X,Y - it must contain the overlapping squares of one less dimension that touch each of the other 3 corners. In other words, to have
XXXX
XXXX
XXXX
XXXX
you must also have...
XXX. .XXX .... ....
XXX. .XXX XXX. ....
XXX. .XXX XXX. ....
.... .... XXX. ...X
As long as you have those 3 (each of the LSBRA checks) N-size squares plus the current square is also "occupied", you will have an (N+1)-size square.
The first algorithm that comes to my mind is:
'&&' column/row 1 with column/row 2 if, this is to say do an '&&' operation between each entry and its corresponding entry in the other column/row.
Check the resulting column, if there are any length 2 1's that means we hit a 2x2 square.
And the next column with the result of the first two. If there are any length 3 1's we have hit a 3x3 square.
Repeat until all columns have been used.
Repeat 1-4 starting at column 2.
I won't show you the implementation as its quite straightforward and your problem sounds like homework. Additionally there are likely much more efficient ways to do this, as this will become slow if the input was very large.
Let input matrix is M: n x m
T[i][j] is DP matrix which contains largest square side with squares bottom right angle (i,j).
General rule to fill the table:
if (M[i][j] == 1) {
int v = min(T[i][j-1], T[i-1][j]);
v = min(v, T[i-1][j-1]);
T[i][j] = v + 1;
}
else
T[i][j] = 0;
The result square size is max value in T.
Filling T[i][0] and T[0][j] is trivial.
I am not sure if this algo can be used for your huge file,
but you don't need to store entire matrix T but only current and previous lines only.
Following notes can help to undestand general idea:
all squares with right bottom angles (i-1, j), (i, j-1), (i-1, j-1) with size s are inside square of with right bottom angle (i, j) with size s+1.
if there is square of size s+1 with right bottom corner at (i, j), then size of maximal square with right bottom angles (i-1, j), (i, j-1), (i-1, j-1) is at least s.
Opposite is also true. If size of at least one square with bottom right angles at (i-1, j), (i, j-1), (i-1, j-1) is less then s, then size of square with right bottom corner at (i, j) can not be larger then s+1.
OK, the most inefficient way but simple would be:
select first item. check if 1, if so you have a 1x1 square.
check one below and one to right, if 1, then check row 2 col 2, if 1, 2x2 square.
check row 3 col 1, col 2 and col 3, plus row 1 col 3, row 2 col 3, if 1, 3x3.
So basically you keep expanding the row and col together and check all the cells inside their boundaries. As soon as you hit a 0, it's broken, so you move along 1 point in a row, and start again.
At end of row, move to next row.
until the end.
You can probably see how those fit into while loops etc, and how &&s can be used to check for the 0s, and as you look at it, you'll perhaps also notice how it can be sped up. But as the other answer just mentioned, it does sound a little like homework so we'll leave the actual code up to you.
Good luck!
The key here is that you can keep track of the root of the area instead of the actual area, using dynamic programming.
The algorithm is as follow:
Store an 2D array of ints called max-square, where an element at index i,j represents the size of the square it's in with i,j being the bottom right corner. (if max[i,j] = 2, it means that index i,j is the bottom right corner of a square of size 2^2 = 4)
For each index i,j:
if at i,j the element is 0, then set max-square i,j to 0.
else:
Find the minimum of max-square[i - 1, j] and max-square[i, j - 1] and max-square[i - 1][j -1]. set max-square[i, j] to 1 + the minimum of the 3. Inductively, you'll end up filling in the max-square array. Find/or keep track of the maximum value in the process, return that value^2.
Take a look at these solutions people have proposed:
https://leetcode.com/discuss/questions/oj/maximal-square?sort=votes
Let N be the amount of cells in the 2D array. There exists a very efficient algorithm to list all the maximum empty rectangles. The largest empty square is inside one of these empty rectangles, and founding it is trivial once the list of the maximum empty rectangles has been computed. A paper presenting a O(N) algorithm to create such a list can be found at www.ulg.ac.be/telecom/rectangles as well as source code (not optimized). Note that a proof exists (see the paper) that the number of largest empty rectangles is bounded by N. Therefore, selecting the largest empty square can be done in O(N), and the overall method is also O(N). In practice, this method is very fast. The implementation is very easy to do, since the whole code should not be more than 40 lines of C (the algorithm to list all the maximum empty rectangles takes about 30 lines of C).

Resources