es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Problema del Juego de la Vida con la función de actualización del tablero en C

Necesito ayuda con mi implementación de Game of Life en C. Otros posts en Stackoverflow me llevan a creer que mi problema tiene que ver con punteros colgantes, pero después de modificar mi programa para usar una matriz 2D global en lugar de pasarla a funciones que devuelven matrices 2D nuevas, me di cuenta de que era un problema con mi función “actualizar”.

He intentado codificar varios patrones simples, incluyendo deslizadores y osciladores, y la cuadrícula no se actualiza correctamente. Los patrones se actualizan de la misma manera cada vez que se ejecuta el programa, así que no creo que sea un problema de memoria no inicializada que cause problemas. También sé que no hay celdas que contengan valores mayores a “1”. Por lo tanto, el problema debe estar en mis mecanismos para actualizar la cuadrícula.

¿Alguien puede ayudarme a encontrar el problema? No puedo encontrar nada mal en mi código y creo que he programado las reglas correctamente.

Aquí están mis funciones “vecinos” y “actualizar”, junto con las declaraciones relevantes de variables y constantes.


#define MAX_Y 10 /* altura */ #define MAX_X 30 /* ancho */ int grid[MAX_Y][MAX_X]; int vecinos(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]; /* usar !! para que los valores diferentes a cero se evalúen como 1 */ } } /* (n > 0) ? printf("¡El punto (%d,%d) tiene %d vecinos!\n", x, y, n) : 0; */ return n; } void actualizar(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 = vecinos(i, j); /* vivo, 2 o 3 vecinos -> ¡vivo! * muerto, 3 vecinos -> ¡vivo! * cualquier otra cosa -> muerto :( */ 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); }
Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema con tu implementación se encuentra dentro de la función update. Específicamente, tu implementación de la función update crea un nuevo array de tipo int llamado new cada vez que se llama. Esto significa que cualquier cambio realizado en el array new no se conserva en llamadas posteriores a la función update.

    Para solucionar este problema, debes cambiar el array new a un array global, similar a cómo cambias el array grid a un array global. Esto permitirá que los cambios realizados en el array new persistan entre llamadas a la función update.

    Aquí tienes un ejemplo de cómo podrías modificar tu código para reflejar este cambio:

    #define MAX_Y 10 /* altura */
    #define MAX_X 30 /* anchura */
    
    int grid[MAX_Y][MAX_X];
    int new[MAX_Y][MAX_X]; /* array global para el nuevo grid */
    
    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]; /* usa !! para que los valores distintos de cero evalúen a 1 */
            }
        }
        /* (n > 0) ? printf("¡El punto (%d,%d) tiene %d vecinos!\n", x, y, n) : 0; */
        return n;
    }
    
    void update(void) {
        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);
    
                /* vive, 2 o 3 vecinos    -> vive
                 * muere, 3 vecinos       -> vive
                 * cualquier otro caso    -> muere :(
                 */
    
                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);
    }
    

    Con estos cambios, el array new ahora será persistente entre llamadas a la función update y tu Juego de la Vida debería actualizarse correctamente.

Comments are closed.