Как мне исправить этот код, который _ вставляет зону, удаляет_зону, печатает_зону

Для создания карты пользователю предоставляется возможность запрашивать следующие четыре функции через меню с одним (переключателем): Вставка зоны в конец списка функций insert_zone. Он создает новую зону в динамической памяти malloc, вставляет ее в список, изменяя значение указателя next_zone последней земли в списке на результат malloc. Тип зоны, а также объект, найденный в зоне, генерируются случайным образом: все зоны равновероятны, no_object имеет вероятность 40%, в то время как другие объекты в перечислении Object_type_zone имеют равную вероятность. Наконец, поле enum Tipo_prova prova будет вставляться с определенной вероятностью каждый раз, когда игрок прибывает в заданную зону, см. функцию advance.

Удалить последнюю зону, вставленную в путь cancel_zone

Вывести поля всех созданных к этому моменту зон print_map.

я оставляю пользователю возможность использовать меню для выполнения следующих четырех функций: вставить_зона: удалить_зона: print_map; . Оставляю копию файла .h (хорошо работает); "Вы можете помочь найти решение проблемы"


#ifndef H_GAMELIB
#define H_GAMELIB


extern void imposta_gioco();
extern void gioca();
extern void termina_gioco();
extern void inserisci_zona();
extern void stampa_mappa();
extern void chiudi_mappa();
extern void cancella_zona();


enum Tipo_Difficolta { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };

struct Zona_mappa {
    enum Tipo_zona zona;
    enum Tipo_prova prova;
    enum Tipo_oggetto_zona oggetto_zona;
    struct Zona_mappa* prossima_zona;
};

struct Giocatore {
    char nome_giocatore[30];
    unsigned char sanita_mentale;
    struct Zona_mappa* posizione;
    unsigned char zaino[4];
};


 

#endif



main.c

#include "gamelib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>




int main (void){
 unsigned short numero;
 int c = 0;

  printf("\033[1;35m    ____ ____ ____ ____ ____ ____ ____ ____ \n");
  printf("   ||P |||h |||a |||l |||s |||o |||P |||h ||\n");
  printf("   ||__|||__|||__|||__|||__|||__|||__|||__||\n");
  printf("   |/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|\n");
  printf("\033[0m\n");
  printf("||preme 'invio' per continuare||\n");
     
     while(getchar()!= '\n');
    
     do{
    printf("\n");
    printf("> \033[1;93m1\033[1m: Imposta Gioco.\n");
    printf("> \033[1;96m2\033[2m: Gioca.\n");
    printf("> \033[1;91m3\033[3m: Termina gioco.\n\n");

  printf ("\033[92mScelta:\033[0m ");
     scanf("%hu",&numero);
     while ((c = getchar()) != '\n' && c != EOF); //pulizia dei buffer

     switch(numero){
        case 1: 
        printf("hai inserito il primo numero\n");
         imposta_gioco();
         break;
        case 2:
        printf("hai inserito il secondo numero\n");
         gioca();break;
        case 3:
        printf("hai inserito il terzo numero");
        termina_gioco();break;
        default: printf("\033[31mAttenzione!\033[0m Opzione non valida, per favore inserisci \033[31mun numero da 1 a 3\033[0m.\n");
        }
         }while (numero != 3);
               return 0;
              }
             
      
gamelib.c


#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include "gamelib.h"

#define ERROR_ARGS_NUM(_min, _max) printf("\033[31mAttenzione!\033[5m Opzione non valida, per favore inserisci \033[31mun numero da " #_min " a " #_max "\033[0m.\n")
#define CHECK_NUM_INPUT_RANGE(n, _min, _max)

struct Zona_mappa *pLast = NULL;
struct Zona_mappa *pFirst = NULL;
static struct Giocatore players[4];
static int nplayers = 0;
static int difficulty_level;

int ask_num(const char *prompt)
{
    if (prompt)
        printf("%s", prompt);

    int n;
    if (scanf("%d", &n) <= 0)
        n = -1;

    return n;
}
void mostra_zaino(struct Giocatore *giocatore)
{
    const char *nome_oggetto_iniziale;
    switch (giocatore->zaino[0])
    {
    case EMF:
        nome_oggetto_iniziale = "EMF";
        break;
    case spirit_box:
        nome_oggetto_iniziale = "Spirit Box";
        break;
    case videocamera:
        nome_oggetto_iniziale = "Videocamera";
        break;
    case calmanti:
        nome_oggetto_iniziale = "Calmanti";
        break;
    case sale:
        nome_oggetto_iniziale = "Sale";
        break;
    default:
        return;
    }
    printf("Contenuto zaino di %s:\nOggetto iniziale: %s\n", giocatore->nome_giocatore, nome_oggetto_iniziale);
    for (int i = 1; i < 3; i++)
    {
        switch (giocatore->zaino[i])
        {
        case cento_dollari:
            printf("100$\n");
            break;
        case nessun_oggetto:
            printf("nessun_oggetto\n");
            break;
        case coltello:
            printf("coltello\n");
            break;
        case calmanti1:
            printf("calmanti1\n");
            break;
        case adrenalina:
            printf("adrenalina\n");
            break;
        }
    }
    printf("\n");
}

void imposta_gioco()
{

    srand(time(NULL));
    memset(players, 0, sizeof(players));
    nplayers = ask_num("Inserisci il numero di giocatori (da 1 a 4): ");
    CHECK_NUM_INPUT_RANGE(nplayers, 1, 4);

    printf("Scegli il livello di difficoltà:\n");
    printf("> \033[1;93m1\033[0m: Dilettante\n");
    printf("> \033[2;93m2\033[0m: Intermedio\n");
    printf("> \033[3;93m3\033[0m: Incubo\n");

    difficulty_level = ask_num("\033[32mInserisci il numero corrispondente: ");
    CHECK_NUM_INPUT_RANGE(difficulty_level, 1, 3);

    for (int i = 0; i < nplayers; i++)
    {
        printf("Inserisci il nome del giocatore %d: ", (i + 1));
        if (scanf("%s", players[i].nome_giocatore) <= 0)
            return;

        players[i].sanita_mentale = 100;
        players[i].zaino[0] = rand() % 5;
        for (int j = 1; j < 4; j++)
            players[i].zaino[j] = nessun_oggetto;

        mostra_zaino(&players[i]);
    }
}

struct Zona_mappa *genera_mappa()
{
    // Crea la prima zona mappa
    struct Zona_mappa *prima_zona = malloc(sizeof(struct Zona_mappa));
     prima_zona->zona = cucina;

    // Crea la seconda zona mappa
    struct Zona_mappa *seconda_zona = malloc(sizeof(struct Zona_mappa));
     seconda_zona->zona = soggiorno;
    prima_zona->prossima_zona = seconda_zona;

    // Crea la terza zona
    struct Zona_mappa *terza_zona = malloc(sizeof(struct Zona_mappa));
     terza_zona->zona = garage;
    seconda_zona->prossima_zona = terza_zona;

    struct Zona_mappa *quarta_zona = malloc(sizeof(struct Zona_mappa));
      quarta_zona->zona = camera;
    terza_zona->prossima_zona = quarta_zona;

    // Crea la terza zona
    struct Zona_mappa *quinta_zona = malloc(sizeof(struct Zona_mappa));
     quinta_zona->zona = bagno;
    quarta_zona->prossima_zona = quinta_zona;

    struct Zona_mappa *ultima_zona = malloc(sizeof(struct Zona_mappa));
     ultima_zona->zona = seminterrato;
    quinta_zona->prossima_zona = ultima_zona;

    ultima_zona->prossima_zona = prima_zona;
    // Assegna i valori ai puntatori globali
    pFirst = prima_zona;
    pLast = ultima_zona;
    printf("la lista è pronta\n");
    return prima_zona; // Restituisce l'indirizzo della prima zona
}
void inserisci_zona()
{
    struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
    if (nuova_zona == NULL)
    {
        fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
        return;
    }
    nuova_zona->zona = rand() % 4;
    int r = rand() % 100;
    if (r < 80)
    {
        nuova_zona->zona = cucina;
    }
    else if (r < 60)
    {
        nuova_zona->zona = bagno;
    }
    else if (r < 50)
    {
        nuova_zona->zona = garage;
    }
    else if (r < 40)
    {
        nuova_zona->zona = seminterrato;
    }
    else if (r < 30)
    {
        nuova_zona->zona = camera;
    }
    else
    {
        nuova_zona->zona = soggiorno;
    }

    r = rand() % 100;
    if (r < 40)
    {
        nuova_zona->oggetto_zona = nessun_oggetto;
    }
    else if (r < 60)
    {
        nuova_zona->oggetto_zona = calmanti1;
    }
    else if (r < 70)
    {
        nuova_zona->oggetto_zona = coltello;
    }
    else if (r < 90)
    {
        nuova_zona->oggetto_zona = cento_dollari;
    }
    else
    {
        nuova_zona->oggetto_zona = adrenalina;
    }
// Insert the new zone at the end of the list
    if (pFirst == NULL)
    {// If the list is empty, set First and Last as the new zone
        pFirst = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = pFirst;
    }
    else
    {
        pLast->prossima_zona = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = pFirst;
    }
}

void cancella_zona()
{
// Special case: the list is empty
    if (pFirst == NULL)
    {
        return;
    }

// Special case: the list contains a single zone
    if (pFirst == pLast)
    {
        free(pFirst);
        pFirst = NULL;
        pLast = NULL;
        return;
    }

   // Otherwise, find the last zone in the list and delete it
    struct Zona_mappa *p = pFirst;
    while (p->prossima_zona != pLast)
    {
        p = p->prossima_zona;
    }

    free(pLast);
    pLast = p;
    pLast->prossima_zona = pFirst;
}
void stampa_mappa()
{

    // Caso particolare: la lista è vuota
    if (pFirst == NULL)
    {
        printf("La mappa è vuota\n");
        return;
    }

    printf("Stampa della mappa:\n");
    struct Zona_mappa *p = pFirst;
    do
    {
        printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
        p = p->prossima_zona;
    } while (p != pFirst);
}

void chiudi_mappa()
{
    gioco_impostato = 1;
}

// Funzione che avvia il gioco
void gioca()
{
    {
    }
    
}

// Funzione che termina il gioco
void termina_gioco()
{
}


            




У меня проблемы в следующих 3 блоках кода

void inserisci_zona()
{
    struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
    if (nuova_zona == NULL)
    {
        fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
        return;
    }
    nuova_zona->zona = rand() % 4;
    int r = rand() % 100;
    if (r < 80)
    {
        nuova_zona->zona = cucina;
    }
    else if (r < 60)
    {
        nuova_zona->zona = bagno;
    }
    else if (r < 50)
    {
        nuova_zona->zona = garage;
    }
    else if (r < 40)
    {
        nuova_zona->zona = seminterrato;
    }
    else if (r < 30)
    {
        nuova_zona->zona = camera;
    }
    else
    {
        nuova_zona->zona = soggiorno;
    }

    r = rand() % 100;
    if (r < 40)
    {
        nuova_zona->oggetto_zona = nessun_oggetto;
    }
    else if (r < 60)
    {
        nuova_zona->oggetto_zona = calmanti1;
    }
    else if (r < 70)
    {
        nuova_zona->oggetto_zona = coltello;
    }
    else if (r < 90)
    {
        nuova_zona->oggetto_zona = cento_dollari;
    }
    else
    {
        nuova_zona->oggetto_zona = adrenalina;
    }
// Insert the new zone at the end of the list
    if (pFirst == NULL)
    {// If the list is empty, set First and Last as the new zone
        pFirst = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = pFirst;
    }
    else
    {
        pLast->prossima_zona = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = pFirst;
    }
}


void cancella_zona()
{
// Special case: the list is empty
    if (pFirst == NULL)
    {
        return;
    }

// Special case: the list contains a single zone
    if (pFirst == pLast)
    {
        free(pFirst);
        pFirst = NULL;
        pLast = NULL;
        return;
    }

   // Otherwise, find the last zone in the list and delete it
    struct Zona_mappa *p = pFirst;
    while (p->prossima_zona != pLast)
    {
        p = p->prossima_zona;
    }

    free(pLast);
    pLast = p;
    pLast->prossima_zona = pFirst;
}
void stampa_mappa()  
{

    // Caso particolare: la lista è vuota
    if (pFirst == NULL)
    {
        printf("La mappa è vuota\n");
        return;
    }

    printf("Stampa della mappa:\n");
    struct Zona_mappa *p = pFirst;
    do
    {
        printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
        p = p->prossima_zona;
    } while (p != pFirst);
}

Мелочь: inserisci_zona()... 4 из 5 чисел будут < 80, так что почти каждое исполнение if (r < 80) будет верным...

Fe2O3 07.01.2023 01:59
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот фиксированный код. Необходимые изменения для исправления кода отмечены и объяснены комментариями в конце строк, начинающихся с "// Edit:". Это один файл, в который я вставил заголовочный файл. В конце небольшой main() для проверки кода.

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

#ifndef H_GAMELIB
#define H_GAMELIB

void imposta_gioco (void);
void gioca         (void);
void termina_gioco (void);
void inserisci_zona(void);
void stampa_mappa  (void);
void chiudi_mappa  (void);
void cancella_zona (void);

enum Tipo_Difficolta       { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona     { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona             { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova            { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };

struct Zona_mappa {
    enum Tipo_zona         zona;
    enum Tipo_prova        prova;
    enum Tipo_oggetto_zona oggetto_zona;
    struct Zona_mappa*     prossima_zona;
};

struct Giocatore {
    char               nome_giocatore[30];
    unsigned char      sanita_mentale;
    struct Zona_mappa* posizione;
    unsigned char      zaino[4];
};

#endif

static struct Zona_mappa* pFirst = NULL;  // Edit: Added since pFirst was missing
static struct Zona_mappa* pLast  = NULL;  // Edit: Added since pLast was missing

void inserisci_zona(void) {
    struct Zona_mappa* nuova_zona = malloc(sizeof(struct Zona_mappa));
    if (nuova_zona == NULL)
    {
        fprintf(stderr, "ERROR of memory allocation for the new zone\n");
        return;
    }
    nuova_zona->zona = rand() % 7;  // Edit: enum has 7 enumerators
    // Edit: Since zones are equiprobable, above line is sufficient
    /*
    int r = rand() % 100;
    if (r < 80)
    {
        nuova_zona->zona = cucina;
    }
    else if (r < 60)
    {
        nuova_zona->zona = bagno;
    }
    else if (r < 50)
    {
        nuova_zona->zona = garage;
    }
    else if (r < 40)
    {
        nuova_zona->zona = seminterrato;
    }
    else if (r < 30)
    {
        nuova_zona->zona = camera;
    }
    else
    {
        nuova_zona->zona = soggiorno;
    }
    */

    int r = rand() % 100;
    if (r < 40)
    {
        nuova_zona->oggetto_zona = nessun_oggetto;
    }
    else if (r < 55) // Edit: No object has 40% and all others 15%
    {
        nuova_zona->oggetto_zona = calmanti1;
    }
    else if (r < 70)
    {
        nuova_zona->oggetto_zona = coltello;
    }
    else if (r < 85) // Edit: No object has 40% and all others 15%
    {
        nuova_zona->oggetto_zona = cento_dollari;
    }
    else
    {
        nuova_zona->oggetto_zona = adrenalina;
    }
    // Insert the new zone at the end of the list
    if (pFirst == NULL)
    {
        // If the list is empty, set First and Last as the new zone
        pFirst = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
    }
    else
    {
        pLast->prossima_zona = nuova_zona;
        pLast = nuova_zona;
        pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
    }
}


void cancella_zona(void) {
    // Special case: the list is empty
    if (pFirst == NULL)
    {
        return;
    }

    // Special case: the list contains a single zone
    if (pFirst == pLast)
    {
        free(pFirst);
        pFirst = NULL;
        pLast = NULL;
        return;
    }

   // Otherwise, find the second to last zone in the list
    struct Zona_mappa *p = pFirst;
    while (p->prossima_zona != pLast)
    {
        p = p->prossima_zona;
    }

    free(pLast);
    pLast = p;
    pLast->prossima_zona = NULL;  // Edit: Next of last zone has to be NULL
}

void stampa_mappa(void) {

    // Special case: the list is empty
    if (pFirst == NULL)
    {
        printf("The map is empty\n");
        return;
    }

    printf("Map printing:\n");
    struct Zona_mappa *p = pFirst;
    do
    {
        printf(" - Zone of type %d, with object %d\n", p->zona, p->oggetto_zona);
        p = p->prossima_zona;
    } while (p != NULL);  // Edit: Iterate until there's no next Zona_mappa which is the case if next is NULL
}

int main(void) {
  stampa_mappa();
  inserisci_zona();
  inserisci_zona();
  inserisci_zona();
  stampa_mappa();
  cancella_zona();
  stampa_mappa();
  cancella_zona();
  cancella_zona();
  stampa_mappa();
  for (;;);
  return 0;
}

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

amine salhi 07.01.2023 11:12

@aminesalhi Код, который я разместил, работает автономно. Можете ли вы описать свою проблему? К сожалению, я не могу помочь, не зная вашей проблемы.

Michael M. 07.01.2023 11:42

привет, я изменил код, как ты мне сказал, код работает, большое спасибо ^^

amine salhi 08.01.2023 21:44

@aminesalhi Приятно слышать, что теперь это работает. Если у вас есть вопросы, почему я сделал это так, не стесняйтесь спрашивать меня. И не могли бы вы отметить мой ответ как принятый? Это очень помогло бы мне заработать репутацию.

Michael M. 09.01.2023 01:21

не беспокойтесь о коде в коде, который вы хорошо объяснили, и я понял, большое спасибо @micheal

amine salhi 11.01.2023 04:08

Другие вопросы по теме