Advertisement
Artem_Chepurov

life

Dec 10th, 2022 (edited)
567
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.41 KB | None | 0 0
  1. #include <iostream>
  2. #include <fstream>
  3. #include <thread>
  4. #include <ctime>
  5.  
  6. using namespace std;
  7.  
  8. #define FILL_CHAR 219
  9. #define EMPTY_CHAR 255
  10.  
  11. void print(unsigned int generation, char* print_arr) {
  12.     printf("Generation:%i\n%s\n", generation, print_arr);
  13. }
  14.  
  15. bool equals(bool* array1, bool* array2, unsigned int size) {
  16.     for (unsigned int x = 0; x < size; x++) //
  17.         for (unsigned int y = 0; y < size; y++)
  18.             if (array1[x * size + y] != array2[x * size + y])
  19.                 return false;
  20.     return true;
  21. }
  22. unsigned short inline get(bool* array, unsigned int size, unsigned int x, unsigned int y) {
  23.     // - высота
  24.     if (x < 1) x = size;
  25.     if (y < 1) y = size;
  26.     if (x > size) x = 1;
  27.     if (y > size) y = 1;
  28.     //if (x < 1 || y < 1 || x > size || y > size) return 0;
  29.     return array[(y - 1) * size + (x - 1)];
  30. }
  31.  
  32. __int64 process(bool* array1, bool* array2, char* print_arr, unsigned int size) {
  33.     __int64 i, j;
  34.     __int64 count_alive = 0;
  35.     #pragma omp parallel for private(i,j) reduction (+:count_alive) num_threads(8) schedule(static)
  36.     for (i = 0; i < (__int64)size; i++)
  37.     {
  38.         for (j = 0; j < size; j++) {
  39.             unsigned short alive_near = get(array1, size, j, i) +
  40.                 get(array1, size, j, i + 1) +
  41.                 get(array1, size, j, i + 2) +
  42.                 get(array1, size, j + 1, i) +
  43.                 get(array1, size, j + 1, i + 2) +
  44.                 get(array1, size, j + 2, i) +
  45.                 get(array1, size, j + 2, i + 1) +
  46.                 get(array1, size, j + 2, i + 2);
  47.  
  48.             if (alive_near > 3)
  49.             {
  50.                 array2[i * size + j] = false;
  51.                 print_arr[i * (size + 1) + j] = EMPTY_CHAR;
  52.             }
  53.             else if (alive_near > 2)
  54.             {
  55.                 array2[i * size + j] = true;
  56.                 print_arr[i * (size + 1) + j] = FILL_CHAR;
  57.                 count_alive++;
  58.             }
  59.             else if (alive_near > 1)
  60.             {
  61.                 array2[i * size + j] = array1[i * size + j];
  62.                 count_alive += array1[i * size + j] ? 1 : 0;
  63.                 print_arr[i * (size + 1) + j] = array1[i * size + j] ? FILL_CHAR : EMPTY_CHAR;
  64.             }
  65.             else {
  66.                 array2[i * size + j] = false;
  67.                 print_arr[i * (size + 1) + j] = EMPTY_CHAR;
  68.             }
  69.         }
  70.         print_arr[size + i * (size + 1)] = '\n';
  71.     }
  72.     print_arr[size * (size + 1) - 1] = '\0';
  73.     return count_alive;
  74. }
  75.  
  76. /**
  77.  * Путь запуска PV_Life\x64\Debug\
  78.  * Команда запуска: ./PV_Life.exe 10 5 0
  79.  * Первый аргумент - размер поля
  80.  * Второй аргумент - количество поколений.
  81.  * Третий аргумент - 1 для вывода каждого поколения, 0 для вывода только первого и последнего поколения
  82.  */
  83. #pragma comment(linker, "/STACK:1024000000")
  84. int main(int argc, char* argv[]) {
  85.     unsigned int size = 900;
  86.     unsigned int max_iterations = 1000;
  87.     bool output = false;
  88.     int count_alive = 0;
  89.     ofstream out("out.txt");
  90.  
  91.     bool* array1 = new bool[size * size];
  92.     bool* array2 = new bool[size * size];
  93.  
  94.     if (argc > 3)// если передаем аргументы, то argc будет больше 1(в зависимости от кол-ва аргументов)
  95.     {
  96.         size = atoi(argv[1]);
  97.         max_iterations = atoi(argv[2]);
  98.         output = atoi(argv[3]);
  99.     }
  100.     cout << "Size = " << size << "*" << size << ", Number of iterations = " << max_iterations << " Output = " << output << endl;
  101.     srand(0);
  102.  
  103.     char* print_arr = new char[size * (size + 1)];
  104.     for (unsigned int x = 0; x < size; x++)
  105.     {
  106.         for (unsigned int y = 0; y < size; y++)
  107.         {
  108.             int r = rand() % 4 + 1;
  109.             array1[x * size + y] = r == 1 ? true : false;
  110.             count_alive += r == 1 ? 1 : 0;
  111.             print_arr[x * (size + 1) + y] = array1[x * size + y] ? FILL_CHAR : EMPTY_CHAR;
  112.         }
  113.         print_arr[size + x * (size + 1)] = '\n';
  114.     }
  115.     print_arr[size * (size + 1) - 1] = '\0';
  116.     unsigned int generation = 0;
  117.     out << generation << " " << count_alive << endl;
  118.     print(generation, print_arr);
  119.  
  120.     //Таймер стартует после генерации нулевого поколения и вывода массива
  121.     chrono::steady_clock::time_point start, end;
  122.     start = chrono::steady_clock::now();
  123.  
  124.     while (true) {
  125.         count_alive = process(array1, array2, print_arr, size);
  126.         generation++;
  127.         out << generation << " " << count_alive << endl;
  128.         if (output)
  129.             print(generation, print_arr);
  130.  
  131.         if (equals(array1, array2, size) || max_iterations != 0 && generation >= max_iterations)
  132.         {
  133.             break;
  134.         }
  135.        
  136.         bool* temp = array1;
  137.         array1 = array2;
  138.         array2 = temp;
  139.     }
  140.     end = chrono::steady_clock::now();
  141.     __int64 time = chrono::duration_cast<chrono::milliseconds>(end - start).count();
  142.     //последнее поколение выводится после отметки времени в таймере.
  143.     print(generation, print_arr);
  144.     cout << "Time, milliseconds: " << time << endl << "seconds: " << time/1000 << endl << "Number of iterations: " << generation << ", Size: " << size;
  145.    
  146.     return 0;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement