Munashedov

Langton's Ant

Nov 26th, 2021 (edited)
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.68 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <sys/time.h>
  6. #include <conio.h>
  7.  
  8. #define NOMINMAX
  9. #define WIN32_LEAN_AND_MEAN
  10. #include <Windows.h>
  11.  
  12. #define COLS 60
  13. #define ROWS COLS
  14. #define START_X COLS/2
  15. #define START_Y ROWS/2
  16.  
  17. #define STEPS_MAX 20000
  18.  
  19. #define ANIMATE 1
  20. #define WRAP 0
  21.  
  22. #define FRAMERATE 600
  23.  
  24. int ToIndex(int x, int y){ return y * COLS + x; }
  25.  
  26. char buffer[(COLS+1)*ROWS] = {0};
  27. void PrintASCII(uint8_t *w);
  28.  
  29. void setCursorPosition(int x, int y);
  30. void setCursorVisibility(int isShown);
  31.  
  32. uint16_t antPath[20000] = {0};
  33.  
  34. uint8_t world[COLS*ROWS] = {0};
  35.  
  36. //up, right, down, left
  37. int dirs[] = {-COLS,+1,+COLS,-1};
  38. int heading = 0;
  39. int stepCounter = 0;
  40.  
  41. int main(void){
  42.     system("cls");
  43.     setCursorVisibility(FALSE);
  44.     for(int i = 0; i < COLS*ROWS; ++i){
  45.         fprintf(stdout, ".");
  46.         if(i % COLS == COLS-1){
  47.             fprintf(stdout, "\n");
  48.         }
  49.     }
  50.     //Place the ant
  51.     uint8_t *ant = &world[ToIndex(START_X, START_Y)];
  52.     *ant = 1;
  53.    
  54.     while(stepCounter < STEPS_MAX){
  55.         //Ant walks forward
  56.         ant += dirs[heading];
  57.         #if WRAP
  58.             //Wrap around to avoid crash from out of bounds
  59.             if(ant - world < 0){ ant = &world[COLS*ROWS]; }
  60.             if(ant - world > COLS*ROWS){ ant = &world[0]; }
  61.         #else
  62.             //Quit when the ant reaches the edge of the board
  63.             if(ant - world < 0 || ant - world > COLS*ROWS){ break; }
  64.         #endif
  65.         //Update the ant
  66.         if(*ant == 0) {
  67.             heading = (heading + 1) % 4;
  68.             *ant = 1;
  69.         } else {
  70.             heading = (heading == 0) ? 3 : heading - 1;
  71.             *ant = 0;
  72.         }
  73.         antPath[stepCounter] = (ant - world);
  74.         #if ANIMATE
  75.             Sleep(1000 / FRAMERATE);
  76.             PrintASCII(world);
  77.         #endif
  78.         stepCounter++;
  79.     }
  80.     PrintASCII(world);
  81.     printf("\nSteps: %i\n", stepCounter);
  82.    
  83.     FILE *fp = fopen("data.txt", "w+");
  84.     if (fp == NULL)
  85.     {
  86.         printf("Error opening file!\n");
  87.         exit(1);
  88.     }
  89.    
  90.     for(int i = 0; i < stepCounter; ++i){
  91.         fprintf(fp, "%i\n", antPath[i]);
  92.     }
  93.     fclose(fp);
  94.    
  95.     return 0;
  96. }
  97.  
  98. void PrintASCII(uint8_t *w){
  99.     setCursorPosition(0,0);
  100.     for(int i = 0; i < (COLS+1)*ROWS; ++i){
  101.         if(w[i]){
  102.             buffer[i] = '#';
  103.         } else {
  104.             buffer[i] = '.';
  105.         }
  106.         if(i % (COLS) == (COLS-1)){
  107.             buffer[i] = '\n';
  108.         }
  109.     }
  110.     buffer[COLS*ROWS] = '\0';
  111.     fprintf(stdout, "%s", buffer);
  112. }
  113.  
  114. void setCursorPosition(int x, int y){
  115.     const HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  116.     fflush(stdout);
  117.     COORD coord = { (SHORT)x, (SHORT)y };
  118.     SetConsoleCursorPosition(hOut, coord);
  119. }
  120.  
  121. void setCursorVisibility(int isShown){
  122.    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  123.    CONSOLE_CURSOR_INFO info;
  124.    info.dwSize = 100;
  125.    info.bVisible = isShown;
  126.    SetConsoleCursorInfo(consoleHandle, &info);
  127. }
Add Comment
Please, Sign In to add comment