import java.util.*;

/**
 *
 * JogglePlay (implements old style JoggleFE,, start and stop only)
 *
 * @version $Id: JogglePlay.java,v 1.5 1996/11/30 23:49:14 ola Exp ola $
 *
 * @author Owen Astrachan
 *
 */

public class JogglePlay implements JoggleFE
{
    /**
     * construct a JogglePlay(er)
     *
     * @param trie The trie of all words in dictionary
     */
    
    public JogglePlay(Trie trie)
    {
	myWords = new Vector();
        myTrie = trie;
	myVisited = new boolean[25];
    }

    /**
     *
     * start a game of Joggle, find all words in board
     *
     * @param board The board on which the game will be played
     */
    
    public void startGame(char board[][])
    {
	int j;
	int k;
	int size = board[0].length;
	for(j=0; j < size; j++)
	{
	    for(k=0; k < size; k++)
	    {
		System.out.print(board[j][k]+" ");
	    }
	    System.out.println();
	}

	for(k=0; k < size*size; k++)
	{
	    myVisited[k] = false;
	}
	myBoard = board;
	mySize = size;
	FindWords();	
    }

    void DoFind(Trie trie, int row, int col, char [] sb, int length)
    {	
	if (0 <= row && row < mySize && 0 <= col && col < mySize)
	{
	    // legal position, now check for already visited
	    
	    int loc = row * mySize + col;
	    if (myVisited[loc]) return;        // already been here


	    // check to see if this is a prefix of any word
	    
	    Trie t;
	    if ((t = trie.childAt(myBoard[row][col])) == null) return;

	    // prefix to here, check for wordness and recurse
	    
	    myVisited[loc] = true;             // mark as visited
	    sb[length++] = myBoard[row][col];
	    if (t.isWord())
	    {
		System.out.println(myCount + " " + sb);
		myCount++;
		synchronized(myWords)
		{
		    myWords.addElement(new String(sb,0,length));
		}
	    }

	    // visit all 8 neighbors
	    
	    DoFind(t,row-1,col-1,sb,length);
	    DoFind(t,row-1,col,sb,length);
	    DoFind(t,row-1,col+1,sb,length);

	    DoFind(t,row,col-1,sb,length);
	    DoFind(t,row,col+1,sb,length);

	    DoFind(t,row+1,col-1,sb,length);
	    DoFind(t,row+1,col,sb,length);
	    DoFind(t,row+1,col+1,sb,length);

	    // we're processed, reset visited and string as unused
		
	    myVisited[loc] = false;
	    sb[--length] = '\0';
	}
    }
    
    void FindWords()
    {
	myCount = 0;
	//StringBuffer sb = new StringBuffer(mySize*mySize);
	char sb[] = new char[mySize*mySize];
	int j,k;
	for(j=0; j < mySize; j++)
	{
	    for(k=0; k <  mySize; k++)
	    {
		DoFind(myTrie,j,k,sb,0);
	    }
	}
    }

    /**
     * stop the game
     *
     * @return a list of words found by the player
     */
    
    public String[] stopGame()
    {
	synchronized(myWords)
	{
	    int count = myWords.size();
	    String words[] = new String[count];
	    myWords.copyInto(words);
	    return words;
	}
    }
    
    private char myBoard[][];            // play on this board
    private boolean myVisited[];         // used to mark positions
    private int mySize;                  // board dimension (square)
    private Trie myTrie;                 // trie of valid words
    private Vector myWords;              // words found

    private int myCount;                 // used to print
}


