home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / HiddenWords.java < prev    next >
Text File  |  1997-11-01  |  12KB  |  409 lines

  1. import aspcomp.*;
  2. import java.util.*;
  3.  
  4. public class HiddenWords
  5. {
  6.     // Size of the generated square
  7.     private final static int X_SIZE = 20;
  8.     private final static int Y_SIZE = 20;
  9.  
  10.     // Number of words in the random square
  11.     private final static int NUM_WORDS = 10;
  12.  
  13.     // Random number object. 
  14.     // Saves us having to instantiate one each time we want a random number
  15.     private Random        m_rnd;
  16.  
  17.     // List of cities
  18.     private String        m_strWords[]=
  19.     {
  20.         "ExAir",        "Auckland",        "Seattle",        "Sydney",
  21.         "London",        "Lusaka",        "Paris",        "Moscow",
  22.         "Tokyo",        "Brasilia",        "Bogota",        "Caracas",
  23.         "Ottowa",        "Toronto",        "Dallas",        "Houston",
  24.         "Manchester",    "Cairo",        "Dublin",        "Khartoum",
  25.         "Riyadh",        "Kuwait",        "Durban",        "Lisbon",
  26.         "Madrid",        "Rome",            "Berlin",        "Warsaw",
  27.         "Stockholm",    "Oslo",            "Helsinki",        "Wellington",
  28.         "Canberra",        "Reykjavik",    "Copenhagen",    "Delhi",
  29.         "Singapore",    "Jakarta",        "Manila",        "Bangkok",
  30.         "Perth",        "Quito",        "Lima",            "Montevideo",
  31.         "Santiago",        "Dunedin",        "Suva",            "Papeete",
  32.         "Apia",            "Adelaide",        "Brisbane",        "Melbourne",
  33.         "Rotorua",        "Napier",        "Liverpool",    "Ndola"
  34.     };
  35.  
  36.     // Do we want to cheat? true means the square has bold words!
  37.     private boolean                m_fWannaCheat = false;
  38.     
  39.     // ASP response object
  40.     private Response             m_Response;
  41.  
  42.     // Array of letters
  43.     private SquareElement[][]    m_seArray = new SquareElement[X_SIZE][Y_SIZE];
  44.  
  45.     // All the valid words
  46.     private Vector                m_vectWords;
  47.  
  48.     ////////////////////////////////////////////////////////////////////////////////
  49.     // ctor
  50.     HiddenWords()
  51.     {
  52.         m_vectWords = new Vector();
  53.         m_rnd = new Random();
  54.     }
  55.  
  56.     ////////////////////////////////////////////////////////////////////////////////
  57.     // buildWordSquare (COM Exposed)
  58.     // Builds and displays a random word square populated with random cities.
  59.     // If fWannaCheat is true then the letters of the cities are bold
  60.     public void buildWordSquare(boolean fWannaCheat) 
  61.     {
  62.         m_fWannaCheat = fWannaCheat;
  63.  
  64.         getIntrinics();
  65.         generateRandomSquare();
  66.         generateRandomWords();
  67.         displaySquare();
  68.     }
  69.  
  70.     ////////////////////////////////////////////////////////////////////////////////
  71.     // getWordList (COM Exposed)
  72.     // Brings back a list of words to the client formatted in a <TABLE>
  73.     public void getWordList()
  74.     {
  75.         // Write the start of the table
  76.         m_Response.write("<TABLE ID=TableCityList>");
  77.         m_Response.write("<TR>\n");
  78.  
  79.         // Count through each word
  80.         int iWhichWord = 0;
  81.         for (Enumeration e = m_vectWords.elements(); e.hasMoreElements(); )
  82.         {
  83.             ChosenWord cw = (ChosenWord)e.nextElement();
  84.             String strWord = cw.m_strWord;
  85.  
  86.             // Split the table into two rows
  87.             if (iWhichWord == m_vectWords.size() / 2)
  88.             {
  89.                 m_Response.write("</TR>");
  90.                 m_Response.write("<TR>");
  91.             }
  92.  
  93.             // Write the word to the table and include the relevant OnClick() code 
  94.             // when the user clicks on this word. 
  95.             // For example, if the city is Auckland then the following is outputted:
  96.             //   <A onclick=WordClick("Auckland") ID=Auckland>Auckland</A>
  97.             // WordClick() is VBScript code in the calling ASP page
  98.             m_Response.write("<TD ALIGN=CENTER>");
  99.             m_Response.write("<A onclick=WordClick(\"" + strWord + "\") ID=" + strWord + ">");
  100.             m_Response.write(strWord + "  ");
  101.             m_Response.write("</A>");
  102.             m_Response.write("</TD>\n");
  103.  
  104.             iWhichWord++;
  105.         }
  106.         
  107.         // Close the table
  108.         m_Response.write("</TR>");
  109.         m_Response.write("</TABLE>\n\n");
  110.     }
  111.  
  112.     ////////////////////////////////////////////////////////////////////////////////
  113.     // getIntrinics
  114.     // Get any ASP intrinsics we need, in this case we are only writing data
  115.     // back to the client so we only need the Response interface.
  116.     private void getIntrinics()
  117.     {
  118.         m_Response = AspContext.getResponse();
  119.     }
  120.  
  121.     ////////////////////////////////////////////////////////////////////////////////
  122.     // displaySquare
  123.     // Displays the fully populated word square in an HTML <TABLE>
  124.     private void displaySquare()
  125.     {
  126.         // Write the start of the table and give it an ID
  127.         m_Response.write("<TABLE ID=TableHiddenWords>");
  128.         m_Response.write("<TR>");
  129.  
  130.         // This is the top/left blank square where there is no x/y coord.
  131.         m_Response.write("<TD> </TD>");
  132.  
  133.         // Write the x-coords
  134.         for (int i=0; i < X_SIZE; i++)
  135.             m_Response.write("<TD ALIGN=CENTER BGCOLOR=#0000FF><FONT COLOR=#FFFFFF><B>" + (i < 10 ? "0" : "") + i + "</B></FONT></TD>");
  136.  
  137.         m_Response.write("</TR>\n");
  138.  
  139.         // Write the y-coord and each letter out in the square
  140.         for (int i=0; i < Y_SIZE; i++)
  141.         {
  142.             // start a new line
  143.             m_Response.write("<TR>");
  144.             
  145.             // write the y coord
  146.             m_Response.write("<TD ALIGN=CENTER BGCOLOR=#0000FF><FONT COLOR=#FFFFFF><B>" + i + "</B></FONT></TD>");
  147.  
  148.             for (int j=0; j < X_SIZE; j++)
  149.             {
  150.                 // get the letter
  151.                 String strLetter = new String();
  152.                 strLetter = strLetter + m_seArray[j][i].m_cLetter;
  153.                 
  154.                 // get other details about the letter
  155.                 boolean fPartOfWord = !m_seArray[j][i].m_fJunkLetter;    // is it junk or part of a word?
  156.  
  157.                 m_Response.write("<TD>");
  158.  
  159.                 // if the letter is part of a valid word then write an <A ID=xx> out with the letter
  160.                 // For example, if the city is Auckland then following is written for the letter 'K'
  161.                 // if it is located at X=19, Y=8 and is written down the square:
  162.                 //    <A ID=AUCKLANDD0819-3>AUCKLAND</A>
  163.                 // This allows the DHTML code to find the data in the square easily
  164.                 if (fPartOfWord) 
  165.                 {
  166.                     if (m_fWannaCheat) m_Response.write("<STRONG>");
  167.  
  168.                     int iIndex = m_seArray[j][i].m_iIndexIntoWord;            // what is the index into the word?
  169.                     int iDirection = m_seArray[j][i].m_cw.m_direction;        // get the direction of the word
  170.                     String strID = m_seArray[j][i].m_cw.m_strWord.toUpperCase() + 
  171.                                    (iDirection == ChosenWord.ACROSS ? "A" : "D") + 
  172.                                    (j < 10 ? "0" : "") + j + 
  173.                                    (i < 10 ? "0" : "") + i + 
  174.                                    "-" +                                    
  175.                                    iIndex;
  176.                     m_Response.write("<A ID=" + strID + ">");
  177.                 }
  178.  
  179.                 m_Response.write(strLetter.toUpperCase());
  180.                 
  181.                 if (fPartOfWord) 
  182.                 {
  183.                     m_Response.write("</A>");
  184.                     if (m_fWannaCheat) m_Response.write("</STRONG>");
  185.                 }
  186.                 
  187.                 m_Response.write("</TD>");
  188.             }
  189.  
  190.             m_Response.write("</TR>\n");
  191.         }
  192.  
  193.         m_Response.write("</TABLE>\n\n");
  194.     }
  195.  
  196.     ////////////////////////////////////////////////////////////////////////////////
  197.     // generateRandomSquare
  198.     // Generates a random square of letters
  199.     private void generateRandomSquare()
  200.     {
  201.         for (int i=0; i<X_SIZE; i++)
  202.         {
  203.             for (int j=0; j<Y_SIZE; j++)
  204.             {
  205.                 m_seArray[i][j] = new SquareElement();
  206.                 m_seArray[i][j].m_cLetter = getRandomLetter();
  207.             }
  208.         }
  209.     }
  210.  
  211.     ////////////////////////////////////////////////////////////////////////////////
  212.     // getRandomLetter
  213.     // Generates one random, uppercase letter
  214.     private char getRandomLetter()
  215.     {
  216.         int iRand = Math.abs(m_rnd.nextInt()) % 26;
  217.         return (char)((int)'A' + iRand);
  218.     }
  219.  
  220.     ////////////////////////////////////////////////////////////////////////////////
  221.     // generateRandomWords
  222.     // Builds all the random words and populates the random square
  223.     private void generateRandomWords()
  224.     {
  225.         for (int i=0; i < NUM_WORDS; i++)
  226.         {
  227.             // Get the word details
  228.             ChosenWord cw = getRandomWordAndLocation();
  229.             m_vectWords.addElement(cw);
  230.  
  231.             // Add the word to the square
  232.             if (cw.m_direction == ChosenWord.ACROSS)
  233.             {
  234.                 for (int j=0; j < cw.m_strWord.length(); j++)
  235.                 {
  236.                     m_seArray[cw.m_x + j][cw.m_y].m_cw = cw;
  237.                     m_seArray[cw.m_x + j][cw.m_y].m_cLetter = cw.m_strWord.charAt(j);
  238.                     m_seArray[cw.m_x + j][cw.m_y].m_fJunkLetter = false;
  239.                     m_seArray[cw.m_x + j][cw.m_y].m_iIndexIntoWord = j;
  240.                 }
  241.             }
  242.             else
  243.             {
  244.                 for (int j=0; j < cw.m_strWord.length(); j++)
  245.                 {
  246.                     m_seArray[cw.m_x][cw.m_y + j].m_cw = cw;
  247.                     m_seArray[cw.m_x][cw.m_y + j].m_cLetter = cw.m_strWord.charAt(j); 
  248.                     m_seArray[cw.m_x][cw.m_y + j].m_fJunkLetter = false;
  249.                     m_seArray[cw.m_x][cw.m_y + j].m_iIndexIntoWord = j;
  250.                 }
  251.             }
  252.         }
  253.     }
  254.  
  255.     ////////////////////////////////////////////////////////////////////////////////
  256.     // getRandomWordLocation
  257.     // Generate a random word (from the list) and make sure it's unique
  258.     private ChosenWord getRandomWordAndLocation()
  259.     {
  260.         String strWord;
  261.  
  262.         // Create a random, unique word
  263.         do
  264.         {
  265.             strWord = getRandomWord();
  266.             
  267.         } while (isWordAlreadyUsed(strWord));
  268.  
  269.         // Create a new ChosenWord object and set the word
  270.         ChosenWord cw = new ChosenWord();
  271.         cw.m_strWord = strWord;
  272.         getRandomLocationAndDirection(cw);
  273.  
  274.         return cw;
  275.     }
  276.  
  277.     ////////////////////////////////////////////////////////////////////////////////
  278.     // getRandomWord
  279.     // Chose a word at random from the lit
  280.     private String getRandomWord()
  281.     {
  282.         int iRand = Math.abs(m_rnd.nextInt()) % m_strWords.length;
  283.         return m_strWords[iRand];
  284.     }
  285.  
  286.     ////////////////////////////////////////////////////////////////////////////////
  287.     // isWordAlreadyUsed
  288.     // Is this word already in the vector of chosen words?
  289.     private boolean isWordAlreadyUsed(String strWord)
  290.     {
  291.         boolean fUsed = false;
  292.         
  293.         for (Enumeration e = m_vectWords.elements(); e.hasMoreElements(); )
  294.         {
  295.             ChosenWord cw = (ChosenWord)e.nextElement();
  296.             if (cw.m_strWord.equals((String)strWord))
  297.             {
  298.                 fUsed = true;
  299.                 break;
  300.             }
  301.         }
  302.  
  303.         return fUsed;
  304.     }
  305.  
  306.     ////////////////////////////////////////////////////////////////////////////////
  307.     // getRandomLocationAndDirection
  308.     // Chose a random location and direction, 
  309.     // making sure we don't cross the path of another word!
  310.     private void getRandomLocationAndDirection(ChosenWord cw)
  311.     {
  312.         do
  313.         {
  314.             int iMaxX=X_SIZE, iMaxY=Y_SIZE;
  315.  
  316.             // 50/50 chance of ACROSS word or DOWN word
  317.             if (m_rnd.nextInt() > 0)
  318.             {
  319.                 iMaxX = X_SIZE - cw.m_strWord.length();
  320.                 cw.m_direction = ChosenWord.ACROSS;
  321.             }
  322.             else
  323.             {
  324.                 iMaxY = Y_SIZE - cw.m_strWord.length();
  325.                 cw.m_direction = ChosenWord.DOWN;
  326.             }
  327.  
  328.             cw.m_x = Math.abs(m_rnd.nextInt()) % iMaxX; 
  329.             cw.m_y = Math.abs(m_rnd.nextInt()) % iMaxY;
  330.  
  331.         } while (isLocationAlreadyUsed(cw));
  332.     }
  333.  
  334.     ////////////////////////////////////////////////////////////////////////////////
  335.     // isWordAlreadyUsed
  336.     // Check if this word crosses the path of another
  337.     private boolean isLocationAlreadyUsed(ChosenWord cw)
  338.     {
  339.         boolean fUsed = false;
  340.         if (cw.m_direction == ChosenWord.ACROSS)
  341.         {
  342.             for (int i=0; i < cw.m_strWord.length(); i++)
  343.             {
  344.                 // if we bump into a non-junk letter then it 
  345.                 // must be a valid word so we're outta here
  346.                 if (!m_seArray[cw.m_x + i][cw.m_y].m_fJunkLetter)
  347.                 {
  348.                     fUsed = true;
  349.                     break;
  350.                 }
  351.             }
  352.         }
  353.         else
  354.         {
  355.             for (int i=0; i < cw.m_strWord.length(); i++)
  356.             {
  357.                 // if we bump into a non-junk letter then it 
  358.                 // must be a valid word so we're outta here
  359.                 if (!m_seArray[cw.m_x][cw.m_y + i].m_fJunkLetter)
  360.                 {
  361.                     fUsed = true;
  362.                     break;
  363.                 }
  364.             }
  365.         }
  366.  
  367.         return fUsed;
  368.     }
  369. }
  370.  
  371. ////////////////////////////////////////////////////////////////////////////////
  372. // SquareElement class
  373. // Each element in the random letter square is actually one of these
  374. class SquareElement
  375. {
  376.     public ChosenWord    m_cw;                // reference to the chosen word (if applicable)
  377.     public char            m_cLetter;            // the letter in this square
  378.     public boolean        m_fJunkLetter;        // is it a junk letter or part of a word?
  379.     public int            m_iIndexIntoWord;    // if it's part of word then what index into the word is it?
  380.  
  381.     SquareElement()
  382.     {
  383.         m_cw             = new ChosenWord();
  384.         m_cLetter         = '0';
  385.         m_fJunkLetter     = true;
  386.         m_iIndexIntoWord = 0;
  387.     }
  388. }
  389.  
  390. ////////////////////////////////////////////////////////////////////////////////
  391. // ChosenWord class
  392. // A Vector of ChosenWord's is maintained
  393. class ChosenWord
  394. {
  395.     public final static int ACROSS=0;    // Word goes left -> right
  396.     public final static int DOWN =1;    // Word goes top -> down
  397.     
  398.     public String    m_strWord;            // The word
  399.     public int        m_x, m_y;            // It's starting location
  400.     public int        m_direction;        // It's direction
  401.  
  402.     ChosenWord()
  403.     {
  404.         m_strWord   = new String("");
  405.         m_x = m_y   = 0;
  406.         m_direction = ACROSS;
  407.     }
  408. }
  409.