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("");
m_Response.write("");
m_Response.write(strWord + "  ");
m_Response.write("");
m_Response.write(" | \n");
iWhichWord++;
}
// Close the table
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("" + (i < 10 ? "0" : "") + i + " | ");
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("" + i + " | ");
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("");
// 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(" | ");
}
m_Response.write("
\n");
}
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;
}
}