// PelikortitApplet.java (c) Kari Laitinen // http://www.naturalprogramming.com /* 2004-08-24 Tiedosto luotu. 2005-02-01 Satunnaisesti.tee_sekoitettu_paritaulukko()-metodi lisätty. 2006-01-14 Korttipakka on Kuningaspakka- ja Pokeripakka-luokkien yhteinen kantaluokka. Satunnaisesti-luokka pantu omaan tiedostoonsa. 2006-10-24 Muutettu Swing-apletiksi 2009-02-05 Muutettu ArrayList-luokkaa käyttäväksi. Ohjelman sisäinen rakenne on näin muuttunut, mutta toimintaan ei ole tullut muutosta. Dynaamiset ArrayList-pohjaiset taulukot ovat korttipeleissä erityisen käteviä koska niistä voidaan mm. kätevästi poistaa olioita tai niihin voidaan helposti lisätä olioita. Satunnaisesti.java:a ei enää tarvita tämän ohjelman kanssa. 2009-11-05 Muutettu JPanel-pohjaiseksi apletiksi. Kortteja suurennettu. 2009-11-06 Viimeisin muutos. */ // Taman ohjelman applet antaa mahdollisuuden kayttajalleen // jakaa kortteja pakasta ja katsella niita naytolla. // Pakan voi myos sekoittaa haluttaessa. import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; import java.util.ArrayList ; import java.util.Collections ; class Kortti { int kortin_arvo ; int kortin_maa ; // oikeinpain = kortti piirretaan tietopuoli nakyviin // nurinpain = kortti piirretaan selkapuoli nakyviin boolean tama_kortti_on_oikeinpain = false ; Point kortin_paikka_pikseleina = null ; static final Font fontti_kortin_teksteihin = new Font( "SansSerif", Font.BOLD, 20 ) ; // Seuraavia staattisia jäseniä voidaan käyttää muista luokista // kun kirjoitetaan Kortti.HERTTA, Kortti.RUUTU, jne. public static final int HERTTA = 1 ; public static final int RUUTU = 2 ; public static final int PATA = 3 ; public static final int RISTI = 4 ; public static final int KORTIN_LEVEYS_PIKSELEINA = 128 ; public static final int KORTIN_KORKEUS_PIKSELEINA = 176 ; public Kortti ( int annettu_kortin_arvo, int annettu_kortin_maa ) { kortin_arvo = annettu_kortin_arvo ; kortin_maa = annettu_kortin_maa ; } public int lue_arvo() { return kortin_arvo ; } public int lue_maa() { return kortin_maa ; } public void kaanna_kortti() { if ( tama_kortti_on_oikeinpain == true ) { tama_kortti_on_oikeinpain = false ; } else { tama_kortti_on_oikeinpain = true ; } } public void kaanna_kortti_oikeinpain() { tama_kortti_on_oikeinpain = true ; } public void kaanna_kortti_nurinpain() { tama_kortti_on_oikeinpain = false ; } public boolean kortti_on_oikeinpain() { return ( tama_kortti_on_oikeinpain == true ) ; } public boolean kortti_on_nurinpain() { return ( tama_kortti_on_oikeinpain == false ) ; } public void aseta_paikka_pikseleina( Point annettu_kortin_paikka_pikseleina ) { kortin_paikka_pikseleina = annettu_kortin_paikka_pikseleina ; } public String lue_maa_stringina() { String palautettava_stringi = "" ; switch( kortin_maa ) { case HERTTA : palautettava_stringi = "Hertta" ; break ; case RUUTU : palautettava_stringi = "Ruutu" ; break ; case PATA : palautettava_stringi = "Pata" ; break ; case RISTI : palautettava_stringi = "Risti" ; break ; default: palautettava_stringi = "Ohjelmavirhe!!!" ; } return palautettava_stringi ; } // Seuraavilla metodeilla voidaan verrata "tätä" // kortti johonkin toiseen korttiin. public boolean on_samaa_maata_kuin( Kortti toinen_kortti ) { return ( kortin_maa == toinen_kortti.kortin_maa ) ; } public boolean on_eri_maata_kuin( Kortti toinen_kortti ) { return ( kortin_maa != toinen_kortti.kortin_maa ) ; } public boolean on_pienempi_kuin( Kortti toinen_kortti ) { return ( kortin_arvo < toinen_kortti.kortin_arvo ) ; } public boolean on_suurempi_kuin( Kortti toinen_kortti ) { return ( kortin_arvo > toinen_kortti.kortin_arvo ) ; } public boolean on_yhtasuuri_kuin( Kortti toinen_kortti ) { return ( kortin_arvo == toinen_kortti.kortin_arvo ) ; } public boolean on_erisuuri_kuin( Kortti toinen_kortti ) { return ( kortin_arvo != toinen_kortti.kortin_arvo ) ; } public boolean piste_on_talla_kortilla( Point annettu_piste ) { return ( kortin_paikka_pikseleina != null && annettu_piste.x >= kortin_paikka_pikseleina.x && annettu_piste.x <= kortin_paikka_pikseleina.x + KORTIN_LEVEYS_PIKSELEINA && annettu_piste.y >= kortin_paikka_pikseleina.y && annettu_piste.y <= kortin_paikka_pikseleina.y + KORTIN_KORKEUS_PIKSELEINA ) ; } public void piirra( Graphics graphics ) { Font alkuperainen_fontti = graphics.getFont() ; graphics.setFont( fontti_kortin_teksteihin ) ; if ( tama_kortti_on_oikeinpain == true ) { graphics.setColor( Color.YELLOW ) ; } else { graphics.setColor( Color.LIGHT_GRAY ) ; } graphics.fillRect( kortin_paikka_pikseleina.x, kortin_paikka_pikseleina.y, KORTIN_LEVEYS_PIKSELEINA, KORTIN_KORKEUS_PIKSELEINA ) ; graphics.setColor( Color.black ) ; graphics.drawRect( kortin_paikka_pikseleina.x, kortin_paikka_pikseleina.y, KORTIN_LEVEYS_PIKSELEINA, KORTIN_KORKEUS_PIKSELEINA ) ; if ( tama_kortti_on_oikeinpain == true ) { graphics.drawString( lue_maa_stringina(), kortin_paikka_pikseleina.x + 20, kortin_paikka_pikseleina.y + ( ( KORTIN_KORKEUS_PIKSELEINA * 2 ) / 3 ) ) ; String kortin_arvo_stringi = "" + kortin_arvo ; if ( kortin_arvo == 1 || kortin_arvo == 14 ) { kortin_arvo_stringi = "1 Ace" ; } else if ( kortin_arvo == 13 ) { kortin_arvo_stringi = "13 King" ; } else if ( kortin_arvo == 12 ) { kortin_arvo_stringi = "12 Queen" ; } else if ( kortin_arvo == 11 ) { kortin_arvo_stringi = "11 Jack" ; } graphics.drawString( kortin_arvo_stringi, kortin_paikka_pikseleina.x + 20, kortin_paikka_pikseleina.y + ( KORTIN_KORKEUS_PIKSELEINA / 3 ) ) ; } graphics.setFont( alkuperainen_fontti ) ; } } // Korttipakka-luokassa ei ole yhtään korttia. Tämä luokka on // tarkoitettu kantaluokaksi siitä johdetuille luokille. class Korttipakka { ArrayList pakan_kortit = new ArrayList() ; int[] maat = { Kortti.HERTTA, Kortti.RUUTU, Kortti.PATA, Kortti.RISTI } ; public void sekoita_pakka() { // ArrayList-pohjainen dynaaminen taulukko voidaan // pistää satunnaiseen järjestykseen Collections-luokan // staattisella shuffle()-metodilla. Collections.shuffle( pakan_kortit ) ; } public void lisaa_kortti( Kortti uusi_kortti ) { if ( pakan_kortit.size() < 52 ) { pakan_kortit.add( uusi_kortti ) ; } } public Kortti ota_kortti() { // Metodi palauttaa null-arvon jos kortteja ei pakassa ole. // Arvo null tarkoittaa Javassa sita etta olioviittaus // ei viittaa (osoita) mihinkaan olioon. // Jos kortteja on pakassa, palautetaan viittaus pakan // alimpaan korttiin, ja poistetaan kyseinen kortti pakasta. // Taman luokan toiminta on ihan ok vaikka kortteja // jaetaankin pakan alta. Kortti annettava_kortti = null ; if ( pakan_kortit.size() > 0 ) { annettava_kortti = pakan_kortit.get( pakan_kortit.size() - 1 ) ; pakan_kortit.remove( pakan_kortit.size() - 1 ) ; } return annettava_kortti ; } } // Kuningaspakka on korttipakka jossa ässä on pienin kortti // ja kuningas on suurin kortti. Tätä taidetaan loppujen lopuksi // tarvita aika harvassa korttipelissä. class Kuningaspakka extends Korttipakka { public Kuningaspakka() // Konstruktori eli muodostin. { for ( int maan_indeksi = 0 ; maan_indeksi < 4 ; maan_indeksi ++ ) { for ( int kortin_arvo = 1 ; kortin_arvo < 14 ; kortin_arvo ++ ) { lisaa_kortti( new Kortti( kortin_arvo, maat[ maan_indeksi ] ) ) ; } } } } /* Luokka Pokeripakka on kuten Kuningaspakka, mutta siina assan numeroarvo on 14. Tuo kortti piirtyy luokan Kortti metodilla piirra() aivan kuten arvon 1 sisaltava assa, mutta Kortti- luokan vertailumetodit ymmartavat assa suurimmaksi. */ class Pokeripakka extends Korttipakka { public Pokeripakka() { for ( int maan_indeksi = 0 ; maan_indeksi < 4 ; maan_indeksi ++ ) { for ( int kortin_arvo = 2 ; kortin_arvo < 15 ; kortin_arvo ++ ) { lisaa_kortti( new Kortti( kortin_arvo, maat[ maan_indeksi ] ) ) ; } } } } class PelikortitPanel extends JPanel implements ActionListener, MouseListener { JButton jaa_kortit_button = new JButton( "Jaa kortit" ) ; JButton sekoita_pakka_button = new JButton( "Sekoita pakka" ) ; // Pokeripakka-oliossa assa on suurin. Korttipakka korttipakka = new Pokeripakka() ; ArrayList rivi_kortteja = new ArrayList() ; Kortti yksinainen_kortti ; Kortti valittu_kortti ; // Tässä käytetään samaa heksadesimaalista taustaväriä kun // on käytetty .html-tiedostossa. Pannaan se apletin taustalle // vähän vaaleampana. Color pelialueen_taustavari = new Color( 0x41C300 ).brighter() ; public PelikortitPanel() { setLayout( new BorderLayout() ) ; setBackground( pelialueen_taustavari ) ; JPanel alareunan_paneeli = new JPanel() ; alareunan_paneeli.setBackground( pelialueen_taustavari ) ; jaa_kortit_button.setBackground( pelialueen_taustavari.darker() ) ; sekoita_pakka_button.setBackground( pelialueen_taustavari.darker() ) ; jaa_kortit_button.addActionListener( this ) ; sekoita_pakka_button.addActionListener( this ) ; alareunan_paneeli.add( jaa_kortit_button ) ; alareunan_paneeli.add( sekoita_pakka_button ) ; add( "South", alareunan_paneeli ) ; addMouseListener( this ) ; } public void actionPerformed( ActionEvent event ) { if ( event.getSource() instanceof JButton ) { if ( event.getSource() == jaa_kortit_button ) { // Tyhjennetää ArrayList-taulukko ensin vanhoista // korteista. rivi_kortteja.clear() ; for ( int kortin_indeksi = 0 ; kortin_indeksi < 5 ; kortin_indeksi ++ ) { Kortti uusi_kortti_riviin = korttipakka.ota_kortti() ; Point kortin_paikka = new Point( 40 + ( Kortti.KORTIN_LEVEYS_PIKSELEINA +20 ) * kortin_indeksi, 50 ) ; uusi_kortti_riviin.aseta_paikka_pikseleina( kortin_paikka ) ; rivi_kortteja.add( uusi_kortti_riviin ) ; } yksinainen_kortti = korttipakka.ota_kortti() ; yksinainen_kortti.aseta_paikka_pikseleina( new Point( 188, 300 ) ); } else if ( event.getSource() == sekoita_pakka_button ) { korttipakka.sekoita_pakka() ; } repaint() ; } } public void mouseClicked( MouseEvent event ) { Point klikkauspaikka = new Point( event.getX(), event.getY() ); if ( rivi_kortteja.size() == 5 ) { // Viisi korttia on rivissä. Tarkastetaan osuiko klikkaus // millekään noista korteista. for ( int kortin_indeksi = 0 ; kortin_indeksi < rivi_kortteja.size() ; kortin_indeksi ++ ) { if ( rivi_kortteja.get( kortin_indeksi ). piste_on_talla_kortilla( klikkauspaikka ) ) { rivi_kortteja.get( kortin_indeksi ).kaanna_kortti() ; // valittu_kortti asetetaan viittaamaan klikattuun // korttiin rivi_kortteja -taulukossa, mutta // valitulla kortilla ei muuten tehda mitaan tassa // ohjelmassa. valittu_kortti = rivi_kortteja.get( kortin_indeksi ) ; } } if ( yksinainen_kortti != null && yksinainen_kortti.piste_on_talla_kortilla( klikkauspaikka ) ) { yksinainen_kortti.kaanna_kortti() ; } repaint() ; } } public void mouseEntered( MouseEvent event ) {} public void mouseExited( MouseEvent event ) {} public void mousePressed( MouseEvent event ) {} public void mouseReleased( MouseEvent event ) {} public void paint( Graphics graphics ) { super.paint( graphics ) ; // Piirretään apletin alueelle mustalla raamit. graphics.drawRect( 0, 0, getWidth() - 1, getHeight() - 1 ) ; // Jos rivi_kortteja-taulukkoon on jo pantu kortit, // piirretaan ne yksitellen. if ( rivi_kortteja.size() > 0 ) { // Käytetään Kortti-olioiden piirtämisessä ns. "foreach" // silmukkaa joka on erikoisversio perinteisestä for-silmukasta. // "foreach"-silmukka käy aina lävitse annetun taulukon kaikki // Kortti-oliot. for ( Kortti kortti_rivissa : rivi_kortteja ) { kortti_rivissa.piirra( graphics ) ; } // Huomaa että yksinäinen kortti piirretään vain jos löytyi // rivistä piirrettäviä kortteja. if ( yksinainen_kortti != null ) { yksinainen_kortti.piirra( graphics ) ; } } else { graphics.drawString( "KORTTEJA EI OLE JAETTU", 100, 100 ) ; } } } public class PelikortitApplet extends JApplet { public void init() { getContentPane().add( new PelikortitPanel() ) ; } }