Roulette con lista concatenata circolare

di il
14 risposte

Roulette con lista concatenata circolare

Buon salve, vorrei cominciare questo esercizio e vorrei soltanto qualche spunto.
Si costruisca un programma che simuli il gioco della roulette mediante una lista concatenata circolare. I nodi della lista contengono le seguenti informazioni delle celle della roulette nelle quali pu`o cadere la pallina: • valore (da 0 a 36); • colore (rosso, nero, verde). Per semplicit`a la roulette gira sempre nello stesso verso. Il programma inizializza la lista secondo la ?gura


In un certo istante, la pallina si trova in corrispondenza di uno dei 37 numeri (`e un puntatore ad uno dei nodi della lista). L’utente-croupier, premendo un tasto, avvia la simulazione del lancio della pallina mediante estrazione di un numero a caso n compreso tra 100 e 200, il programma avanza di n posizioni nella lista circolare e restituisce numero e colore della cella. L’estrazione successiva ripartirà da questo punto della lista (e della roulette). Allora avevo scritto in passato delle funzioni per il funzionamento delle liste circolari:
#include <stdio.h>
#include <stdlib.h>

typedef struct node_
{
	int item;
	struct node_* next;
}node;
typedef node* link;

link init(link* t)
{
	*t = malloc(sizeof *t);
	(*t)->item = 0;
	(*t)->next = *t;
	link x = *t;
	return x;
}

void insert(link* t, link* x, int value)
{
	link new = malloc(sizeof *t);
	(*x)->next = new;
	new->item = value;
	*x = new;
	(*x)->next = *t;
}

int main()
{
	link t;
	link x = init(&t);
	printf("elemento da inserire: ");
	int value;
	scanf("%d", &value);
	insert(&t, &x, value);
	printf("->%d->%d", x->next->item, x->item);
}
(Ovviamente questo mi è servito solo per darmi un'idea, la funzione init potrebbe essere tranquillamente compattata alla insert e il main è solo dimostrativo).
Il link x di questo codice dovrebbe comportarsi come la pallina che verrebbe lanciata facendola scorrere per un numero di volte compreso tra 100 e 200. Per il colore basterebbe aggiungere il campo informativo char*. Va bene la funzione per creare la lista?

14 Risposte

  • Re: Roulette con lista concatenata circolare

    Quale funzione? Va riscritta... fallo e poi si vede...
  • Re: Roulette con lista concatenata circolare

    Quale funzione? Va riscritta... fallo e poi si vede...
    cos? va riscritta cosa? Ancora non ho cominciato guarda
  • Re: Roulette con lista concatenata circolare

    Appunto ... non hai iniziato ... quindi, quando chiedi "Va bene la funzione per creare la lista?" ... a cosa ti riferisci?
  • Re: Roulette con lista concatenata circolare

    Il cuore dell'esercizio è il gioco della roulette e non la lista in sè...Vorrei soltanto un parere su questo codice per la lista e su come posso inizializzare correttemente il colore per ogni numero
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node_
    {
    	int item;
    	struct node_* next;
    	
    	
    }node;
    typedef node* link;
    
    link init(link* t)
    {
    	*t = malloc(sizeof *t);
    	(*t)->next = *t;
    	(*t)->item = 0;
    	link x = *t;
    	return x;
    }
    
    void insert(link* t, link* x, int value)
    {
    	
    	link new = malloc(sizeof *t);
    	(*x)->next = new;
    	new->item = value;
    	*x = new;
    	(*x)->next = *t;
    }
    
    int main()
    {
    	
    	link t;
    	link x = init(&t);
    	insert(&t, &x, 32);
    	insert(&t, &x, 15);
    	insert(&t, &x, 19);
    	...
    	
    	x = t;
    	do
    	{
    	  printf("%d->", x->item);	
    	  x = x->next;
    	}
    	while(x != t);
    }
  • Re: Roulette con lista concatenata circolare

    Questa è un'altra domanda.

    Nella struttura prevedi un valore 0 1 2 per il colore e il valore. Per inizializzare la lista parti da un vettore

    int valrou[] = { 0, 32, 15, ... };

    che scandisce in un ciclo in cui crei gli elementi della lista... per il colore parti da 0 e poi usa alternativamente 1 e 2 (verde... rosso...nero...rosso...nero...)
  • Re: Roulette con lista concatenata circolare

    Questa è un'altra domanda.
    magari mi sarò espresso male ma intendevo proprio quello
    Nella struttura prevedi un valore 0 1 2 per il colore e il valore. Per inizializzare la lista parti da un vettore

    int valrou[] = { 0, 32, 15, ... };

    che scandisce in un ciclo in cui crei gli elementi della lista... per il colore parti da 0 e poi usa alternativamente 1 e 2 (verde... rosso...nero...rosso...nero...)
    Perfetto, grazie mille!
  • Re: Roulette con lista concatenata circolare

    Ho provato ad aggiornare adesso il codice, ma c'è qualcosa che non capisco:
    Ho pure fatto il disegno per avere un riferimento visivo e per tracciare ogni passo( anche qui non capisco come fare per condividere delle immagini mie, perché se uso un sito di condivisione, per esempio imgur, mi da l'errore : "Impossibile determinare le dimensioni dell’immagine. Verifica che l’URL inserito sia corretto.")
    #include <stdio.h>
    #include <stdlib.h>
    #define N 36
    
    typedef struct node_
    {
    	int item;
    	struct node_* next;
    	char* colore;
    	
    	
    }node;
    typedef node* link;
    
    void init(link* t, link* x)
    {
    	
    	*t = malloc(sizeof *t);
    	(*t)->next = *t;
    	(*t)->item = 0;
    	(*t)->colore = "verde";
    	 *x = *t;
    	
    }
    
    void insert(link* t, link* x, int value)
    {
    	
    	link new = malloc(sizeof *t);
    	(*x)->next = new;
    	new->item = value;
    	*x = new;
    	(*x)->next = *t;
    	
    }
    
    int main()
    {
       
    	link t;
    	link x; 
    	init(&t, &x);
    	unsigned int i, j = 0;
    	int valore[N] ={32,15,19,4,21,2,25,17,34,6,27,13,36,11,30,8,23,10,
    	                 5,24,16,33,1,20,14,31,9,22,18,29,7,28,12,35,3,26};
    	
    	 char *c[2] = {"rosso", "nero"};
    	 
    	 
    	for(i = 0; i < N; i++)
    	{
    	 insert(&t,&x, valore[i]);
    	 
    	}		
    	x = t;
    	do
    	{
    		printf("->%d->", x->item);
    		x = x->next;
    	} 
    	while(x != t);
       puts("");
      
      /*do
      {
          puts(x->colore);
    	  if( j%2 == 0)
    		  x->next->colore = c[0];
    	  else
    		  x->next->colore = c[1];
    	  x = x->next;
    	  j++;
      }
      while(x->next != t);*/
    	    
    }
    Alla fine ho mantenuto la funzione init in modo da avere il nodo con lo zero già presente come riferimento fisso con t.
    la funzione insert dentro il ciclo for crea ogni volta un nuovo nodo, gli passa il valore dell'array e scorre la x cosicché sia linkata sempre all'ultimo nodo inserito senza toccare ovviamente la t, quindi Alla fine del for io so che la x si trova nel nodo contenente il 26.
    Successivamente faccio partire la x nuovamente dal nodo 0 e comincio a stampare tutti i valori con il do-while.
    Infine nell'ultimo ciclo( anche se ho già provato a farlo nel ciclo for insieme alla insert) provo a riempire il campo informativo del colore, e anche qui so, senza quindi il bisogno di aggiornare niente, che la x sia linkata al nodo 0.

    Il problema è che so provo a compilare ed avviare il programma includendo anche quest'ultimo ciclo, dopo aver stampato comunque tutti i numeri e anche i colori,
    mi appare una finestra con il messaggio: " a.exe ha smesso di funzionare"....
  • Re: Roulette con lista concatenata circolare

    Meno male che ti avevo detto di usare 0 1 e 2 per i colori. Hai usato un puntatore a char senza inizializzarlo e ci hai copiato una stringa con un semplice =

    ... che ti aspetti che succeda?

    Modifica la struttura ... che significa item? Parliamo di un numero di roulette ... per semplicità usa degli int ma con un nome adeguato
    
    int numero;
    int colore;
    struct node_* next;
    
    I colori sono 3 quindi
    
    char *c[3] = { "verde", "rosso", "nero" };
    
    Nella init manca il colore
    
    (*t)->colore = 0;
    
    La insert diventa
    
    void insert(link* t, link* x, int value, int color)
    
    e chiamerai il nodo nuovo (non new che è una parola riservata per i compilatori C++ da evitare anche se lavori in C)
    
    nuovo->colore = color;
    
    Quindi nel main l'inserimento dei colori alternati
    
    	int col = 1;
    	for (i = 0; i < N; i++)
    	{
    		insert(&t, &x, valore[i], col);
    		col = col ^ 3;
    	}
    
    e la printf nel ciclo di presentazione diventa
    
    printf("%d(%s)->", x->numero, c[x->colore]);
    
  • Re: Roulette con lista concatenata circolare

    Ormai uso item per abitudine in generale, non penso bisnogna essere così pignoli su quello quando non era il punto del problema .
    ]Meno male che ti avevo detto di usare 0 1 e 2 per i colori. Hai usato un puntatore a char senza inizializzarlo e ci hai copiato una stringa con un semplice =

    ... che ti aspetti che succeda?
    Potresti gentilmente spiegarmi invece il perché, nonostante sia sbagliato, vengano stampati correttamente i dati prima di darmi comunque quel messaggio? Magari farmi capire dove sta l'errore evidenziandolo in modo tale da farmi un'idea chiara e di non ripeterlo?
  • Re: Roulette con lista concatenata circolare

    Ormai uso item per abitudine in generale, non penso bisnogna essere così pignoli su quello quando non era il punto del problema .
    E invece sbagli, perché quello è un termine generico usato nel codice didattico. Ma quando ti "cali" nel problema "reale" ti devi abituare a lavorare con i termini reali. Fossi il tuo professore (magari lo sono chissà ...) lo apprezzerei ... a buon intenditor ...

    Per il resto ... hai studiato i puntatori? Se sai cosa sono saprai che un puntatore serve per accedere a memoria che, nel tuo caso, non esiste perché non l'hai mai allocata. Quindi se usi un puntatore per la stringa devi prima allocare la memoria con una malloc.

    Inoltre, una volta allocata la memoria, la copia di una stringa si fa con un trasferimento dei singoli caratteri da memoria a memoria, non con un =
    Per farlo velocemente, puoi usare la funzione strcpy

    Ma sicuramente avrai studiato queste cose ...

    Comunque il problema più grave è quello dell'uso di sizeof *t che NON fa quello che credi. Scrivi esplicitamente sizeof node
  • Re: Roulette con lista concatenata circolare

    Quando ho cominciato a trattare le strutture all'inizio ho cominciato con un programma che inizializzasse un mazzo di carte
    e lo faceva in modo simile. Comunque cercando un pò in giro ho capito qual è il problema ed effettivamente complica inutilmente le cose utilizzando dei puntatori quando si potrebbe fare a meno... Comunque grazie adesso è molto più chiaro!
  • Re: Roulette con lista concatenata circolare

    Non sottovalutare la questione del sizeof ... quello è un errore grave.
  • Re: Roulette con lista concatenata circolare

    Hai ragione , ti dico sinceramente che non ci ho fatto caso è stato veramente un lapsus perché mentre leggevo i vari codici dal libro nella parte riguardante liste circolari è uscito quel sizeof*t e fino alla fine pensavo fosse il nome della struttura quando è in realtà solo il link al nodo e non il nodo stesso... è la prima volta che mi succede questo e l'ho sempre fatto correttamente
  • Re: Roulette con lista concatenata circolare

    Questo genera i problemi di accesso non consentito alla memoria.
Devi accedere o registrarti per scrivere nel forum
14 risposte