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

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; j++) {
        printf("* ");
    }
    printf("\n");

    // Print the map contents
    for (int i = 1; i < rows - 1; i++) {
        printf("* ");
        for (int j = 1; j < cols - 1; j++) {
            if (i == langton_ant.row && j == langton_ant.col) {
                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 ");
                }
            } else if (i == random_ant.row && j == random_ant.col) {
                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 ");
                }
            } else {
                printf("%c ", map[i][j]);
            }
        }
        printf("*\n");
    }

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

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

    int waiting_time = atoi(argv[1]); // get waiting time from command line argument
    FILE *input_file = fopen("input.txt", "r");
    if (input_file == NULL) {
        printf("Error: Unable to open input file\n");
        return 1;
    }

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

    if (fscanf(input_file, "%d %d %d %d %d %d %d", &rows, &cols, &num_steps, &ant1_row, &ant1_col, &ant2_row, &ant2_col) != 7) {
        printf("Error: Invalid input format\n");
        return 1;
    }

    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

    int wait_time = 1; //default wait time between each step is 1 second
    if (argc > 1) {
        wait_time = atof(argv[1]);
    }

    // Run the simulation
    for (int step = 0; step < num_steps; step++) {
        // Update the direction of the Langton ant based on the color of the cell
    	int langton_ant_row = langton_ant.row;
    	int langton_ant_col = langton_ant.col;

   	 if (map[langton_ant_row][langton_ant_col] == '*') {
        	langton_ant.dir = (langton_ant.dir + 1) % 4;
    	} else {
        	langton_ant.dir = (langton_ant.dir - 1 + 4) % 4;
    	}

   	 // Update the color of the cell and move the Langton ant
   	 if (map[langton_ant_row][langton_ant_col] == '*') {
   	     map[langton_ant_row][langton_ant_col] = ' ';
   	 } else {
  	      map[langton_ant_row][langton_ant_col] = '*';
  	  }
    	if (langton_ant.dir == UP) {
        	langton_ant.row--;
    	} else if (langton_ant.dir == RIGHT) {
    	    langton_ant.col++;
    	} else if (langton_ant.dir == LEFT) {
        	langton_ant.col--;
    	} else if (langton_ant.dir == DOWN) {
        	langton_ant.row++;
    	}

    	// Update the direction of the random ant based on a random number
    	int random_number = rand() % 4;
    	if (random_number == 0) {
     	   random_ant.dir = UP;
    	} else if (random_number == 1) {
        	random_ant.dir = RIGHT;
    	} else if (random_number == 2) {
        	random_ant.dir = LEFT;
    	} else if (random_number == 3) {
    	    random_ant.dir = DOWN;
    	}

    	// Move the random ant
    	if (random_ant.dir == UP) {
        	random_ant.row--;
    	} else if (random_ant.dir == RIGHT) {
       	 	random_ant.col++;
   	} else if (random_ant.dir == LEFT) {
        	random_ant.col--;
    	} else if (random_ant.dir == DOWN) {
        	random_ant.row++;
    	}

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

    	// Wait for some time
	sleep(wait_time);
	}

	// 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:

Right now when I run the code, I run it along with the wait time as a command line argument. The dimensions of the map, position of the ants and the number of steps the ants take are all in the file input. I want to make the number of steps - num_steps - work as a command line argument. When I tried to change the code to have the 'num_steps' work as a command line argument the terminal kept displaying 'invalid number of arguments' even though I gave it enough arguments to take in.

Also, how would I modify the code to have it read a file in the following format:

rows cols
ant1_row ant1_col "v"
ant2_row ant2_col ">"

Each description should be a new line in the txt file. The current file has everything in a single line. Also the "v" and ">" are the direction the ants start in, it can any of; "<" ">" "^" "v"
Posted
Updated 15-Apr-23 21:16pm

Start by using the debugger to find out exactly what values you are getting: argc and argv - when you know the number of arguments and what they are, it should be obvious what the problem is.

We can't do that for you: we have no idea what you are providing as input!
 
Share this answer
 
As OriginalGriff said, a debugger should find the problem. However, except for the problem that the file might not be found, I have not found any problem reading in when there are actually exactly 7 positive numbers in the input.txt file.

If input .txt contains the following
5 5 20 1 1 4 4

all parameters seem to be read in correctly. However, the program crashes because, for example, variable langton_ant.row can obviously become negative.

To read a row like this
2 4 v

letters and numbers must be read.

This would be done as before with
C
if (fscanf(input_file, "%d %d %c", &lrow, &lcol, &dir) != 3) {

would work.
 
Share this answer
 
This is the same issue as How to implement a sleep wait time function and take it in as a command line argument?[^], where I gave you a suggestion as to capturing the command line parameters. And I notice that you have still got the erroneous code in the above.
 
Share this answer
 
v2

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