I'm looking for a way to replace the continue statement in this function. The houserules state that they can't be used but I'm having difficulty implementing a replacement that doesn't cause the rest of the code to function incorrectly.
bool neighCheck (int i, int j, int a[][COLLENGTH])
{
bool neighbourOnFire;
int x, y, neighX, neighY, curreNeigh;
/* Bool set up to change after neighbours looped*/
neighbourOnFire = false;
/* The neighbours -looping from -1 -> 1 to get index of each neighbour*/
for (x = -1; x < 2; x++) {
for (y = -1; y < 2; y++) {
/* Disregards current (middle) cell*/
if ((x == 0) && (y == 0)) {
continue;
}
/* Get indexes of the neighbour we're looking at */
neighX = i + x;
neighY = j + y;
/* Checks for edges*/
if (neighX >= 0 && neighY >= 0 && neighX < ROWLENGTH
&& neighY < COLLENGTH) {
/* Get the neighbour using the indexes above */
curreNeigh = a[neighX][neighY];
/* Test to see if the neighbour is burning */
if (curreNeigh == fire) {
neighbourOnFire = true;
continue;
}
}
}
}
return neighbourOnFire;
}
The first continue; can be replaced by inverting the condition and putting the rest code inside if statement.
The second continue; can be simply removed because there are no code to execute after that.
bool neighCheck (int i, int j, int a[][COLLENGTH])
{
bool neighbourOnFire;
int x, y, neighX, neighY, curreNeigh;
/* Bool set up to change after neighbours looped*/
neighbourOnFire = false;
/* The neighbours -looping from -1 -> 1 to get index of each neighbour*/
for (x = -1; x < 2; x++) {
for (y = -1; y < 2; y++) {
/* Disregards current (middle) cell*/
if (!((x == 0) && (y == 0))) {
/* Get indexes of the neighbour we're looking at */
neighX = i + x;
neighY = j + y;
/* Checks for edges*/
if (neighX >= 0 && neighY >= 0 && neighX < ROWLENGTH
&& neighY < COLLENGTH) {
/* Get the neighbour using the indexes above */
curreNeigh = a[neighX][neighY];
/* Test to see if the neighbour is burning */
if (curreNeigh == fire) {
neighbourOnFire = true;
}
}
}
}
}
return neighbourOnFire;
}
Related
I need help with my Game of Life implementation in C. Other posts on Stackoverflow lead me to believe that my problem was to do with dangling pointers, but after modifying my program to use a global 2D array for the game grid instead of passing it to functions which return new 2D arrays, I realized that it was a problem with my update function.
I have tried hard-coding a number of simple patterns, including gliders and oscillators, and the grid doesn't update correctly. The patterns do update the same way every time the program is run, so I don't think it's a problem of uninitialized memory causing problems. I also know that there are no cells which contain values greater than 1. Therefore, the problem must lie in my mechanisms for updating the grid.
Can someone help me find the problem? I can't find anything wrong with my code and I believe I have programmed the rules correctly.
Here are my neighbors and update functions, along with the relevant variable and constant declarations.
#define MAX_Y 10 /* height */
#define MAX_X 30 /* width */
int grid[MAX_Y][MAX_X];
int neighbors(int x, int y) {
int dx, dy, dstx, dsty;
int n = 0;
for (dy = -1; dy <= 1; ++dy) {
for (dx = -1; dx <= 1; ++dx) {
dsty = y + dy;
dstx = x + dx;
if (dsty >= 0 && dsty < MAX_Y && dstx >= 0 && dstx < MAX_X)
n += !!grid[dsty][dstx]; /* use !! so that non-zero values eval to 1 */
}
}
/* (n > 0) ? printf("Point (%d,%d) has %d neighbors!\n", x, y, n) : 0; */
return n;
}
void update(void) {
int new[MAX_Y][MAX_X];
memset(new, 0, sizeof(int) * MAX_Y * MAX_X);
int i, j, n;
for (i = 0; i < MAX_Y; ++i) {
for (j = 0; j < MAX_X; ++j) {
n = neighbors(i, j);
/* alive, 2 or 3 neighbors -> alive!
* dead, 3 neighbors -> alive!
* anything else -> dead :(
*/
if (grid[i][j] && (n == 2 || n == 3))
new[i][j] = 1;
else if (!grid[i][j] && n == 3)
new[i][j] = 1;
else
new[i][j] = 0;
}
}
memcpy(grid, new, sizeof grid);
}
In your neighbors function, you need to think carefully about the loop iteration where dx and dy are both zero. Conway's Game of Life does not consider a cell to be neighbor of itself, so you need to avoid counting it.
You're also confusing yourself by using the letters i and j. You're allowing j to go all the way up to MAX_X, but then you are using j as the y coordinate when you call neighbors, so that will cause overflows and incorrect calculations. (Starting with the easier case of a 10x10 grid would sometimes save you from bugs like this.)
You should adjust the neighbors() function to omit the cell itself.
Here is a modified version:
#define MAX_Y 10 /* height */
#define MAX_X 30 /* width */
unsigned char grid[MAX_Y][MAX_X];
int neighbors(int x, int y) {
int n = -!!grid[y][x];
for (int dy = -1; dy <= 1; ++dy) {
for (int dx = -1; dx <= 1; ++dx) {
int dsty = y + dy;
int dstx = x + dx;
if (dsty >= 0 && dsty < MAX_Y && dstx >= 0 && dstx < MAX_X && grid[dsty][dstx])
n++;
}
}
return n;
}
void update(void) {
int new[MAX_Y][MAX_X] = { 0 };
for (int y = 0; y < MAX_Y; ++y) {
for (int x = 0; x < MAX_X; ++x) {
int n = neighbors(y, x);
/* alive, 2 or 3 neighbors -> alive!
* dead, 3 neighbors -> alive!
* anything else -> dead :(
*/
new[y][x] = (grid[y][x] && n == 2) || n == 3;
}
}
memcpy(grid, new, sizeof grid);
}
The neighbors() function can be simplified with fewer tests:
int neighbors(int x, int y) {
int n = -(grid[y][x] != 0);
int x1 = x - (x > 0);
int x2 = x + (x < MAX_X - 1);
int y1 = y - (y > 0);
int y2 = y + (y < MAX_Y - 1);
for (y = y1; y <= y2; y++) {
for (x = x1; x <= x2; x++) {
n += grid[y][x] != 0;
}
}
return n;
}
I made this backtracking recursive code.
this code shows every 4x4 array filled with 1, 2, 3, 4
but no duplication in every one row and line.
but this prints only one answers, what I expected is every answers.
#include <stdio.h>
#include <stdbool.h>
// initializing array
void init_arr(int arr[][4])
{
int x;
int y;
y = 0;
while (y < 4)
{
x = 0;
while (x < 4)
{
arr[y][x] = 0;
x++;
}
y++;
}
}
// check about promising correct
bool promising(int arr[][4], int x, int y)
{
int i;
i = 0;
while (i < 4)
{
if (arr[y][i] == arr[y][x] && i != x)
return (0);
i++;
}
i = 0;
while (i < 4)
{
if (arr[i][x] == arr[y][x] && i != y)
return (0);
i++;
}
return (1);
}
// recursive function
void fill_arr(int arr[][4], int x, int y)
{
int n;
if (x == 0 && y == 0)
init_arr(arr);
if (y == 4)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
printf("\n");
return ;
}
else if (x == 4)
fill_arr(arr, 0, y + 1);
else
{
n = 1;
while (n < 5)
{
arr[y][x] = n;
if (promising(arr, x, y))
fill_arr(arr, x + 1, y);
n++;
}
}
}
int main(void)
{
int arr[4][4];
fill_arr(arr, 0, 0);
return (0);
}
when I put printf in if(promising), this comes out
it looks like some variables are not initializing, but when I put init function to every other line, it getting messier.
Your fill_arr() isn't cleaning up before it leaves.
Add this line before the final brace:
arr[y][x] = 0;
I'm trying to code a perfect maze generator, but I have few problems in the code due to the recursion which leads to Segfault when the maze is too big. Here is the main part of the code:
t_maze *init_maze(int w, int h)
{
t_maze *maze;
int j;
int i;
if ((maze = malloc(sizeof(t_maze))) == NULL)
return (NULL);
maze->w = w;
maze->h = h;
if ((maze->cells = malloc(sizeof(char *) * maze->h)) == NULL)
return (NULL);
j = -1;
while (++j < maze->h)
{
if ((maze->cells[j] = malloc(sizeof(char) * maze->w)) == NULL)
return (NULL);
i = -1;
while (++i < maze->w)
maze->cells[j][i] = (j % 2 == 1 || i % 2 == 1) ? (1) : (0);
}
return (maze);
}
void detect_neighbours(t_maze *maze, char *neighbours, int x,
int y)
{
int i;
// I fill the array with 1 (means there is no neighbours)
// If there is a neighours, I set the cell to 0
// In this order: Top, right, bottom, left
i = -1;
while (++i < 4)
neighbours[i] = 1;
if (y - 2 >= 0 && x >= 0 && y - 2 < maze->h
&& x < maze->w && maze->cells[y - 2][x] == 0)
neighbours[0] = 0;
if (x + 2 >= 0 && x + 2 < maze->w && y >= 0 && y < maze->h
&& maze->cells[y][x + 2] == 0)
neighbours[1] = 0;
if (y + 2 < maze->h && y + 2 >= 0 && x >= 0
&& x < maze->w && maze->cells[y + 2][x] == 0)
neighbours[2] = 0;
if (x - 2 >= 0 && x - 2 < maze->w && y >= 0 && y < maze->h
&& maze->cells[y][x - 2] == 0)
neighbours[3] = 0;
}
int there_is_no_neighbours(char *neighbours)
{
int i;
// this function returns 0 if there is at least 1 neigbours
i = -1;
while (++i < 4)
if (neighbours[i] == 0)
i = 41;
if (i == 42)
return (0);
return (1);
}
void set_maze_protected(t_maze *maze, int y, int x, int val)
{
// To prevent segfault when I put values in the maze,
// I check the x and y keys
if (x >= 0 && y >= 0 && x < maze->w && y < maze->h)
maze->cells[y][x] = val;
}
int build_maze(t_maze *maze, int x, int y)
{
char neighbours[4];
int i;
int ret;
ret = 0;
detect_neighbours(maze, neighbours, x, y);
if (there_is_no_neighbours(neighbours) == 1)
return (0);
i = rand() % 4;
while (neighbours[i] == 1)
i = rand() % 4;
if (i == 0)
{
set_maze_protected(maze, y - 1, x, 2);
set_maze_protected(maze, y - 2, x, 2);
ret = build_maze(maze, x, y - 2);
}
if (i == 1)
{
set_maze_protected(maze, y, x + 1, 2);
set_maze_protected(maze, y, x + 2, 2);
ret = build_maze(maze, x + 2, y);
}
if (i == 2)
{
set_maze_protected(maze, y + 1, x, 2);
set_maze_protected(maze, y + 2, x, 2);
ret = build_maze(maze, x, y + 2);
}
if (i == 3)
{
set_maze_protected(maze, y, x - 1, 2);
set_maze_protected(maze, y, x - 2, 2);
ret = build_maze(maze, x - 2, y);
}
while (ret != 0)
ret = build_maze(maze, x, y);
return (1);
}
int main()
{
t_maze *maze;
int w;
int h;
w = 50;
h = 50;
srand(time(NULL) * getpid());
if ((maze = init_maze(w, h)) == NULL)
return (1);
maze->cells[0][0] = 2;
build_maze(maze, 0, 0);
// display_maze shows values in the 2D array (maze->cells)
display_maze(maze);
return (0);
}
I call this function in main with this call:
build_maze(maze, 0, 0);
The function detects is the cell has neighbours, and if it has, the function calls one of them randomly and open the door between the two.
If the x and y args are bigger than 2500 for example, it will segfault. (If it is less than 2500, it will work great)
How to fix this ?
I learnt about tail call but I ignore how to implement that in this case,
Thank you,
Best Regards
You can increase the stack size.
On POSIX systems, you can use the following code.
#include<stdio.h>
#include <sys/resource.h>
#define required_stack_size 0x8000000 // change this to the stack size you need
int main (int argc, char **argv)
{
struct rlimit rl;
int result;
if((result = getrlimit(RLIMIT_STACK, &rl)) < 0)
{
fprintf(stderr, "getrlimit returned result %d\n", result);
return -1;
}
if(rl.rlim_cur<required_stack_size)
{
rl.rlim_cur = required_stack_size;
if((result = setrlimit(RLIMIT_STACK, &rl)) < 0)
{
fprintf(stderr, "setrlimit returned result = %d\n", result);
return -1;
}
}
//the rest code
return 0;
}
In a contest, they asked to write a C function which returns the minimum distance between X and Y in the given array, where X and Y are elements of the array Provided X AND Y ARE Distinct.
If have written a piece of code, but that code runs into many if's and else's,
My code (Has Some Bugs):
int getMinXYDist(int arr[],int n,int x,int y){
int i,flag = 0,ele = -1 ,dist = 0;
int minDist = 1000; // SETTING minDist TO MAX VALUE.
for( i = 0 ; i< n; i++)
if(arr[i] == x || arr[i] == y){
if(flag == 0){
flag = 1;
ele = arr[i]==x?x:y;
dist = 0;
}
else{
if(ele == x ){
if(arr[i] == y){
minDist = dist < minDist ? dist : minDist;
dist = 0;
ele = y;
}
else //if(arr[i] == x){
dist = 0;
}
else { //if(ele == y)
if(arr[i] == x){
minDist = dist < minDist ? dist : minDist;
dist = 0;
ele = x;
}
}
}
}
else {
if(flag == 1)
dist++;
}
return minDist;
}
void main(){
int arr = {6,1,5,1,8,6,3,4};
printf("\n%d" ,getMinXYDist(arr,sizeof(arr)/sizeof(int),6,5) ); //Must return 2.
}
Could Any one suggest a smarter way [ Just as in O(n) time complexity ] of calculating the distance?
If x or y is found, record the index it was found at. Once both have been found, each time you find either, compute distance to the last index containing the other value. Update the minimum value if the distance is lower than the previous minimum.
int getMinXYDist(int arr[],int n,int x,int y)
{
int i, indexX, indexY;
int foundX = 0;
int foundY = 0;
int curDist;
int minDist = n;
for (i = 0; i < n; i++)
{
if (arr[i] == x)
{
foundX = 1;
indexX = i;
if (foundX && foundY)
{
curDist = indexX - indexY;
if (curDist < minDist)
{
minDist = curDist;
}
}
}
else if (arr[i] == y)
{
foundY = 1;
indexY = i;
if (foundX && foundY)
{
curDist = indexY - indexX;
if (curDist < minDist)
{
minDist = curDist;
}
}
}
}
return minDist;
}
Basically, I think OP's solution is already optimum, the lower bound for this algorithm is n steps, i.e., done in one iteration.
// if -1 is returned, then none of x and y are in the array
// if n is returned, then one of x and y is not in the array
// otherwise, mindist(x, y) is returned.
int test(int v[], int n, int x, int y)
{
int flag = -1;
int i, a = -1, b = -1, dist = n;
for (i = 0; i < n; ++i) {
if (v[i] == x) {
flag = 0;
a = i;
break;
} else if (v[i] == y) {
flag = 1;
b = i;
break;
}
}
if (flag < 0) return -1; // x and y are both not in array;
for (++i; i < n; ++i) {
if (v[i] == x) {
if (0 == flag) a = i;
else {
flag = 0;
if (i - b < dist) dist = i - b;
a = i;
}
} else if (v[i] == y) {
if (1 == flag) b = i;
else {
flag = 1;
if (i - a < dist) dist = i - a;
b = i;
}
}
}
return dist;
}
int minDistance ( int arr[], int n, int x, int y) {
if(x == y) return 0;
int index1 = -1;
int index2 = -1;
int minvalue = n;
for(int i = 0 ; i < n; i++){
if((arr[i] == x) && ((i-index2) < minvalue)){
index1 = i;
if( index2 != -1)minvalue = i-index2;
}else if((arr[i] == y) && ((i-index1) < minvalue)){
index2 = i;
if( index1 != -1)minvalue = i-index1;
}
}
return minvalue;
}
where
n: size of array.
x and y: two input number of array.
If minvalue returned is n then x or y is not present in array.
complexity: O(n), One Pass.
I have done all the code right and stuck with this silly thing: I cannot mange to stop the print when the previous generation is the same as the new...so when the prints pattern is the same as the previous pattern it should stop.
I need to copy the board before calling 'step' and then compare the new and copied boards, and only print if it has changed
i need is to create a new variable just like i did board[], then to make a nested loop like the one in print, and inside do newboard[y][x] = board[y][x]
Please help me with this i cannot stop the print it always keep printing.
please show me your syntax
void step(int board[][WIDTH], int rows) {
int x, y;
int neighbors[HEIGHT][WIDTH];
for (y = 0; y < rows; y++)
for (x = 0; x < WIDTH; x++)
neighbors[y][x] = count_neighbors(board, rows, y, x);
for (y = 0; y < rows; y++)
for (x = 0; x < WIDTH; x++)
if (board[y][x] == 1) { /* Currently alive */
if (neighbors[y][x] < 2)
board[y][x] = 0; /* Death by boredom */
else if (neighbors[y][x] > 3)
board[y][x] = 0; /* Death by overcrowding */
}
else { /* Currently empty */
if (neighbors[y][x] == 3)
board[y][x] = 1;
}
}
You just have to track changes. Rather trivial to do and far less work (execution/memory wise) than copying and comparing the whole array:
int step(int board[][WIDTH], int rows) { // now returns a bool
int x, y;
int neighbors[HEIGHT][WIDTH];
int changed = 0; // save changes
for (y = 0; y < rows; y++)
for (x = 0; x < WIDTH; x++)
neighbors[y][x] = count_neighbors(board, rows, y, x);
for (y = 0; y < rows; y++)
for (x = 0; x < WIDTH; x++)
if (board[y][x] == 1) { /* Currently alive */
if (neighbors[y][x] < 2)
{
board[y][x] = 0; /* Death by boredom */
changed = 1; // change happened
}
else if (neighbors[y][x] > 3)
{
board[y][x] = 0; /* Death by overcrowding */
changed = 1; // change happened
}
}
else { /* Currently empty */
if (neighbors[y][x] == 3)
{
board[y][x] = 1;
changed = 1; // change happened
}
}
return changed; // return the status (changed yes/no?)
}
int main(void) {
int board[HEIGHT][WIDTH];
init(board, HEIGHT);
while (1) {
print(board, HEIGHT, WIDTH);
if(step(board, HEIGHT) == 0) // no change
break; // leave the loop
}
return 0;
}
Edit:
If wanted, you could as well count the actual changes (instead of just saying yes/no) and return the number of changes. Could would stay almost the same.