Il Gioco del Mese NIM



  • Il Gioco del Mese - NIM
    di Vecchio Frac data: 16/07/2015 09:07:51

    La proposta "Il Gioco del mese" è un'iniziativa di informazione e divulgazione destinata a tutti gli utenti di "ExcelVBA.it". A cura della Redazione viene pubblicato e presentato un semplice gioco costruito con Excel e basato su formule, VBA o un mix di entrambe le caratteristiche.
    Pur fornendo un prodotto finito, completo e giocabile, puntiamo sulla finalità didattica dell'iniziativa, pertanto invitiamo tutti gli utenti a partecipare alla discussione per affinare e migliorare la proposta.

    Conosci un argomento interessante su qualche formula particolare o su qualche aspetto della programmazione VBA e vuoi condividere le tue conoscenze con altri sviluppatori e appassionati? Trasformalo in un gioco e scrivi un articolo per il nostro sito! Saremo lieti di valutare il tuo lavoro e di pubblicarlo per accrescere i contenuti tecnici della nostra comunità!

    Chiunque volesse condividere una propria proposta per la pubblicazione può inviarlo a redazione[@]excelvba.it da dove verrà presto contattato per i dettagli.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Questo mese presentiamo:
    NIM by scossa

    Tutti, credo, conoscerete il gioco del NIM. Per quei pochi che non dovessero conoscerlo, lo presento con un esempio pratico.
    Su un tavolo si dispongono tre file di stuzzicadenti. Quella inferiore contiene 5 stuzzicadenti, quella centrale 4 e quella superiore 3.
    Due giocatori si alternano nel togliere un numero a piacere di stuzzicadenti da una fila a piacere.
    Chi toglie l'ultimo, ovvero lascia la tavola vuota, VINCE.

    Come vedete il gioco è molto semplice e, pertanto, facilmente analizzabile. Esiste infatti una semplice strategia vincente che permette (nella versione che ho presentato) al giocatore che fa la prima mossa di assicurarsi la vittoria.

    Il tutto è spiegato su Wikipedia: Gioco del NIM

    Ho preparato un file Excel molto semplice in cui c'è solo riprodotto il tavolo da gioco nella posizione iniziale:


    I bastoncini si selezionano come si selezionano normalmente le celle

    e premendo il tasto CANC si tolgono dal tavolo.

    In questa prima fase, lavorando solo lato foglio (no VBA), vi invito ad implementare tramite formule - formattazione condizionale e altro a piacere, un "analizzatore" che descriva, riferita al giocatore che deve muovere, la posizione presente sul tavolo ("puoi vincere!", "sei fregato!").







    Nelle immagini sopra ho nascosto le righe che analizzano la situazione "binaria":


    Senza VBA ovviamente i due giocatori saranno umani; il passo successivo sarà creare, con VBA, il nostro avversario artificiale che eseguirà le mosse vincenti!

    Se vi siete presi la briga di leggere la pagina wiki che ho indicato, avrete certamente capito che per creare un "analizzatore" della posizione sul tavolo bisogna tradurla in binario ed eseguire la somma NIM dei valori (1 o 0) delle singole colonne:


    Se il risultato sono 3 zeri la posizione è "sicura" e qualsiasi mossa la renderà "insicura"; viceversa, se il risultato presenta anche un solo 1 la posizione è "insicura" e può essere resa "sicura" con, almeno, una precisa mossa.

    La prima cosa che ho fatto, per cominciare, è stata quella di assegnare un "nome" alla tavola (celle $C$4:$K$8).
    Poi ho assegnato un nome alle singole righe: stick3 ($E$4:$I$4), stick4 ($D$6:$J$6) e stick5 ($C$8:$K$8).

    Quindi in N4 calcolo il numero di bastoncini presenti in stick3: =MATR.SOMMA.PRODOTTO(--(stick3="|"));
    in N6 calcolo il numero di bastoncini presenti in stick4: =MATR.SOMMA.PRODOTTO(--(stick4="|"));
    ed in N8 calcolo il numero di bastoncini presenti in stick5: =MATR.SOMMA.PRODOTTO(--(stick3="|"))

    Ora si tratta di trasformare questi 3 numeri decimali nei rispettivi numeri binari di 3 bit.
    per N4:
    in F11: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$4);3);1;1)
    in G11: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$4);3);2;1)
    in H11: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$4);3);3;1)

    per N6:
    in F12: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$6);3);1;1)
    in G12: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$6);3);2;1)
    in H12: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$6);3);3;1)

    ed infine per N8:
    in F13: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$8);3);1;1)
    in G13: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$8);3);2;1)
    in H13: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO($N$8);3);3;1)

    Ora non resta che fare la somma NIM delle singole colonne F11:F13, G11:G13 e H11:H13
    in F14: =--VAL.DISPARI(SOMMA(F11:F13))
    in G14: =--VAL.DISPARI(SOMMA(G11:G13))
    in H14: =--VAL.DISPARI(SOMMA(H11:H13))

    Infine, nella cella B18 (celle unite B18:L18, colore sfondo rosso, colore testo bianco, formattazione condizionale: =CONTA.VALORI(tavola)>0 formato: colore nero, sfondo bianco) con la seguente formula, comunico il risultato dell'analisi:
    =SE(CONTA.VALORI(tavola)=0;"HAI VINTO!!";SE(CONTA.VALORI(tavola)=12;"";SE(MAX($F$14:$H$14);"puoi vincere!";"sei fregato!")))
    che viene mostrato solo dopo eseguita la prima mossa.

    Per chiarezza ho usato la colonna di appoggio N, ma ovviamente si può evitarla sostituendo nelle formule in F11..H13 il riferimento a N con la rispettiva formula:
    in F11: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO(MATR.SOMMA.PRODOTTO(--($E$4:$I$4="|")));3);1;1)
    etc....
    o assegnando a 3 nomi (Riga1, Riga2, Riga3) rispettivamente:
    Riga1 -> riferito a:: =MATR.SOMMA.PRODOTTO(--(stick3="|"))
    Riga2 -> riferito a:: =MATR.SOMMA.PRODOTTO(--(stick4="|"))
    Riga3 -> riferito a:: =MATR.SOMMA.PRODOTTO(--(stick5="|"))
    si può sostutire il riferimento alla colonna N usando detti nomi:
    In F11: =--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO(Riga1);3);1;1)
    etc....

    Sperando di essere stato sufficientemente chiaro, mi auguro di aver suscitato in voi un po' di interesse.

    Questo il link da cui è possibile scaricare il file:
    Clicca qui

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Disclaimer:
    Con l'invio del materiale a ExcelVBA.it siete coscienti del fatto che il sito acquisisce i diritti di utilizzo del materiale stesso, sebbene voi ne rimaniate sempre e comunque gli autori. Questo avviene per motivi legali relativi al Copyright.
    Ciò significa che voi manterrete il diritto di poter ripubblicare il vostro materiale come e dove volete (anche se sareste davvero carini ad avvisare), ma può farlo anche ExcelVBA.it.





  • di Raffaele_53 data: 17/07/2015 12:56:32

    Se non erro, la richiesta del gioco del Nim sarebbe di sviluppare un codice "VBA" (software excel?).
    In teoria tra un'umano e il Codice (VBA che deve sempre vincere). Intanto non si accena a chi deve fare la prima mossa.
    Gioco a me sconosciuto sino due giorni fà. Se toccasse a me la prima mossa, toglierei due stanghe in riga 1 e credo di essere sicuro di vincere. La partenza fosse alternativa, penso di essere almeno PARI

    Se fosse stato di sviluppare solo le formule per trovare (i tre/3 zeri), sarebbe stato meglio come quesito.
    Comunque tanto per provare..., dopo la mia prima mossa. Qualcuno desidera fare la seconda mossa? Sino alla vittoria? In modo tale di capire meglio il meccanismo del gioco.
    Ps. Le risposte, meglio in un post a parte.

    EDIT = PPs Mi sembra come in un film. (il più grande COMPUTER del mondo è andato in tilt (nel gioco del tre O e tre X), quando gli l'hanno detto di giocare PC contro PC.



  • di Vecchio Frac data: 17/07/2015 13:17:26

    @Raffaele
    Ma in realtà questo thread non pone un vero quesito, nè un esercizio da risolvere.
    Si propone qualcosa che illustra qualche tecnica interessante per fare qualcosa. Lo si fa mediante la semplice implementazione di un piccolo gioco, il che ha la capacità di attirare sempre l'interesse, piuttosto che un noioso articolo tecnico :)
    Se poi c'è chi vuole dilettarsi a espandere/migliorare/integrare (lato codice o lato formule), ben venga.





  • di scossa data: 17/07/2015 13:31:11

    cit. Raffaele_53: "n teoria tra un'umano e il Codice (VBA che deve sempre vincere). "

    A dire il vero, io avrei già preparato la versione VBA in cui Excel è l'avversario (imbattibile se la posizione da cui muove è "insicura").

    Aspettavo solo di vedere partire il progetto e di capire se proporre questo sviluppo direttamente qui o fare la "trafila" Area51->approvazione etc. etc.... (Vecchio Frac???)


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 17/07/2015 13:52:11

    @scossa
    cit. " se proporre questo sviluppo direttamente qui"
    ---> Direi certamente qui senza perderci in formalità inutili. La presentazione in anteprima delle proposte in Area 51 è solo per sondare l'eventuale interesse generale. Ma una volta avviata, la discussione può tranquillamente e serenamente proseguire con i contributi di tutti.





  • di scossa data: 17/07/2015 14:04:50

    Perfertto.

    Mentre preparo, con calma, una spiegazione di quanto sviluppato (oltre al file da allegare), vediamo se quanto esposto finora suscita un po' più di interesse di quello visto in questi giorni (ovviamente il caldo e le ferie giocano contro).


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)




  • di Raffaele_53 data: 17/07/2015 14:24:12

    Io credo che Vari utenti siano alieni di non sò quale pianeta.
    Che Voi "alieni" abbiate già la soluzione, non lo metto in dubbio?

    A Noi comuni mortali cosa richiedette (il semplificare delle formule, forse si può fare)?
    Il sviluppare d'un software (io mi escludo, forse altri).

    Comunque >>>il passo successivo sarà creare, con VBA, il nostro avversario artificiale che eseguirà le mosse vincenti!
    Questa mi è sembrata una richiesta? (alla quale non sono in grado, ben vengano altri utenti?)

    scossa >>>A dire il vero, io avrei già preparato la versione VBA in cui Excel è l'avversario (imbattibile se la posizione da cui muove è "insicura").
    Scusami scossa, non ho mai pensato che dici cavolate, qualche volta gioco a scacchi e "qualche mossa la conosco/imparo".
    Però pensa a Noi (Non siamo alieni). Tutte le partite (con scossa = scossa/1000). Vincerai sempre, finchè Noi mortali non riusciamo "solo una volta" a metterti in crisi.



  • di scossa data: 17/07/2015 14:37:46

    edit



  • di scossa data: 17/07/2015 14:43:47

    cit. Raffaele_53: "A Noi comuni mortali cosa richiedete? "

    di divertirvi giocando col file e cercando di capire le formule sottostanti.
    Se poi, stuzzicati da ciò, vi viene l'ispirazione per apportare delle migliorie (come ad esempio portare a 7 il numero max dei bastoncini in ogni fila), bhe fatevi sotto!

    cit. Raffaele_53: " Vincerai sempre, finchè Noi mortali non riusciamo "solo una volta" a metterti in crisi"
    Raffaele: non sono io che vinco sempre, è che il gioco - per come è strutturato - prevede una strategia vincente che assicura la vittoria al giocatore che muove avendo sulla tavola una posizione "insicura".
    Il significato della frase sopra è ben spiegato nell'articolo, ma soprattutto su wikipedia al link che ho citato.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Vecchio Frac data: 17/07/2015 14:55:06

    [OT]
    cit. "finchè Noi mortali non riusciamo "solo una volta" a metterti in crisi."
    ---> LOL, io non ci sono mai riuscito :) scossa è sempre preparato su tutto e infatti trova sempre qualche crepa nei miei esempi ^_^
    [/OT]





  • di Raffaele_53 data: 17/07/2015 15:09:35

    @Scossa
    Sinora pensavo ad un gioco di tre bastoncini+quattro bastoncini+cinque bastoncini...OK

    >>>cercando di capire le formule sottostanti.
    OK, spero di darTi risposta se il quesito è con bastoncini ugualii EX 1.3,5,7,9 su differenti righe.



  • di ninai data: 17/07/2015 16:00:30

    [OT]
    cit. "finchè Noi mortali non riusciamo "solo una volta" a metterti in crisi."

    Credetemi, io l'ho visto!!!, ha fatto il patto con il diavolo!!!!!

    In cambio, il diavolo ha capito come evitare i social tipo FB.



  • di Raffaele_53 data: 17/07/2015 19:20:59

    Mi permetto di corregermi, da "solo una volta" in "almeno una volta" e non c'entra nulla sul gioco ed scossa... solo in Excel.

    >>>se il quesito è con bastoncini uguali EX 1.3,5,7,9
    Credo sia facile fare formule (nulla è sicuro con "scossa").
    Ex Perchè non numeri? Se nel "Codice fossero degli "IF" in VBA? Ci sarebbero troppi da calcolare?



  • di scossa data: 18/07/2015 12:09:54

    cit. Raffaele_53: "Ex Perchè non numeri? Se nel "Codice fossero degli "IF" in VBA? "

    porta pazienza Raffaele, ma sei troppo sintetico e non riesco a capire quello che chiedi.
    Potresti provare ad essere un po' più discorsivo? grazie.



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Raffaele_53 data: 18/07/2015 12:51:55

    Sicuramente è un mio pensiero malsano .
    Però senza convertirli in binario, credo che il risultato sia lo stesso.
    Ex su tre righe, prima riga (dopo aver tolto 2 bastoncini), sarebbe 1
    Seconda riga rimane a 4
    terza riga rimane a 5
    If (primariga = 1) and (secondariga = 4) and (terzariga = 5) then

    Naturale che se il gioco si sviluppa in EX 1,3,5,7,9 righe le combinazioni sono tante. (Domanda, il gioco potrebbe anche essere sviluppato per 2,4,6,8 ecc ecc righe?)



  • di cromagno data: 18/07/2015 15:52:21

    Da quello che ho capito, la certezza di lasciare l'avversario in una posizione "sicura" è data proprio dalla somma binaria senza riporti (detta appunto "Somma Nim"), quindi non credo si possa ottenere lo stesso risultato senza la conversione.

    P.S.
    A tempo perso stavo provando a utilizzare delle formule che mi possano dare un "suggerimento" per fare una mossa e lasciare l'avversario in posizione sicura (magari rendendolo visibile a richiesta tramite un MsgBox)... ma si sta dimostrando più complicato del previsto....
    Resta comunque un buon esercizio per tenersi in allenamento



  • di scossa data: 18/07/2015 16:06:20

    cit. Raffaele_53: "Però senza convertirli in binario, credo che il risultato sia lo stesso"

    La conversione in binario è utile per stabilire se una posizione è "sicura" od "insicura", ma non è l'unica soluzione.

    Comunque, per semplicità (per il giocatore umano soprattutto) consiglio di limitarsi al numero massimo di 7 bastoncini (numero masimo rappresentabile con 3 bit: 4+2+1).


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di scossa data: 18/07/2015 16:15:29

    Ad integrazione di quanto sopra, va poi considerata la "interfaccia" con l'utente: il gioco nasce con le monete (o bastoncini), e buona parte del lavoro consiste proprio nel convertire la quantità degli oggetti in numero. Certo si possono usare i numeri direttamente però diventa solo un problema matematico e si toglie l'aspetto ludico.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)


  • Il NIM pensatore - parte 1/3
    di scossa data: 18/07/2015 23:22:12

    Att.ne: ho dovuto suddividere l'articolo in 3 parti, abbiate pazienza.

    Parte 1 di 3

    Nel post di presentzione abbiamo visto come creare un "analizzatore" della posizione sul tavolo: bisogna tradurla in binario ed eseguire la somma NIM dei valori (1 o 0) delle singole colonne:



    Se il risultato sono 3 zeri la posizione è "sicura" e qualsiasi mossa la renderà "insicura"; viceversa, se il risultato presenta anche un solo 1 la posizione è "insicura" e può essere resa "sicura" con, almeno, una precisa mossa.

    Ora però vogliamo creare un capolavoro: trasformare il nostro computer in un "essere pensante"

    "Il NIM-pensatore"

    capace di vincere implacabilmente se noi dovessimo sbagliare la nostra mossa o se, masochisticamente, cedessimo a lui il privilegio di eseguire la prima mossa!

    Per semplificare la realizzazione del codice ho apportato una modifica al tavolo da gioco: la posizione dei bastoncini è allineata a sinistra
    |||
    ||||
    |||||

    L'aspetto più interessante di questa versione "intelligente" è che, al contrario della vesione senza VBA, NON ho utilizzato nessun tipo di conversione in binario dei numeri rappresentanti i bastoncini presenti sul tavolo.
    Quindi tutte quelle formule in F11...I13 (=--STRINGA.ESTRAI(DESTRA("000" & DECIMALE.BINARIO(MATR.SOMMA.PRODOTTO(--(stick1="|")));3);1;1)) ed in F14...I14 non servono al nostro "pensatore" per analizzare la posizione.

    Infatti al nostro automa basta una semplice function per analizzare la posizione e stabilire se è "sicura" od "insicura"; una function talmente semplice da stare in una sola istruzione che utilizza un solo "magico" operatore.
    Ma prima di scoprire qual'è, consentitemi di fare un breve riepilogo sugli "operatori logici di confronto".

    Lato celle, Excel ci mette a disposizione due sole funzioni logiche di confronto tra due o più espressioni:
    la funzione E (AND): restituisce VERO se tutti gli argomenti (le espressioni) hanno valore VERO;
    la funzione O (OR): restituisce VERO se almeno un argomento è VERO.
    Questa è la tavola della verità della funzione E():

    E(VERO, FALSO) = FALSO
    E(FALSO, VERO) = FALSO
    E(FALSO, FALSO) = FALSO
    E(VERO, VERO) = VERO


    Questa è la tavola della verità della funzione O():

    O(VERO, FALSO) = VERO
    O(FALSO, VERO) = VERO
    O(FALSO, FALSO) = FALSO
    O(VERO, VERO) = VERO


    Ricordo che in Excel, lato celle, solo il valore 0 è considerato FALSO, mentre qualsiasi valore diverso da 0 è considerato VERO:

    E(2, 0) = FALSO
    E(0, 5) = FALSO
    E(0, 0) = FALSO
    E(5, 2) = VERO
    O(2, 0) = VERO
    O(0, 5) = VERO
    O(0, 0) = FALSO
    O(5, 5) = VERO


    In VBA, anziché le funzioni, abbiamo a disposizione degli operatori (come il +, il - etc) logici di confronto:
    operatore And: il risultato dell'operazione di confronto è VERO solo se tutti gli operandi sono VERO;
    operatore Or: il risultato dell'operazione di confronto è VERO se almeno un operando è VERO.

    Questa è la tavola della verità dell'operatore And:

    1 And 0 = 0
    0 And 1 = 0
    0 And 0 = 0
    1 And 1 = 1

    e questa quella dell'operatore Or

    1 Or 0 = 1
    0 Or 1 = 1
    0 Or 0 = 0
    1 Or 1 = 1


    Normalmente siamo abituati a veder utilizzati questi operatori in istruzioni tipo:
    if anni > 18 And sesso = "F" Then ingresso="gratis" Else ingresso = "100 €"

    dove le istruzione del Then vengono eseguite solo se (anni è maggiore di 18) E (sesso è "F").
    Oppure
    if anni < 10 Or anni > 60 Then ingresso="gratis" Else ingresso = "100 €"

    to be continued .......

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)


  • Il NIM pensatore - parte 2/3
    di scossa data: 18/07/2015 23:26:01

    Parte 2 di 3

    In realtà gli operatori logici messi a disposizione dal VBA sono degli operatori logici binari.
    Questo significa che se gli operandi sono espressioni numeriche il confronto viene eseguito bit per bit tra i bit che occupano la stessa posizione, ed il risultato non sarà True o False ma sarà dato dall'impostazione dei corrispondenti bit nel risultato restituito.

    Sarà più chiaro con alcuni esempi (da provare nella finesta immediata).

    Per l'operatore And:
    ? 2 And 0 restituirà 0
    ? 2 And 1 restituirà 0
    ? 2 And 2 restituirà 2
    ? 2 And 3 restituirà 2
    ? 3 And 5 restituirà 1

    Cerchiamo di capire perché.

    2: 0 1 0
    and
    0: 0 0 0
    risultato: 0 and 0 = 0; 1 and 0 = 0; 0 and 0 = 0
    quindi 000 (bin) :: 0 (dec)

    2: 0 1 0
    and
    1: 0 0 1
    risultato: 0 and 0 = 0; 1 and 0 = 0; 0 and 1 = 0
    quindi 000 (bin) :: 0 (dec)

    2: 0 1 0
    and
    2: 0 1 0
    risultato: 0 and 0 = 0; 1 and 1 = 1; 0 and 0 = 0
    quindi 010 (bin) :: 2 (dec)

    2: 0 1 0
    and
    3: 0 1 1
    risultato: 0 and 0 = 0; 1 and 1 = 1; 0 and 1 = 0
    quindi 010 (bin) :: 2 (dec)

    3: 0 1 1
    and
    5: 1 0 1
    risultato: 0 and 1 = 0; 1 and 0 = 0; 1 and 1 = 1
    quindi 001 (bin) :: 1 (dec)


    Per l'operatore Or:
    ? 2 Or 0 restituirà 2
    ? 2 Or 1 restituirà 3
    ? 2 Or 2 restituirà 2
    ? 2 Or 3 restituirà 3
    ? 3 Or 5 restituirà 7

    Cerchiamo, anche in questo caso, di capire perché.

    2: 0 1 0
    Or
    0: 0 0 0
    risultato: 0 Or 0 = 0; 1 Or 0 = 1; 0 Or 0 = 0
    quindi 010 (bin) :: 2 (dec)

    2: 0 1 0
    Or
    1: 0 0 1
    risultato: 0 Or 0 = 0; 1 OR 0 = 1; 0 Or 1 = 1
    quindi 011 (bin) :: 3 (dec)

    2: 0 1 0
    Or
    2: 0 1 0
    risultato: 0 Or 0 = 0; 1 Or 1 = 1; 0 Or 0 = 0
    quindi 010 (bin) :: 2 (dec)

    2: 0 1 0
    Or
    3: 0 1 1
    risultato: 0 Or 0 = 0; 1 Or 1 = 1; 0 Or 1 = 1
    quindi 011 (bin) :: 2 (dec)

    3: 0 1 1
    Or
    5: 1 0 1
    risultato: 0 Or 1 = 1; 1 Or 0 = 1; 1 Or 1 = 1
    quindi 111 (bin) :: 7 (dec)


    to be continued ....... (domani la parte finale ed il file completo)

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • Il NIM pensatore - parte 3/3
    di scossa data: 18/07/2015 23:43:51

    Parte 3 di 3

    Come ho detto nella prima parte, l'aspetto più interessante di questa versione "intelligente" è che, al contrario della vesione senza VBA, NON ho utilizzato nessun tipo di conversione in binario dei numeri rappresentanti i bastoncini presenti sul tavolo.

    Infatti il VBA non mette a disposizione solo gli operatori di confronto binari And e Or ma anche altri, tra cui il nostro operatore "magico", l'operatore XOr (noto anche come eXclusive-Or ovvero Or esclusivo), la cui tavola della verità è la seguente

    0 XOr 0 = 0
    1 XOr 0 = 1
    0 XOr 1 = 1
    1 XOr 1 = 0


    Vediamo qualche esempio.

    ? 2 XOr 0 restituirà 2
    ? 2 XOr 1 restituirà 3
    ? 2 XOr 2 restituirà 0
    ? 2 XOr 3 restituirà 1
    ? 3 XOr 5 restituirà 6

    Cerchiamo di capire perché.

    2: 0 1 0
    XOr
    0: 0 0 0
    risultato: 0 XOr 0 = 0; 1 XOr 0 = 1; 0 XOr 0 = 0
    quindi 010 (bin) :: 2 (dec)

    2: 0 1 0
    XOr
    1: 0 0 1
    risultato: 0 XOr 0 = 0; 1 XOR 0 = 1; 0 XOr 1 = 1
    quindi 011 (bin) :: 3 (dec)

    2: 0 1 0
    XOr
    2: 0 1 0
    risultato: 0 XOr 0 = 0; 1 XOr 1 = 0; 0 XOr 0 = 0
    quindi 000 (bin) :: 0 (dec)

    2: 0 1 0
    XOr
    3: 0 1 1
    risultato: 0 XOr 0 = 0; 1 XOr 1 = 0; 0 XOr 1 = 1
    quindi 001 (bin) :: 1 (dec)

    3: 0 1 1
    XOr
    5: 1 0 1
    risultato: 0 XOr 1 = 1; 1 XOr 0 = 1; 1 XOr 1 = 0
    quindi 110 (bin) :: 6 (dec)

    Ma visto XOr è il cuore del nostro "analizzatore" andiamo a vedere cosa succede se le espressioni son 3 anziché due:

    ? 3 XOr 4 XOr 5 restituirà 2
    3: 0 1 1
    XOr
    4: 1 0 0
    XOr
    5: 1 0 1
    --------
    r: 0 1 0
    risultato bit di sinistra (msb: most significant bit):
    (0 XOr 1 ) XOr 1 = 0
    risultato bit centrale:
    (1 XOr 0 ) XOr 0 = 1
    risultato bit di destra (lsb: least significant bit):
    (1 XOr 0 ) XOr 1 = 0
    quindi 010 (bin) :: 2 (dec)


    Questa esempio vi ricorda qualcosa vero?

    Ebbene sì, è la posizione iniziale del gioco.
    Poiché il risultato è > 0 la posizione è insicura e, pertanto può essere resa sicura trasformando il 3 in 1:
    ? 1 XOr 4 XOr 5 restituirà 2
    1: 0 0 1
    XOr
    4: 1 0 0
    XOr
    5: 1 0 1
    --------
    r: 0 0 0
    risultato bit di sinistra:
    (0 XOr 1 ) XOr 1 = 0
    risultato bit centrale:
    (0 XOr 0 ) XOr 0 = 0
    risultato bit di destra:
    (1 XOr 0 ) XOr 1 = 0
    quindi 000 (bin) :: 0 (dec)
    Poiché il risultato è 0 la posizione è sicura e, pertanto qualsiasi mossa potrà solo renderla insicura.

    Nell'apposito riquadro potete leggere la function che analizza la posizione e che restituisce Vero se la posizione è sicura o Falso se è insicura.

    Ho allegato il file "NIM_VBA.xlsm".



    Il codice utilizzato è molto semplice e si basa sui soliti "eventi": SelectionChange, Change e BeforeDoubleClick, oltre alla già illustrata funzione di analisi della posizione.
    Ma prima di "sbirciare" il codice, vi invito a divertirvi a giocare contro il "NIM-Pensatore"; mettetelo alla prova cedendo a lui la prima mossa (doppio click su "prima mossa al pc").... non vincerete una partita!

    Per come è impostato il file, la posizione di partenza può essere impostata, con semplice modifica della sub Inizia(), con qualsiasi numero, tra 1 e 5, di bastoncini nelle 3 righe.
    Senza grosse modifiche tale numero può essere portato fino a 7 (massimo numero rappresentabile con 3 bit) per riga; ma con un po' di studio potrete modificare il codice per gestire 15 bastoncini (8+4+2+1) per riga.

    Insomma, questo progetto offre molte possibilità di sviluppo ed è un ottimo spunto per mettere alla prova le proprie conoscenze del VBA.

    Buon divertimento.

    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)


     
    Function isSecure(ByVal nStick1 As Integer, ByVal nStick2 As Integer, ByVal nStick3 As Integer) As Boolean
        isSecure = (nStick1 Xor nStick2 Xor nStick3) = 0
    End Function



  • di Raffaele_53 data: 19/07/2015 14:04:58

    Sapevo che eri bravissimo, vedendo l'allegato sono a bocca aperta.
    Ottimo il metodo e la mentàlità nel farlo.
    Ps. Sarebbe possibile una frase in privato?

    EDIT un'anomalia, però non sono sicuro e volevo la Tua opinione EDIT



  • di scossa data: 19/07/2015 17:34:27

    cit. Raffaele_53: "Sarebbe possibile una frase in privato"

    Sul mio sito (vedi link in firma) trovi a destra un pulsante per lasciarmi una mail.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di scossa data: 19/07/2015 18:38:27

    edit



  • di Vecchio Frac data: 19/07/2015 19:46:26

    Ottimo lavoro, non c'erano dubbi ^_^
    Ho fatto Canc sulla mia bozza di versione :P






  • di alfrimpa data: 19/07/2015 20:01:54

    Complimenti vivissimi Marco!

    Davanti a queste cose ci si rende conto che ci troviamo davanti ad una classe superiore.

    Il file non l'ho ancora guardato perchè sono in vacanza (e mi riprometto di farlo al rientro) però già dalle illustrazioni/spiegazioni che hai dato ci si rende conto dell'altissima qualità del lavoro.

    Da napoletano non posso che definirti: "Il Maradona di Excel VBA"

    Alfredo





  • di cromagno data: 19/07/2015 20:57:06

    Posso solo dire...


  • errata-corrige
    di scossa data: 19/07/2015 21:08:55

    Ovviamente l'errore di scrittura non poteva mancare:
    Errata:
    Poiché il risultato è > 0 la posizione è insicura e, pertanto può essere resa sicura trasformando il 3 in 1:
    ? 1 XOr 4 XOr 5 restituirà 2


    Corrige:
    Poiché il risultato è > 0 la posizione è insicura e, pertanto può essere resa sicura trasformando il 3 in 1:
    ? 1 XOr 4 XOr 5 restituirà 0


    come del resto si deduceva dai singoli passaggi.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di ninai data: 19/07/2015 21:35:48

    cit.
    "Davanti a queste cose ci si rende conto che ci troviamo davanti ad una classe superiore."

    E' da sempre che lo penso/dico!!!!!!!

    Io l'ho visto, ed è umano, ma dovete sapere che per mantenere queste prestazioni usa sostanze strane ( si fa spedire le granite con panna dalla Sicilia)


    Io in questo gioco/ragionamento ancora non ci ho "messo mano" e credo che non lo farò, alias ("non ci capisco un tubo").




  • di scossa data: 19/07/2015 22:55:32

    cit. ninai: "Io in questo gioco/ragionamento ancora non ci ho "messo mano" e credo che non lo farò,"

    non devi metterci mano, puoi limitarti a giocarci e vedere se riesci a non farti fregare dal pc.


    P.S.: grazie a tutti per gli apprezzamenti.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.
    (George Bernard Shaw)



  • di Albatros54 data: 20/07/2015 14:19:42

    cit.
    " ma con un po' di studio potrete modificare il codice per gestire 15 bastoncini (8+4+2+1) per riga. "
    nel mio piccolo , mi sono permesso di apportare alcune modifiche , con 15 bastoncini (8+4+2+1).
    In allegato il file
    gioacchino





  • di scossa data: 20/07/2015 16:55:53

    cit. Albatros54: "mi sono permesso di apportare alcune modifiche , con 15 bastoncini (8+4+2+1)"

    Ottimo Gioacchino, però mi sembra che ci sia qualcosa che non torna:
    prima mossa: tolgo 2 bastoncini dalla riga di 4; il pc toglie 7 bastoncini dalla riga di 8;
    seconda mossa: tolgo 2 bastoncini dalla riga di 2 in alto; il pc toglie 2 bastoncini dall'altra riga di 2;
    terza mossa: tolgo 1 bastoncin0 dalla riga di 1 in alto; il pc NON toglie nessun bastoncino;

    Ora sto uscendo, se nel frattempo non trovi dov'è il problema domani guardo anch'io.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Albatros54 data: 20/07/2015 18:00:58

    effettivamente mi sono dimenticato un ciclo, riallego il file, fammi sapere
    Ciao
    gioacchino





  • di scossa data: 05/08/2015 19:09:21

    Ok, ora mi pare che funzioni correttamente.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno. Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee.
    (George Bernard Shaw)