I am working with a linearized 64x64 array. There are either horizontal or vertical lines with "colors" in them set as color codes in each spot in the array, and I am trying to find the color that has no overlap.
An example of what I mean is here: https://imgur.com/a/geE73aK
It is clear that in this example, since none of the yellow are overlapped by any other colors, yellow's color code would be the solution.
It checks left/right and above/below the current position to see if the color is the same. If the color is the same, it will continue. If the color is different (AKA overlap is found), it will make that color code zero and by the end of the program all but one color code will be zero, making it easy to find the non-zero (AKA non-overlapping) color code.
I currently have this as my code. I am stuck on how to find if there is overlap and make the overlapping color code 0. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
#define DEBUG 1 // RESET THIS TO 0 BEFORE SUBMITTING YOUR CODE
int main(int argc, char *argv[]) {
int PileInts[1024];
int NumInts, TopColor=0;
int Load_Mem(char *, int *);
// This allows you to access the pixels (individual bytes)
// as byte array accesses (e.g., Pile[25] gives pixel 25):
char *Pile = (char *)PileInts;
if (argc != 2) {
printf("usage: ./P1-1 valuefile\n");
exit(1);
}
NumInts = Load_Mem(argv[1], PileInts);
if (NumInts != 1024) {
printf("valuefiles must contain 1024 entries\n");
exit(1);
}
if (DEBUG){
printf("Pile[0] is Pixel 0: 0x%02x\n", Pile[0]);
printf("Pile[107] is Pixel 107: 0x%02x\n", Pile[107]);
}
/* Your program goes here */
int i;
int j;
/*
int black = 0;
int pink = 1;
int red = 2;
int green = 3; // all colors and their codes
int blue = 4;
int orange = 5;
int yellow = 6;
int skyblue = 7;
*/
int rows = 63;
int cols = 63;
int colors[] = [1, 2, 3, 4, 5, 6, 7]; // color codes in array format
int current = Pile[i*64 + j]; //current position in linearized 64x64 array
for (i=1; i<63; i++){ //run through 63 rows
for (j=1; j<63; j++){ //run through 63 columns
// CHECK HORIZONTAL OVERLAP
if (current == Pile[i*64+j+1]) //check to the right current position
if (current == Pile[i*64+j-1]) //check to the left current position
// CHECK VERTICAL OVERLAP
if (current == Pile[(i-1)*64+j]) //check above current position
if (current == Pile[(i+1)*64+j]) //check below current position
}
}
//CHECK FOR COLORS WHICH DID NOT OVERLAP - THAT WILL BE SOLUTION, AS THERE SHOULD ONLY BE ONE
for (int k=0; k<8; k++){
if colors[k] != 0 {
TopColor = k;
}
}
}
As for it running from 1-63, that is okay. There will be no colors along the borders.
Clarifying information about the specifics: There will only be one line in each vertical and horizontal. each vertical or horizontal line will be at least one row/column from the other. There will be exactly one color that does not overlap.
Related
I'm trying to rotate this clockwise 90 degrees, but it works not as expected. Must be something to do with pointers which I'm not that familiar.
OUTPUT Before Rotation:
hiivp
nxhxd
tszeg
xdlqo
kwpae
void rotate_right(char **m, int n) {
char **temp = m;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
m[i][j] = temp[n-1-j][i];
}
}
}
OUTPUT After Rotation:
kxtnk
wdsdx
plzst
aqsdn
entxk
You're partially overwriting your matrix.
To perform a 90° rotation, let us consider the four corners of the square (in caps):
HiivP
nxhxd
tszeg
xdlqo
WwpaE
You need to put the H in the P place, save the P, and put the P in the E place, then the E in the W place, and finally the W in the H place. These four shift must be done each time saving the overwritten value, that becomes the new running value for the next stage.
Then you can see that each cell is part of such a four-cell shift: the corners are numbered 1, and 1 is the first shift. Then you work cells in position 2, then those in 3, and so on.
12341
45652
36-63
25654
14321
Having an odd side, the central square does not rotate and there is no cycle number 7. After six cycles, each involving four cells, the square is rotated (6*4 = 24, and 24+1 = 25). With a larger square, you can see the "law" linking the x,y coordinates for each cycle.
Building on LSerni's answer, adding an implementation for completeness sake.
Assuming the following matrix:
#define STRING_SIZE (5)
char m[][STRING_SIZE+1] = { "hiivp",
"nxhxd",
"tszeg",
"xdlqo",
"kwpae" };
You can define the rotate function like this:
char override_and_backup(char* dest, char val)
{
char tmp = *dest;
*dest = val;
return tmp;
}
void rotate_right(char m[][STRING_SIZE+1], int size)
{
// rotate layer by layer
for (int layer = 0; layer < (size / 2); ++layer)
{
int current_size = size - (2*layer); // side size of current layer
int ncycles = current_size - 1; // number of cycles to complete rotation
// perform the rotating cycles
for (int cycle = 0; cycle < ncycles; ++cycle)
{
char* first = &m[layer][layer+cycle];
char* second = &m[layer+cycle][layer+current_size-1];
char* third = &m[layer+current_size-1][layer+current_size-cycle-1];
char* fourth = &m[layer+current_size-cycle-1][layer];
char tmp = *fourth;
tmp = override_and_backup(first, tmp);
tmp = override_and_backup(second, tmp);
tmp = override_and_backup(third, tmp);
override_and_backup(fourth, tmp);
}
}
}
I'm on a project where I have to code a little game named "recolor", basically it's grid of a certain size, the grid is divided in cells (we have size*size cells), I can play a color (the color have to be in the grid or in the authorized colors) and each time I'm playing a color the grid will change from the top letf corner to color each cells directly connected to the top left corner that has the same color.
That's for the global context, now I already have all the functions to play this game but I have some problems with the function I use to play a move:
The game is defined using this type :
struct game_s
{
color **grid;
color **initial_grid;
uint width;
uint height;
uint nmb_cur_mv;
uint nmb_mv_max;
};
/*
* Def :
* - neighbour_of_origin checks if a cell is in the neighborhood of the (0,0) of the game grid, to be in the neighborhood
* the cell should have the same color as the (0,0) and the cell and (0,0) have to be connected by a path of cells that have the same
* color as (0,0).
* Param :
* - cgame g : the game grid
* - int x, y : coordinates of the cell we are currently checking
* - bool** to_change_tab : 2D array of boolean that represent the game grid and have the same size as it. It is used to mark all the cells to
* modify. By default the whole grid is set to false except (0,0) which is changed no matter what.
* Ret :
* - void function, nothing to return.
*/
void neighbour_of_origin(cgame g, int x, int y, bool **to_change_tab)
{
assert(g);
assert(g->grid);
assert(to_change_tab);
color origin = g->grid[0][0];
int offset[4][2] = {
{-1, 0}, /*W*/
{0, 1}, /*S*/
{1, 0}, /*E*/
{0, -1} /*N*/
};
int off_x;
int off_y;
for (int elem = 0; elem < 4; elem++)
{
off_x = x + offset[elem][0]; /*takes the 'x' coord in the offset matrix and add it to the current x*/
off_y = y + offset[elem][1]; /*takes the 'y' coord in the offset matrix and add it to the current y*/
if (((off_x >= 0 && off_x < SIZE) && (off_y >= 0 && off_y < SIZE)) && (to_change_tab[off_x][off_y] == true) && (g->grid[x][y] == origin))
{
to_change_tab[x][y] = true;
break;
}
}
}
/*
* Def :
* - game_play_one_move will change all the cells that are neighbors of the (0,0)that have the same color as it. The changing always begin
from the (0,0) and then it expands in all directions.
* Param :
* - game g : the game grid that will be modified.
* - color c : the color that will be applied to all the cells we have to change.
* Ret :
* - void function, nothing to return.
*/
void game_play_one_move(game g, color c)
{
assert(g);
assert(g->grid);
bool **to_change_tab = (bool **)malloc(sizeof(bool *) * SIZE);
assert(to_change_tab);
for (int i = 0; i < SIZE; i++)
{
to_change_tab[i] = (bool *)malloc(sizeof(bool) * SIZE);
assert(to_change_tab[i]);
for (int j = 0; j < SIZE; j++)
{
to_change_tab[i][j] = false;
}
}
/*getting all the cells we have to change*/
to_change_tab[0][0] = true; /*(0,0) is always modified */
printf("mark tab : \n");
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
neighbour_of_origin(g, x, y, to_change_tab);
printf("%d ", to_change_tab[x][y]); /*debbuging purpose*/
}
printf("\n");
}
/*modification of the game grid */
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
if (to_change_tab[x][y] == true)
{
g->grid[x][y] = c;
}
}
}
g->nmb_cur_mv += 1;
/*free the temporary array of bools*/
for (int x = 0; x < SIZE; x++)
{
free(to_change_tab[x]);
to_change_tab[x] = NULL;
}
free(to_change_tab);
to_change_tab = NULL;
}
above we have the two functions I've made to change the color as described in the rules, It actually works pretty well but I have a big issue on it.
This is my grid at the very begining :
each number corresponds to a color, the grid is 12*12 cells.
000202101030
033111132010
101232320332
231032111220
212333320100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
Here is my grid when I play the following colors : 3 1 3 0
000202101030
000000002010
000202020332
230002111220
212300020100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
if I play any color (except 0 of course) as my next move I expect every 0 connected to the top left to change but i got this instead:
333202101030
333333332010
333232320332
233332111220
212333320100
033011233213
112220013112
131310101333
030100211130
131000323100
133112232002
202301112301
the 0 on the first line didn't changed whereas they were connected to the origin, I suspected that the bug is in my condition in neighbour_of_origin(cgame g, int x, int y, bool **to_change_tab) because i'm using a for on x and y so the first line is evaluated first and the 0 on the first line did not have any neighbor that corresponds to the if condition at this state, is there a way to evaluate in "the order of propagation",I wanted to rewrite it recursively but I'm really bad in recursion.
Very sorry for the long post, I wish someone could help me, have a good day.
edit : I got a ''''fix'''' I duplicate my for loops in the game_play_one_move() function so it will loop again and again to find each cells he couldn't find before, I know it's not a real fix because in the future i don't know how the grid will be displayed exactly, but i guess that a loop that will check again and again until it can't find any neighbor could be a solution too, in terms of colplexity it would be a real problem since i'm looping in the grid again and again and again
I am making a maze solving game. There is a function in the middle of the game that saves the progress and prints everything into the file. But now i want to read the maze, the character, etc from the file and put it into a bidimensional array but i am not being able to do so.
The array is declared globally (because of its use in several functions) and it is maze[30][30]. N is also declared globally as a variable size but at this point it should be 10. filePath too and it gives the name of the file.
This is how they are declared globally.
int N = 10;
char* filePath = "./save.txt";
char maze[30][30];
This is the read function:
void ler()
{
int i, j;
ex=1; ey=0;
sx=N-2; sy=N-1;
int aux;
FILE *fp = fopen(filePath, "r");
if (fp == NULL)
{
printf("Unable to perform.");
return;
}
system("cls");
for(i=0 ; i<N ; i++)
{
for(j=0 ; j<N ; j++)
{
fscanf(fp, "%c", maze[j][i]);
}
}
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
printf("%c", maze[j][i]); //Double print just for visuals
printf("%c", maze[j][i]);
}
printf("\n");
}
fclose(fp);
}
This is the save function:
void save(char maze[30][30]){
int i,j;
FILE *fp = fopen(filePath, "w");
if(fp==NULL){
printf("Unable to perform.");
return;
}
for(i=0 ; i<N ; i++){
for(j=0 ; j<N ; j++){
fprintf(fp, "%c", maze[j][i]);
fprintf(fp, "%c", maze[j][i]);
}
fprintf(fp, "\n", maze[j][i]);
}
fclose(fp);}
At this point it should only be possible to print the maze but it is not doing even that.
What save.txt file looks like after saving
The weird II is the caharcter and the other is like a highscore thing.
Using multidimensional arrays in C is actually more pain than they're worth. A much better option is to use a structure with a dynamically allocated array describing the maze, and accessor functions to examine and change the maze cells. Instead of putting markers in the maze data, you can put start/end/current location coordinates in the structure.
(I do realize that this does not answer the OP's stated question, but this is an answer to the underlying problem OP is trying to solve.)
Consider the following example. It limits the maze size to 255×255, but because each coordinate and maze cell is always just one byte, the save files are portable between architectures, as there is no byte order (endianness) to worry about. (You, as the programmer, do need to choose to use only codes 0..255 in the maze, though, to keep the data portable; the functions below won't enforce that.)
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct {
unsigned char row;
unsigned char col;
} mazepoint;
typedef struct {
unsigned char rows;
unsigned char cols;
unsigned char *cell;
mazepoint player;
} maze;
#define OUTSIDE 0
static inline unsigned char maze_get(maze *const m,
const int row,
const int col)
{
if (m &&
row >= 0 && row < (int)(m->rows) &&
col >= 0 && col < (int)(m->cols))
return m->cell[ (size_t)col + (size_t)(m->cols) * (size_t)row ];
else
return OUTSIDE;
}
static inline unsigned char maze_set(maze *const m,
const int row,
const int col,
const unsigned char val)
{
if (m &&
row >= 0 && row < (int)(m->rows) &&
col >= 0 && col < (int)(m->cols))
return m->cell[ (size_t)col + (size_t)(m->cols) * (size_t)row ] = val;
else
return OUTSIDE;
}
static inline void maze_free(maze *const m)
{
if (m) {
free(m->cell);
m->rows = 0;
m->cols = 0;
m->cell = NULL;
}
}
int maze_create(maze *const m,
const int rows,
const int cols)
{
size_t cells = (size_t)rows * (size_t)cols;
unsigned char *cell;
if (!m)
return -1; /* NULL reference to a maze variable! */
if (rows < 1 || rows > 255 ||
cols < 1 || cols > 255)
return -1; /* Invalid number of rows or columns! */
cell = malloc(cells); /* sizeof (unsigned char) == 1. */
if (!cell)
return -1;
/* Initialize all maze cells to OUTSIDE. */
memset(cell, OUTSIDE, cells);
m->rows = rows;
m->cols = cols;
m->cell = cell;
/* Let's initialize player location to upper left corner. */
m->player.row = 0;
m->player.col = 0;
return 0; /* Success. */
}
int maze_save(maze *const m, const char *filename)
{
size_t cells;
FILE *out;
if (!m || m->rows < 1 || m->cols < 1)
return -1; /* No maze to save! */
if (!filename || !filename[0])
return -1; /* NULL or empty filename! */
cells = (size_t)(m->rows) * (size_t)(m->cols);
out = fopen(filename, "wb");
if (!out)
return -1; /* Cannot open file for writing! */
do {
/* First byte is the number of rows. */
if (fputc(m->rows, out) == EOF)
break;
/* Second byte is the number of columns. */
if (fputc(m->cols, out) == EOF)
break;
/* rows*cols bytes of maze data follows. */
if (fwrite(m->cell, 1, cells, out) != cells)
break;
/* Player location follows. */
if (fputc(m->player.row, out) == EOF)
break;
if (fputc(m->player.col, out) == EOF)
break;
/* You can save additional data at this point. */
/* That completes the save file. Ensure it is correctly saved. */
if (fflush(out))
break;
if (fclose(out))
break;
/* Maze successfully saved. */
return 0;
} while (0);
/* Save failed. */
fclose(out);
remove(filename);
return -1;
}
int maze_load(maze *const m, const char *filename)
{
size_t cells;
unsigned char *cell;
int rows, cols, r, c;
FILE *in;
if (!m)
return -1; /* No reference to a maze variable to load into! */
/* Just in case, we clear the maze first. Might help finding bugs! */
m->rows = 0;
m->cols = 0;
m->cell = NULL;
if (!filename || !filename[0])
return -1; /* NULL or empty filename! */
in = fopen(filename, "rb");
if (!in)
return -1; /* Cannot open file for reading. */
rows = fgetc(in);
cols = fgetc(in);
if (rows == EOF || rows < 1 || rows > 255 ||
cols == EOF || cols < 1 || cols > 255) {
fclose(in);
return -1; /* Not a saved maze! */
}
cells = (size_t)(rows) * (size_t)(cols);
cell = malloc(cells);
if (!cell) {
fclose(in);
return -1; /* Not enough memory available! */
}
do {
/* Read maze cell data. */
if (fread(cell, 1, cells, in) != cells)
break;
/* Player location. */
r = fgetc(in);
c = fgetc(in);
if (r == EOF || r < 0 || r > 255 ||
c == EOF || c < 0 || c > 255)
break;
m->player.row = r;
m->player.col = c;
/* Load other saved data here. */
/* All data read successfully. */
fclose(in);
m->rows = rows;
m->cols = cols;
m->cell = cell;
return 0;
} while (0);
/* Read error. */
fclose(in);
free(cell);
return -1;
}
In your own program, you'd create a maze thus:
maze m;
/* Create a 20-row, 30-column maze. */
if (maze_create(&m, 20, 30)) {
/* Failed to create maze! Show an error message. */
exit(EXIT_FAILURE);
}
To save the maze to say maze.dat, you use
m.player.row = /* row where the player is */
m.player.col = /* column where the player is */
if (maze_save(&m, "maze.dat")) {
/* Failed! Show an error message. */
exit(EXIT_FAILURE);
}
If you look at the example code, you can add additional data, especially points like the player place, to be saved and loaded along with the maze cells themselves.
To destroy a maze when it is no longer needed, use
maze_free(&m);
To load a saved maze, say from maze.dat, use
if (maze_load(&m, "maze.dat")) {
/* Failed! Show an error message. */
exit(EXIT_FAILURE);
}
/* Restore player place from m.player.row and m.player.col */
The accessor function maze_get() is not limited to the valid coordinates (0 through rows-1 or cols-1, inclusive). If you examine outside the maze itself, it will just return the value of the OUTSIDE macro. For example,
if (maze_get(&m, row, col) == 5) {
/* That cell has value 5 */
} else {
/* Either the cell has a different value,
or row,col is outside the maze. */
}
Similarly, you can try to set any cell value safely. It will only "stick" if it is within the valid maze coordinate range, however; elsewhere it will return OUTSIDE:
if (maze_set(&m, row, col, 5) == 5) {
/* Changed cell value to 5 */
} else {
/* row,col is outside the maze. */
}
The reason I wrote the accessor macros that way, is that it makes rendering only a part of the maze very simple. If the view is viewrows by viewcols in size, centered at row and col, then you can render the view using a simple loop:
const int top = row - viewrows / 2;
const int left = col - viewcols / 2;
int vr, vc;
for (vr = 0; vr < viewrows; vr++) {
for (vc = 0; vc < viewcols; vc++) {
const unsigned char v = maze_get(&m, top+vr, left+vc);
/* Draw v at row vr, col vc */
}
}
and the cells are even drawn in the same order as you read this text; from top to bottom, left to right.
Note that instead of using the maze cell values for character codes, you should use a lookup table instead. For example,
int cell_char[256];
Instead of printing cell values directly, you'd print the corresponding cell_char, for example
fputc(cell_char[maze_get(&m, row, col)], stdout);
That way you can group e.g. different wall characters into a consecutive range, or even use the individual bits in the 8-bit cell value as identifiers. The maze cells then describe the logical contents in that maze cell, rather than its visual representation, with the logical-to-visual mapping in a separate array.
If you used Gtk+, you could have an array of GtkImage pointers,
GtkImage *cell_image[256] = {0}; /* All NULL by default */
or using SDL, you could have the maze cells as textures you can render,
SDL_Texture *cell_texture[256] = {0}; /* All NULL by default */
and in both cases, read them from either one large image (say, divided into 16×16 exact same size rectangles), or from individual image files.
For example, you could decide that the four least significant bits in the cell value specify whether movement from that cell up (previous row), down (next row), left (previous column), or right (next column) is possible:
#define CAN_GO_UP(value) ((value) & (1 << 0)) /* == 1 */
#define CAN_GO_DOWN(value) ((value) & (1 << 1)) /* == 2 */
#define CAN_GO_LEFT(value) ((value) & (1 << 2)) /* == 4 */
#define CAN_GO_RIGHT(value) ((value) & (1 << 3)) /* == 8 */
Note that this allows you to do "trap walls": passages that only work one way. Maze cell values that are multiples of 16 (0, 16, 32, 48, 64, 80, 96, ..., 208, 224, and 240) represent completely blocked cells: no way out. +1 allows passage up; +2 allows passage down; +3 allows passage up and down; +4 allows passage left; +5 allows passage left and up; +6 allows passage left and down; +7 allows passage up, left, and down; +8 allows passage right; +9 allows passage up and right; +10 allows passage down and right; +11 allows passage up, down, and right; +12 allows passage left and right; +13 allows passage up, left, and right; +14 allows passage down, left, and right; and +15 allows passage up, down, left, and right.
I would personally also recommend using the wide version of the ncurses library (ncursesw). (I do not use Windows, so I am not exactly sure how you install and use it in windows, but the ncurses home page does have downloads when using mingw.)
Then, you would have a much wider variety of glyphs you could use. (When using UTF-8 locales, potentially the entire Unicode glyph set -- the Box Drawing block especially would be useful for maze drawing, and most of those glyphs are also available in the old CP437 codepage, which means they should work both in Windows and non-Windows terminals nicely.)
In that case, you'd probably use
cchar_t cell_char[256];
As I mentioned above, you could even do a graphical version (perhaps later on, extending your terminal version?) in C using SDL or GTK+. (Note that the above separation between logical maze cell content value and the visual describing the cell also means you can, at runtime, choose between "themes", by having more than one set of cell images. That allows you to start with crude informational versions, for debugging, and then add visual goodness.)
The approach shown in this answers allows you to start with a simple terminal-based game, and if you decide you want to, add support for graphical UI, with image-based maze cells, without having to rewrite any of your core maze code.
Recursion is the one thing I have loads of trouble with. For this assignment we are supposed to print out an outline of sections and sub-sections. Take the following as an example.
Section 1
Section 1.A
Section 1.A.1
Section 1.A.2
Section 1.B
Section 1.B.1
Section 1.B.2
Section 2
Section 2.A
Section 2.A.1
Section 2.A.2
Section 2.B
Section 2.B.1
Section 2.B.2
This example has a depth of 3 and height of 2.
Here is my code thus far, which doesn't come anywhere near the correct output.
void printDepth(int depth, int width, int minusDepth, int minusWidth) {
int i = 0;
if(depth == 0)
printf("Section XX\n");
else {
printf("\t");
printDepth(depth -1, width, minusDepth, minusWidth);
}
}
Here is the call from main()
int minusDepth = 0;
int minusWidth = 0;
printDepth(depth, width, minusDepth, minusWidth);
However, for a depth = 4 and width = 5 this only prints out:
\t\t\t\tSection XX
I'm really not sure how to proceed. Recursion is the bane of my existence.
You need a loop that prints the sections at the current depth and executes height (which I call width instead) recursions. You also need to pass a string containing the current prefix of the section string.
#include <stdio.h>
#include <assert.h>
#include <math.h>
#define MAX_DEPTH 100
#define MAX_WIDTH 99 // NOTE: if you increase this then section's decl in printDepth needs to be updated too
void printDepth_r(int currDepth, int depth, int width, char *section, char *sub)
{
if (currDepth == depth) // recursion base case
return;
for (int i = 0; i < width; ++i)
{
// TODO: write to sub the subsection determined by (currDepth, width)
fprintf(stdout, "%*sSection %s\n", currDepth * 2, "", section);
// TODO: append "." to sub for descendant recursions
printDepth_r(currDepth + 1, depth, width, section, sub + /* TODO: num chars written to sub */);
}
}
int printDepth(int depth, int width)
{
char section[MAX_DEPTH * (2 + 1) + 1]; // NOTE: 2 == 1 + (int) (log(99) / log(10));
assert(sizeof(section) >= MAX_DEPTH * (1 + (int) (log(MAX_WIDTH) / log(10)) + 1) + 1);
if (depth > MAX_DEPTH || width > MAX_WIDTH)
return -1;
printDepth_r(0, depth, width, section, section);
return 0;
}
int main(int argc, char **argv)
{
printDepth(3, 2);
return 0;
}
Note that we pass the same values of depth, width and section to all of our recursions. So, if we wanted to reduce the amount of stack space the recursion eats at every level, then we could pull these out into a structure and pass 1 struct pointer to these 3 constants instead. Or, even better, we could store these values in thread local storage. Either way would allow deeper recursions before overflowing your stack.
#include <stdio.h>
void printDepth(int deep, int depth, int height, char *table) {
if(deep == depth)
return ;
int i, j;
char bak = table[deep];
for(i = 0; i < height; ++i){
printf("%*s%s", deep*2, "", "Section ");
for(j = 0; j <= deep; ++j){
if(j)
putchar('.');
putchar(table[j]);
}
putchar('\n');
printDepth(deep+1, depth, height, table);
table[deep]++;
}
table[deep] = bak;//restore
}
int main(void){
char table[] = "1A1";//Effective range up to 1-9 and A-Z
printDepth(0, 3, 2, table);
return 0;
}
I'm developing a solitary board game, which has a piece per square, and each piece can be of two colors. If I click a piece, the four adjacent ones (top, bottom, left and right) all change to the next color.
I'm having problems with detecting in which piece the mouse was clicked on.
I have the following code for the mouse callback:
GLuint selectBuf[BUFSIZE]; // BUFSIZE is defined to be 512
GLint hits;
GLint viewport[4];
if( ( state != GLUT_DOWN ) && ( button != GLUT_LEFT_BUTTON ) )
return;
glGetIntegerv (GL_VIEWPORT, viewport);
glSelectBuffer (BUFSIZE, selectBuf);
(void) glRenderMode (GL_SELECT);
glInitNames();
glPushName(0);
gluPickMatrix ((GLdouble) x, (GLdouble) y, 20.0,20.0, viewport);
draw(GL_SELECT); // the function that does the rendering of the pieces
hits = glRenderMode(GL_RENDER);
processHits (hits, selectBuf); // a function that displays the hits obtained
Now, the problem I have is that I don't quite know how to process the hits occurred which are on selectBuf. I have the following code for processHits:
void processHits (GLint hits, GLuint buffer[])
{
unsigned int i, j;
GLuint ii, jj, names, *ptr;
printf ("hits = %d\n", hits);
ptr = (GLuint *) buffer;
for(i = 0; i < hits; i++) {
printf("hit n. %d ---> %d",i, *(buffer+i));
}
}
Finally, in the draw function I have:
void draw(GLenum mode) {
glClear (GL_COLOR_BUFFER_BIT);
GLuint x,y;
int corPeca; //colourpiece in english
int corCasa; //colourHouse (each square has a diferent color, like checkers)
for (x =0; x < colunas; x++) { //columns
for(y=0; y < colunas; y++) {
if ( (tabuleiro[y*colunas+x].peca) == 1) //board
corPeca = 1;
else
corPeca = 2;
if((tabuleiro[y*colunas+x].quadrado)==1) //square
corCasa = 1;
else
corCasa = 2;
if (mode == GL_SELECT){
GLuint name = 4;
glLoadName(name);
}
desenhaCasa(x,y,corCasa); //draws square
desenhaPeca(x,y,corPeca, mode); //draws piece
}
}
}
Now, has you can see, I've just put 4 into the buffer with glLoadName. However when I pull the number out in processHits I always get 1. I know that's because of the structure of the buffer that gets the hits, but what is that structure and how can I access the number 4?
Thank you very much for helping me.
The structure of the selection buffer is a bit more complex than that. For each hit, a "hit record" consisting of several values is appended to the selection buffer. You can look at Question 20.020 in the OpenGL FAQ for details. In your case, where there is only one name on the stack at a time, the hit record will consist 4 values, with the name being the fourth one. So, in your processHits function, you should write
for(i = 0; i < hits; i++) {
printf("hit n. %d ---> %d",i, *(buffer+4*i+3));
}
Also, the size of your name buffer should probably be 4 times longer as well.