Опыт работы с нейронными сетями и простой код на Ассемблере.

Тема в разделе "WASM.BEGINNERS", создана пользователем dcc0, 17 май 2026.

Метки:
  1. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    525
    Ahimov, а какая у вас конфигурация компьютера ? Сколько обычной памяти в компьютере ( 128 GB или сколько?) и сколько видеопамяти содержит видеокарта (24 GB или сколько?) ? И какой у вас тариф ? Платный или бесплатный ?
     
  2. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Так, я все время ругал нейронные сети, но надо и похвалить.
    Вот этот мой код нейронная сеть (alice.yandex) удачно конвертировала из PHP в C89.
    Поиск всех путей на однонаправленном графе.
    Исходник:
    Код (Text):
    1. <?php
    2. /*Поиск всех путей на ориентированном графе из точки а в точку f
    3. на основе упорядочивания массивов и элементов массива по возрастанию
    4. Легко доработать до поиска кратчайшего пути.*/
    5.  
    6. function search_new_val_for_push_int_x($x, $j, $arr) {
    7.     foreach($arr as $key => $val) {
    8.         if($x[count($x) - 1] == $key)
    9.             return $arr[$key];
    10.     }
    11. }
    12.  
    13. function search_val($x, $j, $arr) {
    14.     foreach($arr as $key => $val) {
    15.         if($x[$j - 1] == $key)
    16.             return $arr[$key];
    17.     }
    18. }
    19.  
    20. // Упорядоченный граф
    21. $a = array('b', 'c', 'd');
    22. $b = array('d', 'e', 'f');
    23. $c = array('d', 'e', 'f');
    24. $d = array('e', 'f');
    25. $e = array('f');
    26. $f = array();
    27.  
    28. // Первый путь
    29. $x = array('a', 'b', 'd', 'e', 'f');
    30.  
    31. // Массив соответствий
    32. $arr = array('a' => $a, 'b' => $b, 'c' => $c, 'd' => $d, 'e' => $e, 'f' => $f);
    33.  
    34. // Печатаем первый маршрут
    35. print_r($x);
    36. print "\n";
    37.  
    38. $j = count($x) - 1;
    39.  
    40. while($j != 0) {
    41.     // Ищем новое значение. Значение будет использовано в качестве имени массива.
    42.     $ar = search_val($x, $j, $arr);
    43.     $key = array_search($x[$j], $ar);
    44.     //if (${$x[$j-1]}[$key+1] != '') {
    45.  
    46.     if (isset($ar[$key + 1])) {
    47.         $x = array_slice($x, 0, $j);
    48.         array_push($x, $ar[$key + 1]);
    49.         //$z=$x[count($x)-1];
    50.         //найдем все 0-ые индексы
    51.         $z = search_new_val_for_push_int_x($x, $j, $arr)[0];
    52.  
    53.         while (1) {
    54.             if ($x[count($x) - 1] == 'f') {
    55.                 array_push($x, $z);
    56.                 break;
    57.             }
    58.             array_push($x, $z);
    59.             $z = search_new_val_for_push_int_x($x, $j, $arr)[0];
    60.         }
    61.         $j = count($x);
    62.         print_r($x);
    63.     }
    64.     $j--;
    65. }
    66. ?>
    67.  
    68.  
    Код конвертированный сетью:

    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. /* Максимальное количество вершин в пути.
    5.    Граф небольшой, 20 достаточно с запасом. */
    6. #define MAX_PATH 26
    7.  
    8. /* Функция возвращает указатель на массив соседей для данной вершины.
    9.    Вершины: 'a'..'f'. Возвращает NULL для неверной вершины. */
    10. static const char *get_neighbors(char v) {
    11.     switch (v) {
    12.    case 'a': return "bcdz";
    13.         case 'b': return "defz";
    14.         case 'c': return "defz";
    15.         case 'd': return "efz";
    16.         case 'e': return "fz";
    17.         case 'f': return "ghjz";
    18.         case 'g': return "hijz";
    19.         case 'h': return "ijkz";
    20.         case 'i': return "jklz";
    21.         case 'j': return "kmz";
    22.         case 'k': return "lnoz";
    23.         case 'l': return "mz";
    24.         case 'm': return "noz";
    25.         case 'n': return "oz";
    26.         case 'o': return "pz";
    27.         case 'p': return "qz";
    28.         case 'q': return "rz";
    29.         case 'r': return "sz";
    30.         case 's': return "tuz";
    31.         case 't': return "uvz";
    32.         case 'u': return "vwz";
    33.         case 'v': return "wz";
    34.         case 'w': return "xyz";
    35.         case 'x': return "yz";
    36.         case 'y': return "z";
    37.         case 'z': return "";
    38.         default:  return NULL;
    39.     }
    40. }
    41.  
    42. /* Вспомогательная функция: найти индекс символа в строке.
    43.    Возвращает -1, если не найден. */
    44. static int str_index_of(const char *s, char c) {
    45.     int i = 0;
    46.     while (s[i] != '\0') {
    47.         if (s[i] == c) return i;
    48.         i++;
    49.     }
    50.     return -1;
    51. }
    52.  
    53. int main(void) {
    54.     int p =0;
    55.     /* Первый путь (из PHP-скрипта) */
    56.     char path[MAX_PATH];
    57.     int path_len = 0;
    58.  
    59.     /* Инициализация первого пути: a -> b -> d -> e -> f */
    60.     path[path_len++] = 'a';
    61.     path[path_len++] = 'b';
    62.     path[path_len++] = 'd';
    63.     path[path_len++] = 'e';
    64.     path[path_len++] = 'f';
    65.     path[path_len++] = 'g';
    66.     path[path_len++] = 'h';
    67.     path[path_len++] = 'i';
    68.     path[path_len++] = 'j';
    69.     path[path_len++] = 'k';
    70.     path[path_len++] = 'l';
    71.     path[path_len++] = 'm';
    72.     path[path_len++] = 'n';
    73.     path[path_len++] = 'o';
    74.     path[path_len++] = 'p';
    75.     path[path_len++] = 'q';
    76.     path[path_len++] = 'r';
    77.     path[path_len++] = 's';
    78.     path[path_len++] = 't';
    79.     path[path_len++] = 'u';
    80.     path[path_len++] = 'v';
    81.     path[path_len++] = 'w';
    82.     path[path_len++] = 'x';
    83.     path[path_len++] = 'y';
    84.     path[path_len++] = 'z';
    85.  
    86.     /* Вывод первого маршрута */
    87.     {
    88.         int i;
    89.         for (i = 0; i < path_len; i++) {
    90.             if (i > 0) printf(", ");
    91.             printf("%c", path[i]);
    92.         }
    93.         printf("\n");
    94.     }
    95. p++;
    96.     int j = path_len - 1;
    97.  
    98.     while (j > 0) {
    99.  
    100.         char current_v = path[j - 1];
    101.         const char *neighbors = get_neighbors(current_v);
    102.  
    103.         /* В PHP: $ar = search_val($x, $j, $arr); */
    104.         /* Здесь neighbors — это аналог $ar */
    105.  
    106.         int key = str_index_of(neighbors, path[j]);
    107.  
    108.         /* if (isset($ar[$key + 1])) */
    109.         if ((key != -1) && (neighbors[key + 1] != '\0')) {
    110.             /* $x = array_slice($x, 0, $j); */
    111.             path_len = j;
    112.  
    113.             /* array_push($x, $ar[$key + 1]); */
    114.             path[path_len++] = neighbors[key + 1];
    115.  
    116.             /* Достраиваем путь до 'f', всегда беря первого (нулевого) соседа */
    117.             while (1) {
    118.  
    119.                 char last_v = path[path_len - 1];
    120.                 if (last_v == 'z') {
    121.                     break;
    122.                 }
    123.                 const char *next_neighbors = get_neighbors(last_v);
    124.                 /* В PHP: search_new_val_for_push_int_x(...)[0] */
    125.                 if (next_neighbors[0] != '\0') {
    126.                     path[path_len++] = next_neighbors[0];
    127.                 } else {
    128.                     /* Если нет соседей, а мы не в 'f', дальше идти некуда.
    129.                        В логике PHP это не обрабатывается явно, но предотвратим зацикливание. */
    130.                     break;
    131.                 }
    132.             }
    133.  
    134.             j = path_len;
    135.  
    136.             /* print_r($x); */
    137.             {
    138.                 int i;
    139.  
    140.                 for (i = 0; i < path_len; i++) {
    141.                     if (i > 0) printf(", ");
    142.                     printf("%c", path[i]);
    143.                 }
    144.  
    145.                 printf("\n");
    146.                 p++;
    147.  
    148.  
    149.             }
    150.         }
    151.  
    152.         j--;
    153.     }
    154. printf("Количество путей: %d",p);
    155.     return 0;
    156. }
    157.  
     
    Application нравится это.
  3. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Подумал, неужели не смогу переписать код php на С89 (лень уже, конечно, было).
    Порылася по справочниками и все-таки переписал руками.
    Нейронная сеть мне будто вызов бросила. Мне кажется, handcraft code все-таки легче:

    Код (C):
    1.  
    2. /*Поиск всех путей на однонаправленном графе. Переписан из кода PHP на язык C стандарта 89*/
    3. #include <stdio.h>
    4. #include <string.h>
    5. /*Объявим граф глобально*/
    6. char a[] = "bcdz";
    7. char b[] = "defz";
    8. char c[] = "defz";
    9. char d[] = "efz";
    10. char e[] = "fz";
    11. char f[] = "ghjz";
    12. char g[] = "hijz";
    13. char h[] = "ijkz";
    14. char i[] = "jklz";
    15. char j[] = "kmz";
    16. char k[] = "lnoz";
    17. char l[] = "mz";
    18. char m[] = "noz";
    19. char n[] = "oz";
    20. char o[] = "pz";
    21. char p[] = "qz";
    22. char q[] = "rz";
    23. char r[] = "sz";
    24. char s[] = "tuz";
    25. char t[] = "uvz";
    26. char u[] = "vwz";
    27. char v[] = "wz";
    28. char w[] = "xyz";
    29. char x[] = "yz";
    30. char y[] = "z";
    31. char z[] = "";
    32. /*Вернёт элемент, который потом допишем в массив x*/
    33. char element_search_to_push ( char *first_way) {
    34.  
    35. char elem_to_push;
    36.   if (first_way[strlen(first_way)-1] =='a')
    37.    elem_to_push = a[0];
    38.      if (first_way[strlen(first_way)-1] =='b')
    39.    elem_to_push = b[0];
    40.      if (first_way[strlen(first_way)-1] =='c')
    41.    elem_to_push = c[0];
    42.     if (first_way[strlen(first_way)-1] =='d')
    43.    elem_to_push = d[0];
    44.      if (first_way[strlen(first_way)-1] =='e')
    45.    elem_to_push = e[0];
    46.      if (first_way[strlen(first_way)-1] =='f')
    47.    elem_to_push = f[0];
    48.    if (first_way[strlen(first_way)-1] =='g')
    49.   elem_to_push = g[0];
    50. if (first_way[strlen(first_way)-1] =='h')
    51.   elem_to_push = h[0];
    52. if (first_way[strlen(first_way)-1] =='i')
    53.   elem_to_push = i[0];
    54. if (first_way[strlen(first_way)-1] =='j')
    55.   elem_to_push = j[0];
    56. if (first_way[strlen(first_way)-1] =='k')
    57.   elem_to_push = k[0];
    58. if (first_way[strlen(first_way)-1] =='l')
    59.   elem_to_push = l[0];
    60. if (first_way[strlen(first_way)-1] =='m')
    61.   elem_to_push = m[0];
    62. if (first_way[strlen(first_way)-1] =='n')
    63.   elem_to_push = n[0];
    64. if (first_way[strlen(first_way)-1] =='o')
    65.   elem_to_push = o[0];
    66. if (first_way[strlen(first_way)-1] =='p')
    67.   elem_to_push = p[0];
    68. if (first_way[strlen(first_way)-1] =='q')
    69.   elem_to_push = q[0];
    70. if (first_way[strlen(first_way)-1] =='r')
    71.   elem_to_push = r[0];
    72. if (first_way[strlen(first_way)-1] =='s')
    73.   elem_to_push = s[0];
    74. if (first_way[strlen(first_way)-1] =='t')
    75.   elem_to_push = t[0];
    76. if (first_way[strlen(first_way)-1] =='u')
    77.   elem_to_push = u[0];
    78. if (first_way[strlen(first_way)-1] =='v')
    79.   elem_to_push = v[0];
    80. if (first_way[strlen(first_way)-1] =='w')
    81.   elem_to_push = w[0];
    82. if (first_way[strlen(first_way)-1] =='x')
    83.   elem_to_push = x[0];
    84. if (first_way[strlen(first_way)-1] =='y')
    85.   elem_to_push = y[0];
    86. if (first_way[strlen(first_way)-1] =='z')
    87.   elem_to_push = z[0];
    88.  
    89.    return elem_to_push;
    90. }
    91. /*Возвращает указатель на первый путь x*/
    92. char *element_search ( char *first_way,  int j2 ) {
    93.  
    94. char *ar;
    95.  if (first_way[j2-1] =='a')
    96.    ar = a;
    97.    if (first_way[j2-1] =='b')
    98.    ar = b;
    99.    if (first_way[j2-1] =='c')
    100.    ar = c;
    101.    if (first_way[j2-1] =='d')
    102.    ar = d;
    103.    if (first_way[j2-1] =='e')
    104.    ar = e;
    105.    if (first_way[j2-1] =='f')
    106.    ar = f;
    107.    if (first_way[j2-1] =='g')
    108.   ar = g;
    109. if (first_way[j2-1] =='h')
    110.   ar = h;
    111. if (first_way[j2-1] =='i')
    112.   ar = i;
    113. if (first_way[j2-1] =='j')
    114.   ar = j;
    115. if (first_way[j2-1] =='k')
    116.   ar = k;
    117. if (first_way[j2-1] =='l')
    118.   ar = l;
    119. if (first_way[j2-1] =='m')
    120.   ar = m;
    121. if (first_way[j2-1] =='n')
    122.   ar = n;
    123. if (first_way[j2-1] =='o')
    124.   ar = o;
    125. if (first_way[j2-1] =='p')
    126.   ar = p;
    127. if (first_way[j2-1] =='q')
    128.   ar = q;
    129. if (first_way[j2-1] =='r')
    130.   ar = r;
    131. if (first_way[j2-1] =='s')
    132.   ar = s;
    133. if (first_way[j2-1] =='t')
    134.   ar = t;
    135. if (first_way[j2-1] =='u')
    136.   ar = u;
    137. if (first_way[j2-1] =='v')
    138.   ar = v;
    139. if (first_way[j2-1] =='w')
    140.   ar = w;
    141. if (first_way[j2-1] =='x')
    142.   ar = x;
    143. if (first_way[j2-1] =='y')
    144.   ar = y;
    145. if (first_way[j2-1] =='z')
    146.   ar = z;
    147.    return ar;
    148. }
    149.  
    150. static int array_search (const char *ar, char el) {
    151.   int i = 0;
    152.   while (ar[i] != '\0') {
    153.   if (ar[i] == el) return i;
    154.   i++;
    155.   }
    156.   return -1;
    157. }
    158.  
    159. int main(void) {
    160. int key;
    161. /*Первый путь*/
    162. char first_way[26] = "abdefghijklmnopqrstuvwxyz";
    163. char elem_to_push;
    164.  
    165. int  j2 = strlen(first_way)-1;
    166. int last_point = 'z';
    167. int i2 = 0;
    168. char *ar;
    169. int first_way_len = 0;
    170.  
    171. /*Печать 1-го*/
    172. for (i2=0; first_way[i2] != '\0'; i2++)
    173. printf("%c", first_way[i2]);
    174. printf("\n\r");
    175. int all_ways_count = 1;
    176.  
    177.  
    178. while ( j2 != 0 )
    179.  {
    180.   /*Поиск элемента*/
    181.    ar=element_search (first_way,  j2 );
    182.    /*Поиск ключа*/
    183.   key =  array_search(ar, first_way[ j2]);
    184.   if ((key != -1) && (ar[key + 1] != '\0')) {
    185.        /*Ставим длину массива равной j2*/
    186.       first_way_len = j2;
    187.       /*Заменим substr*/
    188.       first_way[j2+1]='\0';
    189.       /*Пишем в массив x*/
    190.       first_way[first_way_len++]= ar[key+1];
    191.        elem_to_push=element_search_to_push(first_way);
    192. while(1) {
    193.      /*Если дошли до f выходим*/
    194.      if ((first_way[strlen(first_way)-1] == last_point)) {
    195.        /*Пишем в first_way*/
    196.         first_way[first_way_len++] = elem_to_push;
    197.         break;
    198.       }
    199.        /*Пишем в first_way*/
    200.        first_way[first_way_len++] = elem_to_push;
    201.      elem_to_push=element_search_to_push(first_way);
    202.          }
    203.          /*Переменную ставим равной массиву*/
    204.           j2=strlen(first_way);
    205.          /*Выводим*/
    206.          printf("%s", first_way);
    207.          printf("\n\r");
    208.          all_ways_count++;
    209.        }
    210.  j2--;
    211.      }
    212.      printf("%d", all_ways_count);
    213.  }
    214.  
    215.  
    216.  
    217.  
    218.  
     
  4. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Похвалил ИИ, но придется снова отругать:
    Ни Алиса ни deepai.org не могут посчитать количество элементов правильно.
    Ни с какой попытки:

    Код (Text):
    1. "ab", "ac", "ad", "az",
    2.     "bd", "be", "bf", "bz",
    3.     "cd", "ce", "cf", "cz",
    4.     "de", "df", "dz",
    5.     "ef", "ez",
    6.     "fg", "fh", "fj", "fz",
    7.     "gh", "gi", "gj", "gz",
    8.     "hi", "hj", "hk", "hz",
    9.     "ij", "ik", "il", "iz",
    10.     "jk", "jm", "jz",
    11.     "kl", "kn", "ko", "kz",
    12.     "lm", "lz",
    13.     "mn", "mo", "mz",
    14.     "no", "nz",
    15.     "op", "oz",
    16.     "pq", "pz",
    17.     "qr", "qz",
    18.     "rs", "rz",
    19.     "st", "su", "sz",
    20.     "tu", "tv", "tz",
    21.     "uv", "uw", "uz",
    22.     "vw", "vz",
    23.     "wx", "wy", "wz",
    24.     "xy", "xz",
    25.     "yz"
     
  5. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Ещё подпилил рукотворный код и сам алгоритм. Убрал критические замечания:

    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3. //Количество всех вершин
    4. #define ALL_POINTS 26
    5. // Объявим граф глобально
    6. char a[] = "bcdz";
    7. char b[] = "defz";
    8. char c[] = "defz";
    9. char d[] = "efz";
    10. char e[] = "fz";
    11. char f[] = "ghjz";
    12. char g[] = "hijz";
    13. char h[] = "ijkz";
    14. char i[] = "jklz";
    15. char j[] = "kmz";
    16. char k[] = "lnoz";
    17. char l[] = "mz";
    18. char m[] = "noz";
    19. char n[] = "oz";
    20. char o[] = "pz";
    21. char p[] = "qz";
    22. char q[] = "rz";
    23. char r[] = "sz";
    24. char s[] = "tuz";
    25. char t[] = "uvz";
    26. char u[] = "vwz";
    27. char v[] = "wz";
    28. char w[] = "xyz";
    29. char x[] = "yz";
    30. char y[] = "z";
    31. char z[] = "";
    32. /* Массивы соответствий */
    33. char *array_corresp[] = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x,y,z};
    34. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    35.  
    36. //Рёбра
    37. char *ribs[] = {
    38. "ab", "ac", "ad", "az",
    39.     "bd", "be", "bf", "bz",
    40.     "cd", "ce", "cf", "cz",
    41.     "de", "df", "dz",
    42.     "ef", "ez",
    43.     "fg", "fh", "fj", "fz",
    44.     "gh", "gi", "gj", "gz",
    45.     "hi", "hj", "hk", "hz",
    46.     "ij", "ik", "il", "iz",
    47.     "jk", "jm", "jz",
    48.     "kl", "kn", "ko", "kz",
    49.     "lm", "lz",
    50.     "mn", "mo", "mz",
    51.     "no", "nz",
    52.     "op", "oz",
    53.     "pq", "pz",
    54.     "qr", "qz",
    55.     "rs", "rz",
    56.     "st", "su", "sz",
    57.     "tu", "tv", "tz",
    58.     "uv", "uw", "uz",
    59.     "vw", "vz",
    60.     "wx", "wy", "wz",
    61.     "xy", "xz",
    62.     "yz"
    63. };
    64. //Длины рёбeр
    65. int ribs_count[] = { 12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    66.     7,  8,  9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    67.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    68.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    69.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    70.     71, 72, 73, 74, 75, 17, 99, 67};
    71. //Длина массива с длинами рёбер
    72. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    73.  
    74. /////////////////Функции//////////////////////////////////////////////////////
    75. // Вернёт элемент, который потом допишем в массив x
    76. char element_search_to_push(char *x) {
    77.     char z;
    78.     int i;
    79.     int j = strlen(x) - 1;
    80.     for (i = 0; i <  ALL_POINTS; i++) {
    81.         if (x[j] == array_corresp2[i]) {
    82.             z = array_corresp[i][0];
    83.         }
    84.     }
    85.     return z;
    86. }
    87.  
    88. // Возвращает указатель на первый путь x
    89. char *element_search(char *x, int j) {
    90.     char *arr;
    91.     int i;
    92.     for (i = 0; i <  ALL_POINTS; i++) {
    93.         if (x[j - 1] == array_corresp2[i]) {
    94.             arr = array_corresp[i];
    95.         }
    96.     }
    97.     return arr;
    98. }
    99.  
    100. static int array_search(const char *ar, char el) {
    101.     int i = 0;
    102.     while (ar[i] != '\0') {
    103.         if (ar[i] == el) return i;
    104.         i++;
    105.     }
    106.     return -1;
    107. }
    108.  
    109. //Найдем длину каждого пути
    110. int count_way_lenght(int rib_length , char *x) {
    111.     int j =strlen(x) - 1;
    112. rib_length  = 0;
    113.     int i, y;
    114.           for (y = 0; y < j; y++) {
    115.                 for (i = 0; i < ribs_all_count; i++) {
    116.                     if (x[y] == ribs[i][0] && x[y + 1] == ribs[i][1]) {
    117.                         rib_length += ribs_count[i];
    118.                     }
    119.                 }
    120.             }
    121.     return rib_length;
    122. }
    123.  
    124. /////////////////////////////////////////////////////////////////////////////////////////
    125.  
    126. int main() {
    127.  
    128.     char short_way_point[100];
    129.     int y = 0;
    130.     int rib_length = 0;
    131.     int short_way = 1000;
    132.     int key;
    133.     //Первый путь задан
    134.     char x[100] = "abdefghijklmnopqrstuvwxyz";
    135.     char z;
    136.     // Длина j
    137.     int j = strlen(x) - 1;
    138.     char last_point = 'z';
    139.     int i = 0;
    140.     char *ar;
    141.     int x_len = 0;
    142.     //Все пути. 1 потому что выводим 1-ый вне циклов
    143.     int all = 1;
    144.     // Печать 1-го
    145. //////////////////////////////////////////////////
    146.     for (i = 0; x[i] != '\0'; i++)
    147.         printf("%c", x[i]);
    148.  
    149.     // Найдем длину первого пути
    150.     rib_length = 0;
    151.     for (y = 0; y < j; y++) {
    152.         for (i = 0; i < ribs_all_count; i++) {
    153.             if (x[y] == ribs[i][0] && x[y + 1] == ribs[i][1]) {
    154.                 rib_length += ribs_count[i];
    155.             }
    156.         }
    157.     }
    158.     printf(" %d ", rib_length);
    159.     printf("\n\r");
    160. ///////////////////////////////////////////////////
    161.  
    162.     // Основной цикл поиска путей
    163.     while (j != 0) {
    164.         // Определяем и ищем элемент и его ключ
    165.         ar = element_search(x, j);
    166.         key = array_search(ar, x[j]);
    167.  
    168.         if ((key != -1) && (ar[key + 1] != '\0')) {
    169.             // Задаем длину массива равной j
    170.             x_len = j;
    171.             // Заменяем substr
    172.             x[j + 1] = '\0';
    173.             // Пишем в массив x
    174.             x[x_len++] = ar[key + 1];
    175.  
    176.             // Найдем z для записи
    177.             z = element_search_to_push(x);
    178.             while (1) {
    179.                 // Если дошли до 'f', выходим
    180.                 if (x[strlen(x) - 1] == last_point ) {
    181.                     x[x_len++] = z;
    182.                     break;
    183.                 }
    184.                 // Пишем в x
    185.                 x[x_len++] = z;
    186.                 // Ещё найдем z для записи
    187.                 z = element_search_to_push(x);
    188.             }
    189.             // Обновляем j
    190.             j = strlen(x);
    191.             // Выводим текущий путь
    192.             printf("%s", x);
    193.              all++;
    194.             // Пересчитываем длину пути
    195.  
    196.             rib_length=count_way_lenght(rib_length,  x);
    197.             // Печать длины пути
    198.             printf(" %d ", rib_length);
    199.             printf("\n\r");
    200.  
    201.             // Обновляем кратчайший путь
    202.             if (rib_length < short_way) {
    203.                 //Сохраним кратчайший путь
    204.                 strcpy(short_way_point, x);
    205.                 short_way = rib_length;
    206.             }
    207.         }
    208.         j--;
    209.     }
    210.  
    211.     printf("Самый короткий путь: %d \n\r", short_way);
    212.     printf("Лежит через эти точки: %s \n\r", short_way_point);
    213.     printf("Все пути: %d \n\r", all);
    214.  
    215.     return 0;
    216. }
    217.  
     
  6. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. // Количество всех вершин
    5. #define ALL_POINTS 26
    6.  
    7. // Объявим граф глобально
    8. char a[] = "bcdz";
    9. char b[] = "defz";
    10. char c[] = "defz";
    11. char d[] = "efz";
    12. char e[] = "fz";
    13. char f[] = "ghjz";
    14. char g[] = "hijz";
    15. char h[] = "ijkz";
    16. char i[] = "jklz";
    17. char j[] = "kmz";
    18. char k[] = "lnoz";
    19. char l[] = "mz";
    20. char m[] = "noz";
    21. char n[] = "oz";
    22. char o[] = "pz";
    23. char p[] = "qz";
    24. char q[] = "rz";
    25. char r[] = "sz";
    26. char s[] = "tuz";
    27. char t[] = "uvz";
    28. char u[] = "vwz";
    29. char v[] = "wz";
    30. char w[] = "xyz";
    31. char x[] = "yz";
    32. char y[] = "z";
    33. char z[] = "";
    34.  
    35. /* Массивы соответствий */
    36. char *array_corresp[] = {
    37.     a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    38. };
    39. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    40.  
    41. /* Рёбра */
    42. char *ribs[] = {
    43.     "ab", "ac", "ad", "az",
    44.     "bd", "be", "bf", "bz",
    45.     "cd", "ce", "cf", "cz",
    46.     "de", "df", "dz",
    47.     "ef", "ez",
    48.     "fg", "fh", "fj", "fz",
    49.     "gh", "gi", "gj", "gz",
    50.     "hi", "hj", "hk", "hz",
    51.     "ij", "ik", "il", "iz",
    52.     "jk", "jm", "jz",
    53.     "kl", "kn", "ko", "kz",
    54.     "lm", "lz",
    55.     "mn", "mo", "mz",
    56.     "no", "nz",
    57.     "op", "oz",
    58.     "pq", "pz",
    59.     "qr", "qz",
    60.     "rs", "rz",
    61.     "st", "su", "sz",
    62.     "tu", "tv", "tz",
    63.     "uv", "uw", "uz",
    64.     "vw", "vz",
    65.     "wx", "wy", "wz",
    66.     "xy", "xz",
    67.     "yz"
    68. };
    69.  
    70. /* Длины рёбер */
    71. int ribs_count[] = {
    72.     12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    73.     7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    74.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    75.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    76.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    77.     71, 72, 73, 74, 75, 17, 99, 67
    78. };
    79.  
    80. // Длина массива с длинами рёбер
    81. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    82.  
    83. /////////////////Функции//////////////////////////////////////////////////////
    84.  
    85. int print_way(char *first_x_way, int rib_length) {
    86.     // Выводим текущий путь
    87.     printf("%s", first_x_way);
    88.     // Печать длины пути
    89.     printf(" %d ", rib_length);
    90.     printf("\n");
    91.     return 0;
    92. }
    93.  
    94. // Вернёт элемент, который потом допишем в массив first_x_way
    95. char search_element_to_push(char *first_x_way) {
    96.     char z;
    97.     int i;
    98.     int j = strlen(first_x_way) - 1;
    99.     for (i = 0; i < ALL_POINTS; i++) {
    100.         if (first_x_way[j] == array_corresp2[i]) {
    101.             z = array_corresp[i][0];
    102.         }
    103.     }
    104.     return z;
    105. }
    106.  
    107. // Возвращает указатель на первый путь first_x_way
    108. char *element_search(char *first_x_way, int j) {
    109.     char *arr;
    110.     int i;
    111.     for (i = 0; i < ALL_POINTS; i++) {
    112.         if (first_x_way[j - 1] == array_corresp2[i]) {
    113.             arr = array_corresp[i];
    114.         }
    115.     }
    116.     return arr;
    117. }
    118.  
    119. // Поиск ключа элемента
    120. static int array_search(const char *ar_for_element_search, char el) {
    121.     int i = 0;
    122.     while (ar_for_element_search[i] != '\0') {
    123.         if (ar_for_element_search[i] == el) return i;
    124.         i++;
    125.     }
    126.     return -1;
    127. }
    128.  
    129. // Найдем длину каждого пути
    130. int count_way_length(int rib_length, char *first_x_way) {
    131.     int j = strlen(first_x_way) - 1;
    132.     rib_length = 0;
    133.     int i, y;
    134.     for (y = 0; y < j; y++) {
    135.         for (i = 0; i < ribs_all_count; i++) {
    136.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    137.                 rib_length += ribs_count[i];
    138.             }
    139.         }
    140.     }
    141.     return rib_length;
    142. }
    143.  
    144. /////////////////////////////////////////////////////////////////////////////////////////
    145.  
    146. int main() {
    147.     char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    148.     char element_to_push;
    149.     char short_way_point[100];
    150.     char last_point = 'z';
    151.     char *ar_for_element_search;
    152.     int i, y, key;
    153.     int rib_length = 0;
    154.     int all = 1;
    155.     // Вспомогательная переменная для определения самого короткого пути
    156.     int short_way = 5000;
    157.     // Первый путь задан
    158.     // Длина j
    159.     int j = strlen(first_x_way) - 1;
    160.     int first_x_way_len = 0;
    161.  
    162.     // Все пути. 1 потому что выводим 1-ый вне циклов
    163.     // Печать первого пути
    164.     for (i = 0; first_x_way[i] != '\0'; i++)
    165.         printf("%c", first_x_way[i]);
    166.  
    167.     // Найдем длину первого пути
    168.     rib_length = 0;
    169.     for (y = 0; y < j; y++) {
    170.         for (i = 0; i < ribs_all_count; i++) {
    171.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    172.                 rib_length += ribs_count[i];
    173.             }
    174.         }
    175.     }
    176.     printf(" %d ", rib_length);
    177.     printf("\n");
    178.  
    179.     // Основной цикл поиска путей
    180.     while (j > 0) {
    181.         /* Определяем и ищем элемент и его ключ */
    182.         ar_for_element_search = element_search(first_x_way, j);
    183.         key = array_search(ar_for_element_search, first_x_way[j]);
    184.  
    185.         if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    186.             /* Задаем длину массива равной j */
    187.             first_x_way_len = j;
    188.             /* Режем первый путь */
    189.             first_x_way[j + 1] = '\0';
    190.             /* Пишем в массив first_x_way */
    191.             first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    192.             /* Найдем element_to_push для записи */
    193.             element_to_push = search_element_to_push(first_x_way);
    194.  
    195.             while (1) {
    196.                 /* Если дошли до последнего символа, выходим */
    197.                 if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    198.                     first_x_way[first_x_way_len++] = element_to_push;
    199.                     break;
    200.                 }
    201.                 /* Пишем в first_x_way */
    202.                 first_x_way[first_x_way_len++] = element_to_push;
    203.                 /* Ещё найдем element_to_push для записи */
    204.                 element_to_push = search_element_to_push(first_x_way);
    205.             }
    206.             /* Обновляем j */
    207.             j = strlen(first_x_way);
    208.             all++;
    209.             /* Пересчитываем длину пути */
    210.             rib_length = count_way_length(rib_length, first_x_way);
    211.             /* Печать */
    212.             print_way(first_x_way, rib_length);
    213.             /* Обновляем кратчайший путь */
    214.             if (rib_length < short_way) {
    215.                 /* Сохраним кратчайший путь */
    216.                 strcpy(short_way_point, first_x_way);
    217.                 short_way = rib_length;
    218.             }
    219.         }
    220.         j--;
    221.     }
    222.  
    223.     /* Тут результаты */
    224.     printf("Самый короткий путь: %d \n", short_way);
    225.     printf("Лежит через эти точки: %s \n", short_way_point);
    226.     printf("Все пути: %d \n", all);
    227.  
    228.     return 0;
    229. }
    230.  
     
  7. Ahimov

    Ahimov Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    755
    Спросил дипсика, отменный бред выдает, мол компилер удаляет строки и прочии фантазии. У него не получается собрать нужную структуру графа :swoon:

    Это похоже фича бям, как и неспособность видеть фантомы(иллюзии).

    На этой задаче он понимает что она детермин., знает кодировку и формат isa, но мозг" у него выносит полностью :sarcastic:
    - "я запутался, задача ад, используйте z3 солвер и тп."
     
    dcc0 нравится это.
  8. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Мой рукотворный селектор тоже проанализировать не смогли. Deeapai так и написал, слишком сложный. Но правда, и на Лоре не все смогли понять.
    --- Сообщение объединено, 30 июн 2026 ---
    Это ещё интерактиваности нет.
    А вот если добавитью

    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. // Количество всех вершин
    5. #define ALL_POINTS 26
    6.  
    7. // Объявим граф глобально
    8. char a[] = "bcdz";
    9. char b[] = "defz";
    10. char c[] = "defz";
    11. char d[] = "efz";
    12. char e[] = "fz";
    13. char f[] = "ghjz";
    14. char g[] = "hijz";
    15. char h[] = "ijkz";
    16. char i[] = "jklz";
    17. char j[] = "kmz";
    18. char k[] = "lnoz";
    19. char l[] = "mz";
    20. char m[] = "noz";
    21. char n[] = "oz";
    22. char o[] = "pz";
    23. char p[] = "qz";
    24. char q[] = "rz";
    25. char r[] = "sz";
    26. char s[] = "tuz";
    27. char t[] = "uvz";
    28. char u[] = "vwz";
    29. char v[] = "wz";
    30. char w[] = "xyz";
    31. char x[] = "yz";
    32. char y[] = "z";
    33. char z[] = "";
    34.  
    35. /* Массивы соответствий */
    36. char *array_corresp[] = {
    37.     a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    38. };
    39. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    40.  
    41. /* Рёбра */
    42. char *ribs[] = {
    43.     "ab", "ac", "ad", "az",
    44.     "bd", "be", "bf", "bz",
    45.     "cd", "ce", "cf", "cz",
    46.     "de", "df", "dz",
    47.     "ef", "ez",
    48.     "fg", "fh", "fj", "fz",
    49.     "gh", "gi", "gj", "gz",
    50.     "hi", "hj", "hk", "hz",
    51.     "ij", "ik", "il", "iz",
    52.     "jk", "jm", "jz",
    53.     "kl", "kn", "ko", "kz",
    54.     "lm", "lz",
    55.     "mn", "mo", "mz",
    56.     "no", "nz",
    57.     "op", "oz",
    58.     "pq", "pz",
    59.     "qr", "qz",
    60.     "rs", "rz",
    61.     "st", "su", "sz",
    62.     "tu", "tv", "tz",
    63.     "uv", "uw", "uz",
    64.     "vw", "vz",
    65.     "wx", "wy", "wz",
    66.     "xy", "xz",
    67.     "yz"
    68. };
    69.  
    70. /* Длины рёбер */
    71. int ribs_count[] = {
    72.     12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    73.     7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    74.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    75.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    76.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    77.     71, 72, 73, 74, 75, 17, 99, 67
    78. };
    79.  
    80. // Длина массива с длинами рёбер
    81. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    82.  
    83. /////////////////Функции//////////////////////////////////////////////////////
    84.  
    85. int print_way(char *first_x_way, int rib_length) {
    86.     // Выводим текущий путь
    87.     printf("%s", first_x_way);
    88.     // Печать длины пути
    89.     printf(" %d ", rib_length);
    90.     printf("\n");
    91.     return 0;
    92. }
    93.  
    94. // Вернёт элемент, который потом допишем в массив first_x_way
    95. char search_element_to_push(char *first_x_way) {
    96.     char z;
    97.     int i;
    98.     int j = strlen(first_x_way) - 1;
    99.     for (i = 0; i < ALL_POINTS; i++) {
    100.         if (first_x_way[j] == array_corresp2[i]) {
    101.             z = array_corresp[i][0];
    102.         }
    103.     }
    104.     return z;
    105. }
    106.  
    107. // Возвращает указатель на первый путь first_x_way
    108. char *element_search(char *first_x_way, int j) {
    109.     char *arr;
    110.     int i;
    111.     for (i = 0; i < ALL_POINTS; i++) {
    112.         if (first_x_way[j - 1] == array_corresp2[i]) {
    113.             arr = array_corresp[i];
    114.         }
    115.     }
    116.     return arr;
    117. }
    118.  
    119. // Поиск ключа элемента
    120. static int array_search(const char *ar_for_element_search, char el) {
    121.     int i = 0;
    122.     while (ar_for_element_search[i] != '\0') {
    123.         if (ar_for_element_search[i] == el) return i;
    124.         i++;
    125.     }
    126.     return -1;
    127. }
    128.  
    129. // Найдем длину каждого пути
    130. int count_way_length(int rib_length, char *first_x_way) {
    131.     int j = strlen(first_x_way) - 1;
    132.     rib_length = 0;
    133.     int i, y;
    134.     for (y = 0; y < j; y++) {
    135.         for (i = 0; i < ribs_all_count; i++) {
    136.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    137.                 rib_length += ribs_count[i];
    138.             }
    139.         }
    140.     }
    141.     return rib_length;
    142. }
    143.  
    144. /////////////////////////////////////////////////////////////////////////////////////////
    145.  
    146. int main() {
    147.  
    148.     char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    149.     char element_to_push;
    150.     char short_way_point[100];
    151.     char last_point = 'z';
    152.     char *ar_for_element_search;
    153.     char allws_short[100][100];
    154.     char enter_press_to_show_all_small_ways;
    155.     int allws_short_lenght[1000];
    156.     int xxx=0;
    157.     int i, y, key;
    158.     int rib_length = 0;
    159.     int all = 1;
    160.     // Вспомогательная переменная для определения самого короткого пути
    161.     int short_way = 5000;
    162.     // Первый путь задан
    163.     // Длина j
    164.     int j = strlen(first_x_way) - 1;
    165.     int first_x_way_len = 0;
    166.     int all_shorts_way_to_show = 0;
    167.  
    168.   /*Сохраним пути меньше введенного числа*/
    169.    printf("Сохранить все пути меньше [введите число от 1 до 150]  или 0? ");
    170.    scanf("%d", &all_shorts_way_to_show);
    171.     if ( all_shorts_way_to_show  >  150)
    172.     all_shorts_way_to_show = 0;
    173.  
    174.     // Все пути. 1 потому что выводим 1-ый вне циклов
    175.     // Печать первого пути
    176.     for (i = 0; first_x_way[i] != '\0'; i++)
    177.         printf("%c", first_x_way[i]);
    178.  
    179.     // Найдем длину первого пути
    180.     rib_length = 0;
    181.     for (y = 0; y < j; y++) {
    182.         for (i = 0; i < ribs_all_count; i++) {
    183.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    184.                 rib_length += ribs_count[i];
    185.             }
    186.         }
    187.     }
    188.     printf(" %d ", rib_length);
    189.     printf("\n");
    190.  
    191.     // Основной цикл поиска путей
    192.     while (j > 0) {
    193.         /* Определяем и ищем элемент и его ключ */
    194.         ar_for_element_search = element_search(first_x_way, j);
    195.         key = array_search(ar_for_element_search, first_x_way[j]);
    196.  
    197.         if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    198.             /* Задаем длину массива равной j */
    199.             first_x_way_len = j;
    200.             /* Режем первый путь */
    201.             first_x_way[j + 1] = '\0';
    202.             /* Пишем в массив first_x_way */
    203.             first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    204.             /* Найдем element_to_push для записи */
    205.             element_to_push = search_element_to_push(first_x_way);
    206.  
    207.             while (1) {
    208.                 /* Если дошли до последнего символа, выходим */
    209.                 if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    210.                     first_x_way[first_x_way_len++] = element_to_push;
    211.                     break;
    212.                 }
    213.                 /* Пишем в first_x_way */
    214.                 first_x_way[first_x_way_len++] = element_to_push;
    215.                 /* Ещё найдем element_to_push для записи */
    216.                 element_to_push = search_element_to_push(first_x_way);
    217.             }
    218.             /* Обновляем j */
    219.             j = strlen(first_x_way);
    220.             all++;
    221.             /* Пересчитываем длину пути */
    222.             rib_length = count_way_length(rib_length, first_x_way);
    223.             /* Печать */
    224.             print_way(first_x_way, rib_length);
    225.             //Найдем все пути меньше 50
    226.                if (rib_length < all_shorts_way_to_show && (all_shorts_way_to_show  != 0)) {
    227.                    strcpy(allws_short[xxx], first_x_way);
    228.                  allws_short_lenght[xxx]=rib_length;
    229.                  xxx++;
    230.                 }
    231.  
    232.             /* Обновляем кратчайший путь */
    233.             if (rib_length < short_way) {
    234.                 /* Сохраним кратчайший путь */
    235.                 strcpy(short_way_point, first_x_way);
    236.                 short_way = rib_length;
    237.  
    238.             }
    239.         }
    240.         j--;
    241.     }
    242.     /* Тут результаты */
    243.     printf("Самый короткий путь: %d \n", short_way);
    244.     printf("Лежит через эти точки: %s \n", short_way_point);
    245.     printf("Все пути: %d \n", all);
    246.  
    247.    printf("Показать все пути меньше  %d ? y/n" , all_shorts_way_to_show);
    248.    scanf("%c", &enter_press_to_show_all_small_ways);
    249.    scanf("%c", &enter_press_to_show_all_small_ways);
    250.    allws_short_lenght[xxx++]='\0';
    251.     if (enter_press_to_show_all_small_ways == 'y') {
    252.     for (i=0; allws_short_lenght[i] !='\0'; i++)
    253.     printf("Путь: < %d  %s \n", allws_short_lenght[i], allws_short[i]);
    254. } else {
    255.         printf("\nВыходим...!\n");
    256. }
    257.     return 0;
    258. }
    259.  
     
  9. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Так более правильно. Но почему бывает глюк сохранением длин пути, пока понять не могу:

    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. // Количество всех вершин
    5. #define ALL_POINTS 26
    6.  
    7. // Объявим граф глобально
    8. char a[] = "bcdz";
    9. char b[] = "defz";
    10. char c[] = "defz";
    11. char d[] = "efz";
    12. char e[] = "fz";
    13. char f[] = "ghjz";
    14. char g[] = "hijz";
    15. char h[] = "ijkz";
    16. char i[] = "jklz";
    17. char j[] = "kmz";
    18. char k[] = "lnoz";
    19. char l[] = "mz";
    20. char m[] = "noz";
    21. char n[] = "oz";
    22. char o[] = "pz";
    23. char p[] = "qz";
    24. char q[] = "rz";
    25. char r[] = "sz";
    26. char s[] = "tuz";
    27. char t[] = "uvz";
    28. char u[] = "vwz";
    29. char v[] = "wz";
    30. char w[] = "xyz";
    31. char x[] = "yz";
    32. char y[] = "z";
    33. char z[] = "";
    34.  
    35. /* Массивы соответствий */
    36. char *array_corresp[] = {
    37.     a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    38. };
    39. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    40.  
    41. /* Рёбра */
    42. char *ribs[] = {
    43.     "ab", "ac", "ad", "az",
    44.     "bd", "be", "bf", "bz",
    45.     "cd", "ce", "cf", "cz",
    46.     "de", "df", "dz",
    47.     "ef", "ez",
    48.     "fg", "fh", "fj", "fz",
    49.     "gh", "gi", "gj", "gz",
    50.     "hi", "hj", "hk", "hz",
    51.     "ij", "ik", "il", "iz",
    52.     "jk", "jm", "jz",
    53.     "kl", "kn", "ko", "kz",
    54.     "lm", "lz",
    55.     "mn", "mo", "mz",
    56.     "no", "nz",
    57.     "op", "oz",
    58.     "pq", "pz",
    59.     "qr", "qz",
    60.     "rs", "rz",
    61.     "st", "su", "sz",
    62.     "tu", "tv", "tz",
    63.     "uv", "uw", "uz",
    64.     "vw", "vz",
    65.     "wx", "wy", "wz",
    66.     "xy", "xz",
    67.     "yz"
    68. };
    69.  
    70. /* Длины рёбер */
    71. int ribs_count[] = {
    72.     12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    73.     7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    74.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    75.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    76.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    77.     71, 72, 73, 74, 75, 17, 99, 67
    78. };
    79.  
    80. // Длина массива с длинами рёбер
    81. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    82.  
    83. /////////////////Функции//////////////////////////////////////////////////////
    84.  
    85. int print_way(char *first_x_way, int rib_length) {
    86.     // Выводим текущий путь
    87.     printf("%s", first_x_way);
    88.     // Печать длины пути
    89.     printf(" %d ", rib_length);
    90.     printf("\n");
    91.     return 0;
    92. }
    93.  
    94. // Вернёт элемент, который потом допишем в массив first_x_way
    95. char search_element_to_push(char *first_x_way) {
    96.     char z;
    97.     int i;
    98.     int j = strlen(first_x_way) - 1;
    99.     for (i = 0; i < ALL_POINTS; i++) {
    100.         if (first_x_way[j] == array_corresp2[i]) {
    101.             z = array_corresp[i][0];
    102.         }
    103.     }
    104.     return z;
    105. }
    106.  
    107. // Возвращает указатель на первый путь first_x_way
    108. char *element_search(char *first_x_way, int j) {
    109.     char *arr;
    110.     int i;
    111.     for (i = 0; i < ALL_POINTS; i++) {
    112.         if (first_x_way[j - 1] == array_corresp2[i]) {
    113.             arr = array_corresp[i];
    114.         }
    115.     }
    116.     return arr;
    117. }
    118.  
    119. // Поиск ключа элемента
    120. static int array_search(const char *ar_for_element_search, char el) {
    121.     int i = 0;
    122.     while (ar_for_element_search[i] != '\0') {
    123.         if (ar_for_element_search[i] == el) return i;
    124.         i++;
    125.     }
    126.     return -1;
    127. }
    128.  
    129. // Найдем длину каждого пути
    130. int count_way_length(int rib_length, char *first_x_way) {
    131.     int j = strlen(first_x_way) - 1;
    132.     rib_length = 0;
    133.     int i, y;
    134.     for (y = 0; y < j; y++) {
    135.         for (i = 0; i < ribs_all_count; i++) {
    136.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    137.                 rib_length += ribs_count[i];
    138.             }
    139.         }
    140.     }
    141.     return rib_length;
    142. }
    143.  
    144. /////////////////////////////////////////////////////////////////////////////////////////
    145.  
    146. int main() {
    147.  
    148.     char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    149.     char element_to_push;
    150.     char short_way_point[100];
    151.     char last_point = 'z';
    152.     char *ar_for_element_search;
    153.     char allws_short[100][100];
    154.     char enter_press_to_show_all_small_ways;
    155.     int allws_short_lenght[1000];
    156.     int xxx=0;
    157.     int i, y, key;
    158.     int rib_length = 0;
    159.     int all = 1;
    160.     // Вспомогательная переменная для определения самого короткого пути
    161.     int short_way = 5000;
    162.     // Первый путь задан
    163.     // Длина j
    164.     int j = strlen(first_x_way) - 1;
    165.     int first_x_way_len = 0;
    166.     int all_shorts_way_to_show = 0;
    167.  
    168.   /*Сохраним пути меньше введенного числа*/
    169.    printf("Сохранить все пути меньше [введите число от 1 до 150]  или 0? ");
    170.    scanf("%d", &all_shorts_way_to_show);
    171.     if ( all_shorts_way_to_show  >  150)
    172.     all_shorts_way_to_show = 0;
    173.  
    174.     // Все пути. 1 потому что выводим 1-ый вне циклов
    175.     // Печать первого пути
    176.     for (i = 0; first_x_way[i] != '\0'; i++)
    177.         printf("%c", first_x_way[i]);
    178.  
    179.     // Найдем длину первого пути
    180.     rib_length = 0;
    181.     for (y = 0; y < j; y++) {
    182.         for (i = 0; i < ribs_all_count; i++) {
    183.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    184.                 rib_length += ribs_count[i];
    185.             }
    186.         }
    187.     }
    188.     printf(" %d ", rib_length);
    189.     printf("\n");
    190.  
    191.     // Основной цикл поиска путей
    192.     while (j > 0) {
    193.         /* Определяем и ищем элемент и его ключ */
    194.         ar_for_element_search = element_search(first_x_way, j);
    195.         key = array_search(ar_for_element_search, first_x_way[j]);
    196.  
    197.         if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    198.             /* Задаем длину массива равной j */
    199.             first_x_way_len = j;
    200.             /* Режем первый путь */
    201.             first_x_way[j + 1] = '\0';
    202.             /* Пишем в массив first_x_way */
    203.             first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    204.             /* Найдем element_to_push для записи */
    205.             element_to_push = search_element_to_push(first_x_way);
    206.  
    207.             while (1) {
    208.                 /* Если дошли до последнего символа, выходим */
    209.                 if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    210.                     first_x_way[first_x_way_len++] = element_to_push;
    211.                     break;
    212.                 }
    213.                 /* Пишем в first_x_way */
    214.                 first_x_way[first_x_way_len++] = element_to_push;
    215.                 /* Ещё найдем element_to_push для записи */
    216.                 element_to_push = search_element_to_push(first_x_way);
    217.             }
    218.             /* Обновляем j */
    219.             j = strlen(first_x_way);
    220.             all++;
    221.             /* Пересчитываем длину пути */
    222.             rib_length = count_way_length(rib_length, first_x_way);
    223.             /* Печать */
    224.             print_way(first_x_way, rib_length);
    225.             //Найдем все пути меньше 50
    226.                if (rib_length < all_shorts_way_to_show && (all_shorts_way_to_show  != 0)) {
    227.                    strcpy(allws_short[xxx], first_x_way);
    228.                  allws_short_lenght[xxx]=rib_length;
    229.                  xxx++;
    230.                 }
    231.  
    232.             /* Обновляем кратчайший путь */
    233.             if (rib_length < short_way) {
    234.                 /* Сохраним кратчайший путь */
    235.                 strcpy(short_way_point, first_x_way);
    236.                 short_way = rib_length;
    237.  
    238.             }
    239.         }
    240.         j--;
    241.     }
    242.     /* Тут результаты */
    243.     printf("Самый короткий путь: %d \n", short_way);
    244.     printf("Лежит через эти точки: %s \n", short_way_point);
    245.     printf("Все пути: %d \n", all);
    246.  
    247.    printf("Показать все пути меньше  %d ? y/n" , all_shorts_way_to_show);
    248.    scanf(" %c", &enter_press_to_show_all_small_ways);
    249.  
    250.     if (enter_press_to_show_all_small_ways == 'y') {
    251.     for (i=xxx; i !=0; i--)
    252.     printf("Путь: < %d  %s \n", allws_short_lenght[i], allws_short[i]);
    253. } else {
    254.         printf("\nВыходим...!\n");
    255. }
    256.     return 0;
    257. }
    258.  
    --- Сообщение объединено, 2 июл 2026 ---
    Совсем диакая дичь. Можно сохранить пути меньше заданного (поставил 750 - предел, такак на 1000 на моем компе stack smashing):


    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3.  
    4. // Количество всех вершин
    5. #define ALL_POINTS 26
    6.  
    7. // Объявим граф глобально
    8. char a[] = "bcdz";
    9. char b[] = "defz";
    10. char c[] = "defz";
    11. char d[] = "efz";
    12. char e[] = "fz";
    13. char f[] = "ghjz";
    14. char g[] = "hijz";
    15. char h[] = "ijkz";
    16. char i[] = "jklz";
    17. char j[] = "kmz";
    18. char k[] = "lnoz";
    19. char l[] = "mz";
    20. char m[] = "noz";
    21. char n[] = "oz";
    22. char o[] = "pz";
    23. char p[] = "qz";
    24. char q[] = "rz";
    25. char r[] = "sz";
    26. char s[] = "tuz";
    27. char t[] = "uvz";
    28. char u[] = "vwz";
    29. char v[] = "wz";
    30. char w[] = "xyz";
    31. char x[] = "yz";
    32. char y[] = "z";
    33. char z[] = "";
    34.  
    35. /* Массивы соответствий */
    36. char *array_corresp[] = {
    37.     a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    38. };
    39. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    40.  
    41. /* Рёбра */
    42. char *ribs[] = {
    43.     "ab", "ac", "ad", "az",
    44.     "bd", "be", "bf", "bz",
    45.     "cd", "ce", "cf", "cz",
    46.     "de", "df", "dz",
    47.     "ef", "ez",
    48.     "fg", "fh", "fj", "fz",
    49.     "gh", "gi", "gj", "gz",
    50.     "hi", "hj", "hk", "hz",
    51.     "ij", "ik", "il", "iz",
    52.     "jk", "jm", "jz",
    53.     "kl", "kn", "ko", "kz",
    54.     "lm", "lz",
    55.     "mn", "mo", "mz",
    56.     "no", "nz",
    57.     "op", "oz",
    58.     "pq", "pz",
    59.     "qr", "qz",
    60.     "rs", "rz",
    61.     "st", "su", "sz",
    62.     "tu", "tv", "tz",
    63.     "uv", "uw", "uz",
    64.     "vw", "vz",
    65.     "wx", "wy", "wz",
    66.     "xy", "xz",
    67.     "yz"
    68. };
    69.  
    70. /* Длины рёбер */
    71. int ribs_count[] = {
    72.     12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    73.     7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    74.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    75.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    76.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    77.     71, 72, 73, 74, 75, 17, 99, 67
    78. };
    79.  
    80. // Длина массива с длинами рёбер
    81. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    82.  
    83. /////////////////Функции//////////////////////////////////////////////////////
    84.  
    85. int print_way(char *first_x_way, int rib_length) {
    86.     // Выводим текущий путь
    87.     printf("%s", first_x_way);
    88.     // Печать длины пути
    89.     printf(" %d ", rib_length);
    90.     printf("\n");
    91.     return 0;
    92. }
    93.  
    94. // Вернёт элемент, который потом допишем в массив first_x_way
    95. char search_element_to_push(char *first_x_way) {
    96.     char z;
    97.     int i;
    98.     int j = strlen(first_x_way) - 1;
    99.     for (i = 0; i < ALL_POINTS; i++) {
    100.         if (first_x_way[j] == array_corresp2[i]) {
    101.             z = array_corresp[i][0];
    102.         }
    103.     }
    104.     return z;
    105. }
    106.  
    107. // Возвращает указатель на первый путь first_x_way
    108. char *element_search(char *first_x_way, int j) {
    109.     char *arr;
    110.     int i;
    111.     for (i = 0; i < ALL_POINTS; i++) {
    112.         if (first_x_way[j - 1] == array_corresp2[i]) {
    113.             arr = array_corresp[i];
    114.         }
    115.     }
    116.     return arr;
    117. }
    118.  
    119. // Поиск ключа элемента
    120. static int array_search(const char *ar_for_element_search, char el) {
    121.     int i = 0;
    122.     while (ar_for_element_search[i] != '\0') {
    123.         if (ar_for_element_search[i] == el) return i;
    124.         i++;
    125.     }
    126.     return -1;
    127. }
    128.  
    129. // Найдем длину каждого пути
    130. int count_way_length(int rib_length, char *first_x_way) {
    131.     int j = strlen(first_x_way) - 1;
    132.     rib_length = 0;
    133.     int i, y;
    134.     for (y = 0; y < j; y++) {
    135.         for (i = 0; i < ribs_all_count; i++) {
    136.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    137.                 rib_length += ribs_count[i];
    138.             }
    139.         }
    140.     }
    141.     return rib_length;
    142. }
    143.  
    144. /////////////////////////////////////////////////////////////////////////////////////////
    145.  
    146. int main() {
    147.  
    148.     char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    149.     char element_to_push;
    150.     char short_way_point[100];
    151.     char last_point = 'z';
    152.     char *ar_for_element_search;
    153.     char allws_short[22000][ALL_POINTS];
    154.     char enter_press_to_show_all_small_ways;
    155.     int allws_short_lenght[22000];
    156.     int incrx=0;
    157.     int i, y, key;
    158.     int rib_length = 0;
    159.     int all = 1;
    160.     // Вспомогательная переменная для определения самого короткого пути
    161.     int short_way = 5000;
    162.     // Первый путь задан
    163.     // Длина j
    164.     int j = strlen(first_x_way) - 1;
    165.     int first_x_way_len = 0;
    166.     int all_shorts_way_to_show = 0;
    167.  
    168.   /*Сохраним пути меньше введенного числа*/
    169.    printf("Сохранить все пути меньше [введите число от 1 до 750]  или 0? ");
    170.    scanf("%d", &all_shorts_way_to_show);
    171.     if ( all_shorts_way_to_show  >  750)
    172.     all_shorts_way_to_show = 0;
    173.  
    174.     // Все пути. 1 потому что выводим 1-ый вне циклов
    175.     // Печать первого пути
    176.     for (i = 0; first_x_way[i] != '\0'; i++)
    177.         printf("%c", first_x_way[i]);
    178.  
    179.     // Найдем длину первого пути
    180.     rib_length = 0;
    181.     for (y = 0; y < j; y++) {
    182.         for (i = 0; i < ribs_all_count; i++) {
    183.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    184.                 rib_length += ribs_count[i];
    185.             }
    186.         }
    187.     }
    188.     printf(" %d ", rib_length);
    189.     printf("\n");
    190.  
    191.     // Основной цикл поиска путей
    192.     while (j > 0) {
    193.         /* Определяем и ищем элемент и его ключ */
    194.         ar_for_element_search = element_search(first_x_way, j);
    195.         key = array_search(ar_for_element_search, first_x_way[j]);
    196.  
    197.         if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    198.             /* Задаем длину массива равной j */
    199.             first_x_way_len = j;
    200.             /* Режем первый путь */
    201.             first_x_way[j + 1] = '\0';
    202.             /* Пишем в массив first_x_way */
    203.             first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    204.             /* Найдем element_to_push для записи */
    205.             element_to_push = search_element_to_push(first_x_way);
    206.  
    207.             while (1) {
    208.                 /* Если дошли до последнего символа, выходим */
    209.                 if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    210.                     first_x_way[first_x_way_len++] = element_to_push;
    211.                     break;
    212.                 }
    213.                 /* Пишем в first_x_way */
    214.                 first_x_way[first_x_way_len++] = element_to_push;
    215.                 /* Ещё найдем element_to_push для записи */
    216.                 element_to_push = search_element_to_push(first_x_way);
    217.             }
    218.             /* Обновляем j */
    219.             j = strlen(first_x_way);
    220.             all++;
    221.             /* Пересчитываем длину пути */
    222.             rib_length = count_way_length(rib_length, first_x_way);
    223.             /* Печать */
    224.             print_way(first_x_way, rib_length);
    225.  
    226.             //Найдем все пути меньше all_shorts_way_to_show
    227.                if (rib_length < all_shorts_way_to_show && (all_shorts_way_to_show  != 0)) {
    228.                     allws_short_lenght[incrx]=rib_length;
    229.                    strcpy(allws_short[incrx], first_x_way);
    230.                  incrx++;
    231.  
    232.                 }
    233.  
    234.  
    235.             /* Обновляем кратчайший путь */
    236.             if (rib_length < short_way) {
    237.                 /* Сохраним кратчайший путь */
    238.                 strcpy(short_way_point, first_x_way);
    239.                 short_way = rib_length;
    240.  
    241.             }
    242.         }
    243.         j--;
    244.     }
    245.     /* Тут результаты */
    246.     printf("Самый короткий путь: %d \n", short_way);
    247.     printf("Лежит через эти точки: %s \n", short_way_point);
    248.     printf("Все пути: %d \n", all);
    249.  
    250.    printf("Показать все пути меньше  %d ? y/n" , all_shorts_way_to_show);
    251.    scanf(" %c", &enter_press_to_show_all_small_ways);
    252.  
    253.  
    254.     if (enter_press_to_show_all_small_ways == 'y') {
    255.     for (i=0; i < incrx-1; i++)
    256.     printf("Путь: < %d  %s \n", allws_short_lenght[i], allws_short[i]);
    257. } else {
    258.         printf("\nВыходим...!\n");
    259. }
    260.  
    261.     return 0;
    262. }
    263.  
    --- Сообщение объединено, 2 июл 2026 ---
    Вот. Допилил до примитивной игры:

    Код (C):
    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <stdlib.h>
    4. // Количество всех вершин
    5. #define ALL_POINTS 26
    6.  
    7. // Объявим граф глобально
    8. char a[] = "bcdz";
    9. char b[] = "defz";
    10. char c[] = "defz";
    11. char d[] = "efz";
    12. char e[] = "fz";
    13. char f[] = "ghjz";
    14. char g[] = "hijz";
    15. char h[] = "ijkz";
    16. char i[] = "jklz";
    17. char j[] = "kmz";
    18. char k[] = "lnoz";
    19. char l[] = "mz";
    20. char m[] = "noz";
    21. char n[] = "oz";
    22. char o[] = "pz";
    23. char p[] = "qz";
    24. char q[] = "rz";
    25. char r[] = "sz";
    26. char s[] = "tuz";
    27. char t[] = "uvz";
    28. char u[] = "vwz";
    29. char v[] = "wz";
    30. char w[] = "xyz";
    31. char x[] = "yz";
    32. char y[] = "z";
    33. char z[] = "";
    34.  
    35. /* Массивы соответствий */
    36. char *array_corresp[] = {
    37.     a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    38. };
    39. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    40.  
    41. /* Рёбра */
    42. char *ribs[] = {
    43.     "ab", "ac", "ad", "az",
    44.     "bd", "be", "bf", "bz",
    45.     "cd", "ce", "cf", "cz",
    46.     "de", "df", "dz",
    47.     "ef", "ez",
    48.     "fg", "fh", "fj", "fz",
    49.     "gh", "gi", "gj", "gz",
    50.     "hi", "hj", "hk", "hz",
    51.     "ij", "ik", "il", "iz",
    52.     "jk", "jm", "jz",
    53.     "kl", "kn", "ko", "kz",
    54.     "lm", "lz",
    55.     "mn", "mo", "mz",
    56.     "no", "nz",
    57.     "op", "oz",
    58.     "pq", "pz",
    59.     "qr", "qz",
    60.     "rs", "rz",
    61.     "st", "su", "sz",
    62.     "tu", "tv", "tz",
    63.     "uv", "uw", "uz",
    64.     "vw", "vz",
    65.     "wx", "wy", "wz",
    66.     "xy", "xz",
    67.     "yz"
    68. };
    69.  
    70. /* Длины рёбер */
    71. int ribs_count[] = {
    72.     12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    73.     7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    74.     23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    75.     42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    76.     58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    77.     71, 72, 73, 74, 75, 17, 99, 67
    78. };
    79.  
    80. // Длина массива с длинами рёбер
    81. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    82.  
    83. /////////////////Функции//////////////////////////////////////////////////////
    84.  
    85. int print_way(char *first_x_way, int rib_length) {
    86.     // Выводим текущий путь
    87.     printf("%s", first_x_way);
    88.     // Печать длины пути
    89.     printf(" %d ", rib_length);
    90.     printf("\n");
    91.     return 0;
    92. }
    93.  
    94. // Вернёт элемент, который потом допишем в массив first_x_way
    95. char search_element_to_push(char *first_x_way) {
    96.     char z;
    97.     int i;
    98.     int j = strlen(first_x_way) - 1;
    99.     for (i = 0; i < ALL_POINTS; i++) {
    100.         if (first_x_way[j] == array_corresp2[i]) {
    101.             z = array_corresp[i][0];
    102.         }
    103.     }
    104.     return z;
    105. }
    106.  
    107. // Возвращает указатель на первый путь first_x_way
    108. char *element_search(char *first_x_way, int j) {
    109.     char *arr;
    110.     int i;
    111.     for (i = 0; i < ALL_POINTS; i++) {
    112.         if (first_x_way[j - 1] == array_corresp2[i]) {
    113.             arr = array_corresp[i];
    114.         }
    115.     }
    116.     return arr;
    117. }
    118.  
    119. // Поиск ключа элемента
    120. static int array_search(const char *ar_for_element_search, char el) {
    121.     int i = 0;
    122.     while (ar_for_element_search[i] != '\0') {
    123.         if (ar_for_element_search[i] == el) return i;
    124.         i++;
    125.     }
    126.     return -1;
    127. }
    128.  
    129. // Найдем длину каждого пути
    130. int count_way_length(int rib_length, char *first_x_way) {
    131.     int j = strlen(first_x_way) - 1;
    132.     rib_length = 0;
    133.     int i, y;
    134.     for (y = 0; y < j; y++) {
    135.         for (i = 0; i < ribs_all_count; i++) {
    136.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    137.                 rib_length += ribs_count[i];
    138.             }
    139.         }
    140.     }
    141.     return rib_length;
    142. }
    143.  
    144. /////////////////////////////////////////////////////////////////////////////////////////
    145.  
    146. int main() {
    147.  
    148.     char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    149.     char element_to_push;
    150.     char short_way_point[100];
    151.     char last_point = 'z';
    152.     char *ar_for_element_search;
    153.     char allws_short[22000][ALL_POINTS];
    154.     char enter_press_to_show_all_small_ways;
    155.     char max_way[100];
    156.     int allws_short_lenght[22000];
    157.     int rrandd = 0;
    158.     int max_rib = 0;
    159.     int incrx=0;
    160.     int i, y, key;
    161.     int rib_length = 0;
    162.     int all = 1;
    163.     int play_game = 0;
    164.     // Вспомогательная переменная для определения самого короткого пути
    165.     int short_way = 5000;
    166.     // Первый путь задан
    167.     // Длина j
    168.     int j = strlen(first_x_way) - 1;
    169.     int first_x_way_len = 0;
    170.     int all_shorts_way_to_show = 0;
    171.  
    172.   /*Сохраним пути меньше введенного числа*/
    173.    printf("Сохранить все пути меньше [введите число от 1 до 750]  или 0? ");
    174.    scanf("%d", &all_shorts_way_to_show);
    175.     if ( all_shorts_way_to_show  >  750)
    176.     all_shorts_way_to_show = 0;
    177.  
    178.     // Все пути. 1 потому что выводим 1-ый вне циклов
    179.     // Печать первого пути
    180.     for (i = 0; first_x_way[i] != '\0'; i++)
    181.         printf("%c", first_x_way[i]);
    182.  
    183.     // Найдем длину первого пути
    184.     rib_length = 0;
    185.     for (y = 0; y < j; y++) {
    186.         for (i = 0; i < ribs_all_count; i++) {
    187.             if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    188.                 rib_length += ribs_count[i];
    189.             }
    190.         }
    191.     }
    192.     printf(" %d ", rib_length);
    193.     printf("\n");
    194.  
    195.     // Основной цикл поиска путей
    196.     while (j > 0) {
    197.         /* Определяем и ищем элемент и его ключ */
    198.         ar_for_element_search = element_search(first_x_way, j);
    199.         key = array_search(ar_for_element_search, first_x_way[j]);
    200.  
    201.         if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    202.             /* Задаем длину массива равной j */
    203.             first_x_way_len = j;
    204.             /* Режем первый путь */
    205.             first_x_way[j + 1] = '\0';
    206.             /* Пишем в массив first_x_way */
    207.             first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    208.             /* Найдем element_to_push для записи */
    209.             element_to_push = search_element_to_push(first_x_way);
    210.  
    211.             while (1) {
    212.                 /* Если дошли до последнего символа, выходим */
    213.                 if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    214.                     first_x_way[first_x_way_len++] = element_to_push;
    215.                     break;
    216.                 }
    217.                 /* Пишем в first_x_way */
    218.                 first_x_way[first_x_way_len++] = element_to_push;
    219.                 /* Ещё найдем element_to_push для записи */
    220.                 element_to_push = search_element_to_push(first_x_way);
    221.             }
    222.             /* Обновляем j */
    223.             j = strlen(first_x_way);
    224.             all++;
    225.             /* Пересчитываем длину пути */
    226.             rib_length = count_way_length(rib_length, first_x_way);
    227.             /* Печать */
    228.             print_way(first_x_way, rib_length);
    229.  
    230.             //Найдем все пути меньше all_shorts_way_to_show
    231.                if (rib_length < all_shorts_way_to_show && (all_shorts_way_to_show  != 0)) {
    232.                    allws_short_lenght[incrx]=rib_length;
    233.                    strcpy(allws_short[incrx], first_x_way);
    234.                  incrx++;
    235.                 }
    236.  
    237.                 if (rib_length > max_rib) {
    238.                  max_rib = rib_length;
    239.                  strcpy(max_way, first_x_way);
    240.                 }
    241.  
    242.             /* Обновляем кратчайший путь */
    243.             if (rib_length < short_way) {
    244.                 /* Сохраним кратчайший путь */
    245.                 strcpy(short_way_point, first_x_way);
    246.                 short_way = rib_length;
    247.             }
    248.         }
    249.         j--;
    250.     }
    251.     /* Тут результаты */
    252.     printf("Самый короткий путь: %d \n", short_way);
    253.     printf("Лежит через эти точки: %s \n", short_way_point);
    254.     printf("Все пути: %d \n", all);
    255.     printf("\nСамый долгий путь %d %s !\n", max_rib, max_way);
    256.     printf("Показать все пути меньше  %d ? y/n" , all_shorts_way_to_show);
    257.    scanf(" %c", &enter_press_to_show_all_small_ways);
    258.  
    259.  
    260.     if (enter_press_to_show_all_small_ways == 'y') {
    261.     for (i=0; i < incrx-1; i++)
    262.     printf("Путь: < %d  %s \n", allws_short_lenght[i], allws_short[i]);
    263. } else {
    264.         printf("\nВыходим...!\n");
    265.  
    266. }
    267.  
    268.    printf("Сыграем в игру     ? y/n");
    269.    scanf(" %c", &enter_press_to_show_all_small_ways);
    270.  
    271.        if (enter_press_to_show_all_small_ways == 'y') {
    272.          rrandd =  (rand() % incrx-1);
    273.            printf("Какой путь был выбран?! [введи число]");
    274.            scanf(" %d", &play_game);
    275.            if (play_game == allws_short_lenght[rrandd]) {
    276.               printf("\nУгадал...!%d %s\n", allws_short_lenght[rrandd], allws_short[rrandd]);
    277.           }
    278.               else {
    279.                 printf("\n Не угадал...!%d %s\n", allws_short_lenght[rrandd], allws_short[rrandd]);
    280.             }
    281. } else {
    282.         printf("\nВыходим...!\n");
    283.  
    284. }
    285.  
    286.     return 0;
    287. }
    288.  
     
  10. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    С рандомом.
    Код (C):
    1.  
    2. #include <stdio.h>
    3. #include <string.h>
    4. #include <stdlib.h>
    5. #include <time.h>
    6. // Количество всех вершин
    7. #define ALL_POINTS 26
    8.  
    9. // Объявим граф глобально
    10. char a[] = "bcdz";
    11. char b[] = "defz";
    12. char c[] = "defz";
    13. char d[] = "efz";
    14. char e[] = "fz";
    15. char f[] = "ghjz";
    16. char g[] = "hijz";
    17. char h[] = "ijkz";
    18. char i[] = "jklz";
    19. char j[] = "kmz";
    20. char k[] = "lnoz";
    21. char l[] = "mz";
    22. char m[] = "noz";
    23. char n[] = "oz";
    24. char o[] = "pz";
    25. char p[] = "qz";
    26. char q[] = "rz";
    27. char r[] = "sz";
    28. char s[] = "tuz";
    29. char t[] = "uvz";
    30. char u[] = "vwz";
    31. char v[] = "wz";
    32. char w[] = "xyz";
    33. char x[] = "yz";
    34. char y[] = "z";
    35. char z[] = "";
    36.  
    37. /* Массивы соответствий */
    38. char *array_corresp[] = {
    39.   a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z
    40. };
    41. char array_corresp2[] = "abcdefghijklmnopqrstuvwxyz";
    42.  
    43. /* Рёбра */
    44. char *ribs[] = {
    45.   "ab", "ac", "ad", "az",
    46.   "bd", "be", "bf", "bz",
    47.   "cd", "ce", "cf", "cz",
    48.   "de", "df", "dz",
    49.   "ef", "ez",
    50.   "fg", "fh", "fj", "fz",
    51.   "gh", "gi", "gj", "gz",
    52.   "hi", "hj", "hk", "hz",
    53.   "ij", "ik", "il", "iz",
    54.   "jk", "jm", "jz",
    55.   "kl", "kn", "ko", "kz",
    56.   "lm", "lz",
    57.   "mn", "mo", "mz",
    58.   "no", "nz",
    59.   "op", "oz",
    60.   "pq", "pz",
    61.   "qr", "qz",
    62.   "rs", "rz",
    63.   "st", "su", "sz",
    64.   "tu", "tv", "tz",
    65.   "uv", "uw", "uz",
    66.   "vw", "vz",
    67.   "wx", "wy", "wz",
    68.   "xy", "xz",
    69.   "yz"
    70. };
    71.  
    72. /* Длины рёбер */
    73. int ribs_count[] = {
    74.   12, 13, 14, 24, 25, 26, 34, 35, 36, 45, 46, 56,
    75.   7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22,
    76.   23, 27, 28, 29, 30, 31, 32, 33, 37, 38, 39, 40, 41,
    77.   42, 43, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57,
    78.   58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    79.   71, 72, 73, 74, 75, 17, 99, 67
    80. };
    81.  
    82. // Длина массива с длинами рёбер
    83. int ribs_all_count = sizeof(ribs_count) / sizeof(ribs_count[0]);
    84.  
    85. /////////////////Функции//////////////////////////////////////////////////////
    86.  
    87. int print_way(char *first_x_way, int rib_length) {
    88.   // Выводим текущий путь
    89.   printf("%s", first_x_way);
    90.   // Печать длины пути
    91.   printf(" %d ", rib_length);
    92.   printf("\n");
    93.   return 0;
    94. }
    95.  
    96. // Вернёт элемент, который потом допишем в массив first_x_way
    97. char search_element_to_push(char *first_x_way) {
    98.   char z;
    99.   int i;
    100.   int j = strlen(first_x_way) - 1;
    101.   for (i = 0; i < ALL_POINTS; i++) {
    102.   if (first_x_way[j] == array_corresp2[i]) {
    103.   z = array_corresp[i][0];
    104.   }
    105.   }
    106.   return z;
    107. }
    108.  
    109. // Возвращает указатель на первый путь first_x_way
    110. char *element_search(char *first_x_way, int j) {
    111.   char *arr;
    112.   int i;
    113.   for (i = 0; i < ALL_POINTS; i++) {
    114.   if (first_x_way[j - 1] == array_corresp2[i]) {
    115.   arr = array_corresp[i];
    116.   }
    117.   }
    118.   return arr;
    119. }
    120.  
    121. // Поиск ключа элемента
    122. static int array_search(const char *ar_for_element_search, char el) {
    123.   int i = 0;
    124.   while (ar_for_element_search[i] != '\0') {
    125.   if (ar_for_element_search[i] == el) return i;
    126.   i++;
    127.   }
    128.   return -1;
    129. }
    130.  
    131. // Найдем длину каждого пути
    132. int count_way_length(int rib_length, char *first_x_way) {
    133.   int j = strlen(first_x_way) - 1;
    134.   rib_length = 0;
    135.   int i, y;
    136.   for (y = 0; y < j; y++) {
    137.   for (i = 0; i < ribs_all_count; i++) {
    138.   if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    139.   rib_length += ribs_count[i];
    140.   }
    141.   }
    142.   }
    143.   return rib_length;
    144. }
    145.  
    146. /////////////////////////////////////////////////////////////////////////////////////////
    147.  
    148. int main() {
    149.  
    150.   char first_x_way[100] = "abdefghijklmnopqrstuvwxyz";
    151.   char element_to_push;
    152.   char short_way_point[100];
    153.   char last_point = 'z';
    154.   char *ar_for_element_search;
    155.   char allws_short[22000][ALL_POINTS];
    156.   char enter_press_to_show_all_small_ways;
    157.   char max_way[100];
    158.   int allws_short_lenght[22000];
    159.   int rrandd = 0;
    160.   int max_rib = 0;
    161.   int incrx=0;
    162.   int i, y, key;
    163.   int rib_length = 0;
    164.   int all = 1;
    165.   int play_game = 0;
    166.   // Вспомогательная переменная для определения самого короткого пути
    167.   int short_way = 5000;
    168.   // Первый путь задан
    169.   // Длина j
    170.   int j = strlen(first_x_way) - 1;
    171.   int first_x_way_len = 0;
    172.   int all_shorts_way_to_show = 0;
    173.  
    174.   /*Сохраним пути меньше введенного числа*/
    175.   printf("Сохранить все пути меньше [введите число от 1 до 750]  или 0? ");
    176.   scanf("%d", &all_shorts_way_to_show);
    177.    if ( all_shorts_way_to_show  >  750)
    178.    all_shorts_way_to_show = 0;
    179.  
    180.   // Все пути. 1 потому что выводим 1-ый вне циклов
    181.   // Печать первого пути
    182.   for (i = 0; first_x_way[i] != '\0'; i++)
    183.   printf("%c", first_x_way[i]);
    184.  
    185.   // Найдем длину первого пути
    186.   rib_length = 0;
    187.   for (y = 0; y < j; y++) {
    188.   for (i = 0; i < ribs_all_count; i++) {
    189.   if (first_x_way[y] == ribs[i][0] && first_x_way[y + 1] == ribs[i][1]) {
    190.   rib_length += ribs_count[i];
    191.   }
    192.   }
    193.   }
    194.   printf(" %d ", rib_length);
    195.   printf("\n");
    196.  
    197.   // Основной цикл поиска путей
    198.   while (j > 0) {
    199.   /* Определяем и ищем элемент и его ключ */
    200.   ar_for_element_search = element_search(first_x_way, j);
    201.   key = array_search(ar_for_element_search, first_x_way[j]);
    202.  
    203.   if ((key != -1) && (ar_for_element_search[key + 1] != '\0')) {
    204.   /* Задаем длину массива равной j */
    205.   first_x_way_len = j;
    206.   /* Режем первый путь */
    207.   first_x_way[j + 1] = '\0';
    208.   /* Пишем в массив first_x_way */
    209.   first_x_way[first_x_way_len++] = ar_for_element_search[key + 1];
    210.   /* Найдем element_to_push для записи */
    211.   element_to_push = search_element_to_push(first_x_way);
    212.  
    213.   while (1) {
    214.   /* Если дошли до последнего символа, выходим */
    215.   if (first_x_way[strlen(first_x_way) - 1] == last_point) {
    216.   first_x_way[first_x_way_len++] = element_to_push;
    217.   break;
    218.   }
    219.   /* Пишем в first_x_way */
    220.   first_x_way[first_x_way_len++] = element_to_push;
    221.   /* Ещё найдем element_to_push для записи */
    222.   element_to_push = search_element_to_push(first_x_way);
    223.   }
    224.   /* Обновляем j */
    225.   j = strlen(first_x_way);
    226.   all++;
    227.   /* Пересчитываем длину пути */
    228.   rib_length = count_way_length(rib_length, first_x_way);
    229.   /* Печать */
    230.   print_way(first_x_way, rib_length);
    231.  
    232.        //Найдем все пути меньше all_shorts_way_to_show
    233.   if (rib_length < all_shorts_way_to_show && (all_shorts_way_to_show  != 0)) {
    234.           allws_short_lenght[incrx]=rib_length;
    235.           strcpy(allws_short[incrx], first_x_way);
    236.           incrx++;
    237.          }
    238.  
    239.          if (rib_length > max_rib) {
    240.           max_rib = rib_length;
    241.           strcpy(max_way, first_x_way);
    242.          }
    243.  
    244.   /* Обновляем кратчайший путь */
    245.   if (rib_length < short_way) {
    246.   /* Сохраним кратчайший путь */
    247.   strcpy(short_way_point, first_x_way);
    248.   short_way = rib_length;
    249.   }
    250.   }
    251.   j--;
    252.   }
    253.   /* Тут результаты */
    254.   printf("Самый короткий путь: %d \n", short_way);
    255.   printf("Лежит через эти точки: %s \n", short_way_point);
    256.   printf("Все пути: %d \n", all);
    257.   printf("\nСамый долгий путь %d %s !\n", max_rib, max_way);
    258.   printf("Показать все пути меньше  %d ? y/n" , all_shorts_way_to_show);
    259.   scanf(" %c", &enter_press_to_show_all_small_ways);
    260.  
    261.  
    262.   if (enter_press_to_show_all_small_ways == 'y') {
    263.    for (i=0; i < incrx-1; i++)
    264.   printf("Путь: < %d  %s \n", allws_short_lenght[i], allws_short[i]);
    265. } else {
    266.     printf("\nВыходим...!\n");
    267.  
    268. }
    269.  
    270.   printf("Сыграем в игру    ? y/n");
    271.   scanf(" %c", &enter_press_to_show_all_small_ways);
    272.  
    273.   if (enter_press_to_show_all_small_ways == 'y') {
    274.       srand(time(NULL));
    275.       rrandd =  (rand() % incrx-1);
    276.       printf("Какой путь был выбран?! [введи число]");
    277.       scanf(" %d", &play_game);
    278.  
    279.       if (play_game == allws_short_lenght[rrandd]) {
    280.       printf("\nУгадал...!%d %s\n", allws_short_lenght[rrandd], allws_short[rrandd]);
    281.       }
    282.       else {
    283.       printf("\n Не угадал...!%d %s\n", allws_short_lenght[rrandd], allws_short[rrandd]);
    284.        }
    285. } else {
    286.     printf("\nВыходим...!\n");
    287.  
    288. }
    289.  
    290.   return 0;
    291. }
    292.  
    293.  
     
  11. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Ещё немного тестов:
    Код (Text):
    1.  
    2. Ещё немного тестов:
    3. $b=2;
    4. $a=3;
    5. $a = ($a*2)-$b = $b+3;
    6. echo $a;
    7. Ещё немного тестов:
    8. $b=2;
    9. $a=3;
    10. $a = ($a*2)-$b = $b+3;
    11. echo $a;
    12. $b=2; $a=3; $a = ($a*2)-$b = $b+3; echo $a;
    13.  
    14. $b=2; $a=3;
    15.  $a = ($a*2)-$b = $b+3;
    16.  echo $a;
    17.  
    Алиса и deepai считает такой код не правильным (цепочка присвоения).

    Соответственно и такой код для ИИ невернйы (при том, что он корректно работает):

    Код (Text):
    1. <?php
    2. if (isset($_GET['ok'])) {
    3. $x= $_GET['x']*cos(1)-$y=$_GET['y']*sin(1);
    4. $y= $_GET['x']*sin(1)+$y=$_GET['y']*cos(1);
    5. }
    6. ?>
    7.  
    8.  
    9.  
    10.         <style>
    11.             #rotation_martix {
    12.             position: absolute;
    13.             top:  <?=$x+300?>px;
    14.             left: <?=$y+300?>px;
    15.             background-color: #999;
    16.             width: 10px;
    17.             height: 10px;
    18.             }
    19.             </style>
    20.  
    21.  
    22.  
    23. < div id="rotation_martix">
    24. </  div>
    25. <form  method="GET" >
    26. <input type="submit" name="ok" value="ok">
    27. <input type="text" name="x" value="<?=$x?>">
    28. <input type="text" name="y" value="<?=$y?>">
    29. </form>
     
  12. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    deepai сумел написать такое:
    А запрос был (Ты можешь сделать так: вывести карту команты со стенами и игрока. по wsad и enter менять положение игрока на карте, направление его взгляда?)

    Код (C):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <math.h>
    4.  
    5. #define MAP_WIDTH 20
    6. #define MAP_HEIGHT 20
    7.  
    8. int map[MAP_HEIGHT][MAP_WIDTH] = {
    9.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    10.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    11.     {1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1},
    12.     {1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,1},
    13.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1},
    14.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1},
    15.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,1},
    16.     {1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1},
    17.     {1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,0,1},
    18.     {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1},
    19.     {1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1},
    20.     {1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1},
    21.     {1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1},
    22.     {1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1},
    23.     {1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1},
    24.     {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1},
    25.     {1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1},
    26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    27.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    28. };
    29.  
    30. double playerX = 1.5; // начальные координаты
    31. double playerY = 1.5;
    32. double angle = 0.0;   // направление взгляда (в радианах)
    33.  
    34. #define PI 3.14159265358979323846
    35.  
    36. void clear_screen() {
    37.     printf("\033[2J");
    38.     printf("\033[H");
    39. }
    40.  
    41. void draw_map() {
    42.     clear_screen();
    43.     for(int y=0; y<MAP_HEIGHT; y++) {
    44.         for(int x=0; x<MAP_WIDTH; x++) {
    45.             if ((int)playerX == x && (int)playerY == y) {
    46.                 printf("P"); // игрок
    47.             } else if (map[y][x] == 1) {
    48.                 printf("#");
    49.             } else {
    50.                 printf(" ");
    51.             }
    52.         }
    53.         printf("\n");
    54.     }
    55.     printf("Положение: (%.1f, %.1f)  Направление: %.2f градусов\n", playerX, playerY, angle * 180 / PI);
    56.     printf("Команды:\n");
    57.     printf("  w - идти вперед\n");
    58.     printf("  s - идти назад\n");
    59.     printf("  a - повернуть налево\n");
    60.     printf("  d - повернуть направо\n");
    61.     printf("  q - выйти\n");
    62.     printf("Введите команду и нажмите Enter: ");
    63. }
    64.  
    65. int main() {
    66.     char cmd;
    67.     while (1) {
    68.         draw_map();
    69.         scanf(" %c", &cmd);
    70.         if (cmd == 'q') break;
    71.  
    72.         if (cmd == 'w') {
    73.             // идти вперед
    74.             double newX = playerX + cos(angle) * 0.5;
    75.             double newY = playerY + sin(angle) * 0.5;
    76.             if (map[(int)newY][(int)newX] == 0) {
    77.                 playerX = newX;
    78.                 playerY = newY;
    79.             }
    80.         }
    81.         else if (cmd == 's') {
    82.             // идти назад
    83.             double newX = playerX - cos(angle) * 0.5;
    84.             double newY = playerY - sin(angle) * 0.5;
    85.             if (map[(int)newY][(int)newX] == 0) {
    86.                 playerX = newX;
    87.                 playerY = newY;
    88.             }
    89.         }
    90.         else if (cmd == 'a') {
    91.             // повернуть налево
    92.             angle -= PI / 12; // повернуть на 15 градусов
    93.             if (angle < 0) angle += 2 * PI;
    94.         }
    95.         else if (cmd == 'd') {
    96.             // повернуть направо
    97.             angle += PI / 12;
    98.             if (angle > 2*PI) angle -= 2*PI;
    99.         }
    100.     }
    101.     return 0;
    102. }
    --- Сообщение объединено, 4 июл 2026 ---
    deepai.org сделал рейкастинг. Можно сказать игру, я только условие победы добавил (C89).
    Вполне работает:

    Код (C):
    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <math.h>
    4.  
    5. #define MAP_WIDTH 20
    6. #define MAP_HEIGHT 20
    7.  
    8. int map[MAP_HEIGHT][MAP_WIDTH] = {
    9.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    10.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    11.     {1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1},
    12.     {1,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,1,0,1},
    13.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1},
    14.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,0,1},
    15.     {1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,0,1},
    16.     {1,0,0,0,0    ,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    17.     {1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,0,1},
    18.     {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1},
    19.     {1,0,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1},
    20.     {1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1},
    21.     {1,0,1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,0,0,1},
    22.     {1,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1},
    23.     {1,0,1,0,1,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1},
    24.     {1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1},
    25.     {1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,0,1},
    26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    27.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    28. };
    29.  
    30. double playerX = 1.5; // начальные координаты
    31. double playerY = 1.5;
    32. double angle = 0.0;   // направление взгляда (в радианах)
    33.  
    34. #define PI 3.14159265358979323846
    35. #define FIELD_SIZE 10 // Размер области для отображения стены
    36.  
    37. void clear_screen() {
    38.     printf("\033[2J");
    39.     printf("\033[H");
    40. }
    41.  
    42. // Функция для получения расстояния до стены прямо перед игроком
    43. double cast_ray(double ray_angle) {
    44.     double rayX = cos(ray_angle);
    45.     double rayY = sin(ray_angle);
    46.     double rayPosX = playerX;
    47.     double rayPosY = playerY;
    48.  
    49.     while (1) {
    50.         rayPosX += rayX * 0.05;
    51.         rayPosY += rayY * 0.05;
    52.         int mapX = (int)rayPosX;
    53.         int mapY = (int)rayPosY;
    54.         if (mapX < 0 || mapX >= MAP_WIDTH || mapY < 0 || mapY >= MAP_HEIGHT)
    55.             return -1; // за границей
    56.         if (map[mapY][mapX] == 1)
    57.             return sqrt((rayPosX - playerX)*(rayPosX - playerX) + (rayPosY - playerY)*(rayPosY - playerY));
    58.     }
    59. }
    60.  
    61. // Функция для отображения карты и стены
    62. int draw() {
    63.     clear_screen();
    64.  
    65.     // Размер для отображения стены
    66.     int wallLine[FIELD_SIZE];
    67.  
    68.     // Инициализация
    69.     for(int x=0; x<FIELD_SIZE; x++) {
    70.         wallLine[x] = 0; // 0 - ничего, 1 - стена
    71.     }
    72.  
    73.     // Расчет расстояния до стены прямо перед игроком
    74.     double dist = cast_ray(angle);
    75.     int wallPosition = (int)(dist * 2); // масштабирование
    76.     if (wallPosition >= FIELD_SIZE) wallPosition = FIELD_SIZE - 1;
    77.     if (wallPosition < 0) wallPosition = 0;
    78.  
    79.     // Заполняем линию горизонтальной стены
    80.     for(int x=0; x<FIELD_SIZE; x++) {
    81.         wallLine[x] = (x == wallPosition) ? 1 : 0;
    82.     }
    83.  
    84.     // Вывод карты слева
    85.     for(int y=0; y<MAP_HEIGHT; y++) {
    86.         for(int x=0; x<MAP_WIDTH; x++) {
    87.             if ((int)playerX == x && (int)playerY == y) {
    88.                 printf("P");
    89.             } else if (map[y][x] == 1) {
    90.                 printf("#");
    91.             } else {
    92.                 printf(" ");
    93.  
    94.             }
    95.            if (playerX > 7.0 && playerY > 8.9) {
    96.          printf("  Вы прошли игру !\n");
    97.          return 0;
    98.      }
    99.         }
    100.  
    101.         printf("   "); // разделитель
    102.         // Вывод горизонтальной линии справа
    103.         for(int x=0; x<FIELD_SIZE; x++) {
    104.             if (wallLine[x] == 1) {
    105.                 printf("=");
    106.             } else {
    107.                 printf(" ");
    108.             }
    109.         }
    110.         printf("\n");
    111.     }
    112.     printf("Положение: (%.1f, %.1f)  Направление: %.2f градусов\n", playerX, playerY, angle * 180 / PI);
    113.     printf("Команды:\n");
    114.     printf("  w - идти вперед\n");
    115.     printf("  s - идти назад\n");
    116.     printf("  a - повернуть налево\n");
    117.     printf("  d - повернуть направо\n");
    118.     printf("  q - выйти\n");
    119.     printf("Введите команду и нажмите Enter: ");
    120. }
    121.  
    122. int main() {
    123.     char cmd;
    124.     while (1) {
    125.         draw();
    126.         scanf(" %c", &cmd);
    127.         if (cmd == 'q') break;
    128.  
    129.         if (cmd == 'w') {
    130.             double newX = playerX + cos(angle) * 0.5;
    131.             double newY = playerY + sin(angle) * 0.5;
    132.             if (map[(int)newY][(int)newX] == 0) {
    133.                 playerX = newX;
    134.                 playerY = newY;
    135.             }
    136.         }
    137.         else if (cmd == 's') {
    138.             double newX = playerX - cos(angle) * 0.5;
    139.             double newY = playerY - sin(angle) * 0.5;
    140.             if (map[(int)newY][(int)newX] == 0) {
    141.                 playerX = newX;
    142.                 playerY = newY;
    143.             }
    144.         }
    145.         else if (cmd == 'a') {
    146.             angle -= PI / 12;
    147.             if (angle < 0) angle += 2*PI;
    148.         }
    149.         else if (cmd == 'd') {
    150.             angle += PI / 12;
    151.             if (angle > 2*PI) angle -= 2*PI;
    152.         }
    153.     }
    154.     return 0;
    155. }
    156.  
     
    Application нравится это.
  13. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Еще интересного. Полноценный Raycasting 3D на C c использование ncurses. Двигаться на стрелки. Вывод стен псевдографикой.
    Компиляция и запуск gcc -o ray14 ray14.c -lncurses -ltinfo -lm; ./ ray14


    Код (C):
    1. /*Модель 3D Raycasting на C89 с библиотекой ncurses. Написана нейронной сетью.
    2. Стены с помощью символов
    3. Компиляция и запуск gcc -o ray14 ray14.c -lncurses -ltinfo  -lm; ./ ray14
    4. */
    5. #include <ncurses.h>
    6. #include <math.h>
    7. #include <stdlib.h>
    8.  
    9. #define MAP_WIDTH 16
    10. #define MAP_HEIGHT 16
    11. #define FOV (M_PI / 3.0) // 60 градусов
    12. #define MAX_DEPTH 16
    13.  
    14. // Карта: 0 - пусто, 1 - стена
    15. int worldMap[MAP_HEIGHT][MAP_WIDTH] = {
    16.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    17.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    18.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    19.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    20.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    21.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    22.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    23.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    24.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    25.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    27.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    29.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    30. };
    31.  
    32. double playerX = 3.0, playerY = 3.0; // Начальные координаты игрока
    33. double playerAngle = 0.0;
    34.  
    35. void draw(int width, int height) {
    36.     for (int x = 0; x < width; x++) {
    37.         // Вычисляем угол для каждого луча
    38.         double rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)width) * FOV;
    39.         double distanceToWall = 0;
    40.         int hit = 0;
    41.  
    42.         double eyeX = cos(rayAngle);
    43.         double eyeY = sin(rayAngle);
    44.  
    45.         while (!hit && distanceToWall < MAX_DEPTH) {
    46.             distanceToWall += 0.1;
    47.             int testX = (int)(playerX + eyeX * distanceToWall);
    48.             int testY = (int)(playerY + eyeY * distanceToWall);
    49.  
    50.             // Проверка выхода за границы
    51.             if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    52.                 hit = 1;
    53.                 distanceToWall = MAX_DEPTH;
    54.             } else {
    55.                 if (worldMap[testY][testX] == 1) {
    56.                     hit = 1;
    57.                 }
    58.             }
    59.         }
    60.  
    61.         // Рассчитаем высоту стен
    62.         int ceiling = (int)((double)(height / 2.0) - height / distanceToWall);
    63.         int floor = height - ceiling;
    64.  
    65.         for (int y = 0; y < height; y++) {
    66.             if (y < ceiling) {
    67.                 mvaddch(y, x, ' ');
    68.             } else if (y > ceiling && y <= floor) {
    69.                 // Можно добавить тень
    70.                 if (distanceToWall <= MAX_DEPTH / 4.0) {
    71.                     mvaddch(y, x, '#'); // Ближе - темнее
    72.                 } else if (distanceToWall < MAX_DEPTH / 2.0) {
    73.                     mvaddch(y, x, '+');
    74.                 } else {
    75.                     mvaddch(y, x, '.');
    76.                 }
    77.             } else {
    78.                 mvaddch(y, x, ' ');
    79.             }
    80.         }
    81.     }
    82.     refresh();
    83. }
    84.  
    85. int main() {
    86.     initscr();
    87.     noecho();
    88.     curs_set(FALSE);
    89.     keypad(stdscr, TRUE);
    90.     nodelay(stdscr, TRUE); // Не блокировать getch
    91.  
    92.     int width, height;
    93.     getmaxyx(stdscr, height, width);
    94.  
    95.     while (1) {
    96.         // Обработка ввода
    97.         int ch = getch();
    98.         if (ch == 'q') break; // Выход
    99.         if (ch == KEY_UP) {
    100.             // Вперёд
    101.             double newX = playerX + cos(playerAngle) * 0.1;
    102.             double newY = playerY + sin(playerAngle) * 0.1;
    103.             if (worldMap[(int)newY][(int)newX] == 0) {
    104.                 playerX = newX;
    105.                 playerY = newY;
    106.             }
    107.         }
    108.         if (ch == KEY_DOWN) {
    109.             // Назад
    110.             double newX = playerX - cos(playerAngle) * 0.1;
    111.             double newY = playerY - sin(playerAngle) * 0.1;
    112.             if (worldMap[(int)newY][(int)newX] == 0) {
    113.                 playerX = newX;
    114.                 playerY = newY;
    115.             }
    116.         }
    117.         if (ch == KEY_LEFT) {
    118.             playerAngle -= 0.1;
    119.         }
    120.         if (ch == KEY_RIGHT) {
    121.             playerAngle += 0.1;
    122.         }
    123.  
    124.         draw(width, height);
    125.     }
    126.  
    127.     endwin();
    128.     return 0;
    129. }
    130.  
     
  14. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    29 мар 2021
    Сообщения:
    380
     
    dcc0 нравится это.
  15. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Забыл написать. Код выше написала н. сеть deepai.org
     
  16. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    Попросил deepai.org убрать рыбий глаз (получаем полноценный аски 3d в терминале в 130 строк. Код писан для Linux.):



    Код (C):
    1. /*Модель 3D Raycasting на C89 с библиотекой ncurses. Написана нейронной сетью.
    2. Стены с помощью символов
    3. Компиляция и запуск gcc -o ray14 ray14.c -lncurses -ltinfo  -lm; ./ ray14
    4. Убран эффект рыбьего глаза*/
    5. #include <ncurses.h>
    6. #include <math.h>
    7. #include <stdlib.h>
    8.  
    9. #define MAP_WIDTH 16
    10. #define MAP_HEIGHT 16
    11. #define FOV (M_PI / 3.0) // 60 градусов
    12. #define MAX_DEPTH 16
    13.  
    14. // Карта: 0 - пусто, 1 - стена
    15. int worldMap[MAP_HEIGHT][MAP_WIDTH] = {
    16.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    17.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    18.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    19.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    20.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    21.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    22.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    23.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    24.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    25.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    27.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    29.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    30. };
    31.  
    32. double playerX = 3.0, playerY = 3.0; // Начальные координаты игрока
    33. double playerAngle = 0.0;
    34.  
    35. void draw(int width, int height) {
    36.     for (int x = 0; x < width; x++) {
    37.         // Вычисляем угол для каждого луча
    38.         double rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)width) * FOV;
    39.         double distanceToWall = 0;
    40.         int hit = 0;
    41.  
    42.         double eyeX = cos(rayAngle);
    43.         double eyeY = sin(rayAngle);
    44.  
    45.         while (!hit && distanceToWall < MAX_DEPTH) {
    46.             distanceToWall += 0.1;
    47.             int testX = (int)(playerX + eyeX * distanceToWall);
    48.             int testY = (int)(playerY + eyeY * distanceToWall);
    49.  
    50.             // Проверка выхода за границы
    51.             if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    52.                 hit = 1;
    53.                 distanceToWall = MAX_DEPTH;
    54.             } else {
    55.                 if (worldMap[testY][testX] == 1) {
    56.                     hit = 1;
    57.                 }
    58.             }
    59.         }
    60.  
    61.         // new: Корректировка расстояния для устранения эффекта рыбьего глаза (new)
    62.         double angleDifference = rayAngle - playerAngle; // new: расчет разницы углов (new)
    63.         if (angleDifference > M_PI) angleDifference -= 2 * M_PI; // new: приведение к диапазону (-π, π) (new)
    64.         if (angleDifference < -M_PI) angleDifference += 2 * M_PI; // new
    65.  
    66.         distanceToWall = distanceToWall * cos(angleDifference); // new: исправление расстояния (new)
    67.  
    68.         // Рассчитаем высоту стен
    69.         int ceiling = (int)((double)(height / 2.0) - height / distanceToWall);
    70.         int floor = height - ceiling;
    71.  
    72.         for (int y = 0; y < height; y++) {
    73.             if (y < ceiling) {
    74.                 mvaddch(y, x, ' ');
    75.             } else if (y > ceiling && y <= floor) {
    76.                 // Можно добавить тень
    77.                 if (distanceToWall <= MAX_DEPTH / 4.0) {
    78.                     mvaddch(y, x, '#'); // Ближе - темнее
    79.                 } else if (distanceToWall < MAX_DEPTH / 2.0) {
    80.                     mvaddch(y, x, '+');
    81.                 } else {
    82.                     mvaddch(y, x, '.');
    83.                 }
    84.             } else {
    85.                 mvaddch(y, x, ' ');
    86.             }
    87.         }
    88.     }
    89.     refresh();
    90. }
    91. int main() {
    92.     initscr();
    93.     noecho();
    94.     curs_set(FALSE);
    95.     keypad(stdscr, TRUE);
    96.     nodelay(stdscr, TRUE); // Не блокировать getch
    97.  
    98.     int width, height;
    99.     getmaxyx(stdscr, height, width);
    100.  
    101.     while (1) {
    102.         // Обработка ввода
    103.         int ch = getch();
    104.         if (ch == 'q') break; // Выход
    105.         if (ch == KEY_UP) {
    106.             // Вперёд
    107.             double newX = playerX + cos(playerAngle) * 0.1;
    108.             double newY = playerY + sin(playerAngle) * 0.1;
    109.             if (worldMap[(int)newY][(int)newX] == 0) {
    110.                 playerX = newX;
    111.                 playerY = newY;
    112.             }
    113.         }
    114.         if (ch == KEY_DOWN) {
    115.             // Назад
    116.             double newX = playerX - cos(playerAngle) * 0.1;
    117.             double newY = playerY - sin(playerAngle) * 0.1;
    118.             if (worldMap[(int)newY][(int)newX] == 0) {
    119.                 playerX = newX;
    120.                 playerY = newY;
    121.             }
    122.         }
    123.         if (ch == KEY_LEFT) {
    124.             playerAngle -= 0.1;
    125.         }
    126.         if (ch == KEY_RIGHT) {
    127.             playerAngle += 0.1;
    128.         }
    129.  
    130.         draw(width, height);
    131.     }
    132.  
    133.     endwin();
    134.     return 0;
    135. }
    136.  
    --- Сообщение объединено, 5 июл 2026 ---
    Интересно, что код самого raycasting всего строк 50. Т.е. линейная перспектива переводится в дискретную модель за такое количество строк. Но надо отдать должное разработчикам, до этого ещё надо додуматься. И там, где начинаются синусы и косинусы с числом Pi, то там не прям все очевидно. Но все равно относительно просто.
    Вообще для себя замметил пока алгоритм для себя не объяснил, то и понять код довольно сложно. В рейкастинге надо держать в голове, что 1 итерация внешнего цикла - это 1 брошенный луч до одного деления стенки. И основаная задача высчитать расстояние от наблюдателя, а на основе расстояния потом отрисовать его высоту (потолок и пол) и тут уже синусы с косинусами.
    --- Сообщение объединено, 5 июл 2026 ---
    Подоспел вариант с миникартой и направлением взгляда:

    Код (C):
    1. /*Модель 3D Raycasting на C89 с библиотекой ncurses. Написана нейронной сетью.
    2. Стены с помощью символов
    3. Компиляция и запуск gcc -o ray14 ray14.c -lncurses -ltinfo  -lm; ./ray14
    4. Убран эффект рыбьего глаза*/
    5. #include <ncurses.h>
    6. #include <math.h>
    7. #include <stdlib.h>
    8.  
    9. #define MAP_WIDTH 16
    10. #define MAP_HEIGHT 16
    11. #define FOV (M_PI / 3.0) // 60 градусов
    12. #define MAX_DEPTH 16
    13.  
    14. // Карта: 0 - пусто, 1 - стена
    15. int worldMap[MAP_HEIGHT][MAP_WIDTH] = {
    16.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    17.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    18.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    19.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    20.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    21.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    22.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    23.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    24.     {1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1},
    25.     {1,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1},
    26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    27.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    29.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    30. };
    31.  
    32. double playerX = 3.0, playerY = 3.0; // Начальные координаты игрока
    33. double playerAngle = 0.0;
    34.  
    35. // Функция для отрисовки мини-карты
    36. void drawMiniMap(int mapX, int mapY, int mapSize) {
    37.     for (int y = 0; y < MAP_HEIGHT; y++) {
    38.         for (int x = 0; x < MAP_WIDTH; x++) {
    39.             char ch = (worldMap[y][x] == 1) ? '#' : ' ';
    40.             mvaddch(mapY + y, mapX + x, ch);
    41.         }
    42.     }
    43.     // Отметка положения игрока
    44.     mvaddch(mapY + (int)playerY, mapX + (int)playerX, '@');
    45.  
    46.     // Добавляем линию направления взгляда
    47.     double dirX = cos(playerAngle);
    48.     double dirY = sin(playerAngle);
    49.     int lineXEnd = (int)(playerX + dirX * 3);
    50.     int lineYEnd = (int)(playerY + dirY * 3);
    51.  
    52.     // Рисуем линию направления (используем Bresenham или простую)
    53.     int x1 = (int)playerX;
    54.     int y1 = (int)playerY;
    55.     int x2 = lineXEnd;
    56.     int y2 = lineYEnd;
    57.  
    58.     int dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
    59.     int dy = -abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
    60.     int err = dx + dy, e2;
    61.  
    62.     while (1) {
    63.         mvaddch(mapY + y1, mapX + x1, '*'); // или другой символ
    64.         if (x1 == x2 && y1 == y2) break;
    65.         e2 = 2 * err;
    66.         if (e2 >= dy) { err += dy; x1 += sx; }
    67.         if (e2 <= dx) { err += dx; y1 += sy; }
    68.     }
    69. }
    70.  
    71. void draw(int width, int height) {
    72.     for (int x = 0; x < width; x++) {
    73.         // Исправленная строка
    74.         double rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)width) * FOV;
    75.         double distanceToWall = 0;
    76.         int hit = 0;
    77.  
    78.         double eyeX = cos(rayAngle);
    79.         double eyeY = sin(rayAngle);
    80.  
    81.         while (!hit && distanceToWall < MAX_DEPTH) {
    82.             distanceToWall += 0.1;
    83.             int testX = (int)(playerX + eyeX * distanceToWall);
    84.             int testY = (int)(playerY + eyeY * distanceToWall);
    85.  
    86.             if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    87.                 hit = 1;
    88.                 distanceToWall = MAX_DEPTH;
    89.             } else {
    90.                 if (worldMap[testY][testX] == 1) {
    91.                     hit = 1;
    92.                 }
    93.             }
    94.         }
    95.  
    96.         double angleDifference = rayAngle - playerAngle;
    97.         if (angleDifference > M_PI) angleDifference -= 2 * M_PI;
    98.         if (angleDifference < -M_PI) angleDifference += 2 * M_PI;
    99.  
    100.         distanceToWall = distanceToWall * cos(angleDifference);
    101.  
    102.         int ceiling = (int)((double)(height / 2.0) - height / distanceToWall);
    103.         int floor = height - ceiling;
    104.  
    105.         for (int y = 0; y < height; y++) {
    106.             if (y < ceiling) {
    107.                 mvaddch(y, x, ' ');
    108.             } else if (y > ceiling && y <= floor) {
    109.                 if (distanceToWall <= MAX_DEPTH / 4.0) {
    110.                     mvaddch(y, x, '#');
    111.                 } else if (distanceToWall < MAX_DEPTH / 2.0) {
    112.                     mvaddch(y, x, '+');
    113.                 } else {
    114.                     mvaddch(y, x, '.');
    115.                 }
    116.             } else {
    117.                 mvaddch(y, x, ' ');
    118.             }
    119.         }
    120.     }
    121.     refresh();
    122. }
    123.  
    124. int main() {
    125.     initscr();
    126.     noecho();
    127.     curs_set(FALSE);
    128.     keypad(stdscr, TRUE);
    129.     nodelay(stdscr, TRUE);
    130.  
    131.     int width, height;
    132.     getmaxyx(stdscr, height, width);
    133.  
    134.     // Позиция мини-карты в левом нижнем углу
    135.     int miniMapSizeX = 16;
    136.     int miniMapSizeY = 16;
    137.     int miniMapPosX = 1;
    138.     int miniMapPosY = height - miniMapSizeY - 1; // снизу
    139.  
    140.     while (1) {
    141.         int ch = getch();
    142.         if (ch == 'q') break;
    143.         if (ch == KEY_UP) {
    144.             double newX = playerX + cos(playerAngle) * 0.1;
    145.             double newY = playerY + sin(playerAngle) * 0.1;
    146.             if (worldMap[(int)newY][(int)newX] == 0) {
    147.                 playerX = newX;
    148.                 playerY = newY;
    149.             }
    150.         }
    151.         if (ch == KEY_DOWN) {
    152.             double newX = playerX - cos(playerAngle) * 0.1;
    153.             double newY = playerY - sin(playerAngle) * 0.1;
    154.             if (worldMap[(int)newY][(int)newX] == 0) {
    155.                 playerX = newX;
    156.                 playerY = newY;
    157.             }
    158.         }
    159.         if (ch == KEY_LEFT) {
    160.             playerAngle -= 0.1;
    161.         }
    162.         if (ch == KEY_RIGHT) {
    163.             playerAngle += 0.1;
    164.         }
    165.  
    166.         draw(width, height);
    167.         drawMiniMap(miniMapPosX, miniMapPosY, miniMapSizeX);
    168.     }
    169.  
    170.     endwin();
    171.     return 0;
    172. }
    173.  
     
    Application нравится это.
  17. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    На C89 без ncurses.

    Код (C):
    1. /*Модель 3D Raycasting на C(89). Написана нейронной сетью.
    2. Стены с помощью символов
    3. Компиляция и запуск gcc -o ray ray.c   -lm; ./ray
    4. * или gcc -std=c89  -o ray ray.c   -lm; ./ray
    5. Убран эффект рыбьего глаза*/
    6. #include <stdio.h>
    7. #include <math.h>
    8. #include <string.h>
    9.  
    10. /*Размеры карты и экрана*/
    11. #define MAP_WIDTH 16
    12. #define MAP_HEIGHT 16
    13. #define SCREEN_WIDTH 80
    14. #define SCREEN_HEIGHT 24
    15. #define M_PI 3.14159265358979323846
    16. #define FOV (M_PI / 3.0)
    17. #define MAX_DEPTH 16.0
    18.  
    19. /*Карта*/
    20. int worldMap[MAP_HEIGHT][MAP_WIDTH] = {
    21.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    22.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    23.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    24.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    25.     {1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1},
    26.     {1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,1},
    27.     {1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1},
    28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    29.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    30.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    31.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    32.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    33.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    34.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    35.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    36.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    37. };
    38.  
    39. double playerX = 3.0;  /*Начальные координаты игрока*/
    40. double playerY = 3.0;
    41. double playerAngle = 0.0;
    42.  
    43. void draw() {
    44.     int y, x, testX, testY, hit, ceiling, floor;
    45.     double angleDifference;
    46.         double eyeX, eyeY, rayAngle, distanceToWall;
    47.     printf("\033[2J");
    48.     printf("\033[H");
    49.     fflush(stdout);
    50.  
    51.     for (y = 0; y < SCREEN_HEIGHT; y++) {
    52.         for (x = 0; x < SCREEN_WIDTH; x++) {
    53.               /*Вычисляем угол для каждого луча*/
    54.             rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)SCREEN_WIDTH) * FOV;
    55.             distanceToWall = 0.0;
    56.              hit = 0;
    57.  
    58.             eyeX = cos(rayAngle);
    59.             eyeY = sin(rayAngle);
    60.  
    61.             while (!hit && distanceToWall < MAX_DEPTH) {
    62.                 distanceToWall += 0.1;  /* шаг по лучу*/
    63.                  testX = (int)(playerX + eyeX * distanceToWall); /*переменная луча по X*/
    64.                  testY = (int)(playerY + eyeY * distanceToWall); /*по Y*/
    65.  
    66.                 if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    67.                     hit = 1;  /*луч вышел за границы карты, считаем, что столкнулся с границей*/
    68.                     distanceToWall = MAX_DEPTH;
    69.                 } else {
    70.                     if (worldMap[testY][testX] == 1) {
    71.                         hit = 1; /*столкновение со стеной*/
    72.                     }
    73.                 }
    74.             }
    75.  
    76.             /*Корректировка расстояния для устранения эффекта рыбьего глаза*/
    77.              angleDifference = rayAngle - playerAngle;
    78.             if (angleDifference > M_PI) angleDifference -= 2 * M_PI;
    79.             if (angleDifference < -M_PI) angleDifference += 2 * M_PI;
    80.  
    81.             ceiling = (int)((SCREEN_HEIGHT / 2.0) - SCREEN_HEIGHT / distanceToWall);
    82.             floor = SCREEN_HEIGHT - ceiling;
    83.  
    84.             if (y < ceiling) {
    85.                 printf(" "); /*рисуем пробел - небо*/
    86.             } else if (y > ceiling && y <= floor) {
    87.                 if (distanceToWall <= MAX_DEPTH / 4.0) {
    88.                     printf("#"); /*рисуем стены разной жирности*/
    89.                 } else if (distanceToWall < MAX_DEPTH / 2.0) {
    90.                     printf("+");
    91.                 } else {
    92.                     printf(".");
    93.                 }
    94.             } else {
    95.                 printf(" "); /*рисуем пол*/
    96.             }
    97.         }
    98.         printf("\n");
    99.     }
    100. }
    101.  
    102. int main() {
    103.     char command[10];
    104.     double newX,  newY;
    105.     char c;
    106.  
    107.     while (1) {
    108.         draw();
    109.         printf("Введите команду (W/A/S/D для движения, 'exit' для выхода): ");
    110.         if (!fgets(command, sizeof(command), stdin)) break;
    111.  
    112.         if (strncmp(command, "exit", 4) == 0) {
    113.             break; /*Выход из программы*/
    114.         }
    115.  
    116.         c = command[0];
    117.         if (c == 'w' || c == 'W') {
    118.             /*Вперед*/
    119.              newX = playerX + cos(playerAngle) * 0.2;
    120.              newY = playerY + sin(playerAngle) * 0.2;
    121.             if (worldMap[(int)newY][(int)newX] == 0) {
    122.                 playerX = newX;
    123.                 playerY = newY;
    124.             }
    125.         } else if (c == 's' || c == 'S') {
    126.             /*Назад*/
    127.             newX = playerX - cos(playerAngle) * 0.2;
    128.             newY = playerY - sin(playerAngle) * 0.2;
    129.             if (worldMap[(int)newY][(int)newX] == 0) {
    130.                 playerX = newX;
    131.                 playerY = newY;
    132.             }
    133.         } else if (c == 'a' || c == 'A') {
    134.             /*Поворот налево*/
    135.             playerAngle -= 0.1;
    136.         } else if (c == 'd' || c == 'D') {
    137.             /*Поворот направо*/
    138.             playerAngle += 0.1;
    139.         }
    140.     }
    141.     return 0;
    142. }
     
    Application нравится это.
  18. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    29 мар 2021
    Сообщения:
    380
    Имхо. Вынести математику рейкастинга:
    Код (C):
    1.     for (y = 0; y < SCREEN_HEIGHT; y++) {
    2.         for (x = 0; x < SCREEN_WIDTH; x++) {
    3.               /*Вычисляем угол для каждого луча*/
    4.             rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)SCREEN_WIDTH) * FOV;
    5.             distanceToWall = 0.0;
    6.              hit = 0;
    7.             eyeX = cos(rayAngle);
    8.             eyeY = sin(rayAngle);
    9.             while (!hit && distanceToWall < MAX_DEPTH) {
    10.                 distanceToWall += 0.1;  /* шаг по лучу*/
    11.                  testX = (int)(playerX + eyeX * distanceToWall); /*переменная луча по X*/
    12.                  testY = (int)(playerY + eyeY * distanceToWall); /*по Y*/
    13.                 if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    14.                     hit = 1;  /*луч вышел за границы карты, считаем, что столкнулся с границей*/
    15.                     distanceToWall = MAX_DEPTH;
    16.                 } else {
    17.                     if (worldMap[testY][testX] == 1) {
    18.                         hit = 1; /*столкновение со стеной*/
    19.                     }
    20.                 }
    21.             }
    22.             /*Корректировка расстояния для устранения эффекта рыбьего глаза*/
    23.              angleDifference = rayAngle - playerAngle;
    24.             if (angleDifference > M_PI) angleDifference -= 2 * M_PI;
    25.             if (angleDifference < -M_PI) angleDifference += 2 * M_PI;
    26.  
    И отрисовку:
    Код (Text):
    1.                 printf(" "); /*рисуем пробел - небо*/
    2.             } else if (y > ceiling && y <= floor) {
    3.                 if (distanceToWall <= MAX_DEPTH / 4.0) {
    4.                     printf("#"); /*рисуем стены разной жирности*/
    5.                 } else if (distanceToWall < MAX_DEPTH / 2.0) {
    6.                     printf("+");
    7.                 } else {
    8.                     printf(".");
    9.                 }
    10.             } else {
    11.                 printf(" "); /*рисуем пол*/
    В 2 отдельные функции.
    --- Сообщение объединено, 6 июл 2026 ---
    Код (C):
    1. /*Модель 3D Raycasting на C(89). Написана нейронной сетью.
    2. Стены с помощью символов
    3. Компиляция и запуск gcc -o ray ray.c   -lm; ./ray
    4. * или gcc -std=c89  -o ray ray.c   -lm; ./ray
    5. Убран эффект рыбьего глаза*/
    6. #include <stdio.h>
    7. #include <math.h>
    8. #include <string.h>
    9.  
    10. /*Размеры карты и экрана*/
    11. #define MAP_WIDTH 16
    12. #define MAP_HEIGHT 16
    13. #define SCREEN_WIDTH 80
    14. #define SCREEN_HEIGHT 24
    15. #define M_PI 3.14159265358979323846
    16. #define FOV (M_PI / 3.0)
    17. #define MAX_DEPTH 16.0
    18.  
    19. /*Карта*/
    20. int worldMap[MAP_HEIGHT][MAP_WIDTH] = {
    21.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
    22.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    23.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    24.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    25.     {1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1},
    26.     {1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,1},
    27.     {1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1},
    28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    29.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    30.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    31.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    32.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    33.     {1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1},
    34.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    35.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    36.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    37. };
    38.  
    39. double playerX = 3.0;  /*Начальные координаты игрока*/
    40. double playerY = 3.0;
    41. double playerAngle = 0.0;
    42.  
    43. /* Функция для вычисления расстояния до стены по лучу */
    44. double castRay(double rayAngle) {
    45.     double distanceToWall = 0.0;
    46.     int hit = 0;
    47.     double eyeX, eyeY;
    48.     int testX, testY;
    49.  
    50.     eyeX = cos(rayAngle);
    51.     eyeY = sin(rayAngle);
    52.  
    53.     while (!hit && distanceToWall < MAX_DEPTH) {
    54.         distanceToWall += 0.1;  /* шаг по лучу */
    55.         testX = (int)(playerX + eyeX * distanceToWall); /* переменная луча по X */
    56.         testY = (int)(playerY + eyeY * distanceToWall); /* по Y */
    57.  
    58.         if (testX < 0 || testX >= MAP_WIDTH || testY < 0 || testY >= MAP_HEIGHT) {
    59.             hit = 1;  /* луч вышел за границы карты, считаем, что столкнулся с границей */
    60.             distanceToWall = MAX_DEPTH;
    61.         } else {
    62.             if (worldMap[testY][testX] == 1) {
    63.                 hit = 1; /* столкновение со стеной */
    64.             }
    65.         }
    66.     }
    67.  
    68.     return distanceToWall;
    69. }
    70.  
    71. /* Функция для коррекции расстояния (устранение эффекта рыбьего глаза) */
    72. double correctDistance(double rayAngle, double distanceToWall) {
    73.     double angleDifference = rayAngle - playerAngle;
    74.  
    75.     if (angleDifference > M_PI) angleDifference -= 2 * M_PI;
    76.     if (angleDifference < -M_PI) angleDifference += 2 * M_PI;
    77.  
    78.     return distanceToWall * cos(angleDifference);
    79. }
    80.  
    81. /* Функция для отрисовки одного пикселя (символа) */
    82. void drawPixel(int y, int x, double correctedDistance, int ceiling) {
    83.     int floor = SCREEN_HEIGHT - ceiling;
    84.  
    85.     if (y < ceiling) {
    86.         printf(" "); /* рисуем пробел - небо */
    87.     } else if (y > ceiling && y <= floor) {
    88.         if (correctedDistance <= MAX_DEPTH / 4.0) {
    89.             printf("#"); /* рисуем стены разной жирности */
    90.         } else if (correctedDistance < MAX_DEPTH / 2.0) {
    91.             printf("+");
    92.         } else {
    93.             printf(".");
    94.         }
    95.     } else {
    96.         printf(" "); /* рисуем пол */
    97.     }
    98. }
    99.  
    100. /* Функция для отрисовки всей сцены */
    101. void renderScene() {
    102.     int y, x;
    103.     double rayAngle, distanceToWall, correctedDistance;
    104.     int ceiling;
    105.  
    106.     printf("\033[2J");
    107.     printf("\033[H");
    108.     fflush(stdout);
    109.  
    110.     for (y = 0; y < SCREEN_HEIGHT; y++) {
    111.         for (x = 0; x < SCREEN_WIDTH; x++) {
    112.             /* Вычисляем угол для каждого луча */
    113.             rayAngle = (playerAngle - FOV / 2.0) + ((double)x / (double)SCREEN_WIDTH) * FOV;
    114.  
    115.             /* Получаем расстояние до стены */
    116.             distanceToWall = castRay(rayAngle);
    117.  
    118.             /* Корректируем расстояние для устранения эффекта рыбьего глаза */
    119.             correctedDistance = correctDistance(rayAngle, distanceToWall);
    120.  
    121.             /* Вычисляем высоту потолка */
    122.             ceiling = (int)((SCREEN_HEIGHT / 2.0) - SCREEN_HEIGHT / correctedDistance);
    123.  
    124.             /* Отрисовываем пиксель */
    125.             drawPixel(y, x, correctedDistance, ceiling);
    126.         }
    127.         printf("\n");
    128.     }
    129. }
    130.  
    131. int main() {
    132.     char command[10];
    133.     double newX, newY;
    134.     char c;
    135.  
    136.     while (1) {
    137.         renderScene();
    138.         printf("Введите команду (W/A/S/D для движения, 'exit' для выхода): ");
    139.         if (!fgets(command, sizeof(command), stdin)) break;
    140.  
    141.         if (strncmp(command, "exit", 4) == 0) {
    142.             break; /* Выход из программы */
    143.         }
    144.  
    145.         c = command[0];
    146.         if (c == 'w' || c == 'W') {
    147.             /* Вперед */
    148.             newX = playerX + cos(playerAngle) * 0.2;
    149.             newY = playerY + sin(playerAngle) * 0.2;
    150.             if (worldMap[(int)newY][(int)newX] == 0) {
    151.                 playerX = newX;
    152.                 playerY = newY;
    153.             }
    154.         } else if (c == 's' || c == 'S') {
    155.             /* Назад */
    156.             newX = playerX - cos(playerAngle) * 0.2;
    157.             newY = playerY - sin(playerAngle) * 0.2;
    158.             if (worldMap[(int)newY][(int)newX] == 0) {
    159.                 playerX = newX;
    160.                 playerY = newY;
    161.             }
    162.         } else if (c == 'a' || c == 'A') {
    163.             /* Поворот налево */
    164.             playerAngle -= 0.1;
    165.         } else if (c == 'd' || c == 'D') {
    166.             /* Поворот направо */
    167.             playerAngle += 0.1;
    168.         }
    169.     }
    170.     return 0;
    171. }
    172.  
    --- Сообщение объединено, 6 июл 2026 ---
    Можно сделать в отдельной функции обработку ввода:
    Код (C):
    1.  
    2. int playerInput(char *command) {
    3.     double newX, newY;
    4.     char c;
    5.    
    6.     printf("Введите команду (W/A/S/D для движения, 'exit' для выхода): ");
    7.     if (!fgets(command, sizeof(command), stdin)) {
    8.         return 0; /* Ошибка ввода */
    9.     }
    10.    
    11.     if (strncmp(command, "exit", 4) == 0) {
    12.         return 0; /* Выход из программы */
    13.     }
    14.    
    15.     c = command[0];
    16.     if (c == 'w' || c == 'W') {
    17.         /* Вперед */
    18.         newX = playerX + cos(playerAngle) * 0.2;
    19.         newY = playerY + sin(playerAngle) * 0.2;
    20.         if (worldMap[(int)newY][(int)newX] == 0) {
    21.             playerX = newX;
    22.             playerY = newY;
    23.         }
    24.     } else if (c == 's' || c == 'S') {
    25.         /* Назад */
    26.         newX = playerX - cos(playerAngle) * 0.2;
    27.         newY = playerY - sin(playerAngle) * 0.2;
    28.         if (worldMap[(int)newY][(int)newX] == 0) {
    29.             playerX = newX;
    30.             playerY = newY;
    31.         }
    32.     } else if (c == 'a' || c == 'A') {
    33.         /* Поворот налево */
    34.         playerAngle -= 0.1;
    35.     } else if (c == 'd' || c == 'D') {
    36.         /* Поворот направо */
    37.         playerAngle += 0.1;
    38.     } else {
    39.         /* Неизвестная команда */
    40.         printf("Неизвестная команда. Используйте W/A/S/D или 'exit'\n");
    41.     }
    42.    
    43.     return 1; /* Продолжение работы */
    44. }
    --- Сообщение объединено, 6 июл 2026 ---
    Точнее так:
    Код (C):
    1.  
    2. int playerInput() {
    3.     double newX, newY;
    4.     char c;
    5.     char command[10];
    6.     printf("Введите команду (W/A/S/D для движения, 'exit' для выхода): ");
    7.     if (!fgets(command, sizeof(command), stdin)) {
    8.         return 0; /* Ошибка ввода */
    9.     }
    10.     if (strncmp(command, "exit", 4) == 0) {
    11.         return 0; /* Выход из программы */
    12.     }
    13.     c = command[0];
    14.     if (c == 'w' || c == 'W') {
    15.         /* Вперед */
    16.         newX = playerX + cos(playerAngle) * 0.2;
    17.         newY = playerY + sin(playerAngle) * 0.2;
    18.         if (worldMap[(int)newY][(int)newX] == 0) {
    19.             playerX = newX;
    20.             playerY = newY;
    21.         }
    22.     } else if (c == 's' || c == 'S') {
    23.         /* Назад */
    24.         newX = playerX - cos(playerAngle) * 0.2;
    25.         newY = playerY - sin(playerAngle) * 0.2;
    26.         if (worldMap[(int)newY][(int)newX] == 0) {
    27.             playerX = newX;
    28.             playerY = newY;
    29.         }
    30.     } else if (c == 'a' || c == 'A') {
    31.         /* Поворот налево */
    32.         playerAngle -= 0.1;
    33.     } else if (c == 'd' || c == 'D') {
    34.         /* Поворот направо */
    35.         playerAngle += 0.1;
    36.     } else {
    37.         /* Неизвестная команда */
    38.         printf("Неизвестная команда. Используйте W/A/S/D или 'exit'\n");
    39.     }
    40.     return 1; /* Продолжение работы */
    41. }
    42.  
    43.  
    Код (C):
    1.  
    2. int main() {
    3.     while (1) {
    4.         renderScene();
    5.         if (!playerInput()) {
    6.             break;
    7.         }
    8.     }
    9.     return 0;
    10. }
    11.  
    12.  
     
    dcc0 нравится это.
  19. dcc0

    dcc0 Active Member

    Публикаций:
    2
    Регистрация:
    22 дек 2022
    Сообщения:
    136
    who_know777, в общем во варианте с ncurses математика в двух циклах, а вывод отдельно, но в той же функции. А без ncurses сеть обернула математику ещё одним циклом for.
    А там, где вывод, цикл убрала. Т.е. перенесла цикл наверх.

    Да. Можно все поделить на функции. Я, правда, искал способ сделать код таким, чтобы был виден весь алгоритм как бы целиком. Без лишнего. В выводе и тень можно убрать. И прокомментировать математику.

    P.S.
    Мне кажется, даже, что рейкастинг руками бы я не написал или писал бы долго и криво. Уж очень много мелочей, которые влияют на корректность и, скажем так, на визуальный эффект. В косинусах и синусах можно запутаться. Одно понятно: алгоритм рисует символы по столбцам по всей ширине видимой области. Пропускает потолок - пробел. И до пола, который не трогает, понятно, что высота столбцов зависит от расстояния до них.
    Для разбора алгоритма (не кода) нужен, конечно, максимально сокращённый код..
     
    Последнее редактирование: 6 июл 2026
  20. Application

    Application Active Member

    Публикаций:
    1
    Регистрация:
    29 мар 2021
    Сообщения:
    380
    dcc0, если делать графику, надо по таймеру делать перерисовку.

    2026-07-06_16-30-36.png

    Если долго вглядываться в бездну то бездна начинает смотреть в тебя (в этой версии именно так).
    Код (Pascal):
    1. program Raycaster;
    2.  
    3. {$APPTYPE GUI}
    4.  
    5. uses
    6.   Windows, Messages, SysUtils, Math;
    7.  
    8. const
    9.   ID_TIMER = 1;
    10.   TIMER_INTERVAL = 30;
    11.  
    12.   MAP_WIDTH = 16;
    13.   MAP_HEIGHT = 16;
    14.   WINDOW_WIDTH = 800;
    15.   WINDOW_HEIGHT = 600;
    16.   FOV = Pi / 3.0;
    17.   MAX_DEPTH = 16.0;
    18.   MOVE_SPEED = 0.1;
    19.   ROTATE_SPEED = 0.05;
    20.  
    21. const
    22.   VK_W = 87;
    23.   VK_A = 65;
    24.   VK_S = 83;
    25.   VK_D = 68;
    26.  
    27. const
    28.   worldMap: array[0..MAP_HEIGHT-1, 0..MAP_WIDTH-1] of Integer = (
    29.     (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1),
    30.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    31.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    32.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    33.     (1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1),
    34.     (1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1),
    35.     (1,0,0,0,1,1,1,0,0,1,1,1,0,0,0,1),
    36.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    37.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    38.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    39.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    40.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    41.     (1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1),
    42.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    43.     (1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1),
    44.     (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
    45.   );
    46.  
    47. type
    48.   TPlayerState = record
    49.     X, Y, Angle: Double;
    50.   end;
    51.  
    52.   TInputState = record
    53.     W, A, S, D: Boolean;
    54.   end;
    55.  
    56.   TGameGraphics = record
    57.     hWnd: HWND;
    58.     Width: Integer;
    59.     Height: Integer;
    60.     hBuffer: HDC;
    61.     hBitmap: HBITMAP;
    62.     hOldBitmap: HBITMAP;
    63.   end;
    64.  
    65. var
    66.   Running: Boolean;
    67.   Graphics: TGameGraphics;
    68.   InputState: TInputState;
    69.   PlayerState: TPlayerState;
    70.  
    71. // ============================================
    72. // ФУНКЦИИ РИСОВАНИЯ
    73. // ============================================
    74.  
    75. procedure DrawRect(hDC: HDC; X, Y, W, H: Integer; Color: COLORREF);
    76. var
    77.   Brush: HBRUSH;
    78. begin
    79.   Brush := CreateSolidBrush(Color);
    80.   SelectObject(hDC, Brush);
    81.   Rectangle(hDC, X, Y, X + W, Y + H);
    82.   DeleteObject(Brush);
    83. end;
    84.  
    85. // ============================================
    86. // ВЫВОД ТЕКСТА
    87. // ============================================
    88.  
    89. procedure DrawText(hDC: HDC; X, Y: Integer; const Text: string; Color: COLORREF);
    90. var
    91.   OldColor: COLORREF;
    92.   OldBkMode: Integer;
    93. begin
    94.   OldColor := SetTextColor(hDC, Color);
    95.   OldBkMode := SetBkMode(hDC, TRANSPARENT);
    96.  
    97.   TextOut(hDC, X, Y, PChar(Text), Length(Text));
    98.  
    99.   SetBkMode(hDC, OldBkMode);
    100.   SetTextColor(hDC, OldColor);
    101. end;
    102.  
    103. // ============================================
    104. // ФУНКЦИЯ РИСОВАНИЯ ПРИЦЕЛА
    105. // ============================================
    106.  
    107. procedure DrawCrosshair(hDC: HDC; Width, Height: Integer);
    108. var
    109.   CenterX, CenterY: Integer;
    110.   LineLength, Gap, Thickness: Integer;
    111.   Pen: HPEN;
    112.   OldPen: HPEN;
    113. begin
    114.   CenterX := Width div 2;
    115.   CenterY := Height div 2;
    116.  
    117.   // Адаптивный размер прицела в зависимости от размера окна
    118.   LineLength := 6;
    119.  
    120.   Thickness := 2;
    121.   Gap := 3;
    122.  
    123.   // Создаем зеленое перо
    124.   Pen := CreatePen(PS_SOLID, Thickness, RGB(0, 255, 0));
    125.   OldPen := SelectObject(hDC, Pen);
    126.  
    127.   // Верхняя линия
    128.   MoveToEx(hDC, CenterX, CenterY - Gap, nil);
    129.   LineTo(hDC, CenterX, CenterY - Gap - LineLength);
    130.  
    131.   // Нижняя линия
    132.   MoveToEx(hDC, CenterX, CenterY + Gap, nil);
    133.   LineTo(hDC, CenterX, CenterY + Gap + LineLength);
    134.  
    135.   // Левая линия
    136.   MoveToEx(hDC, CenterX - Gap, CenterY, nil);
    137.   LineTo(hDC, CenterX - Gap - LineLength, CenterY);
    138.  
    139.   // Правая линия
    140.   MoveToEx(hDC, CenterX + Gap, CenterY, nil);
    141.   LineTo(hDC, CenterX + Gap + LineLength, CenterY);
    142.  
    143.   // Восстанавливаем старые объекты
    144.   SelectObject(hDC, OldPen);
    145.   DeleteObject(Pen);
    146. end;
    147.  
    148. // ============================================
    149. // ФУНКЦИЯ ВЫВОДА HUD
    150. // ============================================
    151.  
    152. procedure DrawHUD(hDC: HDC; Width, Height: Integer);
    153. var
    154.   InfoText: string;
    155. begin
    156.   // Рисуем прицел
    157.   DrawCrosshair(hDC, Width, Height);
    158.  
    159.   // Координаты (внизу слева)
    160.   InfoText := Format('X: %.2f  Y: %.2f', [PlayerState.X, PlayerState.Y]);
    161.   DrawText(hDC, 10, Height - 70, InfoText, RGB(0, 255, 0));
    162.  
    163.   // Угол (вверху справа)
    164.   InfoText := Format('Angle: %.2f deg', [PlayerState.Angle * 180 / Pi]);
    165.   DrawText(hDC, Width - 150, 10, InfoText, RGB(0, 255, 0));
    166.  
    167.   // Управление (внизу слева)
    168.   DrawText(hDC, 10, Height - 90, 'W/A/S/D - движение, Q - выход', RGB(0, 255, 0));
    169. end;
    170.  
    171. // ============================================
    172. // ПЕРЕСОЗДАНИЕ БУФЕРА ПРИ ИЗМЕНЕНИИ РАЗМЕРА
    173. // ============================================
    174.  
    175. procedure RecreateBuffer(var G: TGameGraphics);
    176. var
    177.   hdcWin: HDC;
    178. begin
    179.   if G.hBitmap <> 0 then
    180.   begin
    181.     SelectObject(G.hBuffer, G.hOldBitmap);
    182.     DeleteObject(G.hBitmap);
    183.     G.hBitmap := 0;
    184.   end;
    185.  
    186.   if G.hBuffer = 0 then
    187.   begin
    188.     G.hBuffer := CreateCompatibleDC(0);
    189.   end;
    190.  
    191.   hdcWin := GetDC(G.hWnd);
    192.   G.hBitmap := CreateCompatibleBitmap(hdcWin, G.Width, G.Height);
    193.   G.hOldBitmap := SelectObject(G.hBuffer, G.hBitmap);
    194.   ReleaseDC(G.hWnd, hdcWin);
    195. end;
    196.  
    197. // ============================================
    198. // ИНИЦИАЛИЗАЦИЯ ГРАФИКИ
    199. // ============================================
    200.  
    201. procedure InitGraphics(var G: TGameGraphics);
    202. begin
    203.   FillChar(G, SizeOf(G), 0);
    204.  
    205.   G.Width := WINDOW_WIDTH;
    206.   G.Height := WINDOW_HEIGHT;
    207.  
    208.   RecreateBuffer(G);
    209. end;
    210.  
    211. // ============================================
    212. // ИНИЦИАЛИЗАЦИЯ ИГРЫ
    213. // ============================================
    214.  
    215. procedure InitGame;
    216. begin
    217.   PlayerState.X := 3.0;
    218.   PlayerState.Y := 4.0;
    219.   PlayerState.Angle := 0.0;
    220.   FillChar(InputState, SizeOf(InputState), 0);
    221. end;
    222.  
    223. // ============================================
    224. // ПРОВЕРКА СТОЛКНОВЕНИЙ
    225. // ============================================
    226.  
    227. function CanMove(X, Y: Double): Boolean;
    228. var
    229.   MapX, MapY: Integer;
    230. begin
    231.   Result := False;
    232.   MapX := Trunc(X);
    233.   MapY := Trunc(Y);
    234.  
    235.   if (MapX >= 0) and (MapX < MAP_WIDTH) and
    236.      (MapY >= 0) and (MapY < MAP_HEIGHT) then
    237.   begin
    238.     if worldMap[MapY, MapX] = 0 then
    239.       Result := True;
    240.   end;
    241. end;
    242.  
    243. // ============================================
    244. // ОБНОВЛЕНИЕ ИГРОКА
    245. // ============================================
    246.  
    247. procedure UpdatePlayer;
    248. var
    249.   NewX, NewY: Double;
    250. begin
    251.   if InputState.W then
    252.   begin
    253.     NewX := PlayerState.X + Cos(PlayerState.Angle) * MOVE_SPEED;
    254.     NewY := PlayerState.Y + Sin(PlayerState.Angle) * MOVE_SPEED;
    255.     if CanMove(NewX, NewY) then
    256.     begin
    257.       PlayerState.X := NewX;
    258.       PlayerState.Y := NewY;
    259.     end;
    260.   end;
    261.  
    262.   if InputState.S then
    263.   begin
    264.     NewX := PlayerState.X - Cos(PlayerState.Angle) * MOVE_SPEED;
    265.     NewY := PlayerState.Y - Sin(PlayerState.Angle) * MOVE_SPEED;
    266.     if CanMove(NewX, NewY) then
    267.     begin
    268.       PlayerState.X := NewX;
    269.       PlayerState.Y := NewY;
    270.     end;
    271.   end;
    272.  
    273.   if InputState.A then
    274.     PlayerState.Angle := PlayerState.Angle - ROTATE_SPEED;
    275.  
    276.   if InputState.D then
    277.     PlayerState.Angle := PlayerState.Angle + ROTATE_SPEED;
    278. end;
    279.  
    280. // ============================================
    281. // ФУНКЦИИ РЕЙКАСТИНГА
    282. // ============================================
    283.  
    284. function CastRay(RayAngle: Double): Double;
    285. var
    286.   Distance: Double;
    287.   Hit: Boolean;
    288.   EyeX, EyeY: Double;
    289.   TestX, TestY: Integer;
    290. begin
    291.   Distance := 0;
    292.   Hit := False;
    293.  
    294.   EyeX := Cos(RayAngle);
    295.   EyeY := Sin(RayAngle);
    296.  
    297.   while (not Hit) and (Distance < MAX_DEPTH) do
    298.   begin
    299.     Distance := Distance + 0.1;
    300.     TestX := Trunc(PlayerState.X + EyeX * Distance);
    301.     TestY := Trunc(PlayerState.Y + EyeY * Distance);
    302.  
    303.     if (TestX < 0) or (TestX >= MAP_WIDTH) or
    304.        (TestY < 0) or (TestY >= MAP_HEIGHT) then
    305.     begin
    306.       Hit := True;
    307.       Distance := MAX_DEPTH;
    308.     end
    309.     else if worldMap[TestY, TestX] = 1 then
    310.       Hit := True;
    311.   end;
    312.  
    313.   Result := Distance;
    314. end;
    315.  
    316. function CorrectDistance(RayAngle, Distance: Double): Double;
    317. var
    318.   AngleDiff: Double;
    319. begin
    320.   AngleDiff := RayAngle - PlayerState.Angle;
    321.   if AngleDiff > Pi then AngleDiff := AngleDiff - 2 * Pi;
    322.   if AngleDiff < -Pi then AngleDiff := AngleDiff + 2 * Pi;
    323.   Result := Distance * Cos(AngleDiff);
    324. end;
    325.  
    326. function GetWallColor(Distance: Double): COLORREF;
    327. var
    328.   Brightness: Double;
    329.   Gray: Integer;
    330. begin
    331.   if Distance <= 0 then Distance := 0.1;
    332.  
    333.   Brightness := 1.0 - (Distance / MAX_DEPTH);
    334.   if Brightness < 0.1 then Brightness := 0.1;
    335.  
    336.   Gray := Trunc(200 * Brightness);
    337.   Result := RGB(Gray, Gray, Gray);
    338. end;
    339.  
    340. // ============================================
    341. // РЕНДЕРИНГ
    342. // ============================================
    343.  
    344. procedure RenderScene(const G: TGameGraphics);
    345. var
    346.   DC: HDC;
    347.   x: Integer;  
    348.   HalfHeight: Integer;
    349.   Ceiling, Floor: Integer;
    350.   RayAngle, Distance, CorrectedDist: Double;
    351.   WallColor: COLORREF;
    352.   Pen: HPEN;
    353.   OldPen: HPEN;
    354. begin
    355.   DC := G.hBuffer;
    356.   HalfHeight := G.Height div 2;
    357.  
    358.   // Очистка экрана
    359.   DrawRect(DC, 0, 0, G.Width, G.Height, RGB(0, 0, 0));
    360.  
    361.   // Рендеринг стен
    362.   for x := 0 to G.Width - 1 do
    363.   begin
    364.     RayAngle := (PlayerState.Angle - FOV / 2.0) + (x / G.Width) * FOV;
    365.     Distance := CastRay(RayAngle);
    366.     CorrectedDist := CorrectDistance(RayAngle, Distance);
    367.  
    368.     if CorrectedDist > 0.1 then
    369.     begin
    370.       Ceiling := Trunc(HalfHeight - HalfHeight / CorrectedDist);
    371.       Floor := G.Height - Ceiling;
    372.    
    373.       if Ceiling < 0 then Ceiling := 0;
    374.       if Floor > G.Height then Floor := G.Height;
    375.    
    376.       WallColor := GetWallColor(CorrectedDist);
    377.    
    378.       if Ceiling < Floor then
    379.       begin
    380.         Pen := CreatePen(PS_SOLID, 1, WallColor);
    381.         OldPen := SelectObject(DC, Pen);
    382.      
    383.         MoveToEx(DC, x, Ceiling, nil);
    384.         LineTo(DC, x, Floor);
    385.      
    386.         SelectObject(DC, OldPen);
    387.         DeleteObject(Pen);
    388.       end;
    389.     end;
    390.   end;
    391.  
    392.   // Рисуем HUD (прицел + координаты)
    393.   DrawHUD(DC, G.Width, G.Height);
    394. end;
    395.  
    396. // ============================================
    397. // ОСВОБОЖДЕНИЕ РЕСУРСОВ
    398. // ============================================
    399.  
    400. procedure FreeGraphics(var G: TGameGraphics);
    401. begin
    402.   if G.hBitmap <> 0 then
    403.   begin
    404.     SelectObject(G.hBuffer, G.hOldBitmap);
    405.     DeleteObject(G.hBitmap);
    406.     G.hBitmap := 0;
    407.   end;
    408.   if G.hBuffer <> 0 then
    409.   begin
    410.     DeleteDC(G.hBuffer);
    411.     G.hBuffer := 0;
    412.   end;
    413. end;
    414.  
    415. // ============================================
    416. // ОБРАБОТЧИК ОКНА
    417. // ============================================
    418.  
    419. function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
    420. var
    421.   DC: HDC;
    422.   PS: TPaintStruct;
    423.   NewWidth, NewHeight: Integer;
    424. begin
    425.   case Msg of
    426.     WM_CREATE:
    427.       begin
    428.         Graphics.hWnd := hWnd;
    429.         InitGame;
    430.         InitGraphics(Graphics);
    431.         SetTimer(hWnd, ID_TIMER, TIMER_INTERVAL, nil);
    432.         Result := 0;
    433.       end;
    434.    
    435.     WM_TIMER:
    436.       begin
    437.         if wParam = ID_TIMER then
    438.         begin
    439.           UpdatePlayer;
    440.           InvalidateRect(hWnd, nil, False);
    441.         end;
    442.         Result := 0;
    443.       end;
    444.    
    445.     WM_PAINT:
    446.       begin
    447.         DC := BeginPaint(hWnd, PS);
    448.         RenderScene(Graphics);
    449.         BitBlt(DC, 0, 0, Graphics.Width, Graphics.Height,
    450.                Graphics.hBuffer, 0, 0, SRCCOPY);
    451.         EndPaint(hWnd, PS);
    452.         Result := 0;
    453.       end;
    454.    
    455.     WM_SIZE:
    456.       begin
    457.         // Получаем новый размер окна
    458.         NewWidth := LOWORD(lParam);
    459.         NewHeight := HIWORD(lParam);
    460.      
    461.         // Обновляем размеры в структуре
    462.         if (NewWidth > 0) and (NewHeight > 0) then
    463.         begin
    464.           Graphics.Width := NewWidth;
    465.           Graphics.Height := NewHeight;
    466.        
    467.           // Пересоздаем буфер под новый размер
    468.           RecreateBuffer(Graphics);
    469.        
    470.           // Перерисовываем окно
    471.           InvalidateRect(hWnd, nil, False);
    472.         end;
    473.         Result := 0;
    474.       end;
    475.    
    476.     WM_GETMINMAXINFO:
    477.       begin
    478.         // Ограничиваем минимальный размер окна
    479.         PMinMaxInfo(lParam)^.ptMinTrackSize.X := 400;
    480.         PMinMaxInfo(lParam)^.ptMinTrackSize.Y := 300;
    481.         Result := 0;
    482.       end;
    483.    
    484.     WM_KEYDOWN:
    485.       begin
    486.         case wParam of
    487.           VK_W: InputState.W := True;
    488.           VK_A: InputState.A := True;
    489.           VK_S: InputState.S := True;
    490.           VK_D: InputState.D := True;
    491.           Ord('Q'), Ord('q'):
    492.             begin
    493.               Running := False;
    494.               PostQuitMessage(0);
    495.             end;
    496.         end;
    497.         Result := 0;
    498.       end;
    499.    
    500.     WM_KEYUP:
    501.       begin
    502.         case wParam of
    503.           VK_W: InputState.W := False;
    504.           VK_A: InputState.A := False;
    505.           VK_S: InputState.S := False;
    506.           VK_D: InputState.D := False;
    507.         end;
    508.         Result := 0;
    509.       end;
    510.    
    511.     WM_DESTROY:
    512.       begin
    513.         KillTimer(hWnd, ID_TIMER);
    514.         FreeGraphics(Graphics);
    515.         PostQuitMessage(0);
    516.         Result := 0;
    517.       end;
    518.    
    519.   else
    520.     Result := DefWindowProc(hWnd, Msg, wParam, lParam);
    521.   end;
    522. end;
    523.  
    524. // ============================================
    525. // ГЛАВНАЯ ПРОГРАММА
    526. // ============================================
    527.  
    528. var
    529.   Msg: TMsg;
    530.   wc: TWndClass;
    531. begin
    532.   FillChar(wc, SizeOf(wc), 0);
    533.   wc.style := CS_HREDRAW or CS_VREDRAW;
    534.   wc.lpfnWndProc := @WndProc;
    535.   wc.hInstance := HInstance;
    536.   wc.hbrBackground := GetStockObject(BLACK_BRUSH);
    537.   wc.lpszClassName := 'RaycasterClass';
    538.   RegisterClass(wc);
    539.  
    540.   Graphics.hWnd := CreateWindow('RaycasterClass', '3D Raycaster - CS 1.6 Crosshair',
    541.     WS_OVERLAPPEDWINDOW or WS_VISIBLE,
    542.     (GetSystemMetrics(SM_CXSCREEN) - WINDOW_WIDTH) div 2,
    543.     (GetSystemMetrics(SM_CYSCREEN) - WINDOW_HEIGHT) div 2,
    544.     WINDOW_WIDTH, WINDOW_HEIGHT,
    545.     0, 0, HInstance, nil);
    546.  
    547.   Running := True;
    548.   InitGraphics(Graphics);
    549.  
    550.   while GetMessage(Msg, 0, 0, 0) do
    551.   begin
    552.     TranslateMessage(Msg);
    553.     DispatchMessage(Msg);
    554.   end;
    555. end.
     

    Вложения:

    • 3d_game.rar
      Размер файла:
      24,7 КБ
      Просмотров:
      56
    Последнее редактирование модератором: 6 июл 2026
    dcc0 нравится это.