import aspcomp.*; import java.util.*; public class HiddenWords { // Size of the generated square private final static int X_SIZE = 20; private final static int Y_SIZE = 20; // Number of words in the random square private final static int NUM_WORDS = 10; // Random number object. // Saves us having to instantiate one each time we want a random number private Random m_rnd; // List of cities private String m_strWords[]= { "ExAir", "Auckland", "Seattle", "Sydney", "London", "Lusaka", "Paris", "Moscow", "Tokyo", "Brasilia", "Bogota", "Caracas", "Ottowa", "Toronto", "Dallas", "Houston", "Manchester", "Cairo", "Dublin", "Khartoum", "Riyadh", "Kuwait", "Durban", "Lisbon", "Madrid", "Rome", "Berlin", "Warsaw", "Stockholm", "Oslo", "Helsinki", "Wellington", "Canberra", "Reykjavik", "Copenhagen", "Delhi", "Singapore", "Jakarta", "Manila", "Bangkok", "Perth", "Quito", "Lima", "Montevideo", "Santiago", "Dunedin", "Suva", "Papeete", "Apia", "Adelaide", "Brisbane", "Melbourne", "Rotorua", "Napier", "Liverpool", "Ndola" }; // Do we want to cheat? true means the square has bold words! private boolean m_fWannaCheat = false; // ASP response object private Response m_Response; // Array of letters private SquareElement[][] m_seArray = new SquareElement[X_SIZE][Y_SIZE]; // All the valid words private Vector m_vectWords; //////////////////////////////////////////////////////////////////////////////// // ctor HiddenWords() { m_vectWords = new Vector(); m_rnd = new Random(); } //////////////////////////////////////////////////////////////////////////////// // buildWordSquare (COM Exposed) // Builds and displays a random word square populated with random cities. // If fWannaCheat is true then the letters of the cities are bold public void buildWordSquare(boolean fWannaCheat) { m_fWannaCheat = fWannaCheat; getIntrinics(); generateRandomSquare(); generateRandomWords(); displaySquare(); } //////////////////////////////////////////////////////////////////////////////// // getWordList (COM Exposed) // Brings back a list of words to the client formatted in a public void getWordList() { // Write the start of the table m_Response.write("
"); m_Response.write("\n"); // Count through each word int iWhichWord = 0; for (Enumeration e = m_vectWords.elements(); e.hasMoreElements(); ) { ChosenWord cw = (ChosenWord)e.nextElement(); String strWord = cw.m_strWord; // Split the table into two rows if (iWhichWord == m_vectWords.size() / 2) { m_Response.write(""); m_Response.write(""); } // Write the word to the table and include the relevant OnClick() code // when the user clicks on this word. // For example, if the city is Auckland then the following is outputted: // Auckland // WordClick() is VBScript code in the calling ASP page m_Response.write("\n"); iWhichWord++; } // Close the table m_Response.write(""); m_Response.write("
"); m_Response.write(""); m_Response.write(strWord + "  "); m_Response.write(""); m_Response.write("
\n\n"); } //////////////////////////////////////////////////////////////////////////////// // getIntrinics // Get any ASP intrinsics we need, in this case we are only writing data // back to the client so we only need the Response interface. private void getIntrinics() { m_Response = AspContext.getResponse(); } //////////////////////////////////////////////////////////////////////////////// // displaySquare // Displays the fully populated word square in an HTML private void displaySquare() { // Write the start of the table and give it an ID m_Response.write("
"); m_Response.write(""); // This is the top/left blank square where there is no x/y coord. m_Response.write(""); // Write the x-coords for (int i=0; i < X_SIZE; i++) m_Response.write(""); m_Response.write("\n"); // Write the y-coord and each letter out in the square for (int i=0; i < Y_SIZE; i++) { // start a new line m_Response.write(""); // write the y coord m_Response.write(""); for (int j=0; j < X_SIZE; j++) { // get the letter String strLetter = new String(); strLetter = strLetter + m_seArray[j][i].m_cLetter; // get other details about the letter boolean fPartOfWord = !m_seArray[j][i].m_fJunkLetter; // is it junk or part of a word? m_Response.write(""); } m_Response.write("\n"); } m_Response.write("
 " + (i < 10 ? "0" : "") + i + "
" + i + ""); // if the letter is part of a valid word then write an out with the letter // For example, if the city is Auckland then following is written for the letter 'K' // if it is located at X=19, Y=8 and is written down the square: // AUCKLAND // This allows the DHTML code to find the data in the square easily if (fPartOfWord) { if (m_fWannaCheat) m_Response.write(""); int iIndex = m_seArray[j][i].m_iIndexIntoWord; // what is the index into the word? int iDirection = m_seArray[j][i].m_cw.m_direction; // get the direction of the word String strID = m_seArray[j][i].m_cw.m_strWord.toUpperCase() + (iDirection == ChosenWord.ACROSS ? "A" : "D") + (j < 10 ? "0" : "") + j + (i < 10 ? "0" : "") + i + "-" + iIndex; m_Response.write(""); } m_Response.write(strLetter.toUpperCase()); if (fPartOfWord) { m_Response.write(""); if (m_fWannaCheat) m_Response.write(""); } m_Response.write("
\n\n"); } //////////////////////////////////////////////////////////////////////////////// // generateRandomSquare // Generates a random square of letters private void generateRandomSquare() { for (int i=0; i 0) { iMaxX = X_SIZE - cw.m_strWord.length(); cw.m_direction = ChosenWord.ACROSS; } else { iMaxY = Y_SIZE - cw.m_strWord.length(); cw.m_direction = ChosenWord.DOWN; } cw.m_x = Math.abs(m_rnd.nextInt()) % iMaxX; cw.m_y = Math.abs(m_rnd.nextInt()) % iMaxY; } while (isLocationAlreadyUsed(cw)); } //////////////////////////////////////////////////////////////////////////////// // isWordAlreadyUsed // Check if this word crosses the path of another private boolean isLocationAlreadyUsed(ChosenWord cw) { boolean fUsed = false; if (cw.m_direction == ChosenWord.ACROSS) { for (int i=0; i < cw.m_strWord.length(); i++) { // if we bump into a non-junk letter then it // must be a valid word so we're outta here if (!m_seArray[cw.m_x + i][cw.m_y].m_fJunkLetter) { fUsed = true; break; } } } else { for (int i=0; i < cw.m_strWord.length(); i++) { // if we bump into a non-junk letter then it // must be a valid word so we're outta here if (!m_seArray[cw.m_x][cw.m_y + i].m_fJunkLetter) { fUsed = true; break; } } } return fUsed; } } //////////////////////////////////////////////////////////////////////////////// // SquareElement class // Each element in the random letter square is actually one of these class SquareElement { public ChosenWord m_cw; // reference to the chosen word (if applicable) public char m_cLetter; // the letter in this square public boolean m_fJunkLetter; // is it a junk letter or part of a word? public int m_iIndexIntoWord; // if it's part of word then what index into the word is it? SquareElement() { m_cw = new ChosenWord(); m_cLetter = '0'; m_fJunkLetter = true; m_iIndexIntoWord = 0; } } //////////////////////////////////////////////////////////////////////////////// // ChosenWord class // A Vector of ChosenWord's is maintained class ChosenWord { public final static int ACROSS=0; // Word goes left -> right public final static int DOWN =1; // Word goes top -> down public String m_strWord; // The word public int m_x, m_y; // It's starting location public int m_direction; // It's direction ChosenWord() { m_strWord = new String(""); m_x = m_y = 0; m_direction = ACROSS; } }