1   package hirsipuu;
2   
3   import java.io.BufferedReader;
4   import java.io.FileNotFoundException;
5   import java.io.FileReader;
6   import java.io.IOException;
7   import java.util.Random;
8   
9   /**
10   * Luokka sanaolioiden kokoelman hallintaan. Sanalista osaa palauttaa satunnaisen sanan
11   * pyydetylt? tasolta sek? lukea sanat sanalistat.dat -tiedostosta.
12   * @author Anna-Leena Latvala, Toni Purontaka
13   * @version 0.5, 10.3.2008
14   *
15   */
16  public class Sanalista {
17  
18      private static int SANOJENLKM = 15;
19      private int lkm=0;
20      private Sana[] sanat = new Sana[SANOJENLKM];
21      private final static String POLKU = "sanalistat.dat";
22      Random generator = new Random();
23      
24      /**
25       * Alustaa tasot ja luo tasolistan defaulttitiedostosta.
26       */
27      public Sanalista() {
28          lisaaTiedostosta(POLKU);
29      }
30      
31      /**
32       * Alustaa tasot ja luo tasolistan halutusta tiedostosta polussa "polku.
33       */
34      public Sanalista(String polku) {
35          lisaaTiedostosta(polku);
36      }
37      
38      /**
39       * Lukee tiedostosta tasojen tiedot ja luo kokoelman taso-olioita.
40       *
41       * @example
42       * <pre name="test">
43       * #THROWS IOException
44       * #import java.io.IOException;
45       * #import fi.jyu.mit.ohj2.VertaaTiedosto;
46       *  VertaaTiedosto.kirjoitaTiedosto("testilista.txt",
47       *      "1 | 1| kissa\n"+
48       *      "1 | 2| koira\n"+
49       *      "2 | 1| typpi");
50       *  Sanalista sanat = new Sanalista("testilista.txt");
51       *  sanat.sana(2) === "typpi";
52       *  VertaaTiedosto.tuhoaTiedosto("testilista.txt");
53       * </pre>
54       */
55      public final void lisaaTiedostosta(String polku) {
56          BufferedReader fi;
57          
58          try {  //aukaistaan lukija
59            fi = new BufferedReader(new FileReader(polku));
60          } catch (FileNotFoundException ex) {
61            System.err.println("Tiedosto " + polku + " ei aukea!");
62            return;
63          }        
64                 
65          try {
66            String s;
67            Sana sana;
68            int i = 0;
69            while ( ( s = fi.readLine() ) != null) {
70                sana = new Sana();
71                sana.parse(s);
72                if (i >= sanat.length) kasvata();
73                sanat[i] = sana; 
74                i++; 
75                lkm++;
76              
77             }
78            lkm--;        //damage control :)
79          } catch (IOException ex) {
80            System.err.println("Virhe tiedostoa luettaessa!");
81    
82          } finally {  // suljetaan tietovirta
83            try {
84              fi.close(); 
85            } catch (IOException ex) {
86              System.err.println("Tiedostoa ei saa suljettua!");
87            }
88          }
89        }
90      
91      /**
92       * Palauttaa satunnaisen sanan tasolta "taso". Satunnaisuus uudistettu.
93       * @param taso pyydetyn tason numero
94       * @return satunnainen sana, mik?li t?llaista tasoa vastaavia sanoja on;
95       *         muutoin palauttaa null-viitteen.
96       *         
97       * 
98       */
99      public String sana(int taso){
100         int sanatlkm=0;
101         int i=0,j=0;
102         for(i=0;i<lkm;i++){
103             if(sanat[i].taso(taso)) sanatlkm++;
104         }
105         
106         if (sanatlkm == 0) return null; // jos tasoa vastaavia sanoja ei ole, niin t?ss? vaiheessa on hyv? h?ipy?
107         
108         int k=generator.nextInt( sanatlkm )+1;      //k:s tason taso sana palautetetaan
109         i=0;
110         while(j<k){
111             if(sanat[i].taso(taso)) j++;
112             i++;
113         }
114         return sanat[i-1].getSana();
115     }
116    
117     /**
118      * Kasvattaa taulukon koon kaksinkertaiseksi ja kopioi siihen 
119      * aikaisemmat alkiot.
120      */
121     private void kasvata() {
122         Sana[] sanat1 = new Sana[SANOJENLKM*2];
123         for (int i=1; i < SANOJENLKM; i++) {
124             sanat1[i] = sanat[i];
125         }
126         SANOJENLKM = SANOJENLKM*2;
127         sanat = sanat1;
128     }
129     
130     /**
131      * Testip??ohjelma
132      * 
133      * @param Args ei k?yt?ss?
134      */
135     public static void main(String[] Args){
136         Sanalista sanalista=new Sanalista();
137         System.out.println(sanalista.sana(1));
138         System.out.println(sanalista.sana(2));
139     }
140 }
141