Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Salve a tutti. Sto incontrando alcune difficoltà nell'implementazione di un algoritmo. Come da titolo, l'esercizio è riferito al cammino casuale di due pedine su una scacchiera (la traccia dell'esercizio è nel codice). Quello che non riesco a fare è tenere traccia del cammino della pedina, ed inoltre mi capita che a volte il cammino termina quando le due pedine si incontrano, mentre altre volte no. Qualcuno riesce a farmi capire qual è l'errore che faccio??
Codice sorgente - presumibilmente Python
/**Si vuole sviluppare un algoritmo del cammino casuale di una pedina. Un cammino si svolge su una scacchiera in cui ogni casella
rappresenta una possibile posizione del cammino della pedina. Standoin una casella, una pedina può muoversi solo nella casella
a destra, nella casella a sinistra, nella casella sopra o nella casella sotto. La scelta di una tra queste quattro caselle deve
essere fatta a caso (generando per esempio un numero intero in{0,1,2,3}).
Ogni movimento da una casella all’altra è detto passo del cammino. L’algoritmo usa un array 2D nxn, con n=30, per simulare la scacchiera.
Ci sono due pedine sulla scacchiera, e all’inizio una si trova nella casella in alto a sinistra e l’altra nella casella in basso a destra.
A ogni movimento di una pedina, segue il movimento dell’altra pedina. Fare attenzione al movimento di una pedina quando si trova sul bordo
della scacchiera. L’algoritmo procede finché accade che le due pedine tentano di muoversi sulla stessa casella della scacchiera;in tal caso
l’algoritmo termina (cammino terminato), restituendo il numero di passi effettuati. Organizzare l’algoritmo come una function che restituisce
il numero di passi (lunghezza)del cammino. Scrivere un main che per 100 volte chiama la function e visualizza la lunghezza di ogni cammino
effettuati.**/
Ultima modifica effettuata da eclix il 11/06/2012 alle 19:43
23: Perché passi singolarmente tutti quei valori quando puoi passare direttamente le 2 struct "ped_1" e "ped_2"? con una semplice modifica puoi inserire anche il carattere che rappresenta la pedina nella struttura
Come mai disegni il movimento delle pedine a video se non è richiesto nella consegna?
Ultima modifica effettuata da subazu il 21/05/2012 alle 16:40
intanto puoi modificare il prototipo della funzione da così:
Codice sorgente - presumibilmente C++
int function_mia (char[][N], int*, int*, char, int*, int*, char);
a così
Codice sorgente - presumibilmente C/C++
int function_mia (struct pedina*, struct pedina*);
apportando però prima delle modifiche alla struttura
1 dargli un nome (struct pedina{....} al posto di struct {})
2 inserirci una variabile di tipo char nella struttura
in modo che poi all'interno della funzione tu possa usare le variabili utilizzando questa sintassi:
Non mi sono spiegato bene, la funzione "function_mia" ha come prototipo:
Codice sorgente - presumibilmente C++
int function_mia (char[][N], int*, int*, char, int*, int*, char);
Passare così tanti parametri alla funzione può essere solo che fonte di errore, no?
Non sarebbe più comodo passare le "pedine" alla funzione, invece che ogni loro capo?
così è come invochi tu la tua funzione:
Questo è solo un consiglio che è però necessario seguire per programmare correttamente, anche non seguendolo il programma funzionerà, ma la sua fluidità logica ne risente.
Per il tuo problema principale invece devi ripensare un attimo a cosa devi fare.
Intanto in informatica i concetti: "scrivere", "leggere" e sopratutto "vedere" sono sempre relativi.
Per vedere se due pedine sono nello stesso posto basta confrontarne le coordinate
Codice sorgente - presumibilmente C/C++
if ((p1.x == p2.x) && (p1.y == p2.y)) {
//le pedine sono nello stesso posto
}
else{
//le pedine sono in posti diversi
}
La parte logica del programma deve essere, indipendente da ciò che vedi a video.
Non so se è chiaro ma la parte video (i caratteri del terminale per intenderci) sono l'ultima cosa a cui devi pensare, prima devi pensare alle variabili, ai loro valori, e a come gestirle.
Il problema è chiaro, devi:
1posizionare** le pedine
2fino a che non si scontrano
1muovi una delle pedine (prima una, il ciclo dopo l'altra)
3fine.
**anche posizionare in questo caso è relativo, infatti non devi posizionare proprio niente da nessuna parte, questo perché a te interessano solo le coordinate delle pedine (tralascia il comparto video per ora, lo risolviamo in seguito).
allora... ho aggiustato un pochino il codice apportando delle modifiche mie e dei vari suggerimenti che mi hai dato aggiungendo man mano anche dei commenti per ogni riga.
Ti posto ora l'intero codice in modo tale che tu abbia una panoramica più chiara di cosa abbia potuto combinare XD
Codice sorgente - presumibilmente C++
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 30
#define SU 0
#define GIU 1
#define DESTRA 2
#define SINISTRA 3
//struttura
struct pedina {
int x;
int y;
char simb;
};
// viene definito un nuovo tipo 'Pedina'
typedefstruct pedina Pedina;
//prototipi delle function
void build_chess(char[][N]);
void show_chess(char v[][N]);
void movimento_casuale(char[][30],Pedina*,int);
int function_mia (char[][N], Pedina *, Pedina *);
void main ()
{
Pedina p1={0,0,''}, p2={29,29,'y'};/* le pedine p1 e p2 sono variabili di tipo struttura alle quali vengono assegnate,
per ciascuna pedina, le proprie coordinate (1° campo e 2° campo) e il corrispettivo simbolo (3° campo)*/
char walk[N][N];//dichiarazione della matrice (scacchiera 30x30)
int conta_passi;// variabile utilizzata per chiamare la function che dovrebbe restituire il numero dei passi delle pedine
build_chess(walk);//chiamata alla void function che costruisce la scacchiera
walk[p1.x][p1.y]=p1.simb;//postazione iniziale della pedina1
walk[p2.x][p2.y]=p2.simb;//postazione iniziale della pedina2
printf("\n");
show_chess(walk);//chiamata alla procedura per la visualizzazione su schermo della scacchiera
system("pause");
system("cls");//pulisce lo schermo
conta_passi=function_mia(walk, &p1, &p2);
printf("Cammino terminato!\nNumero di passi eseguiti: %d", conta_passi);
}
/*La void function seguente esegue lo spostamento della pedina in base alla direzione ottenuta attraverso la chiamata alla rand.
Per ciascun caso (case) viene stabilito l'intervallo delle coordinate entro le quali la pedina può eseguire lo spostamento, evitando, in tal modo,
che essa possa uscire fuori dai bordi della scacchiera*/
Ecco, io direi molto bene, già solo con 2 modifiche alla struttura tutto il programma ne giova.
Un altro modo per passare i parametri alle funzioni è per reference, e si fa così
Codice sorgente - presumibilmente C/C++
int function_mia (char [][N], Pedina &, Pedina &);
con questo tipo di parametri puoi accedere ai campi della struttura con una sintassi semplificata, da così
Codice sorgente - presumibilmente Plain Text
(*pawn).x=0;
a così
Codice sorgente - presumibilmente Plain Text
pawn.x=0;
Il prossimo passo è fare il restyling del main, anche se non è corretto che ti imposti io l'intero programma, in questo caso ti risparmio un sacco di teoria, ovvio che hai l'obbligo di mettere in discussione i miei metodi dove non ti garbano, e ricevere delle spiegazioni
Prima di tutto io diminuirei al minimo le istruzioni base dal main, non so se hai mai sentito del principio "divide et impera", bene tienilo sempre a mente.
Atomizzare il codice, spezzettare e dividere in unità più piccole tutto ciò che si può porta ad un sacco di vantaggi
- leggibilità maggiore
- meno errori
- facilita la correzione e gli upgrade
- rende più facile scovare i bug
- ecc.
Per programmi così piccoli non dovrebbe essere necessario tutto questo rigore, ma prima si impara a programmare così, prima si è in grado di capire quando non è necessario farlo.
io ad esempio farei così;
Codice sorgente - presumibilmente C++
void main (){
//variabili
Pedina p1, p2;//pedine
int conta_passi;//contatore
int nPed= TRUE ;//true se ped1, false se ped2
//inizializzazione
initialize(p1,p2);//imposta i valori iniziali alle pedine
while(!((p1.x== p2.x)&&(p1.y== p2.y))){//se due pedine non hanno coordinate uguali
system("cls");//pulisce lo schermo
show_chess(p1,p2);//disegno le 2 pedine
//muovo a turno una delle pedine
if(nPed){
//muovo la pedina 1
movimento_casuale(p1);
nPed =! nPed;//cambio la pedina che verrà mossa il giro dopo
}
else{
//muovo la pedina 2
movimento_casuale(p2);
nPed =! nPed;
}
conta_passi++;//incremento il numero di mosse
}
}
printf("Cammino terminato!\nNumero di passi eseguiti: %d", conta_passi);
}
Se hai qualche dubbio chiedi, anche se leggendo solo i commenti il codice si spiega da solo.
Devi intanto capire come funziona, per le altre implementazioni ci penserai dopo, sono comunque tutte molto semplici (non ti spaventare se non vedi la matrice perché in realtà non ti serve)
Credo che questo sia una impostazione abbastanza carina, il codice non è testato e potrebbero esserci degli errori di SINTASSI.
Ultima modifica effettuata da subazu il 27/05/2012 alle 22:14
allora... per quanto riguarda il primo punto, cioè il passaggio dei parametri alle funzioni, ho provato a farlo nel modo che mi hai suggerito, ma il compilatore continua a darmi un errore del tipo:
"expected ';', ',' or ')' before '&' token".
non credo di aver commesso errori di sintassi dato che non ho fatto altro che mettere & al posto di *.
Poi, per quanto riguarda il restyling del main, quel ciclo while dovrei inserirlo nella funzione "function_mia" visto che nella traccia è richiesto di organizzare l'algoritmo come una function che restituisce il numero dei passi effettuati?
Ma togliendo la scacchiera la funzione "show_chess" deve essere cambiata suppongo, giusto?
la spostamento che esegue la pedina con la chiamata alla rand perché non compare? Si trova all'interno della funzione movimento_casuale?
Scusa se ti faccio troppe domande, ma te lo chiedo semplicemente per vedere se ho effettivamente capito i cambiamenti che hai apportato.