#include #include #include #include #include #include #include #define SHARK 1 #define FISH 2 struct animal { int kind; /* SHARK oder FISH */ int age; /* Das Alter des Tiers seit der letzten Geburt. */ int hunger; /* Nur falls kind == SHARK: Zahl der Zuege in denen * nicht gefressen wuerde */ int todo; /* Diese Runde noch zu ziehen? */ }; int MAXI; int MAXJ; int HBRUT, FBRUT, FASTEN; struct animal *** wator; /* struct animal * wator[MAXI][MAXJ]; */ #define REST -1 #define NORTH 0 #define SOUTH 1 #define EAST 2 #define WEST 3 int ni (int i, int dir) { switch (dir) { case NORTH: return (i+MAXI-1) % MAXI; case SOUTH: return (i+1) % MAXI; case EAST: case WEST: return i; default: assert (0); } return -1; } int nj (int j, int dir) { switch (dir) { case NORTH: case SOUTH: return j; case EAST: return (j+MAXJ-1) % MAXJ; case WEST: return (j+1) % MAXJ; default: assert (0); } return -1; } int newcount = 0; void new_animal (int i, int j, int kind) { struct animal * t; assert (wator[i][j] == NULL); assert ((kind == FISH) || (kind == SHARK)); t = malloc (sizeof (struct animal)); assert (t); t->kind = kind; t->age = 0; t->hunger = 0; t->todo = 0; wator[i][j] = t; newcount++; } int myrand (int max) { return rand () % max; } int choose_fish (int i, int j) { int k = 0; int dir; int dirs[4]; for (dir=0; dir < 4; dir++) { int npi = ni (i, dir); int npj = nj (j, dir); struct animal * t = wator[npi][npj]; if (t && (t->kind == FISH)) { dirs[k] = dir; k++; } } if (k == 0) return REST; return dirs[myrand (k)]; } int choose_empty (int i, int j) { int k = 0; int dir; int dirs[4]; for (dir=0; dir < 4; dir++) { int npi = ni (i, dir); int npj = nj (j, dir); struct animal * t = wator[npi][npj]; if (t == NULL) { dirs[k] = dir; k++; } } if (k == 0) return REST; return dirs[myrand (k)]; } int freecount = 0; int move_to_fish (int i, int j) { int npi, npj; int dir; struct animal * t; t = wator[i][j]; assert ((t != NULL) && (t->kind == SHARK)); dir = choose_fish (i, j); if (dir == REST) return 0; npi = ni (i, dir); npj = nj (j, dir); assert (wator[npi][npj]->kind == FISH); free (wator[npi][npj]); freecount++; wator[npi][npj] = t; wator[i][j] = NULL; t->hunger = 0; if (t->age >= HBRUT) { t->age = 0; new_animal (i, j, SHARK); } return 1; } int move_to_empty (int i, int j) { int npi, npj; int dir; struct animal * t; t = wator[i][j]; assert (t && ((t->kind == SHARK) || (t->kind == FISH))); dir = choose_empty (i, j); if (dir == REST) return 0; npi = ni (i, dir); npj = nj (j, dir); assert (wator[npi][npj] == NULL); wator[npi][npj] = t; wator[i][j] = NULL; if ((t->kind == FISH) && (t->age >= FBRUT)) { t->age = 0; new_animal (i, j, FISH); } if ((t->kind == SHARK) && (t->age >= HBRUT)) { t->age = 0; new_animal (i, j, SHARK); } return 1; } void move (int i, int j) { struct animal * t; t = wator[i][j]; assert (t && ((t->kind == SHARK) || (t->kind == FISH))); t->age++; if (t->kind == SHARK) { t->hunger++; if (t->hunger >= FASTEN) { wator[i][j] = NULL; free (t); freecount++; return; } if (move_to_fish (i, j)) return; } move_to_empty (i, j); } int fd = -1; void show_wator () { int i, j; int shark = 0, fish = 0; for (i=0; ikind == SHARK) { printf ("X"); shark++; } else { printf ("*"); fish++; } } else { printf ("."); } } printf ("\n"); } printf ("SHARKS: %d, FISH: %d NEW: %d, FREE: %d\n\n", shark, fish, newcount, freecount); if (fd >= 0) { char buf[100]; int ret; static int tick = 0; sprintf (buf, "%d %d %d\n", tick, shark, fish); tick++; ret = write (fd, buf, strlen (buf)); if (ret != strlen (buf)) { fprintf (stderr, "Write to output file failed\n"); exit (2); } } newcount = freecount = 0; } void init_wator (int maxi, int maxj, int hbrut, int fbrut, int fasten) { int i, j; MAXI = maxi; MAXJ = maxj; HBRUT = hbrut; FBRUT = fbrut; FASTEN = fasten; assert (hbrut > FASTEN); wator = malloc (MAXI * sizeof (struct animal **)); assert (wator); for (i=0; itodo = 1; } } } for (i=0; itodo) { wator[i][j]->todo = 0; move (i, j); } } } } int main (int argc, char * argv[]) { char ch; srand (time (NULL)); fd = -1; if (argc > 2) { fprintf (stderr, "usage: wator [ file ]\n"); exit (1); } if (argc == 2) { fd = open (argv[1], O_WRONLY|O_TRUNC|O_CREAT, 0600); if (fd < 0) { perror ("open"); exit (1); } } init_wator (14, 34, 10, 3, 3); show_wator (); while (1) { moveall (); show_wator (); ch = getchar (); if (ch < 0) break; } return 0; }