PDA

View Full Version : [C#] Risiko


malocchio
01-08-2009, 23:29
http://mauriziomastromauro.files.wordpress.com/2008/10/risiko.jpeg


Salve a tutti, scrivo questa volta non per chiedere un aiuto ma per condividere il risultato di un mio studio.
Sono un appassionato di Risiko e, conseguentemente, anche di rosiko :muro:. Il Risiko, c'è da dirlo, è fortemente influenzato dal caso: senza un'adeguata quantità di fattore C, non si fa nulla :O. E' per questo che ho pensato di scavare nei meandri del calcolo delle probabilità per cercare di capire i limiti e le costanti di questo interessante gioco. ;)
Per il primo appuntamento, ho pensato di studiare che relazione fortunosa esiste tra attaccante e difensore.
Per chi non lo sapesse, la sessione di attacco nel Risiko si svolge con le seguenti regole:

- L'attaccante dichiara da quale stato di sua "proprietà" attacca quale stato altrui
es: Dall'Ontario all'Alberta
- A questo punto può decidere con quanti dadi attaccare: se 1, 2 o 3. Può attaccare con un numero di dadi che sia <= al numero di armate (i carrarmati) presenti nello stato di attacco - 1
Ontario: 3 armate -> attacco con massimo 2 dadi
Ontario: 6 armate -> attacco con massimo 3 dadi
- Il difensore decide con quanti dadi difendersi: se 1, 2 o 3. Può difendersi con un numero di dadi che sia <= al numero di armate presenti nello stato attaccato.
- L'attaccante tira i dadi
- Il difensore tira anch'egli i dadi
- Il dado con il valore più alto dell'attaccante viene confrontato con il dado con il valore più grande del difensore.

- Il confronto avviene così (A e D sono rispettivamente il valore del dado dell'attaccante e del difensore confrontati):
A > D allora vince A
A <= D allora vince D
A = 5 e D = 5 allora vince D
A = 1 allora vince D (qualsiasi valore di D tra 1 e 6 è >= 1)
D = 6 allora vince D
Il confronto avviene partendo dal valore più alto fino al valore più basso. Per chiarire:
L'attaccante tira 3 dadi e ottiene [4, 3, 5], il difensore tira 2 dadi e ottiene [4, 4]:
Si creano così le coppie di confronto:
[5, 4] e [4, 4]
Il 3 non viene considerato perché è il più piccolo del lancio e non ha un valore di confronto dalla parte della difesa.
[5, 4] vince A perché 5 > 4
[4, 4] vince D perché 4 <= 4.
In questo caso l'attaccante ed il difensore tolgono dal proprio stato 1 armata ciascuno.
Diventa chiaro che attaccare/difendersi con il maggior numero di dadi possibile risulta vantaggioso. Si nota anche che l'attaccante è in svantaggio rispetto al difensore sulla base dei valori dei dadi, secondo la tabella di confronto. E' proprio di questo che sto parlando: voglio quantificare lo svantaggio che ha l'attaccante, e voglio farlo calcolando il rapporto medio tra il numero di armate che un attaccante riesce ad abbattere e che un difensore riesce ad abbattere in una sessione di attacco/difesa.
Mi spiego meglio, con termini matematici: voglio trovare
il limite,
per numero di lanci effettuati tendente ad infinito,
di D/A,
dove A è il numero di armate perse dall'attaccante e D il numero di armate perse dal difensoreMeglio di così non posso... :rolleyes:

Siccome risulta più vantaggioso tirare sempre 3 dadi, e siccome questo è il caso più comune, ipotizzo che l'attaccante tiri 3 dadi e che il difensore faccia lo stesso. Per ogni possibile risultato dei due lanci valuto il numero di armate perse da ciascuna parte e lo sommo, per poi calcolare finalmente il rapporto D/A.

Bisogna cominciare a studiare i dadi. 3 dadi tirati contemporaneamente generano delle terzine rappresentabili da
COMBINAZIONI RIPETUTE DI ORDINE 6 E CLASSE 3
Queste sono tutte le possibili combinazioni di valori ottenute dal tiro di 3 dadi:
[1, 1, 1] - 1
[1, 1, 2] - 3
[1, 1, 3] - 3
[1, 1, 4] - 3
[1, 1, 5] - 3
[1, 1, 6] - 3
[1, 2, 2] - 3
[1, 2, 3] - 6
[1, 2, 4] - 6
[1, 2, 5] - 6
[1, 2, 6] - 6
[1, 3, 3] - 3
[1, 3, 4] - 6
[1, 3, 5] - 6
[1, 3, 6] - 6
[1, 4, 4] - 3
[1, 4, 5] - 6
[1, 4, 6] - 6
[1, 5, 5] - 3
[1, 5, 6] - 6
[1, 6, 6] - 3
[2, 2, 2] - 1
[2, 2, 3] - 3
[2, 2, 4] - 3
[2, 2, 5] - 3
[2, 2, 6] - 3
[2, 3, 3] - 3
[2, 3, 4] - 6
[2, 3, 5] - 6
[2, 3, 6] - 6
[2, 4, 4] - 3
[2, 4, 5] - 6
[2, 4, 6] - 6
[2, 5, 5] - 3
[2, 5, 6] - 6
[2, 6, 6] - 3
[3, 3, 3] - 1
[3, 3, 4] - 3
[3, 3, 5] - 3
[3, 3, 6] - 3
[3, 4, 4] - 3
[3, 4, 5] - 6
[3, 4, 6] - 6
[3, 5, 5] - 3
[3, 5, 6] - 6
[3, 6, 6] - 3
[4, 4, 4] - 1
[4, 4, 5] - 3
[4, 4, 6] - 3
[4, 5, 5] - 3
[4, 5, 6] - 6
[4, 6, 6] - 3
[5, 5, 5] - 1
[5, 5, 6] - 3
[5, 6, 6] - 3
[6, 6, 6] - 1che sono in tutto 56.
Il numero dopo il trattino è la probabilità associata, su 216 (6³), che sono le disposizioni ripetute di ordine 6 e classe 3.
E' in definitiva il numero di permutazioni possibili per quella terzina, ottenuto così:
3! / n!,
dove n è il numero di elementi uguali tra loro nella terzina.
es:
P([4, 5, 5]) = 3! / 2!
perché l'elemento 5 è ripetuto 2 volte.
Otteniamo 3.

A questo punto, non ho fatto altro che confrontare ogni possibile terzina dell'attaccante con ogni possibile terzina del difensore, determinare il numero di armate perse da ciascun giocatore, sommarle e calcolarne il rapporto, tenendo conto però della probabilità che ciascuna terzina ha di comparire.

Bando alle ciance, questo è il codice. Non è il massimo dell'efficienza, visto che non presenta nessuna ottimizzazione. Ho appena iniziato ad usare il C#, quindi perdonatemi errori madornali.
using System;
using System.Collections.Generic;

namespace Risiko {
class Risiko {
static void Main ( string[] args )
{
List<Terzina> lanci = combinazioniDadi( );
uint[][][] esiti = new uint[lanci.Count][][];
for ( int i = 0 ; i < esiti.Length ; i++ ) {
esiti[i] = new uint[lanci.Count][];
for ( int j = 0 ; j < esiti[i].Length ; j++ ) {
esiti[i][j] = new uint[2];
}
}

for ( int i = 0 ; i < esiti.Length ; i++ ) {
for ( int j = 0 ; j < esiti[i].Length ; j++ ) {
esiti[i][j][0] = lanci[i].abbatteDifesa( lanci[j] );
esiti[i][j][1] = lanci[i].permutazioni * lanci[j].permutazioni;
}
}

ulong pAttacco = 0, pDifesa = 0;
for ( int i = 0 ; i < esiti.Length ; i++ ) {
for ( int j = 0 ; j < esiti[i].Length ; j++ ) {
pAttacco += (ulong)( esiti[i][j][0] * esiti[i][j][1] );
pDifesa += (ulong)( ( 3 - esiti[i][j][0] ) * esiti[i][j][1] );
}
}

double rapporto = (double)pAttacco / pDifesa;
System.Console.WriteLine( "{0} / {1}", pAttacco, pDifesa );
System.Console.WriteLine( rapporto );
System.Console.ReadLine( );

}



public static List<Terzina> combinazioniDadi ( )
{
List<Terzina> l = new List<Terzina>( );
for ( uint a = 1 ; a <= 6 ; a++ ) {
for ( uint b = a ; b <= 6 ; b++ ) {
for ( uint c = b ; c <= 6 ; c++ ) {
l.Add( new Terzina( a, b, c));
}
}
}
return l;
}
}

class Terzina {
public uint a;
public uint b;
public uint c;
public uint permutazioni
{
get
{
return calcPermutazioni( );
}

}

public Terzina ( uint a, uint b, uint c )
{
if ( a <= b && b <= c ) {
this.a = a;
this.b = b;
this.c = c;
} else {
throw new Exception( );
}
}

public uint abbatteDifesa ( Terzina dif )
{
uint k = 0;
if ( this.a > dif.a ) k++;
if ( this.b > dif.b ) k++;
if ( this.c > dif.c ) k++;
return k;
}

public uint abbatteAttacco ( Terzina att )
{
uint k = 0;
if ( this.a >= att.a ) k++;
if ( this.b >= att.b ) k++;
if ( this.c >= att.c ) k++;
return k;
}

private uint calcPermutazioni ( )
{
if ( a == b && a == c )
return 1;
else if ( a == b || a == c || c == b )
return 3;
else
return 6;
}

}
}

Il risultato è il seguente:
51642 / 88326
0,584674954147137
E' da leggere così:
in una sessione di attacco prolugata, il numero di armate perse dall'attaccante si avvicina sempre più a 1,71 (il reciproco di 0.5846) volte le armate perse dal difensore.

Insomma, conviene giocare in difesa ;)


Sono apprezzati consigli, critiche, eccetera

zulutown
02-08-2009, 19:34
in una sessione di attacco prolugata, il numero di armate perse dall'attaccante si avvicina sempre più a 1,71 (il reciproco di 0.5846) volte le armate perse dal difensore.

Insomma, conviene giocare in difesa ;)



è logico che è favorita la difesa, a parità di punteggio vince il difensore.

da bambino risiko mi piaceva molto
poi ho giocato un po' su internet in partite da 6 persone e mi son accorto che è un gioco abbastanza "stupido", fondamentalmente accade che tutti giocano in difesa cercando di aumentare le proprie truppe sui territori di frontiera,

poi arriva il "kamikaze" di turno:

DI solito il giocatore che è messo peggio e che non avendo speranze usa tutta le sue truppe contro qualche "vicino" in un attacco che annienta entrambi e quindi gli altri 4 possono di nuovo espandersi, poi nuovamente tutti stanno sulla difensiva e chi è messo peggio e sa che comunque perderà tenta altro attacco disperato e l'altro sfortunato giocatore scelto viene penalizzato. e così via..

banryu79
03-08-2009, 09:34
Ho sempre preferito il futuRisiKo!
http://www.arkadeigiochi.it/arka/images/stories//giochi/futurisiko.jpg

malocchio
03-08-2009, 09:36
Ho sempre preferito il futuRisiKo!
http://www.arkadeigiochi.it/arka/images/stories//giochi/futurisiko.jpg

Io ho sempre e solo giocato al classico ;)

malocchio
04-08-2009, 09:58
è logico che è favorita la difesa, a parità di punteggio vince il difensore.

da bambino risiko mi piaceva molto
poi ho giocato un po' su internet in partite da 6 persone e mi son accorto che è un gioco abbastanza "stupido", fondamentalmente accade che tutti giocano in difesa cercando di aumentare le proprie truppe sui territori di frontiera,

poi arriva il "kamikaze" di turno:

DI solito il giocatore che è messo peggio e che non avendo speranze usa tutta le sue truppe contro qualche "vicino" in un attacco che annienta entrambi e quindi gli altri 4 possono di nuovo espandersi, poi nuovamente tutti stanno sulla difensiva e chi è messo peggio e sa che comunque perderà tenta altro attacco disperato e l'altro sfortunato giocatore scelto viene penalizzato. e così via..

Sì il Risiko sotto certi punti di vista presenta delle dinamiche che si reiterano sempre, ma dipende anche dai giocatori... Penso che la situazione cambi da compagnia a compagnia ;).

A me danno fastidio quelli che giocano solo sulla difensiva, lasciando armate un po' qui un po' là invece di puntare su confini solidi nel tentativo di ammortizzare i danni. Io sono uno invece che si butta, e il 90% delle volte non ho abbastanza fortuna per fare quello che voglio fare, per cui finisco con l'auto-abbattermi :asd: (tipico, il kamikaze di prima :D).

Però, ignorando il fatto che ci sono tanti fattori che portano alla sconfitta o alla vittoria, il Risiko si presta abbastanza bene a considerazioni logiche/probabilistiche, che regolarmente si rivelano (quasi) inutili :cry:.

A questo punto potrei fare un'azione commerciale di questo genere:
Avete presente il SuperPI, il programma usato per benchare che calcola un certo numero di cifre del pigreco? Potrei fare come quelli che l'hanno scritto e mettermi a vendere le cifre della "costante del Risiko" :asd:
Qualche offerente? :fagiano:

Kralizek
04-08-2009, 10:32
A questo punto potrei fare un'azione commerciale di questo genere:
Avete presente il SuperPI, il programma usato per benchare che calcola un certo numero di cifre del pigreco? Potrei fare come quelli che l'hanno scritto e mettermi a vendere le cifre della "costante del Risiko" :asd:
Qualche offerente? :fagiano:

Appena trovo un'utilitá per la sedicesima cifra decimale della "costante del Risiko", te lo compro io :sofico:

malocchio
04-08-2009, 10:37
Appena trovo un'utilitá per la sedicesima cifra decimale della "costante del Risiko", te lo compro io :sofico:

Asta sulla baia :sofico:

Vabbè :ot: