New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sistema Cerca #20
Comments
Il sistema in se è semplicissimo da fare, saranno si e no 20 minuti di lavoro. |
Se ogni oggetto ha probabilità diverse di venire estratto la cosa si fa complessa, perchè pur potendo memorizzare per ogni oggetto la probabilità di essere ritrovato, quest'ultima è legata al totale degli oggetti presenti; all'aumentare degli oggetti esistenti la probabilità di trovare un oggetto in particolare si diluisce. Bisogna anche contare che la probabilità totale deve essere 100 (meno il valore dell probabilità del fallimento, eventualmente), e quindi ogni volta che si aggiunge o toglie un oggetto è necessario risistemare le probabilità memorizzate per tutti gli oggetti. In effetti la cosa è problematica. Non sono una cima in probabilità.....esiste un qualche indice che non dipende dal numero totale di oggetti? Se invece tutti gli oggetti hanno la stessa probabilità di essere ritrovati allora la cosa è davvero molto semplice. Ma non credo che qualcuno vorrebbe un sistema in cui una spada leggendaria abbia la stessa probabilità di essere ritrovata di un vecchio stivale. |
Secondo me bisognerebbe mettere un valore "%di trovarlo" poi si sommano tutti i valori degli oggetti trovabili e si lancia un dado in base al numero che esce so va a ripescare l'oggetto. 10+1+7= 18 quindi 1d18 |
Il problema è quello ci sono oggetti infatti che sono più difficili da trovare,quindi,correggetemi se sbaglio va impostato sull'oggetto la rarità che viene poi elaborata come dici tu breaker,no? |
si dovrebbe andare. |
Se esce 1-10 prendi una spada, se esce 11 prendi cristallo se esce 12-18 prendi l'ascia. Questo passaggio non ho idea di come scriverlo xD |
Quando fai la somma per trovare il totale su cui fare il random devi decidere un ordinamento fisso che terrai per gli oggetti. Mettili in un array in quell'ordine, ogni elemento dell'array deve contenere l'ID dell'oggetto e la sua probabilità. Ora inizia a scandire l'array dall'inizio e a ogni iterazione somma in una variabile la probabilità dell'oggetto attuale. Nel momento in cui la somma passa da minore a maggiore o uguale del numero estratto a caso fermati. L'oggetto corrente è quello da selezionare. |
Boh, ti ho scritto in 2 minuti come lo farei io senza sbatterci molto la testa. Edit: forse come lo avevo scritto faceva confusione, intendevo il mio sistema lavora in percentuale ma i valori di rarità che puoi assegnare ad ogni oggetto non definiscono la sua diretta percentuale, quanto più la sovrabbondanza (o carenza) di esso rispetto a qualcun altro in lista. Se in lista ho un oggetto che vale 5 e un altro che vale 10, significa che quello che vale 10 si trova in proporzione il doppio delle volte rispetto a quello che vale 5, mentre si trova 10 volte più spesso contro un ipotetico oggetto che vale 1. Spero sia più chiaro così ;) <?php
#> Agevoliamoci la vita
function calcolaPercentuale($totale, $valore)
{
return intval((100/$totale)*$valore);
}
#> Elenco oggetti e percentuali
$valori = array(
'idoggetto1' => 30,
'idoggetto2' => 25,
'idoggetto3' => 15,
'idoggetto4' => 44,
'nulla' => 80);
#> L'ordinamento è fondamentale
asort($valori);
#> Totale ci serve per fare i calcoli
$totale = array_sum($valori);
#> Tiriamo il nostro dado immaginario
$casualita = mt_rand(0,100);
foreach ($valori as $riferimento => $valore)
{
$calcolo = calcolaPercentuale($totale, $valore);
echo 'Il riferimento "',
$riferimento,
'" ha una percentuale di uscita del ',
$calcolo,
'... ';
if ($casualita <= $calcolo)
{
echo 'Trovato!';
#> Trovato, interrompo bruscamente il mio foreach
break;
}else{
echo 'Non trovato.';
}
echo '<br>';
}
echo '<br><br>
Coff, coff, ripeto se non ti fosse chiaro che ho trovato un "',
$riferimento,
'" !';
?> |
Potrei sbagliarmi ma l'algoritmo qui sopra non mi sembra essere corretto. |
Mi sa che hai pienamente ragione, per completarlo a dovere ci vorrebbe una funzione di ordinamento casuale degli indici aventi gli stessi valori. |
Toh, oggi ho qualche minuto libero xD function riordinaValori($valori)
{
asort($valori);
$oggetti = array();
foreach ($valori as $idOgg => $valOgg)
{
if (!isset($oggetti[$valOgg]))
$oggetti[$valOgg] = array();
$oggetti[$valOgg][] = $idOgg;
}
$valori = array();
foreach ($oggetti as $valOgg => $idOgg)
{
if (count($idOgg) == 1)
{
$valori[$idOgg[0]] = $valOgg;
}elseif (count($idOgg) > 1) {
shuffle($idOgg);
foreach ($idOgg as $singoloOgg)
{
$valori[$singoloOgg] = $valOgg;
}
}
}
return $valori;
} |
Oppure fai il tiro casuale tra 0 e $totale e selezioni l'oggetto che deve uscire in base all'intervallo in cui si trova il numero casuale, come voleva fare sopra breaker |
Anche il mio usa la stessa logica, solo che standardizza i range nell'intervallo 0-100% |
Eh non esattamente. Con il tuo approccio hai bisogno dell'operazione che hai appena scritto, che contiene codice con complessità abbastanza alta. Questa operazione non è necessaria con l'approccio che ho descritto nel mio commento di ieri, che quindi risulta avere una complessità più bassa. |
Ah questo è sicuro, il tuo approccio è più conveniente dal momento in cui mi hai fatto notare quel problema. |
Ora che ho un po' di tempo posso mettere in codice il mio algoritmo, affitto il codice di @PHPmyWay modificandolo XD #> Elenco oggetti e percentuali
$valori = array(
'idoggetto1' => 30,
'idoggetto2' => 25,
'idoggetto3' => 15,
'idoggetto4' => 44,
'nulla' => 80);//Ricordati di inserire nell'array anche la percentuale di non trovare nulla
/**
* L'ordinamento è importante per avere risultati più consistenti tra diverse chiamate alla funzione ricerca.
* Se riesci a farlo nella query SQL piuttosto che in PHP è molto meglio!
* Non importa che tipo di ordinamento fai, l'importante è che sia deterministico
*/
asort($valori);
#> Totale ci serve per fare i calcoli
$totale = array_sum($valori);
#> Tiriamo il nostro dado immaginario
$casualita = mt_rand(0,$totale);
$sum=0;
foreach ($valori as $riferimento => $valore)
{
$sum+=$valore;
if ($sum>=$casualita)
{
echo 'Trovato un ".$riferimento."!';
break;
}
}
?> Dovrebbe andare |
chiudo per inattività. |
Sarebbe utile averlo per gli oggetti ma se verranno tolti,non so. Però molti giochi utilizzano la funzione giornaliera della caccia o della cerca che comporta il trovare un'oggetto qualsiasi o un fallimento.
The text was updated successfully, but these errors were encountered: