I'm trying to write a function or method for the code. I'm really lost at how to come with the loop that print out the number born and number died in the output below.
Here is my code:
#include <stdio.h>
char grid[10][10];
// Moved this function here
int occ(int x, int y) {
int i, j, count;
char gridCopy[10][10];
// You probably are going to do this often in the future
// Make a function for it instead of having the same code often
void printGrid() {
int i, j;
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++)
printf("%c", grid[i][j]);
printf("\n");
}
}
You don't need gridCopy in occ function.
Please remember that array is transposed. When you access element (x,y) you need to use grid[y][x]
Below is the working code with function generateNext() which generates next state for whole grid array. This is place where you need girdCopy. Results are exactly the same as in your example.
#include <stdio.h>
#include <stdlib.h>
char grid[10][10];
int born,died,generation;
// Moved this function here
int occ(int x, int y) {
int count;
int xm1,xp1,ym1,yp1;
xm1=x-1;xp1=x+1;ym1=y-1;yp1=y+1;
if (xm1<0) // handle boundary cases - wrap around
xm1=9;
if (ym1<0)
ym1=9;
if (xp1>9)
xp1=0;
if (yp1>9)
yp1=0;
// Checking on the value of the neighboring cells
count = 0;
if (grid[ym1][x] == '*')
count++;
if (grid[ym1][xp1] == '*')
count++;
if (grid[y][xp1] == '*')
count++;
if (grid[yp1][xp1] == '*')
count++;
if (grid[yp1][x] == '*')
count++;
if (grid[yp1][xm1] == '*')
count++;
if (grid[y][xm1] == '*')
count++;
if (grid[ym1][xm1] == '*')
count++;
return count;
}
void generateNext()
{
int x,y;
char gridCopy[10][10];
born=0;died=0;
generation++;
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
gridCopy[y][x]=grid[y][x];
}
}
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
if (grid[y][x]=='*' && occ(x,y)<2)
{gridCopy[y][x]='-';died++;}
if (grid[y][x]=='*' && occ(x,y)>3)
{gridCopy[y][x]='-';died++;}
if (grid[y][x]=='-' && occ(x,y)==3)
{gridCopy[y][x]='*';born++;}
}
}
for (y=0; y<10; y++) {
for (x=0; x<10; x++) {
grid[y][x]=gridCopy[y][x];
}
}
}
// You probably are going to do this often in the future
// Make a function for it instead of having the same code often
void printGrid() {
int x, y;
for (y = 0; y < 10; y++) {
for (x = 0; x < 10; x++)
printf("%c", grid[y][x]);
printf("\n");
}
}
/*
*
*/
int main(int argc, char** argv) {
int x, y, answ;
// Setting entire grid to '-'
for (y = 0; y < 10; y++)
for (x = 0; x < 10; x++)
grid[y][x] = '-'; // No need for a variable, just use '-' directly
// Printing out grid
printf("This is the original array\n");
printGrid();
// Setting initial state
grid[5][4] = '*'; // No need for a variable, just use '*' directly
grid[5][5] = '*';
grid[5][6] = '*';
grid[4][4] = '*'; grid[3][4] = '*';
grid[4][6] = '*'; grid[3][6] = '*';
// Printing out grid
printf("This is the new array\n");
printGrid();
//printf("The number of neighbors is: %d\n", occ(3, 3));
generation=0;
answ=1;
while(answ)
{
generateNext();
printf("\n\nGeneration number %d",generation);
printf("\nBorn=%d,Died=%d\n",born,died);
printGrid();
printf("\nPrint next generation-1,Exit-0:");
scanf("%d",&answ);
}
return (EXIT_SUCCESS);
}
Counting is similar to what you have to do to print or copy the whole grid: you use the same loop(s), but at each cell, add to the appropriate counter depending on what is in it.
Alternatively, if keep counts of the number of dead and live cells, you can update those as you update the grid: if a cell changes, update the counters appropriately if the cell becomes alive or becomes dead. This can also be used if you need to report how many were born & how many died each turn.
Related
I wrote a function where a 1-dimensional array (int8_t tabelle1[768]) is transferred into a 2-dimensional array (int8_t tabelle[24][32]).
I now want to find a "Hotspot" in the 2-dimensional array. A "Hotspot" is an 2x2 block in the array (can be located anywhere) where each value of the block has to be equal or over 30.
My Problem is now that my program is not going into my if statement.
The "Checkpoint" is not being printed.
The function:
bool Hotspotberechnung(int8_t tabelle1[768],int8_t tabelle2[24][32])
{
int i=0, j=0, x=0, y=0;
for(j=0; j<24; j++) //Transfer from 1D into 2D
{
for(i=0; i<32; i++)
{
tabelle2[j][i] = tabelle1[(j*32)+i];
}
}
for(y=0; y<24; y++) //search for hotspot
{
for(x=0; x<32; x++)
{
if(tabelle2[y][x]>=30)
{
printf ("1\n"); // checkpoint
if(tabelle2[y][x+1]>=30)
{
if(tabelle2[y+1][x]>=30)
{
if(tabelle2[y+1][x+1]>=30)
{
for(j=0; j<24; j++)
{
for(i=0; i<32; i++)
{
printf("%d.%d=%d\n",j+1,i+1,tabelle2[j][i]);
}
}
printf ("Hotspot!");
return true;
}
else
return false;
}
else
return false;
}
else
return false;
}
else
return false;
}
}
return 0;
}
It never reaches the print, because one of your many returns ends the function much sooner than you think. Specifically the one in the else of the then wich contains the print.
Use a debugger and you will see that.
Alternatively put a print next to each else, make sure to use {} for that. Also put a print after the call to the shown function.
for(y=0; y<24; y++) //search for hotspot
{
for(x=0; x<32; x++)
{
if(tabelle2[y][x]>=30)
{
/* this is not reached for y=0 and x=0, i.e. first */
printf ("1\n"); // checkpoint
/* much code deleted */
}
else
return false;
/* this is reached first,
end of the function,
end of the loop,
no printing ever */
}
}
A few things ...
The kernal width/height is 2, so we have to stop short of the array width/height or we'll go beyond the end of the array
Once we find an element that matches, we have to use that element as the upper left anchor of the 2x2 box
Here's the refactored code (it compiles, but is not tested):
#include <stdio.h>
#include <stdint.h>
#define YMAX 24
#define XMAX 32
#define BOXWID 2
#define MARG (BOXWID - 1)
int
Hotspotberechnung(int8_t tabelle1[YMAX * XMAX], int8_t tabelle2[YMAX][XMAX])
{
int i = 0,
j = 0,
x = 0,
y = 0;
// Transfer from 1D into 2D
for (j = 0; j < YMAX; j++) {
for (i = 0; i < XMAX; i++)
tabelle2[j][i] = tabelle1[(j * XMAX) + i];
}
for (y = 0; y < (YMAX - MARG); y++) {
int8_t *row = tabelle2[y];
for (x = 0; x < (XMAX - MARG); x++) {
if (row[x] < 30)
continue;
int8_t *box = &row[x];
int match = 1;
for (int yoff = 0; yoff < BOXWID; ++yoff) {
for (int xoff = 0; xoff < BOXWID; ++xoff) {
if (box[(yoff * XMAX) + xoff] < 30) {
match = 0;
break;
}
}
if (! match)
break;
}
if (! match)
continue;
for (int yoff = 0; yoff < BOXWID; ++yoff) {
for (int xoff = 0; xoff < BOXWID; ++xoff) {
int8_t val = box[(yoff * XMAX) + xoff];
printf("[%d,%d] = %d\n",y + yoff,x + xoff,val);
}
}
}
}
return 0;
}
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 am trying to build a square/rectangle using "Xs" on a 1:1 scale with the length and width, but the logic seems to be not perfect
void draw (float x, float y) {
int i, j;
int length = (int)x + 0;
int width = (int)y + 0;
for (i = 1; i < length; i++) {
for (j = 1; j < width; j++) {
if (((i = 1) || (i = length)) && ((j = 1) || (j = width))) {
printf("x");
} else {
printf(" ");
}
}
printf("\n");
}
}
The problem is that the loop iterates endlessly printing x's everywhere. I'm expecting Xs to be printed out in either a square or rectangular shape (depending on the length or width).
I see 3 flaws in your logic.
you mix = (assignment) with == comparison.
This is why your loop never ends: you always reset i to 1 with your if (((i = 1) || (i = length)) &...
you're not going far enough with your variables:
if i < length, then you'll never have it reach length and print the bottom line of X's
you can't draw a rectangle because your && in the test (((i = 1) || (i = length)) && ((j = 1) || (j = width))) is too restrictive. It can't work if width different from length.
You must learn the logic by yourself using tutorials:
Here such questions will be discarded by sometime-sad people. But as a welcome, here it is (you can replace y in the second case by x, but I thought it would help you understand):
#include <stdio.h>
#include <string.h>
void draw (float x, float y)
{
int i,j;
int length = (int)x + 0;
int width = (int)y + 0;
for(i=1; i<=length; i++) {
for(j=1;j<=width;j++) {
if(((i==1)||(i==length))) {
printf("x");
} else {
if (((j==1)||(j==width))) {
printf("y");
} else {
printf(" ");
}
}
}
printf("\n");
}
}
I am trying to create a program in C that, given the user's input of a character boarder for a shape, fills the shape in.
http://pastebin.com/aax1dt0b
#include <stdio.h>
#include "simpio.h"
#include "genlib.h"
#define size 100
bool initArray(bool a[size][size]);
bool getshape(bool a[size][size]); /* Gets the input of the boarder of the shape from the user */
void fill(int x, int y, bool a[size][size]); /* fills the shape */
void printarray(bool a[size][size]); /* prints the filled shape */
main()
{
int x, y;
char i;
bool a[size][size];
initArray(a);
getshape(a);
printf("Enter the coordinates of the point the shape should be filled.\n");
printf("x=n\n"); /* gets the coordinates of the array to begin the fill algorithm from */
x = GetInteger();
printf("y=\n");
y = GetInteger();
fill(x, y, a);
printarray(a);
printf("Scroll up to view your filled shape\n");
getchar();
}
bool initArray(bool a[size][size])
{
int i, j;
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
a[i][j] = FALSE;
}
}
}
bool getshape(bool a[size][size])
{
int i, j, k;
bool flag;
char ch;
ch = 1;
printf("Enter your shape. When you are finished, type 'E'. \n");
for (i = 0; i < 100; i++)
{
flag = TRUE;
for (j = 0; ch != 10; j++)
{
ch = getchar();
if (ch == 69)
{
return a;
}
if (ch != 32) a[i][j] = TRUE;
}
ch = 1;
}
}
void fill(int x, int y, bool a[size][size])
{
if (a[y][x] != TRUE) a[y][x] = TRUE;
if (a[y][x - 1] != TRUE) fill(x - 1, y, a);
if (a[y - 1][x] != TRUE) fill(x, y - 1, a);
if (a[y][x + 1] != TRUE) fill(x + 1, y, a);
if (a[y + 1][x] != TRUE) fill(x, y + 1, a);
}
void printarray(bool a[size][size])
{
int i, j;
printf("\n\n\n");
for (i = 0; i < 100; i++)
{
for (j = 0; j < 100; j++)
{
if (a[i][j] == FALSE) printf(" ");
if (a[i][j] == TRUE) printf("*");
}
printf("\n");
}
}
My program works for the most part, but when it prints the filled shape, it adds one additional character to each row. For example, if the user's input it
***
* *
***
Then the output will be
****
****
**** (one extra row then it should be)
whereas it should be
***
***
***
anyone know how I can fix this?
Although there are several potential problems in your code, I'm going to just identifying the problem of the 4th column *'s. In the code below, although you're checking ch!=10 in the for statement, the value of a[i][j] is getting assigned TRUE before terminating the loop. So you might want to do if(ch!=32 && ch!=10) a[i][j]=TRUE;.
flag=TRUE;
for(j=0;ch!=10;j++)
{
ch=getchar();
if(ch==69)
{
return a;
}
if(ch!=32) a[i][j]=TRUE;
}
ch=1;
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.