Progetto di una Slot Machine da sala scommesse implementata in VHDL e C#.

Documenti analoghi
Progetto di una Slot Machine da sala scommesse implementata in VHDL e C# Andrea Manganaro Elio Romanelli

BLACK SLOT COME SI GIOCA A BLACK SLOT:

Registratori di Cassa

MONDIAL REGOLAMENTO Regole del gioco Simbolo WILD Simbolo Scatter

Introduzione al VHDL. Alcuni concetti introduttivi

BALDAZZI STYL ART S.P.A. - VIA DELL ARTIGIANO PIANORO (BO) TEL FAX INFO@BALDAZZI.COM. Caratteristiche Tecniche

Guida Compilazione Piani di Studio on-line

BALDAZZI STYL ART S.p.A. - Via dell artigiano Pianoro (BO) Tel Fax info@baldazzi.com

Guida alla configurazione della posta elettronica dell Ateneo di Ferrara sui più comuni programmi di posta

Invio SMS. DM Board ICS Invio SMS

MANUALE PARCELLA FACILE PLUS INDICE

Excel. A cura di Luigi Labonia. luigi.lab@libero.it

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

Play Avvia la giocata con il bet level e il numero di linee impostati. Messaggio: "Spin". Tasto scelta rapida: Spazio.

Manuale Amministratore Legalmail Enterprise. Manuale ad uso degli Amministratori del Servizio Legalmail Enterprise

Guida alla registrazione on-line di un DataLogger

Regolamento Casinò Poker Joker Poker

BALDAZZI STYL ART S.p.A. - Via dell artigiano Pianoro (BO) Tel Fax info@baldazzi.com

CALCOLATORI ELETTRONICI A cura di Luca Orrù. Lezione n.7. Il moltiplicatore binario e il ciclo di base di una CPU

Gestione Risorse Umane Web

Mac Application Manager 1.3 (SOLO PER TIGER)

Il calendario di Windows Vista

BALDAZZI STYL ART S.p.A. - Via dell artigiano Pianoro (BO) Tel Fax info@baldazzi.com

IL MIO PRIMO SITO: NEWS

REGOLAMENTO TENNIS STAR

Mon Ami 3000 Multimagazzino Gestione di più magazzini fisici e/o logici

REGOLAMENTO GLADIATOR

In questo manuale sono indicate le procedure per utilizzare correttamente la gestione delle offerte dei fornitori.

PROCEDURA INVENTARIO DI MAGAZZINO di FINE ESERCIZIO (dalla versione 3.2.0)

ICARO Terminal Server per Aprile

GHPPEditor è un software realizzato per produrre in modo rapido e guidato un part program per controlli numerici Heidenhain.

APPARECCHIO CON CABINET ORIGINARIO LAS VEGAS COMPACT (PRODUTTORE: BALDAZZI STYL ART)

CONTATORI ASINCRONI. Fig. 1

ControlloCosti. Cubi OLAP. Controllo Costi Manuale Cubi

REGOLAMENTO TOP TRUMPS CELEBS

PORTALE CLIENTI Manuale utente

AD HOC Servizi alla Persona

CTVClient. Dopo aver inserito correttamente i dati, verrà visualizzata la schermata del tabellone con i giorni e le ore.

Mon Ami 3000 Produzione base Produzione articoli con distinta base e calcolo dei fabbisogni

Aggiornamento v Integrazione al manuale d uso

ARCHITETTURA DI RETE FOLEGNANI ANDREA

CHIUSURE di MAGAZZINO di FINE ANNO

SOMMARIO... 3 INTRODUZIONE...

Guida per l'installazione del software MasterOnEuro

OSSERVATORIO REGIONALE CONTRATTI PUBBLICI DI LAVORI, SERVIZI E FORNITURE

Mon Ami 3000 Centri di costo Contabilità analitica per centri di costo/ricavo e sub-attività

FOWL PLAY GOLD 2. Metodo valido per tutte le versioni QUESTO METODO E STATO RICEVUTO GRATUITAMENTE DA TRUCCHIVSLOT. LA VENDITA E VIETATA.

Consiglio regionale della Toscana. Regole per il corretto funzionamento della posta elettronica

BALDAZZI STYL ART S.p.A. - Via dell artigiano Pianoro (BO) Tel Fax info@baldazzi.com

SPHINX ULTIMATE. id permanente dell apparecchio CODEID _. (Introdotto dalla rete telematica AAMS e qui trascritto dal proprietario/possessore)

PROGRAMMA SVOLTO NELLA SESSIONE N.

MANUALE D USO DEL CONTATEMPO

REGOLAMENTO FRANKIE DETTORI MAGIC 7

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

INDIZIONE E MODALITÀ TECNICHE DI SVOLGIMENTO DELLA LOTTERIA AD ESTRAZIONE ISTANTANEA CON PARTECIPAZIONE A DISTANZA DENOMINATA LA FORTUNA GIRA ON LINE

Raggruppamenti Conti Movimenti

Modulo 4 Il pannello amministrativo dell'hosting e il database per Wordpress

Gestione Turni. Introduzione

Mon Ami 3000 Provvigioni agenti Calcolo delle provvigioni per agente / sub-agente

Lezione 8. La macchina universale

Airone Gestione Rifiuti Funzioni di Esportazione e Importazione

Database 1 biblioteca universitaria. Testo del quesito

Determinare la grandezza della sottorete

Esempio: dest = parolagigante, lettere = PROVA dest (dopo l'invocazione di tipo pari ) = pprrlogvgante

ZFIDELITY - ZSE Software & Engineering Pag.1 / 11

Sistema operativo. Sommario. Sistema operativo...1 Browser...1. Convenzioni adottate

Sarà del tutto identico a come se giocassimo 4 schedine da 2 euro ciascuna così fatte, avremo quindi 4 combinazioni:

ESEMPIO 1: eseguire il complemento a 10 di 765

GESTIONE INVENTARI E COLLOCAZIONI. A cura di Michela Fedi

TRASMISSIONE RAPPORTO ARBITRALE IN FORMATO PDF

WoWords. Guida all uso: creare ed utilizzare le frasi. In questa guida è descritto come creare ed utilizzare le frasi nel software WoWords.

Spiegazione Open Interest Storico:

Mon Ami 3000 Varianti articolo Gestione di varianti articoli

Dispensa di Informatica I.1

Dispense di Informatica per l ITG Valadier

Manuale Gestore. Utilizzo Programma. Magazzino

PROGRAMMA GESTIONE TURNI MANUALE UTENTE. Programma Gestione Turni Manuale Utente versione 1.1

COLLI. Gestione dei Colli di Spedizione. Release 5.20 Manuale Operativo

MANUALE EDICOLA 04.05

lo PERSONALIZZARE LA FINESTRA DI WORD 2000

LA GESTIONE DELLE VISITE CLIENTI VIA WEB

SPRING SQ COMUNICAZIONE OPERAZIONI IVA NON INFERIORI A 3000 EURO PER L ANNO 2011

SIMULAZIONE CIRCUITI LOGICI CON LOGISIM

GENERAZIONE ARCHIVIO F24 AGENZIA ENTRATE

Double Bonus Poker - Regole di Gioco

Convertitori numerici in Excel

REGOLAMENTO ROULETTE FRANCESE

Come costruire una presentazione. PowerPoint 1. ! PowerPoint permette la realizzazione di presentazioni video ipertestuali, animate e multimediali

OSSIF WEB. Manuale query builder

REGOLAMENTO LIVE ROULETTE

[MANUALE VISUAL BASIC SCUOLA24ORE PROF.SSA PATRIZIA TARANTINO] 14 dicembre 2008

REGOLAMENTO KONG THE 8 TH WONDER OF THE WORLD

Regole di gioco Roulette Mobile

Manuale Terminal Manager 2.0

Moduli (schede compilabili) in Word Esempio: scheda di alimentazione per un degente

Hitman è una slot machine a cinque rulli, quindici payline e 300 monete con:

NAS 251 Introduzione al RAID

IL DIRETTORE GENERALE

Joker Poker - Regole di Gioco

Introduzione a Visual Basic Lezione 1 Concetti base e istruzioni condizionali

Transcript:

UNIVERSITA' DEGLI STUDI DI BOLOGNA FACOLTA' DI INGEGNERIA Corso di Laurea Magistrale in Ingegneria Informatica Calcolatori Elettronici M Prof. Giovanni Neri, Prof. Stefano Mattoccia Progetto di Calcolatori Elettronici M Progetto di una Slot Machine da sala scommesse implementata in VHDL e C#. Realizzato da: Andrea Manganaro Elio Romanelli Anno Accademico 2010 2011

Introduzione: Scopo della nostra applicazione è quello di sviluppare e simulare la centralina di una Slot Machine da sala scommesse, avente tre rulli con ognuno 8 simboli diversamente distribuiti e delle caratteristiche di vincita sottostanti a leggi del Monopolio di Stato. Queste macchine sono prepotentemente presenti in ambienti di scommesse come la SNAI o il BINGO e rappresentano uno dei maggiori introiti dello Stato Italiano a pari di beni di largo consumo come il tabacco e gli alcolici, anch essi sottoposti a tassazione e Monopolio Statale. Sono da considerarsi giochi d azzardo legalizzati, almeno nel territorio Italiano, e si basano sulla scommessa di denaro per trarne altro in base a delle combinazioni che i diversi simboli dei vari rulli possono creare. Sono stati presi dati tecnici da manuali reali di Slot Machine, dove venivano indicate tutte le caratteristiche fondamentali legate al funzionamento della stessa come valori di alimentazione, tempi di gioco (rispettati), percentuali di vincite (rispettate in base a leggi probabilistiche) e vari meccanismi di protezione del corretto funzionamento della macchina stessa (ad esempio distacco dell alimentazione, del cavo di rete o tentata forzatura del cassetto contenente la scheda o il denaro che bloccano la macchina avvertendo il gestore della stessa e le forze dell ordine), che non sono state implementate. Caratteristiche Tecniche del gioco (sito AAMS): Insieme con l'elemento aleatorio sono presenti anche elementi di abilità, che consentono al giocatore la possibilità di scegliere, all'avvio o nel corso della partita, la propria strategia, selezionando appositamente le opzioni di gara ritenute più favorevoli tra quelle proposte dal gioco; Ciascun apparecchio di gioco può funzionare unicamente se collegato alla rete telematica di AAMS, si attiva con l'introduzione di moneta nella divisa corrente (euro) e prevede un costo, per ciascuna partita, non superiore a 1 euro; La durata della partita non può essere inferiore a 4 secondi; La distribuzione di vincite in denaro, ciascuna di valore non superiore a 100,00 (cento) euro, avviene subito dopo la conclusione della partita esclusivamente in monete; Le vincite, computate dall apparecchio, in modo non predeterminabile, su un ciclo complessivo di non più di 140.000 partite, non devono risultare inferiori al 75% delle somme giocate; L'uso di tali apparecchi è vietato ai minori di 18 anni;

Nel nostro progetto abbiamo cercato di rimanere fedeli alle specifiche ufficiali, permettendo al giocatore arbitrarietà nella scelta della modalità di gioco e dei simboli da mantenere. La valuta utilizzata è il credito singolo, rapportabile all'euro classicamente utilizzato nelle slot italiane, e le vincite saranno visualizzate tramite un display 7 segmenti. L'inserimento e il cashout sono processi meccanici non contemplati in fase di modellamento vhdl. La vincita massima corrisponde a 100 crediti e le possibilità di vittoria sono calcolate tramite tutte le possibili combinazioni possibili dei simboli in gioco. A livello statistico essere garantiscono un valore di payout simile al 75%. Moduli del progetto: Il progetto sottostante è stato sviluppato per moduli diversi, ognuno con una complessità particolare ma tutti interagenti nella simulazione del nostro prototipo di Slot Machine. Tutte le diverse entità sono attivate tramite dei segnali interni, che gestiscono la sincronizzazione e l'attivazione dei diversi processi presenti. L'allineamento di questi segnali, e l'avvio di una nuova fase di gioco sono garantiti dal modulo Game, che determina la fine della fase di gioco precedente tramite il restore dei segnali interni utilizzati nell'intero ciclo precedente. Le tre fasi di Random creano tre vettori pseudo-casuali che corrispondono agli 8 simboli diversi posizionati nelle wheels della slot machine, adeguatamente convertiti. Game2 gestisce la seconda fase di gioco, che precede il secondo spin, e quindi l'utilizzo dei pulsanti Hold e la creazione dei simboli sostituiti. L'ultimo modulo, Final, verifica ed assegna l'eventuale vincita. La Trascodifica, infine, visualizza il credito ottenuto tramite due unità 7segmenti, rispettivamente per le unità e le decine. L'interfaccia utente prevede diversi pulsanti, che permettono all'utente di gestire le varie fasi. I pulsanti Double e Play sono utilizzati nella prima fase per scegliere quale mosalità di gioco utilizzare. I pulsanti Hold1, Hold2, Hold3 e Play2, invece, sono utilizzabili nella seconda fase e consentono all'utente di stabilire la propria strategia di gioco e gli eventuali simboli da mantenere. Gli spin sono quindi 2, e, come si vedrà più avanti, la realizzazione della generazione dei rispettivi simboli è demandata a dei moduli appositi che si avvalgono di registri a scorrimento retroazionati con ex-or, e quindi che necessitano del clock. Gli altri moduli, essendo attivati a discrezione dell'utente, non presentano particolari esigenze di sincronismo hardware

Grafico totale delle connessioni tra moduli:

Entità SLOT MACHINE (VHDL): Button_Play: in std_logic; -- Pulsante di inizio gioco, proveniente dall'esterno Button_Double: in std_logic; -- Pulsante di modalità di gioco raddoppiata Button_Play2: in std_logic; -- Pulsante per attivare l'ultima fase di gioco Button_Hold1: in std_logic; -- Pulsante Hold 1 (mantenimento simbolo 1) Button_Hold2: in std_logic; -- Pulsante Hold 2 (mantenimento simbolo 2) Button_Hold3: in std_logic; -- Pulsante Hold 3 (mantenimento simbolo 3) Credit_Uni: out std_logic_vector(6 downto 0); -- Unità credito visualizzato sul display in 7segm. Credit_Dec: out std_logic_vector(6 downto 0); -- Decine credito visualizzato sul display in 7segm. Clock: in std_logic; -- Clock proveniente dall'esterno Clock1: in std_logic; -- Clock proveniente dall'esterno utilizzato per la randomizzazione dello spin della prima ruota su random Clock2: in std_logic; -- Clock proveniente dall'esterno utilizzato per la randomizzazione dello spin della seconda ruota su random2 Clock3: in std_logic -- Clock proveniente dall'esterno utilizzato per la randomizzazione dello spin della terza ruota su random3

Vediamo la definizione dei segnali interni utilizzati: signal start1_sign: std_logic; --Segnale interno che avvia la prima fase di gioco signal col1_sign, col2_sign, col3_sign: std_logic_vector(2 downto 0); -- Segnali per la generazione dei simboli nella fase 1 di gioco signal col1final_sign, col2final_sign, col3final_sign: std_logic_vector(2 downto 0); -- Segnali per la generazione dei simboli nella fase 2 di gioco signal start2_sign: std_logic; --Segnale interno che avvia la seconda fase di gioco signal start3_sign: std_logic; Segnale interno che avvia l'ultima fase di gioco signal double_sign: std_logic; --Segnale interno che avvia la modalità di gioco "Double" signal credit_sign: std_logic_vector(6 downto 0); --Segnale interno che comunica il credito vinto signal enable_sign: std_logic; --Segnale interno che abilita l'intero ciclo di gioco Entità SLOT MACHINE (C#): Diamo ora una rappresentazione iniziale della nostra Slot Machine nel linguaggio di programmazione usato per simulare, il C#. La prima interfaccia che compare all utente è quella di INSERT COIN, con la quale si abilita la fase di gioco e che rappresenta il requisito fondamentale per il funzionamento dell apparecchio. Dopo aver inserito una moneta, a livello software rappresentata dal valore 1, si materializza una seconda interfaccia, quella del gioco vero e proprio dove possiamo notare in alto il (CREDIT). La fase di Insert Coin non è presente in hardware essendo un procedimento meccanico, quindi, come vedremo più avanti, la modellazione vhdl prevederà direttamente l'avvio del gioco tramite il pulsante Play.

Lo (SPIN/PLAY/PLAY2) è il pulsante di avvio gioco con il quale i rulli inizieranno a distribuire i simboli che poi saranno comparati con le possibili vincite. Il pulsante DoubleBet, se selezionato prima di avviare il gioco, avvia la modalità di gioco raddoppiata, in cui non sarà possibile effettuare il secondo spin, ma che garantirà, in caso di vincita, premi raddoppiati. Ecco le configurazioni di vincita: if (final[1] == dragon && final[2] == dragon && final[3] == dragon) winnings = 50; gotospin = 0; jackpot.play();

if (final[1] == hero && final[2] == hero && final[3] == hero) winnings = 30; gotospin = 0; jackpot.play(); if (final[1] == dragon && final[2] == dragon && final[3]!= dragon final[1] == dragon && final[2]!= dragon && final[3] == dragon final[1]!= dragon && final[2] == dragon && final[3] == dragon) winnings = 5; if (final[1] == hero && final[2] == hero && final[3]!= hero final[1] == hero && final[2]!= hero && final[3] == hero final[1]!= hero && final[2] == hero && final[3] == hero) winnings = 3; if (final[1] == elf && final[2] == elf && final[3]!= elf final[1] == elf && final[2]!= elf && final[3] == elf final[1]!= elf && final[2] == elf && final[3] == elf) winnings = 1; Al termine di questa fase, le possibili configurazioni sono due: o si riesce a vincere o si perde e in quest ultimo caso se avevamo solo un credito, si materializza il GAME OVER (OUT OF CASH) con conseguente uscita dal sistema di gioco e visualizzazione dell interfaccia di INSERT COIN per un eventuale altra sessione.

Per la generazione dei CLOCK, a livello software, abbiamo usate le entità Timer, con le seguenti caratteristiche: // timspin // this.timspin.tick += new System.EventHandler(this.timSpin_Tick); // // timstop1 // this.timstop1.interval = 1000; this.timstop1.tick += new System.EventHandler(this.timStop1_Tick); // // timstop2 // this.timstop2.interval = 2000; this.timstop2.tick += new System.EventHandler(this.timStop2_Tick); // // timstop3 // this.timstop3.interval = 3000; this.timstop3.tick += new System.EventHandler(this.timStop3_Tick);

Componente GAME (VHDL): Il funzionamento di questa unità è duplice. Il processo principale gestisce l'avvio di una nuova fase di gioco, in cui il Player può scegliere tra modalità di gioco raddoppiata premendo il pulsante Double, o modalità di gioco normale direttamente tramite il tasto Play. Quest'ultimo invierà il segnale start ai tre moduli random successivi. Come si nota dallo schema generale i segnali start, utilizzati successivamente, sono posti in retroazione a questo modulo. Per la gestion delle diverse fasi di gioco questi segnali sono fondamentali, e la loro sincronizzazione, problematica, fondamentale per il funzionamento dell'intero sistema. L'entità Game viene avvertita del termina della fase di gioco precedente tramite il segnale Enable, e, una volta ricevuto quest'ultimo, azzererà Start1, Start2 e Start3, e sarà pronta per una nuova pressione del tasto Play. entity Game is Port ( Enable: inout std_logic; Play: in std_logic; start1: inout std_logic; start2: inout std_logic; start3: inout std_logic; Double: out std_logic;

end Game; Double_button: in std_logic ); Credit_refresh : process (enable) variable Credit_temp : std_logic_vector (6 downto 0) := (others => '0'); variable Credit_temp2 : std_logic_vector (6 downto 0) := (others => '0'); variable Credit_temp_bis : std_logic_vector (6 downto 0) := (others => '0'); start2 <= signal_null; start3 <= signal_null; Enable <= signal_null; end process Credit_refresh; Start_Game_process : process (Play) variable Double_temp : std_logic := '0'; variable Start1_var : std_logic := '0'; variable Start_start_1 : std_logic := '1'; variable Start_start_0 : std_logic := '0'; if (Play'event) and (Play = '1') then Start1_var := Start_start_1; if (Double_button = '1') then Double_temp := Start_start_1; else Double_temp := Start_start_0; end if; end if; Start1 <= Start1_var; Double <= Double_temp;

end process Start_game_process; end Behavioral; Componente RANDOM (VHDL): Componente necessario al sistema per generare dei valori che poi andranno a determinare il simbolo che comparirà sul display della Slot Machine. E un componente attivato al CLK e al segnale di START che fa partire la nostra applicazione e restituisce in uscita un numero che entrerà nella fase di conversione in immagine. component random1 Port ( clk1 : in std_logic; start1: in std_logic; col1: out std_logic_vector (2 downto 0) end component; component random2 is Port ( clk2 : in std_logic; start1: in std_logic; col2: out std_logic_vector (2 downto 0) end component; component random3 is Port ( clk3 : in std_logic; start1: in std_logic; start2: out std_logic; --output vector col3: out std_logic_vector (2 downto 0) end component;

Nei Random, andiamo a definire la grandezza dei valori che ci interessano. Nel nostro caso vogliamo ottenere casualmente un numero da 1 a 8 e trasferirlo in uscita per essere computato. Di sotto, il codice relativo al RANDOM_1, dove possiamo notare che il valore che vogliamo ottenere è compreso tra 0 e 7. Il processo di random è avviato al clock (alto). Il modulo random3, a differenza degli altri2, gestisce anche l'utilizzo del segnale interno start2, che, una volta generati i vettori, verrà inviato a game2 per permettere l'avvio della seconda fase di gioco e l'interazione dell'utente con i simboli appena visualizzati. A livello Software il tutto è stato semplicemente implementato come segue: private int NewIndex() return (myrandom.next(6) + 1);

Generazione dei numeri casuali, con relative immagini nella slot in movimento. if (timstop1.enabled) picbandit1.image = choices[newindex()].image; if (timstop2.enabled) picbandit2.image = choices[newindex()].image; if (timstop3.enabled) picbandit3.image = choices[newindex()].image; In C# la trascodifica è molto più semplice, prendo il numero random generato, lo interfaccio con il mio array e metto lo slot corrispondente nella maschera che mi visualizza l immagine. // Put random pictures in display picbandit1.image = choices[r1[r1]].image; picbandit2.image = choices[r2[r2]].image; picbandit3.image = choices[r3[r3]].image; private void timstop1_tick(object sender, EventArgs e) // Stop spinning of first display timstop1.enabled = false; final[1] = R1[r1]; picbandit1.image = choices[final[1]].image; picbandit1.refresh(); private void timstop2_tick(object sender, EventArgs e) // Stop spinning of second display timstop2.enabled = false; final[2] = R2[r2]; picbandit2.image = choices[final[2]].image; picbandit2.refresh(); private void timstop3_tick(object sender, EventArgs e) // Stop spinning of third display timstop3.enabled = false; final[3] = R3[r3]; picbandit3.image = choices[final[3]].image; picbandit3.refresh();

Per quanto riguarda i random, essi sono generati da 2 clock distinti e da una seria di registri retro-azionati con un ex-or. Eccone una dimostrazione grafica del funzionamento: Il componente utilizzato è un generatore di numeri pseudo-casuali, con sequenze numeriche di periodo (2^n -1), dove n è pari al numero di shift register utilizzati. Abbiamo optato per una sequenza di 7 bit per ogni processo di randomizzazione. I bit selezionati alla fine saranno 3, e in ogni modulo variano i pind di ingresso all' ex-or, in modo da aggiungere un ulteriore fattore di impredicibilità. architecture Behavioral of random1 is signal exit_num1 : std_logic_vector (2 downto 0); signal random_num : std_logic_vector (width-1 downto 0); process(clk1) -- processo che gestisce l'evoluzione dei numeri casuali variable rand_temp : std_logic_vector(width-1 downto 0):=(6 => '1',others => '0'); variable temp : std_logic := '0'; if(rising_edge(clk1)) then temp := rand_temp(width-2) xor rand_temp(width-5); rand_temp(width-1 downto 1) := rand_temp(width-2 downto 0); rand_temp(0) := temp; end if; random_num <= rand_temp after 1 ps; end process; processo_exit1: process(start1) is variable exit_temp : std_logic_vector(2 downto 0); if (start1' event) then exit_temp(2) := random_num(5); exit_temp(1) := random_num(3); exit_temp(0) := random_num(1); exit_num1 (2 downto 0) <= exit_temp (2 downto 0); end if; end process processo_exit1; END;

Per la conversione, si prendono in ingresso i 3 numeri random generati in precedenza e restituisce i simboli di ingresso alle fasi successive del nostro sistema. Da notare la conformazione dei rulli, dove i simboli più importanti, che danno maggiore vincita, sono in numero minore. Ad ogni valore generato dunque, corrisponde un immagine visualizzata nella slot. conversione_col1: process(exit_num1) is if (exit_num1 = "000") then col1 <="000"; --mage elsif (exit_num1 = "001") then col1 <="001"; --dragon elsif (exit_num1 = "010") then col1 <="010"; --hero elsif (exit_num1 = "011") then col1 <="010"; --hero elsif (exit_num1 = "100") then col1 <="011"; --elf elsif (exit_num1 = "101") then col1 <="100"; --orc elsif (exit_num1 = "110") then col1 <="100"; --orc elsif (exit_num1 = "111") then col1 <="101"; --death (anche 110 e 111) end if; end process conversione_col1; conversione_col2: process(exit_num2) is if (exit_num2 = "000") then col2 <="000"; --mage elsif (exit_num2 = "001") then col2 <="001"; --dragon elsif (exit_num2 = "010") then col2 <="010"; --hero elsif (exit_num2 = "011") then col2 <="011"; --elf elsif (exit_num2 = "100") then col2 <="011"; --elf elsif (exit_num2 = "101") then col2 <="100"; --orc elsif (exit_num2 = "110") then col2 <="100"; --orc elsif (exit_num2 = "111") then col2 <="101"; --death end if; end process conversione_col2; conversione_col3: process(exit_num3) is if (exit_num3 = "000") then col3 <="000"; --mage elsif (exit_num3 = "001") then col3 <="001"; --dragon elsif (exit_num3 = "010") then col3 <="010"; --hero elsif (exit_num3 = "011") then col3 <="011"; --elf elsif (exit_num3 = "100") then col3 <="011"; --elf elsif (exit_num3 = "101") then col3 <="100"; --orc elsif (exit_num3 = "110") then col3 <="100"; --orc elsif (exit_num3 = "111") then col3 <="101"; --death end if; end process conversione_col3; In C# invece abbiamo fatto uso di un semplice Array: // Conformazione Rulli di Default

int[] R1 = new int[8] 6, 5, 4, 4, 3, 2, 2, 1 ; int[] R2 = new int[8] 6, 5, 4, 3, 3, 2, 2, 1 ; int[] R3 = new int[8] 6, 5, 4, 3, 3, 2, 2, 1 ; Componente TRASCODIFICA (VHDL): Questo componente riceve in ingresso il CREDITO vinto, in base alla configurazione dei vari valori dei rulli è restituisce in uscita una rappresentazione a 7 segmenti del valore computato, sia in unità che in decine. component Trascodifica is Port ( Credit_win : in STD_LOGIC_VECTOR (6 downto 0); Credit_Disp_Uni: out STD_LOGIC_VECTOR (6 downto 0); Credit_Disp_Dec: out STD_LOGIC_VECTOR (6 downto 0)); end component; Dei 7 bit utilizzati non sono rappresentati tutti i valori visto che la vincita massima corrisponde a 100 crediti. Abbiamo fatto riferimento ad un display a 7 segmenti, vediamo il suo funzionamento.

Per convertire il segnale da STD_LOGIC ad intero, usiamo una variabile di appoggio. Ad ogni configurazione in decimale, facciamo corrispondere una configurazione binaria che andrà ad attivare i 7 segmenti del nostro display. processo_trascoder: process(credit) is variable T:integer:=0; --variabile di appoggio in cui convertire il segnale di ingresso in intero variable Du:integer:=0; intero adeguato variable Dd:integer:=0; intero adeguato --variabile di appoggio a cui assegnare il valore --variabile di appoggio a cui assegnare il valore T:=CONV_INTEGER(Credit); --conversione da std_logic ad intero if T=0 then Dd:=0; Du:=63; elsif T=1 then Dd:=0; Du:=9; elsif T=2 then Dd:=0; Du:=94; elsif T=3 then Dd:=0; Du:=91; elsif T=4 then Dd:=0; Du:=105; Credit_Disp_Uni<=CONV_STD_LOGIC_VECTOR(Dd,7); std_logic Credit_Disp_Dec<=CONV_STD_LOGIC_VECTOR(Du,7); std_logic --conversione da intero a --conversione da intero a Ecco come gestisco in C# le vincite: if (winnings > 0 && spin == 1 && gotospin==0) Hold1.Visible = false; Hold2.Visible = false; Hold3.Visible = false;

button1.visible = true; winnings = 0; spin++; gotospin = 1; if (winnings >= 0 && spin == 0) spin = 2; a = 0; b = 0; winnings = 0; Componente GAME2 (VHDL): Questa entità rappresenta la seconda parte del gioco, che si attiva tramite il segnale start2 e in seguito alla generazione casuale dei 3 simboli. Tramite i pulsanti HOLD1, HOLD2 e HOLD3 si ha la possibilità di mantenere i simboli più favorevoli per la seconda fase di spin. Questa possibilità di gioco è invece inibita qualora il giocatore avesse selezionato (all'inizio del gioco) per la modalità di gioco DOUBLE, che non prevede la seconda fase di spin ma che, in caso di vincita, raddoppia i premi in palio. In questo secondo caso, gli HOLD sono disabilitati e si passa alla fase FINAL, alle quali passo le configurazioni di simboli definitive, dove saprò se ho vinto o meno. L'assegnamento dei nuovi simboli è determinato da un nuovo generatore di numeri pseudo-casuali, come in precedenza, ma questa voltà sarà condiviso da tutte e 3 le colonne sebbene i

simboli siano calcolati retro-azionando diversamente i pin di ingresso. Una volta completata questa seconda fase di spin vine attivato il segnale start3 che trasporta i segnali col1final, col2final, col3final alla fase finale di gioco. Questi sono i simboli definitivi, e nel modulo successivo verrà implementato il check di vincita. Via software, il tutto è stato trattato nel seguente modo: if (doublebet == 1) button1.backcolor = System.Drawing.Color.Beige; spin++; //Forzatura del conteggio, che riporta lo stato inziale bankroll += (2 * winnings); MessageBox.Show("DOUBLE BET - You Win" + Convert.ToString(2 * winnings)); component Game2 is Port (clk: in std_logic; col1, col2, col3: in std_logic_vector(2 downto 0); col1final, col2final, col3final: out std_logic_vector(2 downto 0); hold1, hold2, hold3: in std_logic; double: in std_logic; start2: in std_logic; start3: out std_logic; play2: in std_logic); end component; architecture Behavioral of Game2 is shared variable new_col1: std_logic_vector(2 downto 0); shared variable new_col2: std_logic_vector(2 downto 0); shared variable new_col3: std_logic_vector(2 downto 0); second_random: process (clk) is variable rand_temp_fin : std_logic_vector(6 downto 0):=(6 => '1',others => '0'); variable exit_temp_fin1 : std_logic_vector(2 downto 0); variable exit_temp_fin2 : std_logic_vector(2 downto 0); variable exit_temp_fin3 : std_logic_vector(2 downto 0); variable temp_fin : std_logic := '0'; if(rising_edge(clk)) then temp_fin := rand_temp_fin(4) xor rand_temp_fin(1); rand_temp_fin(6 downto 1) := rand_temp_fin(5 downto 0); rand_temp_fin(0) := temp_fin; end if; exit_temp_fin1(2) := rand_temp_fin(5); exit_temp_fin1(1) := rand_temp_fin(3);

exit_temp_fin1(0) := rand_temp_fin(1); new_col1(2 downto 0) := exit_temp_fin1 (2 downto 0); exit_temp_fin2(2) := rand_temp_fin(6); exit_temp_fin2(1) := rand_temp_fin(2); exit_temp_fin2(0) := rand_temp_fin(0); new_col2(2 downto 0) := exit_temp_fin2 (2 downto 0); exit_temp_fin3(2) := rand_temp_fin(4); exit_temp_fin3(1) := rand_temp_fin(3); exit_temp_fin3(0) := rand_temp_fin(1); new_col3(2 downto 0) := exit_temp_fin3 (2 downto 0); end process second_random; second_spin: process (start2) is variable temp2: std_logic := '1'; In C# il random è stato implementato come segue: r1 = myrandom.next(7); r2 = myrandom.next(7); r3 = myrandom.next(7); Sotto, viene evidenziata la modalità con la quale vengono gestite le colonne del caso del secondo PLAY con eventuali HOLD. Se si è scelta la modalità DOUBLE non si passa per l HOLD e si mantengono le colonne avute in precedenza, ritornando così alla fase iniziale. Se invece una colonna viene mantenuta con il pulsante di HOLD, il suo valore resta costante anche durante la seconda computazione mentre varia quello del rullo lasciato libero. A livello software, abbiamo fatto una semplice disattivazione dei pulsanti di HOLD, che sotto alcune condizioni non vengono visualizzati, non dando al giocatore la possibilità di poterli adoperare. if (spin == 1 && doublebet!= 1) Hold1.BackColor = System.Drawing.Color.Beige;

Hold2.BackColor = System.Drawing.Color.Beige; Hold3.BackColor = System.Drawing.Color.Beige; Hold1.Visible = true; Hold2.Visible = true; Hold3.Visible = true; button1.visible = false; else Hold1.Visible = false; Hold2.Visible = false; Hold3.Visible = false; button1.visible = true; if (play2' event) and (play2='1') then elsif (col1=col2) and (col2=col3) then col1final <= col1; col2final <= col2; col3final <= col3; start3 <= temp2; elsif (hold1='1') then col1final <= col1; col2final <= new_col2; col3final <= new_col3; start3 <= temp2; els if (hold1='1') and (hold2='1') then col1final <= col1; col2final <= col2; col3final <= new_col3; start3 <= temp2; elsif (hold1='1') and (hold2='1') and (hold3='1') then col1final <= col1; col2final <= col2; col3final <= col3; start3 <= temp2; elsif (hold2='1') then col1final <= new_col1; col2final <= col2; col3final <= new_col3; start3 <= temp2; elsif (hold2='1') and (hold3='1') then col1final <= new_col1; col2final <= col2; col3final <= col3; start3 <= temp2; elsif (hold3='1') then col1final <= new_col1; col2final <= new_col2; col3final <= col3; start3 <= temp2; end if;

end if; end process second_spin; In C# l HOLD è stato implementato come segue, con le variabili a,b e c che fermano lo spin del rullo selezionato // Start timers timspin.enabled = true; if (spin == 1) timstop1.enabled = true; timstop2.enabled = true; timstop3.enabled = true; else if (spin == 0 && a == 1 && b == 1) timstop1.enabled = false; timstop2.enabled = false; timstop3.enabled = true; else if (spin == 0 && a == 0 && b == 1) timstop1.enabled = true; timstop2.enabled = false; timstop3.enabled = true; else if (spin == 0 && a == 1 && b == 0) timstop1.enabled = false; timstop2.enabled = true; timstop3.enabled = true; else if (spin == 0 && a == 0 && b == 0) timstop1.enabled = true; timstop2.enabled = true; timstop3.enabled = true; Il pulsante di HOLD, attivato soltanto se non si è scelta l opzione DOUBLE BET e la prima fase di SPIN non ha riscontrato una configurazione valida (quindi una vincita che fa ripartire il sistema dalla condizione iniziale) serve per mantenere fissa la posizione di uno o più rulli per avviarsi alla fase 2 dove

si cercherà di ottenere una vincita (relativamente alle combinazioni valide definite). Componente Final (VHDL): entity Final is port (clk1,clk : in std_logic; double: in std_logic;

end Final; start1: inout std_logic; start3: in std_logic; col1final, col2final, col3final: in std_logic_vector(2 downto 0); enable: out std_logic; credit_win: out std_logic_vector(6 downto 0)); Questo componente gestisce il check delle vincite ed è attivato dal segnale start3. In ingresso avremo i valori finali delle 3 colonne, il valore di double (1 se la modalità è attivata) e i valori del clock clk e clk1 (utilizzati per la creazione dei premi in caso di bonus). Il processo di check_win confronta i risultati delle 3 colonne con la tabella dei premi, e, qualora la combinazione restituisca una vincita, pone questo valore in uscita tramite il segnale credit_win e l'enable, utilizzato per segnalare la conclusione del gioco. Se il gioco era in modalità double i premi (ad eccezione del bonus) sono raddoppiati. L implemetazione in C# di questo sotto gioco (dato dal BONUS) è la seguente con relativi screen shoot. int[] Bonus = new int[3] 100, 50, 10 ; if (final[1] == mage && final[2] == mage && final[3] == mage)

MessageBox.Show("BONUS"); button2.visible = true; button3.visible = true; button4.visible = true; Hold1.Visible = false; Hold2.Visible = false; Hold3.Visible = false; spin++;

In VHDL il tutto è stato implementato utilizzando i valori temporanei di clk1 e clk per gestire la casualità dei premi dati dal bonus, che ammontano rispettivamente a 100 crediti, 50 crediti e 10 crediti. if (bonus_sign'event) and (bonus_sign='1') and (hold1='1')then if (clk1 = '1') then credit_win <= "1100100"; enable <= temp3; elsif (clk = '1') then credit_win <= "0110010"; enable <= temp3; else credit_win <= "0001010"; enable <= temp3; end if; en d if; end process Bonus_process; Per quanto riguarda la modalità DOUBLE, sotto è indicato il caso in cui il giocatore nell unico tiro a disposizione non riesce a indovinare una configurazione di pagamento quindi non ha a disposizione il secondo SPIN e quindi la possibilità di fare l HOLD dei simboli prima comparsi. Vediamo come è stato implementata in C# la modalità DOUBLE: if (doublebet == 1) button1.backcolor = System.Drawing.Color.Beige; spin++; bankroll += (2 * winnings); MessageBox.Show("DOUBLE BET - You Win" + Convert.ToString(2 * winnings));

E adesso l implementazione in VHLD della giocata DOUBLE (nel caso escano 3 figure drago ): if (start3'event) and (start3 = '1') then if (col1final="001") and (col2final="001") and (col3final="001") then if (double = '1') then credit_win <= "1100100"; enable <= temp3; else credit_win <= "0110010"; enable <= temp3; end if; NB: L implementazione del raddoppio dei primi (in caso di vincita) è stato semplicement e effettuato spostando a destra la configurazione binaria della vincita, che rappr esenta tecnicamente una moltiplicazione per 2.

Simulazione: Per quanto riguarda la simulazione, i risultati ottenuti sono stati soddisfacenti. A livello software (dagli screen shot prima postati) possiamo vedere come il sistema reagisca come deve agli impulsi dati. Abbiamo dunque formalizzato degli array con quello che volevamo e abbiamo ottenuto le giuste risposte. Ecco le configurazioni che danno i vari tipi di scenari: // Conformazione Rulli di Default int[] R1 = new int[8] 6, 5, 4, 3, 3, 2, 2, 1 ; int[] R2 = new int[8] 6, 5, 4, 3, 3, 2, 2, 1 ; int[] R3 = new int[8] 6, 5, 4, 4, 3, 2, 2, 1 ; // Conformazione Rulli per BONUS int[] R1 = new int[8] 6, 6, 6, 6, 6, 6, 6, 6 ; int[] R2 = new int[8] 6, 6, 6, 6, 6, 6, 6, 6 ; int[] R3 = new int[8] 6, 6, 6, 6, 6, 6, 6, 6 ; // Conformazione Rulli per vincita di 50E // int[] R1 = new int[8] 5, 5, 5, 5, 5, 5, 5, 5 ; // int[] R2 = new int[8] 5, 5, 5, 5, 5, 5, 5, 5 ; // int[] R3 = new int[8] 5, 5, 5, 5, 5, 5, 5, 5 ; // Conformazione Rulli per vincita di 0E (Credito=0 --> GAME OVER) // int[] R1 = new int[8] 1, 1, 1, 1, 1, 1, 1, 1 ; // int[] R2 = new int[8] 1, 1, 1, 1, 1, 1, 1, 1 ; // int[] R3 = new int[8] 1, 1, 1, 1, 1, 1, 1, 1 ; // Conformazione Rulli per vincita di 3E --> XCC (VERIFICA HOLD) // int[] R1 = new int[8] 1, 2, 3, 4, 5, 6, 1, 2 ; // int[] R2 = new int[8] 4, 4, 4, 4, 4, 4, 4, 4 ; // int[] R3 = new int[8] 4, 4, 4, 4, 4, 4, 4, 4 ; Per quanto riguarda la simulazione hardware del funzionamento, come si vedrà più avanti, il testbench generale del sistema rappresenta in uscita esclusicamente il credito vinto in seguito alle due fasi di gioco, non permettendo quindi di vedere l'andamento dei segnali interni. E' di maggiore interesse analizzare il funzionamento delle singole entità e la loro reazione in base a determinati valori di ingresso. FASE RANDOM: Abbiamo generato un clock e abbiamo visto come il sistema reagisce alla fornitura del valore casuale ARCHITECTURE behavior OF randomtest IS --Input and Output definitions. signal clk1 : std_logic := '0'; signal start1: std_logic := '0';