"a" - a fast guide to effective Java programming

"a" - Pikaopas tehokkaaseen Java-koodiin

(Please enable Java to play a - Salli Java pelataksesi a:ta)

Basics - Perusteet

The a is a simplified "ship-sinking" game Java applet. Because it uses the JDK 1.1 applet features, it may be run only on new browsers like Netscape Navigator 4.5 or Micro$oft Internet Exploder 4.

a on yksinkertainen laivanupotuspeli-Java-sovelma. Koska se käyttää JDK 1.1:n sovelmaominaisuuksia, se toimii ainoastaan uusissa selaimissa kuten Micro$oft Internet Exploder 4:ssä.

To play - Pelataksesi

Try to find five hidden ships on the grid by clicking the squares. Avoid missed clicks. "Found all" message is displayed in the message box when the game is over. To play again, click the "Start!" button.

Yritä löytää viisi piilotettua laivaa ruudukosta napauttelemalla neliöitä. Vältä hutilaukauksia. Kun peli on loppunut, "Found all" viesti ilmestyy viestiruutuun. Valitse "Start!", kun haluat pelata uudestaan.

About effective Java coding - Tehokkaasta Java-ohjelmoinnista

The a was Panu M Tuominen's ultimate program in the code compressing competition in early 1998. The competition was arranged by Janne Kalliola, one of the assistants of the Object-oriented programming course in the Helsinki University of Technology. The aim was to minimize the character count of the Java source code of the game. The main requirements were: The applet size must be 300 x 300. There must be five hidden "ships" randomly distributed on a 5 x 5 grid. There must be a text field showing the messages "A new game", "Missed", "Hit!", and "Found all". The played boxes must be marked showing also if the box was occupied. There must be a button labeled "Start!", and by clicking it the game will start over.

a on Panu M Tuomisen upea ohjelma koodintiivistyskilpailuun vuoden 1998 alussa. Kilpailun järjesti Janne Kalliola, joka oli yksi Teknillisen Korkeakoulun Olio-ohjelmoinnin kurssin assistenteista. Tavoitteena oli minimoida pelin Java-lähdekoodin merkkimäärä. Päävaatimukset olivat: Sovelman koko pitää olla 300 x 300. Viisi piilotettua "laivaa" pitää sijoitella satunnaisesti 5 x 5 ruudukkoon. Sovelmassa pitää olla tekstikenttä, joka näyttää viestit "A new game", "Missed", "Hit!" ja "Found all". Pelatut laatikot pitää merkitä siten, että osumat voidaan erottaa. Sovelmassa pitää olla nappula "Start!", jota painamalla peli alkaa alusta.

The source code - Lähdekoodi

import java.awt.*;import java.awt.event.*;import java.util.*;public class a extends java.applet.Applet implements ActionListener{int i,s,l[];Button b,n[]=new Button[27];TextField t;Random R=new Random();public void init(){removeAll();setLayout(new GridLayout(0,5));for(l=new int[i=27];i-->1;b.setActionCommand(""+i),(n[i]=b).addActionListener(this))add(b=new Button(i<2?"Start!":""));add(t=new TextField("A new game"));for(t.setFont(new Font("Serif",s=0,8));s<5;i=R.nextInt()%27)if(i>1&&l[i]<1)l[i]=++s;validate();}public void actionPerformed(ActionEvent e){if(l[i=Byte.parseByte(e.getActionCommand())]<6){String T="Missed";if(l[i]>0){T="Hit!";s--;}n[i].setLabel(T);t.setText(s<1?"Found all":T);l[i]=6;}if(i<2)init();}}

1 line, 719 characters. The applet class used on this page is compiled exactly from this line.

1 rivi, 719 merkkiä. Sovelmaluokka, jota on käytetty tällä sivulla, on käännetty juuri tästä nimenomaisesta rivistä.

Commented source code - Kommentoitu lähdekoodi

/** 
 * VAROITUS: Tämä tiedosto on kommentoitu versio tiedostosta a.java. Tämän
 * kääntyvyyttä ja/tai toimivuutta ei ole tarkistettu, eikä sitä ole vaadittu.
 * Kommentoituja kohtia on syytä verrata tiedoston a.java vastaaviin kohtiin.
 * Olennaisesti tiedosto a.java on kommentoitu tässä
 */
import java.awt.*;
import java.awt.event.*;
import java.util.*;

/**
 * Laivanupotuspeliappletin kommenttitiedosto Janne Kalliolan järjestämään
 * koodintiivistämiskilpailuun.
 * @author Panu.Tuominen@hut.fi
 */
public class a extends java.applet.Applet implements ActionListener{
  
  // i = dummy, s = ampumattomien laivojen lkm, l[] (käytössä (1)2-26) =
  // >0 tarkoittaa "laiva on ko. ruudussa".
  int i,s,l[];
  // b = dummy, n[] (käytössä (1)2-26) = viittaukset nappulaolioihin
  // labelin muuttamista varten.
  Button b,n[]=new Button[27];
  TextField t;
  // Satunnaisluvut generoidaan seuraavasta satunnaislukugeneraattorista.
  // Ohjelma lyhenisi merkittävästi, jos satunnaislukuihin käytettäisiin
  // suoraan muotoa (new java.util.Random()).nextInt(), mutta tällöin jokainen
  // satunnaisluku perustuisi vain yhteen iteraatioon systeemikellosta,
  // jota ei voida pitää tehtävänannon mukaisena _satunnaisena_. 
  Random R=new Random();
  
  /**
   * Alustaa laivanupotuspeliappletin.
   * init-metodi on valmisteltu siten, että sitä kutsumalla voidaan suorittaa
   * myös pelin uudelleen aloittaminen.
   */	
  public void init(){
    // Poistaa appletin paneelissa jo olevat vehkeet. Tarvitaan Start!-
    // näppäimen takia kutsuttaessa.
    removeAll();
    setLayout(new GridLayout(0,5));
    // Seuraavassa on syytä huomioida käskyjen suoritusjärjestys. For-loopin
    // alustuslauseessa tyhjennetään samalla laivojen sijoitusruudukko.
    // Viimeinen nappula saa labelin Start!, mutta ActionCommand asetetaan 
    // kuitenkin numeromerkkijonoksi. Rivin jälkeen i==0.
    for(l=new int[i=27];i-->1;b.setActionCommand(""+i),(n[i]=b).addActionListener(this))add(b=new Button(i<2?"Start!":""));
    // Luo informointitekstikentän. Se on editoitavissa, mutta eipä sitä
    // kielletty.
    add(t=new TextField("A new game"));
    // Arpoo viisi laivaa. Ensimmäisellä kierroksella i==0, siksi uusi i
    // arvotaan, vaikka randomi on vasta inkrementointilauseessa. Alustuslause
    // pienentää fontin tekstikentässä siten, että se mahtuu 300 x 300 -
    // applettiin näkymään kokonaan valitulla layoutilla:
    for(t.setFont(new Font("Serif",s=0,8));s<5;i=R.nextInt()%27)if(i>1&&l[i]<1)l[i]=++s;
    // Päivitää appletin paneelin. Olennainen Start!-näppäimen painalluksen
    // yhteydessä.
    validate();
  }
  
  /**
   * Suorittaa olennaisesti näppäintenpainelutapahtumat.
   * Näppäimet tunnistetaan niiden actionCommand:iin asetetusta numeroa
   * esittävästä Stringistä.
   * @param e tapahtunut tapahtuma
   */
  public void actionPerformed(ActionEvent e){
    // Tulkitaan näppäimen numero ja oliko jo ammuttu ruutu. Byte.parseByte
    // on lyhyempi kuin Integer.parseInt ja kaastaus intiksi on automaattinen
    if(l[i=Byte.parseByte(e.getActionCommand())]<6){
      // Tutki mahdollinen osuma ja ilmoita siitä.
      // Pelikentällä ruutuihin tulee pääsääntöisesti sama teksti kuin
      // tekstikenttään, joka täyttää vaatimukset ammuttujen ruutujen
      // osumien ja hutien ilmaisusta.
      String T="Missed";
      if(l[i]>0){
	T="Hit!";
	s--;
      }
      n[i].setLabel(T);
      // Kuitenkin jos kaikki on jo ammuttu, niin tekstikenttä pysyy
      // arvossa "Found all".
      t.setText(s<1?"Found all":T);
      l[i]=6;
    }
    // jos olikin Start!, niin kaikki edellä olikin turhaa, alusta uusi peli.
    if(i<2)init();
  }
}

To see PanuWorld's finest appearance, update your web browser!