C语言游戏地图模块:插入/删除/打印区域函数修复请求
C语言恐怖游戏循环链表地图函数修复
问题背景
开发基于C语言的恐怖题材游戏,游戏地图采用循环链表存储Zona_mappa结构体。当前实现中,inserisci_zona(区域插入)、cancella_zona(区域删除)、stampa_mappa(地图打印)三个函数存在功能异常,需针对性修复。
修复需求
- 区域类型需等概率随机生成
- 区域物品需符合概率规则:
NESSUN_OGGETTO占40%,其余物品等概率分配剩余60% - 确保循环链表的插入、删除、打印操作逻辑完全正确
完整修复代码
头文件(gioco_horror.h)
#ifndef GIOCO_HORROR_H #define GIOCO_HORROR_H #include <stdio.h> #include <stdlib.h> #include <time.h> // 区域类型枚举 typedef enum { CORRIDOIO, STANZA, LABIRINTO, SALA_ATTESA, NUM_TIPI_ZONA // 用于计算类型总数 } TipoZona; // 物品类型枚举 typedef enum { NESSUN_OGGETTO, CHIAVE, POTIONE_SALUTE, ARMA, AMULETTO, NUM_OGGETTI // 用于计算物品总数 } TipoOggetto; // 地图区域结构体 typedef struct Zona_mappa { TipoZona tipo; TipoOggetto oggetto; struct Zona_mappa* prossima; } Zona_mappa; // 函数声明 void inizializza_srand(); TipoZona genera_tipo_zona(); TipoOggetto genera_oggetto(); Zona_mappa* inserisci_zona(Zona_mappa* testa, TipoZona tipo, TipoOggetto oggetto); Zona_mappa* cancella_zona(Zona_mappa** testa, int indice); void stampa_mappa(Zona_mappa* testa); void libera_mappa(Zona_mappa* testa); #endif
源文件(gioco_horror.c)
#include "gioco_horror.h" // 初始化随机数种子 void inizializza_srand() { srand(time(NULL)); } // 等概率生成区域类型 TipoZona genera_tipo_zona() { return (TipoZona)(rand() % NUM_TIPI_ZONA); } // 按概率生成物品:NESSUN_OGGETTO占40%,其余等概率 TipoOggetto genera_oggetto() { int rand_val = rand() % 100; if (rand_val < 40) { return NESSUN_OGGETTO; } else { // 剩余60%分配给其余4种物品,每种15% int oggetto_idx = (rand_val - 40) % (NUM_OGGETTI - 1); return (TipoOggetto)(oggetto_idx + 1); } } // 循环链表插入区域(尾部插入) Zona_mappa* inserisci_zona(Zona_mappa* testa, TipoZona tipo, TipoOggetto oggetto) { Zona_mappa* nuova_zona = (Zona_mappa*)malloc(sizeof(Zona_mappa)); if (!nuova_zona) { perror("Errore allocazione memoria"); exit(EXIT_FAILURE); } nuova_zona->tipo = tipo; nuova_zona->oggetto = oggetto; if (!testa) { // 空链表,新节点自己形成循环 nuova_zona->prossima = nuova_zona; return nuova_zona; } // 找到最后一个节点(prossima指向testa的节点) Zona_mappa* corrente = testa; while (corrente->prossima != testa) { corrente = corrente->prossima; } corrente->prossima = nuova_zona; nuova_zona->prossima = testa; return testa; } // 按索引删除循环链表节点 Zona_mappa* cancella_zona(Zona_mappa** testa, int indice) { if (!*testa) { printf("Mappa vuota, nessuna zona da cancellare.\n"); return NULL; } Zona_mappa* corrente = *testa; Zona_mappa* precedente = NULL; // 处理只有一个节点的情况 if (corrente->prossima == *testa) { free(corrente); *testa = NULL; return NULL; } // 找到目标节点 int i = 0; while (i < indice && corrente->prossima != *testa) { precedente = corrente; corrente = corrente->prossima; i++; } if (i != indice) { printf("Indice fuori dai limiti.\n"); return *testa; } // 删除节点:如果是头节点 if (corrente == *testa) { // 找到最后一个节点,让它指向新的头节点 Zona_mappa* ultimo = *testa; while (ultimo->prossima != *testa) { ultimo = ultimo->prossima; } *testa = corrente->prossima; ultimo->prossima = *testa; } else { precedente->prossima = corrente->prossima; } free(corrente); return *testa; } // 打印循环链表所有区域 void stampa_mappa(Zona_mappa* testa) { if (!testa) { printf("Mappa vuota.\n"); return; } Zona_mappa* corrente = testa; int contatore = 0; char* tipo_nomi[] = {"Corridoio", "Stanza", "Labirinto", "Sala d'attesa"}; char* oggetto_nomi[] = {"Nessun oggetto", "Chiave", "Pozione di salute", "Arma", "Amuletto"}; do { printf("Zona %d:\n", contatore); printf(" Tipo: %s\n", tipo_nomi[corrente->tipo]); printf(" Oggetto: %s\n\n", oggetto_nomi[corrente->oggetto]); corrente = corrente->prossima; contatore++; } while (corrente != testa); } // 释放循环链表内存 void libera_mappa(Zona_mappa* testa) { if (!testa) return; Zona_mappa* corrente = testa; Zona_mappa* prossima; do { prossima = corrente->prossima; free(corrente); corrente = prossima; } while (corrente != testa); } // 测试主函数 int main() { inizializza_srand(); Zona_mappa* mappa = NULL; // 插入5个随机区域 for (int i = 0; i < 5; i++) { TipoZona tipo = genera_tipo_zona(); TipoOggetto oggetto = genera_oggetto(); mappa = inserisci_zona(mappa, tipo, oggetto); } printf("=== Mappa iniziale ===\n"); stampa_mappa(mappa); // 删除索引2的区域 printf("\n=== Dopo cancellazione zona indice 2 ===\n"); mappa = cancella_zona(&mappa, 2); stampa_mappa(mappa); libera_mappa(mappa); return 0; }
关键修复点说明
区域类型随机生成:
- 新增
NUM_TIPI_ZONA枚举值,避免硬编码类型数量 genera_tipo_zona函数通过rand() % NUM_TIPI_ZONA实现等概率随机
- 新增
物品概率控制:
- 新增
NUM_OGGETTI枚举值,方便扩展物品类型 genera_oggetto函数通过100份概率分配:前40份返回NESSUN_OGGETTO,剩余60份平均分配给其他4种物品(每种15%)
- 新增
循环链表操作修复:
- 插入函数:处理空链表情况,确保新节点形成循环;非空链表时找到最后一个节点(指向头节点的节点),将其
prossima指向新节点,新节点再指向头节点 - 删除函数:单独处理单节点链表;删除头节点时需更新最后一个节点的
prossima指向新头节点;处理索引越界情况 - 打印函数:使用
do-while循环确保循环链表的所有节点都被遍历,避免遗漏头节点
- 插入函数:处理空链表情况,确保新节点形成循环;非空链表时找到最后一个节点(指向头节点的节点),将其
内容的提问来源于stack exchange,提问作者amine salhi
相关产品推荐
相关产品推荐

