Click here to Skip to main content
15,885,998 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
C
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h> // for sleep() function
#include <errno.h>

enum direction { UP, DOWN, LEFT, RIGHT };

struct ant {
    int row;
    int col;
    enum direction dir;
};

void print_map(char **map, int rows, int cols, struct ant langton_ant, struct ant random_ant) {
    system("clear"); // Clear the console

    // Print the borders of the map
    for (int j = 0; j < cols+2; j++) {
        printf("* ");
    }
    printf("\n");

    // Print the map contents
    for (int i = 0; i < rows; i++) {
        printf("* ");
        for (int j = 0; j < cols; j++) {
            if (i == langton_ant.row && j == langton_ant.col) {
                printf("\x1b[41m"); // Red background color for Langton's ant
                if (langton_ant.dir == UP) {
                    printf("^ ");
                } else if (langton_ant.dir == RIGHT) {
                    printf("> ");
                } else if (langton_ant.dir == LEFT) {
                    printf("< ");
                } else if (langton_ant.dir == DOWN) {
                    printf("v ");
                }
                printf("\x1b[0m"); // Reset color to default
            } else if (i == random_ant.row && j == random_ant.col) {
                printf("\x1b[44m"); // Blue background color for random ant
                if (random_ant.dir == UP) {
                    printf("^ ");
                } else if (random_ant.dir == RIGHT) {
                    printf("> ");
                } else if (random_ant.dir == LEFT) {
                    printf("< ");
                } else if (random_ant.dir == DOWN) {
                    printf("v ");
                }
                printf("\x1b[0m"); // Reset color to default
            } else if (i == rows/2 && j == cols/2) {
                printf("\x1b[42m"); // Green background color for center of the map
                printf("  ");
                printf("\x1b[0m"); // Reset color to default
            } else {
                printf("%c ", map[i][j]);
            }
        }
        printf("*\n");
    }

    // Print the borders of the map
    for (int j = 0; j < cols+2; j++) {
        printf("* ");
    }
    printf("\n");
}

void update_langton_ant(char **map, struct ant *ant) {
	// Check the color of the cell the ant is on
	char cell_color = map[ant->row][ant->col];
	if (cell_color == ' ') { // Neutral cell
	// Turn clockwise
	ant->dir = (ant->dir + 1) % 4;
	// Turn the previous cell to red
	map[ant->row][ant->col] = 'R';
	} else if (cell_color == 'R') { // Red cell
	// Turn counter-clockwise
	ant->dir = (ant->dir + 3) % 4;
	// Turn the previous cell back to default color
	map[ant->row][ant->col] = ' ';
	} else if (cell_color == 'B') { // Blue cell
	// Turn clockwise
	ant->dir = (ant->dir + 1) % 4;
	// Turn the previous cell back to default color
	map[ant->row][ant->col] = ' ';
	}
	// Move the ant one step in the current direction
	if (ant->dir == UP) {
	    ant->row--;
	} else if (ant->dir == RIGHT) {
	    ant->col++;
	} else if (ant->dir == LEFT) {
	    ant->col--;
	} else if (ant->dir == DOWN) {
	    ant->row++;
	}
	
	if (langton_ant.row < 0 || langton_ant_row >= rows || langton_ant_col < 0 || langton_ant_col >= cols) {
	    // handle out-of-bounds access
	    // For example, you can wrap around the grid
	    langton_ant.row = (langton_ant.row + rows) % rows;
	    langton_ant_col = (langton_ant_col + cols) % cols;
	}
}

void update_random_ant(char **map, struct ant *ant) {
	// Check the color of the cell the ant is on
	char cell_color = map[ant->row][ant->col];
	if (cell_color == ' ') { // Neutral cell
	// Turn the cell to blue
	map[ant->row][ant->col] = 'B';
	} else if (cell_color == 'R' || cell_color == 'B') { // Red or blue cell
	// Turn the cell back to default color
	map[ant->row][ant->col] = ' ';
	}
	// Move the ant randomly in one of the four directions
	int rand_dir = rand() % 4;
	if (rand_dir == UP) {
	    ant->row--;
	} else if (rand_dir == RIGHT) {
	    ant->col++;
	} else if (rand_dir == LEFT) {
	    ant->col--;
	} else if (rand_dir == DOWN) {
	    ant->row++;
	}
	if (random_ant.row < 0 || random_ant.row >= rows || random_ant.col < 0 || random_ant.col >= cols) {
	    // handle out-of-bounds access
	    // For example, you can wrap around the grid
	    random_ant.row = (random_ant.row + rows) % rows;
	    random_ant.col = (random_ant.col + cols) % cols;
	}

}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Error: Invalid number of arguments\n");
        return 1;
    }

    errno = 0;
    char *endptr;
    long waiting_time = strtol(argv[1], &endptr, 10);
    if (errno != 0 || *endptr != '\0') {
    	printf("Error: Invalid waiting time\n");
    	return 1;
    }

    errno = 0;
    long num_steps = strtol(argv[2], &endptr, 10);
    if (errno != 0 || *endptr != '\0') {
    	printf("Error: Invalid number of steps\n");
    	return 1;
    }

    FILE *input_file = fopen("input.txt", "r");
    if (input_file == NULL) {
        printf("Error: Unable to open input file\n");
        return 1;
    }

    int rows, cols, ant1_row, ant1_col, ant2_row, ant2_col;

    if (fscanf(input_file, "%d %d %d %d %d %d", &rows, &cols, &ant1_row, &ant1_col, &ant2_row, &ant2_col) != 6) {
    	printf("Error: Invalid input format\n");
    	fclose(input_file); // close the input file
    	return 1;
    }

    fclose(input_file); // close the input file


    char **map = (char**)malloc(rows * sizeof(char*));

    for (int i = 0; i < rows; i++) {
        map[i] = (char*)malloc(cols * sizeof(char));
        for (int j = 0; j < cols; j++) {
            if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1) {
                map[i][j] = ' ';
            } else {
                map[i][j] = ' ';
            }
        }
    }

    // Initialize the first ant
    struct ant langton_ant = { ant1_row, ant1_col, UP };

	// Initialize the second ant
    struct ant random_ant = { ant2_row, ant2_col, DOWN };

    srand(time(NULL)); // Seed the random number generator with the current time

    // Run the simulation
    for (int step = 0; step < num_steps; step++) {
    
        update_langton_ant(map, &langton_ant)

	update_random_ant(map, &random_ant)

    	// Print the current state of the map
    	print_map(map, rows, cols, langton_ant, random_ant);

    	// Wait for some time
	usleep(waiting_time * 1000); // convert milliseconds to microseconds
	}

	// Free the memory used by the map
	for (int i = 0; i < rows; i++) {
    		free(map[i]);
	}
	free(map);

	return 0;
}


What I have tried:

issue with this code is that the variables langton_ant and random_ant are not declared anywhere in the code, but are used in both update_langton_ant and update_random_ant. This will cause compilation errors.

Another issue is that the if statement in update_langton_ant that checks for out-of-bounds access refers to variables that are not defined in that function (rows and cols). These variables should be passed as arguments to the function or declared as global variables.

Finally, the code does not use any sort of synchronization mechanism to ensure that the two ants do not occupy the same cell at the same time, which could lead to unpredictable behavior.
Posted
Updated 17-Apr-23 11:02am
v2
Comments
CPallini 17-Apr-23 16:03pm    
All those questions are just a testing plan for our patience?

1 solution

Those variables ARE declared in your code. The problem is you are not passing them to the functions that need them. They do not need to be global.

Your program does not appear to be multi-threaded so no synchronization is needed. You just need to write your logic so it pays attention to things like that.
 
Share this answer
 
Comments
merano99 17-Apr-23 19:49pm    
5+ Thus, everything is actually said.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900