|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
[scacchiera] problema di logica
Secondo voi c'è qualche errore nel seguente ragionamento?
Immaginatevi di avere una scacchiera 10*10, con le caselle numerate da 1 a 100, dove 1 è la prima in alto a sinistra e la 10 l'ultima in alto a destra. C'è un damino per esempio alla casella 91, deve arrivare alla posizione 24. Il numero di caselle di cui si deve muovere il damino per arrivare dalla 91 alla 24 lo calcolo sottraendo le decine alle decine e le unità alle unità della cella da raggiungere e da quella di posizione iniziale. Sottraggo ovviamente il valore più grande al più piccolo. In questo caso: (9-2)+(4-1)=10, ci sono quindi 10 movimenti da fare tra la 91 e la 24. Ora , supponendo di avere più di una casella da raggiungere contenute in un vettore, il damino per muoversi in maniera intelligente dovrà tentare di raggiungere prima la più vicina, poi la seconda più vicina e così via. Quindi io mi creo un nuovo vettore che chiamo distanza e ci metto i calcoli come sopra per avere il numero di mosse da fare per conquistare ogni casella. Tutti i vettori sono di uguale lunghezza, cioè 10. Io ora ho questi vettori non necessariamente ordinati: caselle da conquistare (12, 14, 25, 32, 92, 93, 95, 4, 1, 13) distanza (9 , 11, 11, 7 , 1 , 2 , 4 , 12, 9, 10) (ho fatto i calcoli un po' in fretta spero siano giusti) Faccio un ciclo sul vettore distanza cercando il minimo numero contenuto. Una cosa del genere: Codice:
min=distanza[1];
for(i=1;i<=10;i++)
{
if(distanza[i]<min)
{
min=distanza[i];
obiettivo=i;
}
}
Per spostare il damino faccio un ragionamento del tipo: se le decinde della casella da conquistare sono minori delle decine della casella di posizione allora lo spostamento sarà verso l'alto. Se le decine sono maggiori lo spostamento è verso il basso. Se le unità sono minori è verso sinistra. Se le unità sono maggiori è verso destra. (ci sono delle eccezioni per i numeri a unità pari a 0 ma per quelli ho delle condizioni a parte, per ora mi interessa che funzioni questo). Ogni volta che faccio uno spostamento aggiorno la variabile posizione così la volta seguente che viene chiamata la funzione tutti i calcoli sono fatti di nuovo e tutto viene aggiornato. Ovviamente quando una casella viene conquistata imposto i vettori in modo che non vengano considerate le celle che si riferivano a quella casella. Vedete degli errori in questa logica? Perchè implementando il tutto, il pc già alla prima mossa mi si muove male. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Aug 2003
Messaggi: 114
|
ah... il classico problema del commesso viaggiatore
comunque se vuoi usare la tua strategia dovresti aggiornare il tutto quando arrivi all'obbiettivo, non prima, tanto non serve anzi probabilmente ti introduce dei casini. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
Qual è il problema del commesso viaggiatore?
L'obiettivo lo modifico una volta effettuato lo spostamento di casella. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Scusa perpaciere il codice
Scusa la logica mi sembra giusta se puoi mi fai vedere il codice di questa parte forse riesco a capire meglio
Ciao !! |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
Ecco qua il codice.
Questa è una funzione, le variabili non vengono usate in nessuna altra parte. Codice:
void IA()
{
int k=0;
int minimo=0;
int obiettivo=0;
int temp=0;
//decine e unità della casella da conquistare
int dc[10]={0,0,0,0,0,0,0,0,0,0};
int uc[10]={0,0,0,0,0,0,0,0,0,0};
//decine e unità della casella di posizione
int dp=0;
int up=0;
//Calcolo qual'è la casella più vicina da conquistare per il pc
for(k=1;k<=10;k++)
{
dc[k]=caselle_da_conquistare[k]/10;
uc[k]=caselle_da_conquistare[k]-(dc[k]*10);
}
dp=pos/10;
up=pos-(dp*10);
//ciclo per il riempimento del vettore distanza
for(k=1;k<=10;k++)
{
if(dc[k]>=dp)
{
temp=dc[k]-dp;
}
if(dc[k]<dp)
{
temp=dp-dc[k];
}
if(uc[k]>=up)
{
temp=temp+(uc[k]-up);
}
if(uc[k]<up)
{
temp=temp+(up-uc[k]);
}
distanza[k]=temp;
}
//Ora ho 2 vettori di uguale dimensione, uno con tutte le caselle da conquistare
//ed uno con le distanze dalla posizione attuale
minimo=distanza[1];
obiettivo=1;
for(k=1;k<=10;k++)
{
if(distanza[k]<minimo){obiettivo=k;minimo=distanza[k];}
}
//Obiettivo adesso contiene l'indice della casella che il pc
//deve tentare di conquistare al momento
//coord_xp ed yp sono le coordinate a cui viene disegnato il pedino
//del pc e 60 è la lunghezza di una casella, quindi il codice seguente
//non fa altro che spostare il pedino di una casella in una direzione
if(dc[obiettivo]<dp)
{
coord_yp=coord_yp-60;
}
if(dc[obiettivo]>dp)
{
coord_yp=coord_yp+60;
}
if(uc[obiettivo]<up)
{
coord_xp=coord_xp-60;
}
if(uc[obiettivo]>up)
{
coord_xp=coord_xp+60;
}
Sleep(150);
disegna(pc, coord_xp, coord_yp, 40, 40, 0, 0);
}
La posizione iniziale è la casella 91. Non ci sono nemmeno i controlli per l'ultima colonna a destra, ovvero quella della casella 10,20,30... |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Risposta ap rimo sguardo..
non ho avuto molto tempo per controllare tutto il codice ma le prime cose che mi sono balzate agli occhi sono gli indici dei cicli che iniziano da uno, facendo iniziare l'indice da uno di perdi il primo elemento del vettore (un vettore dichiarato int vett[10] a gli indici da 0 a 9 i cicli fatti da te vanno da 1 a 9).
Poi aggiusta il codice, esempio if (a>=b).... if(a<b)... si puo scrivere anche if(a>=b)..... else ..... forse questa scrittura e meno conprensibile da chi legge il codice ma è certamente più performante |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
Re: Risposta ap rimo sguardo..
Quote:
Ho paura che ci sia un errore molto camuffato da qualche parte perchè non funziona proprio, neanche se metto gli indici da 0 a 9. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Rieccomi
Penso che questo l'hai capito:
il for lo devi scrivere cosi: Codice:
for(k=0;k<=9;k++) Codice:
for(k=1;k<=9;k++) non mi sembra che ci siano errori l'unica cosa che mi può destare sospetto può essere solo l'eliminazione delle distanze zero che potrebbero impedire la mossa ma nient'altro attento comunque con l'uso dell'altro vettore, quello che usi per inizializzare il tutto... Ciao !!! (Bello pero il nome della funzione) |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Consilio
Se continua a non funzionarti fatti un log dove scrivere tutti i risultati dei calcoli che ai fatto..
Ariciao !!! |
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Aug 2003
Messaggi: 114
|
Ma caselle_da_conquistare è inizializzato correttamente ??
Poi ricordati che devi usare gli indici da 0 a 9 anche qui: minimo=distanza[1]; obiettivo=1; Ultima modifica di Ragazzo del '99 : 21-02-2005 alle 22:12. |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Mar 2003
Città: Rimini
Messaggi: 1846
|
Quote:
Non ci posso credere, sto sbattendo la testa da un quarto d'ora contro lo spigolo della porta. caselle_da_conquistare era inizializzato in una funzione che mi sono dimenticao di chiamare. Adesso funziona, è l'errore più stupido che abbia mai fatto. Grazie a tutti adesso il pc muove correttamente.. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Succede...
Non ti preoccupare questi problemi li anno anche gli esperti programmatori
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 414
|
Curiosita
Lo sai che il calcolo della distanza lo potevi scrivere anche in una sola riga ...
Provaci poi ti do la soluzione ..... Inoltre altre cose possono essere ristrette come codice, il che non vuol dire che siao più veloci o performanti da eseguire ma che solo occupano meno spazio nel file sorgente (cioè non ciè non cambia niente) |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:28.



















