Disposizioni di permutazioni di combinazioni?

utente335
Buongiorno, sto cercando di scrivere un algoritmo per enumerare tutti i casi possibili di [strike]distribuzioni[/strike] assegnazioni di carte a un certo numero di giocatori. Ogni giocatore può tenere in mano da 2 a 5 carte. Diversi giocatori possono avere un numero diverso di carte contemporaneamente. Cosa dovrei usare: distribuzioni, permutazioni, o combinazioni? A me sembrano quasi "una disposizione di permutazioni di combinazioni", o uno strano misto di tutte.

Supponiamo il caso semplice in cui il mazzo contenga 7 carte, e ci siano due giocatori, e mi interessa sapere tutte le possibili assegnazioni di carte supponendo che uno di essi tenga in mano 2 carte e l'altro 3 carte. Vorrei sapere se il mio algoritmo è corretto:

-Dispongo tutte le carte del mazzo in ordine in un array di 7 elementi
-Faccio scorrere degli indici su quell'array, che mi indicano quali carte assegnare ai giocatori ad ogni iterazione, sono due indici per il primo giocatore e tre indici per il secondo
Siano da 1 a 7 le carte ordinate, "A" gli indici del primo giocatore, "B" gli indici del secondo giocatore, pertanto sono due gruppi di indici (A e B). All'interno di ogni gruppo suppongo si debbano considerare le combinazioni, all'esterno dei gruppi le permutazioni, ma ogni gruppo può "incastrarsi" in un altro. La situazione iniziale è la seguente:
1 2 3 4 5 6 7
A A B B B - -

In questo caso il primo giocatore avrà in mano le carte [1,2] e l'altro giocatore avrà le carte [3,4,5]

Ora faccio scorrere in avanti di una posizione l'ultimo indice, ottenendo:
1 2 3 4 5 6 7
A A B B - B -
In questo caso il primo giocatore avrà in mano le carte [1,2] e il secondo giocatore avrà le carte [3,4,6]

E così via. Ecco più o meno l'algoritmo generico:
-Provo a spostare a destra di una posizione l'ultimo indice dell'ultimo gruppo a destra
-Se non ci riesco (perché è arrivato in fondo o perché non ci sono più posizioni libere alla sua destra), allora provo con l'indice precedente nello stesso gruppo
-Se riesco, allora faccio avanzare quell'indice e compatto alla sua destra tutti gli indici dello stesso gruppo, e (se possibile) compatto a sinistra nelle posizioni libere tutti gli indici di tutti i gruppi alla destra di quel gruppo
-Se non ci riesco, allora provo con il primo indice spostabile del gruppo precedente, e se riesco a spostarlo, allora compatto a sinistra in tutte le posizioni libere gli indici di tutti i gruppi successivi
-Ricomincio a spostare l'ultimo indice dell'ultimo gruppo a destra...
facendo ciò, dovrei ottenere i seguenti casi:
1 2 3 4 5 6 7
A A B B B - -
A A B B - B -
A A B B - - B sono arrivato in fondo, devo far avanzare il B precedente
A A B - B B - e tutti i B successivi (qui solo uno) li "comprimo" verso il B che è avanzato
A A B - B - B
A A B - - B B
A A - B B B -
A A - B B - B
A A - B - B B
A A - - B B B l'intero gruppo B non ha indici da poter avanzare, considero il gruppo precedente A
A B A B B - - faccio avanzare l'ultimo A, e compatto il blocco B nelle posizioni libere verso sinistra
A B A B - B -
A B A B - - B
A B A - B B -
A B A - B - B
A B A - - B B
A - A B B B -
A - A B B - B
A - A B - B B
A - A - B B B
A B B A B - -
A B B A - B -
A B B A - - B
A B - A B B -
A B - A B - B
A B - A - B B
A - B A B B -
A - B A B - B
A - - A - B B
A - - A B B B qui non posso far avanzare il secondo A, quindi avanza il primo
B A A B B - -
...
B B B A A - - dopo un po' i gruppi A e B si scambiano di "posizione"
B B B A - A -
-e-così-via...

E poi vorrei generalizzare per poterlo applicare prendendo come ingresso una lista di dimensioni, rappresentanti le dimensioni dei gruppi, applicandoli a un mazzo di n carte generiche.
Ma mi sembra un po' troppo complicato e mi sfugge qualche cosa o qualche caso, e poi dovrò anche tradurlo in linguaggio C# (probabilmente usando le ricorsioni), esiste un modo più semplice?

Risposte
Umby2
Se ho ben capito quello che vuoi fare si tratta di combinazioni.
Nel tuo esempio hai le combinazioni di 2 carte tra le 7 possibili per il giocatore A,
e subito dopo le combinazioni di 3 carte tra le 5 carte rimanenti.

Il ciclo che hai fatto è un po contorto, ma dovrebbe funzionare,
tutto sta a sapere se ti interessa solo il risultato finale (il numero dei casi possibili), oppure se ti serve l'elenco completo di tutti i casi possibili.
Nle primo caso, potresti (anziche' fare un programma ), mettere in un foglio excel, i seguenti dati:
- il numero di carte totali (nel tuo esempio 7)
- il numero di carte del gioc. A (nel tuo esempio 2)
- e quelle del gioc. B (nel tuo esempio 3)
e scrivere la formuletta, per il calcolo delle possibili combinazioni. Dovrebbe venire 210 (salvo errori).

Nel caso ti serve l'elenco completo, mbè.. ti consiglierei di fare sempre il conteggio , cosi' da poter controllare se il software funziona correttamente.

utente335
Il gioco di carte che sto tentando di analizzare è la variante "Royal" del Texas Hold'em, dove si usano solo 20 carte invece di 52.
Purtroppo mi interessa ottenere la lista completa di tutti i casi possibili e non solo la quantità che, come giustamente hai scritto, è facilmente ottenibile moltiplicando tra loro i coefficienti binomiali delle combinazioni, e il mio esempio prevede 210 casi possibili, come hai riportato. Posso testare la correttezza dell'algoritmo usando queste formule.

Ma ora mi sorge un altro dubbio: supponiamo il caso di tre giocatori aventi tutti due carte in mano. Il caso [(1,2);(3,4);(5,6)] è da considerarsi equivalente al caso [(1,2);(5,6);(3,4)]? Nel mio algoritmo attuale questi due verrebbero conteggiati come casi separati. E poi c'è il fatto che non devo considerare solo gli avversari, ma anche la board (le 5 carte condivise), quindi nel caso di un solo avversario e della board condivisa, considerando la situazione di carte [(1,2);(3,4,5,6,7)], non credo avrebbe senso considerarla diversa dalla situazione: [(3,4,5,6,7);(1,2)], giusto?

Questa lista di casi possibili mi interessa perché poi la darò in pasto a una funzione che calcola se hero ha vinto o perso in ognuno di quei casi (usando quindi un gruppo di 5 per la board, e un gruppo di 2 per ogni possibile opponent), in modo da poter ottenere la percentuale di vittoria stimata in ogni possibile situazione al tavolo.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.