2 svar
110 visningar
unicarl 21
Postad: 18 okt 2022 13:37

Varför printar den inte ut den uppdaterade världen?

Håller på med en riktigt trög uppgift kallad Game of Life (baserad på detta) och kommer ingen vart. Allt funkar som det ska förutom att den inte printar ut nästa generation, den printar bara samma. Jag förstår verkligen inte hur jag sak få den att printa ut nästa generation och inte bara printa en kopia av samma. All hjälp uppskattas.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* Constants, representation of states */
#define ALIVE 'X'
#define DEAD '.'

#define BUFLEN 1024

/* Declaration of data structure */
typedef struct {
	char current;
	char next;
} cell;

/* Function:    get_start_state
 * Description: Lets the user choose starting state
 * Input:       None.
 * Output:      The users choice. Should be one of the letters G, S,R or C.
 */
char get_start_state(void)
{
	int ch = 0;

	printf("Select world spec to load ([G]lider, [S]emaphore, [R]andom ");
	printf("or [C]ustom): ");

	ch = getchar();

	/* Eat any trailing newline */
	if (ch != '\n') {
		getchar();
	}
	return ch;
}

/* Function:    clear_world
 * Description: Initialize all the cells in the world to dead
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated.
 */
void clear_world(const int rows, const int cols, cell world[rows][cols])
{
	for (int r = 0 ; r < rows ; r++) {
		for (int c = 0 ; c < cols ; c++) {
			world[r][c].current = DEAD;
		}
	}
}

/* Function:    load_glider
 * Description: Inserts a glider into the world.
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated.
 */
void load_glider(const int rows, const int cols, cell world[rows][cols])
{
	world[0][1].current = ALIVE;
	world[1][2].current = ALIVE;
	world[2][0].current = ALIVE;
	world[2][1].current = ALIVE;
	world[2][2].current = ALIVE;
}

/* Function:    load_semaphore
 * Description: Inserts a semaphore into the world.
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated.
 */
void load_semaphore(const int rows, const int cols, cell world[rows][cols])
{
	world[8][1].current = ALIVE;
	world[8][2].current = ALIVE;
	world[8][3].current = ALIVE;
}

/* Function:    load_random_state
 * Description: Inserts a random structure into the world.
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated. There is a 50 % chance that a cell
 *              is alive.
 */
void load_random_state(const int rows, const int cols, cell world[rows][cols])
{
    srand(time(NULL));
	int state;

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            state = rand() % 2;
            if (state == 0) {
                world[r][c].current = DEAD;
            } else {
                world[r][c].current = ALIVE;
            }
        }
    }
}

/* Function:    load_custom_state
 * Description: Lets the user specify a structure that then is inserted into
 *              the world.
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated.
 */
void load_custom_state(const int rows, const int cols, cell world[rows][cols])
{
	char buf[BUFLEN];
	char *sc;
	int r, c;

	printf("Give custom format string (r1,c1; r2,c2; ...): ");

	// Read input into buffer
	fgets(buf,BUFLEN,stdin);
	// First pair to parse
	sc=buf;
	do {
		// Parse row, column pair
		if (sscanf(sc,"%d,%d;", &r, &c) == 2) {
			world[r][c].current = ALIVE;
		}
		// Advance semicolon pointer to next semi-colon
		sc=strchr(sc,';');
		if (sc) {
			// If we found a semi-colon, advance past it
			sc++;
		}
	} while (sc != NULL);
}

/* Function:    init_world
 * Description: Loads a structure that the user selects
 * Input:       rows - the number of rows in the world
 *              cols - the number of columns in the world
 *              world - the array representing the world
 * Output:      The world array is updated.
 */
void init_world(const int rows, const int cols, cell world[rows][cols])
{
	char choice;

	clear_world(rows,cols,world);

	choice=get_start_state();

	switch (choice) {
	case 'g':
	case 'G':
		load_glider(rows, cols, world);
		break;
	case 's':
	case 'S':
		load_semaphore(rows, cols, world);
		break;
	case 'r':
	case 'R':
		load_random_state(rows, cols, world);
		break;
	case 'c':
	case 'C':
	default:
		load_custom_state(rows, cols, world);
		break;
	}
}

/* Function:    print_world
 * Description: Prints the 20x20 world used in the game.
 * Input:       None
 * Output:      The 20x20 matrix wirh either dead or alive cells.
 */
void print_world(const int rows, const int cols, cell world[rows][cols])
{
    do {
        for (int r = 0; r < rows; r++) {
            if (r != 0) {
                printf("\n");
            }
        for (int c = 0; c < cols; c++) {
            if (world[r][c].current == ALIVE) {
                printf("X ");
            } else {
                printf(". ");
                }
            }
        }
        printf("\n");
        printf("Select one of the following options:\n (enter) Step\n");
        printf(" (any) Exit \n");
    } while (getchar() == '\n');
}

void update_state (const int rows, const int cols, cell world[rows][cols])
{
    int neighbours = 0;

    for (int r = 0; r < 0; r++) {
        for (int c = 0; c < 0; c++) {
            if (world[r + 1][c].current == ALIVE && (r + 1) <= 19) {
                neighbours++;
            }
            if (world[r - 1][c].current == ALIVE && (r-1) >= 0) {
                neighbours++;
            }
            if (world[r][c + 1].current == ALIVE && (c + 1) <= 19) {
                neighbours++;
            }
            if (world[r][c - 1].current == ALIVE && (c-1) >= 0) {
                neighbours++;
            }
            if (world[r + 1][c + 1].current == ALIVE) {
                if ((r + 1 <= 19) && (c + 1 <= 19)) {
                    neighbours++;
                }
            }
            if (world[r + 1][c - 1].current == ALIVE) {
                if ((r + 1 <= 19) && (c - 1 >= 0)) {
                    neighbours++;
                }
            }
            if (world[r - 1][c + 1].current == ALIVE) {
                if ((r + 1 >= 0) && (c - 1 <= 19)) {
                    neighbours++;
                }
            }
            if (world[r - 1][c - 1].current == ALIVE) {
                if ((r + 1 >= 0) && (c - 1 >= 0)) {
                    neighbours++;
                }
            }
            if (world[rows][cols].current == ALIVE && (neighbours == 2 || neighbours == 3)) {
                world[rows][cols].next = ALIVE;
            } else if (world[rows][cols].current == ALIVE && (neighbours < 2 || neighbours > 3)) {
                world[rows][cols].next = DEAD;
            } else if (world[rows][cols].current == DEAD && neighbours == 3) {
                world[rows][cols].next = ALIVE;
            } else if (world[rows][cols].current == DEAD && neighbours != 3) {
                world[rows][cols].next = DEAD;
            }
        }
    }
    for (int r = 0; r < 0; r++) {
        for (int c = 0; c < 0; c++) {
            world[rows][cols].current = world[rows][cols].next;
        }
    }
}

/* Function:    main
 * Description: Start and run simulations, interact with the user.
 *              Lets the user choose initial structure and whether to step
 *              or exit. Writes information to the user, and the game world
 *              in each step.
 * Input:       None
 * Output:      Zero for normal exit, non-zero for error.
 */
int main(void)
{
	const int rows = 20;
    const int cols = 20;
    cell world[rows][cols];

    init_world(rows, cols, world);
    print_world(rows, cols, world);
    update_state(rows, cols, world);

    return 0;
}
haraldfreij 1315
Postad: 18 okt 2022 15:42 Redigerad: 18 okt 2022 15:42

Du anropar update_state utanför huvudloopen, dvs while-loopen i print_world. Den while-loopen borde ligga i main, och inte inne i print-funktionen.

anders_k Online 234
Postad: 20 okt 2022 18:29 Redigerad: 20 okt 2022 18:30

Kolla igenom koden igen, t.ex. jag ser jag saker som

for (int r = 0; r < 0; r++) {
  for (int c = 0; c < 0; c++) {
    world[rows][cols].current = world[rows][cols].next;
  }
}

det ser väl inte rätt ut?

Svara Avbryt
Close