Для создания карты пользователю предоставляется возможность запрашивать следующие четыре функции через меню с одним (переключателем): Вставка зоны в конец списка функций 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);
}
Вот фиксированный код. Необходимые изменения для исправления кода отмечены и объяснены комментариями в конце строк, начинающихся с "// 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;
}
Прошу прощения, ошибся при склейке кода, удалил ту часть и вставил весь написанный до сих пор код. Я продолжаю пытаться, но не могу решить эту проблему, что вы предлагаете мне делать?
@aminesalhi Код, который я разместил, работает автономно. Можете ли вы описать свою проблему? К сожалению, я не могу помочь, не зная вашей проблемы.
привет, я изменил код, как ты мне сказал, код работает, большое спасибо ^^
@aminesalhi Приятно слышать, что теперь это работает. Если у вас есть вопросы, почему я сделал это так, не стесняйтесь спрашивать меня. И не могли бы вы отметить мой ответ как принятый? Это очень помогло бы мне заработать репутацию.
не беспокойтесь о коде в коде, который вы хорошо объяснили, и я понял, большое спасибо @micheal
Мелочь:
inserisci_zona()
... 4 из 5 чисел будут< 80
, так что почти каждое исполнениеif (r < 80)
будет верным...