Zenway

Linux - это интересно!

Вы не вошли.

#1 13-04-2023 17:52:41

vovans
Администратор
Откуда: Ростов-на-Дону
Здесь с 19-10-2010
Сообщений: 513
Сайт
LinuxChrome 112.0

Тестовая бродилка на Си с ChatGPT

С одной стороны, упоминания всюду ChatGPT уже многих достали. С другой стороны, время от времени интересно "поболтать" с ботом.

Недавно попросил его написать текстовую бродилку на тему зомби-апокалипсиса. На Си.

Может кто помнит старый текстовый шутер под DOS - Zombie. Вот получить бы что-то такое, а если ещё и развить идею...

Вот что из этого вышло:

```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
  srand(time(NULL));
  printf("Добро пожаловать в мир зомби!\n");
  printf("Сначала выберите персонажа, которым будете играть:\n");
  printf("1. Полицейский\n");
  printf("2. Медик\n");
  printf("3. Военный\n");
  
  int choice;
  scanf("%d", &choice);
  
  int health = 100; // здоровье игрока
  int bullets = 6; // количество патронов
  
  switch (choice) {
    case 1:
      printf("Вы выбрали Полицейского.\n");
      break;
    case 2:
      printf("Вы выбрали Медика.\n");
      break;
    case 3:
      printf("Вы выбрали Военного.\n");
      break;
    default:
      printf("Неправильный выбор!\n");
      return 0;
  }
  
  printf("Вы начинаете игру в заброшенном городе, где полно зомби. Ваша задача - выжить!\n");
  
  while (health > 0) {
    int zombie_health = rand() % 50 + 50; // здоровье зомби
    printf("Вы встретили зомби! У зомби здоровье %d.\n", zombie_health);
    
    // Игрок должен решить, стрелять ли или убегать
    printf("Что вы хотите сделать?\n");
    printf("1. Стрелять\n");
    printf("2. Убежать\n");
    int action;
    scanf("%d", &action);
    
    if (action == 1) {
      if (bullets > 0) {
        printf("Вы стреляете в зомби.\n");
        int damage = rand() % 50 + 50; // урон, наносимый зомби
        zombie_health -= damage;
        printf("Вы нанесли %d урона зомби. Здоровье зомби: %d.\n", damage, zombie_health);
        bullets--;
      } else {
        printf("У вас кончились патроны! Убежать или драться руками?\n");
        printf("1. Убежать\n");
        printf("2. Драться руками\n");
        int choice2;
        scanf("%d", &choice2);
        if (choice2 == 1) {
          printf("Вы убежали от зомби.\n");
          continue;
        } else if (choice2 == 2) {
          int damage = rand() % 10 + 1; // урон, наносимый зомби
          health -= damage;
          printf("Вы нанесли %d урона зомби, но зомби тоже ударил вас. Ваше здоровье: %d. Здоровье зомби: %d.\n", damage, health, zombie_health);
        }
      }
    } else if (action == 2) {
      printf("Вы убежали от зомби.\n");
      continue;
    } else {
      printf("Неправильный выбор!\n");
      continue;
    }
    
    // Если зомби еще не убит, то он атакует игрока
    if (zombie_health > 0) {
      int damage = rand() % 10 + 1; // урон, наносимый зомби
      health -= damage;
      printf("Зомби атакует вас. Вы получаете %d урона. Ваше здоровье: %d.\n", damage, health);
    } else {
      printf("Вы убили зомби!\n");
    }
  }
  
  printf("Вы проиграли! Количество убитых зомби: %d.\n", rand() % 10 + 1);
  return 0;
}
```

Этот пример использует генератор случайных чисел (srand) для создания случайных значений здоровья зомби и урона, наносимого зомби. Игрок выбирает персонажа (Полицейский, Медик или Военный) и должен решить, стрелять или убегать от зомби. Если игрок выбирает стрельбу, то он может убить зомби или остаться без патронов и сражаться руками. Если зомби атакует игрока, то он теряет здоровье. Если здоровье игрока становится меньше или равно 0, игрок проигрывает.

Добавлено спустя 02 мин 31 с:
Интересно, но пока бесполезно. Стал уточнять задание. По крайней мере, первый уровень, а может и вся игра, должен проходить в многоэтажном доме. И чтобы по его комнатам и по этажам можно было ходить вперёд и назад, вверх и вниз:

Чтобы добавить возможность движения по многоэтажному дому и поиск предметов, можно использовать массив для хранения данных о комнатах и двумерный массив для отображения карты дома. Например:

```
// Данные о комнатах
struct Room {
  int floor;
  int number;
  int has_ammo; // наличие патронов
  int has_food; // наличие еды
};
struct Room rooms[] = {
  {1, 101, 1, 0},
  {1, 102, 0, 1},
  {1, 103, 0, 0},
  {2, 201, 1, 1},
  {2, 202, 0, 1},
  {2, 203, 1, 0},
  {3, 301, 0, 1},
  {3, 302, 1, 0},
  {3, 303, 0, 0}
};

// Карта дома
int map[3][3] = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9}
};

printf("Вы начинаете игру на первом этаже, в комнате 101.\n");
int current_floor = 1; // текущий этаж
int current_room = 1; // текущая комната
while (health > 0) {
  printf("Вы находитесь в комнате %d на %d этаже.\n", current_room, current_floor);
  printf("Что вы хотите сделать?\n");
  printf("1. Идти вперед\n");
  printf("2. Идти назад\n");
  printf("3. Подняться на верхний этаж\n");
  printf("4. Спуститься на нижний этаж\n");
  printf("5. Искать предметы в комнате\n");
  printf("6. Посмотреть на карту дома\n");

  int action;
  scanf("%d", &action);

  struct Room current = rooms[current_room - 1];
  switch (action) {
    case 1:
      if (current.number == 103) {
        printf("Вы не можете идти вперед из комнаты 103!\n");
      } else {
        current_room++;
        if (current_room > 9 || (current_floor == 3 && current_room > 6) || (current_floor == 2 && current_room > 3)) {
          printf("Вы вышли из дома на улицу. Переход на следующий уровень!\n");
          // Здесь можно добавить логику для перехода на следующий уровень
          return 0;
        } else {
          printf("Вы перешли в комнату %d на %d этаже.\n", current_room, current_floor);
        }
      }
      break;
    case 2:
      if (current.number == 101) {
        printf("Вы не можете идти назад из комнаты 101!\n");
      } else {
        current_room--;
        if (current_room < 1 || (current_floor == 1 && current_room < 4) || (current_floor == 2 && current_room < 7)) {
          printf("Вы не можете идти назад дальше.\n");
          current_room++;
        } else {
          printf("Вы перешли в комнату %d на %d этаже.\n", current_room, current_floor);
        }
      }
      break;
    case 3:
      if (current_floor == 3) {
        printf("Вы уже находитесь на верхнем этаже!\n");
      } else {
        current_floor++;
        printf("Вы поднялись на %d этаж.\n", current_floor);
        if (current_floor == 3 && current_room > 6) {
          printf("Вы перешли в огромную комнату на верхнем этаже. Будьте осторожны!\n");
        }
      }
      break;
    case 4:
      if (current_floor == 1) {
        printf("Вы уже находитесь на нижнем этаже!\n");
      } else {
        current_floor--;
        printf("Вы спустились на %d этаж.\n", current_floor);
        if (current_floor == 2 && current_room > 3) {
          printf("Вы перешли в огромную комнату на втором этаже. Будьте осторожны!\n");
        }
      }
      break;
    case 5:
      if (current.has_ammo) {
        bullets+= 6;
        printf("Вы нашли 6 дополнительных патронов!\n");
        current.has_ammo = 0;
      }
      if (current.has_food) {
        health += 20;
        printf("Вы нашли 20 единиц еды и восстановили здоровье!\n");
        current.has_food = 0;
      }
      if (!current.has_ammo && !current.has_food) {
        printf("Вы искали предметы, но ничего не нашли.\n");
      }
      break;
    case 6:
      printf("Карта многоэтажного дома:\n");
      for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
          if (map[i][j] == current_room) {
            printf(" * ");
          } else {
            printf(" %d ", map[i][j]);
          }
        }
        printf("\n");
      }
      break;
    default:
      printf("Неправильный выбор!\n");
      break;
  }
}
```

Эта версия игры добавляет возможности двигаться по комнатам и этажам, искать предметы и просмотреть карту дома. Также добавляются новые переменные: current_floor и current_room для отслеживания текущих положений игрока, и структура Room для хранения данных о каждой комнате. При поиске предметов игрок может найти патроны или еду, которые увеличивают количество патронов и здоровье соответственно. При выборе действия игрок может также просмотреть карту дома, чтобы выполнять действия осознанно.

Думаю, понятно, что этот код нужно вставить в функцию main предыдущего листинга. Когда я вставил этот код, при движении назад не вычитался номер комнаты. Не было времени вчитываться в код. Да и сперва приведу всё, как есть. А потом, в идеале, составить бы что-то целостное и рабочее

Добавлено спустя 09 мин 30 с:
Чего не хватает? Рандомности. И восстановления здоровья. Не на каждом же шагу должны попадаться зомберы. А иногда должно находиться что-то полезное - пища, патроны. Прошу бота развить этот момент:

Для реализации случайного расположения патронов, зомби и еды можно использовать функцию rand(), которая генерирует случайные числа. Например, при создании каждой комнаты можно генерировать случайное число от 0 до 2, которое будет обозначать наличие патронов, зомби или еды в комнате.

// Данные о комнатах
struct Room {
  int floor;
  int number;
  int has_ammo; // наличие патронов
  int has_food; // наличие еды
  int has_zombie; // наличие зомби
};
struct Room rooms[] = {
  {1, 101, rand() % 3, rand() % 3, rand() % 3},
  {1, 102, rand() % 3, rand() % 3, rand() % 3},
  {1, 103, rand() % 3, rand() % 3, rand() % 3},
  {2, 201, rand() % 3, rand() % 3, rand() % 3},
  {2, 202, rand() % 3, rand() % 3, rand() % 3},
  {2, 203, rand() % 3, rand() % 3, rand() % 3},
  {3, 301, rand() % 3, rand() % 3, rand() % 3},
  {3, 302, rand() % 3, rand() % 3, rand() % 3},
  {3, 303, rand() % 3, rand() % 3, rand() % 3}
};

// Карта дома
int map[3][3] = {
  {1, 2, 3},
  {4, 5, 6},
  {7, 8, 9}
};


/* Здесь rand() % 3 генерирует случайное число от 0 до 2, которое определяет наличие патронов,
зомби или еды в комнате. Эти переменные также могут быть использованы при исследовании 
комнаты во время игры.
*/


case 5:
  if (current.has_ammo) {
    bullets += 6;
    printf("Вы нашли 6 дополнительных патронов!\n");
    current.has_ammo = 0;
  }
  if (current.has_food) {
    health += 20;
    printf("Вы нашли 20 единиц еды и восстановили здоровье!\n");
    current.has_food = 0;
  }
  if (current.has_zombie) {
    printf("Вы нашли зомби в комнате! Бейте его палкой!\n");
    current.has_zombie = 0;
  }
  if (!current.has_ammo && !current.has_food && !current.has_zombie) {
    printf("Вы искали предметы, но ничего не нашли.\n");
  }
  break;

Здесь при поиске предметов игрок может столкнуться с зомби, если зомби находится в комнате. Это добавляет элемент неожиданности и опасности в игру.


Добавлено спустя 5 ч 39 мин 37 с:
Возвращаясь к первому варианту. Вот типичный пример работы кода:

Вы выбрали Полицейского.
Вы начинаете игру в заброшенном городе, где полно зомби. Ваша задача - выжить!
Вы встретили зомби! У зомби здоровье 74.
Что вы хотите сделать?
1. Стрелять
2. Убежать
1
Вы стреляете в зомби.
Вы нанесли 55 урона зомби. Здоровье зомби: 19.
Зомби атакует вас. Вы получаете 5 урона. Ваше здоровье: 95.

Я бы тут добавил возможность драться, а не только стрелять. Патронов мало, стреляешь, здоровья совсем чуть-чуть остатся, его бы добить простым ударом, он уже еле живой, но нет...

Как и принято в пошаговых играх, тут вполне могло быть три действия:

1. Выстрел
2. Ответный удар домби и "вы получаете 5 урона"
3. Удар кулаком, дубиной, чем угодно и всё

Ну и в первом варианте нет смысла убивать зомби. Разумнкее убежать. И патроны целее, и урона никакого. Что странно.


zenway admin

Вне форума

#2 14-04-2023 17:13:25

BigOrange
Модератор
Откуда: Саратов
Здесь с 20-11-2010
Сообщений: 2,304
LinuxFirefox 102.0

Re: Тестовая бродилка на Си с ChatGPT

Надо небольшую фору юзверю давать. Или иногда заставлять машину делать ошибки и нелогичные действия.


Долой DE! Даёшь WM!

Вне форума

#3 15-04-2023 15:21:45

vovans
Администратор
Откуда: Ростов-на-Дону
Здесь с 19-10-2010
Сообщений: 513
Сайт
LinuxChrome 112.0

Re: Тестовая бродилка на Си с ChatGPT

Да, это вс нужно продумать и реализовать. Тут сложнее продумать, чем реализовать )

Ну, недостатки вскрываются сразу. Как только начинаешь делать первые шаги, примерно вырисоывается, чего не хватает, и чего много. Нужна продуманная рандомность. ДОбавить четвертое событие - ничего не происходит и в комнате ничего нет ) ну и убегать просто так... В идеале бы, чтобы можно было наткруться на второго зомби и чтобы первый тоже скоро настиг с другой стороры. Чтобы побеги не были такими уж крутыми. Или терять часть здоровья при побеге - типа, зомби ударил, пока вы там ...


zenway admin

Вне форума

#4 17-04-2023 11:14:08

BigOrange
Модератор
Откуда: Саратов
Здесь с 20-11-2010
Сообщений: 2,304
LinuxFirefox 102.0

Re: Тестовая бродилка на Си с ChatGPT

Зомби кинул в спину какахой:  -1 хп )


Долой DE! Даёшь WM!

Вне форума

Сейчас в этой теме пользователей: 0, гостей: 1
[Bot] CCBot

Подвал форума

Под управлением FluxBB
Модифицировал Visman

[ Сгенерировано за 0.020 сек, 10 запросов выполнено - Использовано памяти: 1.68 Мбайт (Пик: 1.78 Мбайт) ]