import java.awt.*;
import java.applet.*;
import java.util.Random;
import java.lang.Math;

public class TicTac extends Applet
{
	private static final int STATE_EMPTY = 0;
	private static final int STATE_CROSS = 1;
	private static final int STATE_CIRCLE = -1;
	
	private static final int WIN_NONE = 0;
	private static final int WIN_CROSS = 1;
	private static final int WIN_CIRCLE = 2;
	private static final int WIN_DRAW = 3;
	
	private int w, h;
	private int cellw, cellh;
	private Color fgcolor;
	
	private int[] state;
	private int win;
	
	private Random rnd;
	
	public void init()
	{
		w = getWidth();
		h = getHeight();
		
		cellw = w / 3;
		cellh = h / 3;
		
		setBackground(new Color(getHexIntParam("backcolor")));
		fgcolor = new Color(getHexIntParam("forecolor"));
		
		state = new int[9];
		
		for(int i = 0; i < 9; i++)
		{
			state[i] = STATE_EMPTY;
		}
		
		win = WIN_NONE;
		
		rnd = new Random();
		
		if(Math.abs(rnd.nextInt()) % 100 >= 50)
		{
			state[Math.abs(rnd.nextInt()) % 9] = STATE_CIRCLE;
		}
	}
	
	private int getHexIntParam(String param)
	{
		try
		{
			return Integer.parseInt(getParameter(param), 16);
		}
		catch(Exception e)
		{
			return 0;
		}
	}
	
	public boolean mouseDown(Event evt, int x, int y)
	{
		if(win != WIN_NONE)
		{
			
			for(int i = 0; i < 9; i++)
			{
				state[i] = STATE_EMPTY;
			}
			
			if(win == WIN_CIRCLE || (win == WIN_DRAW && Math.abs(rnd.nextInt()) % 100 >= 50))
			{
				state[Math.abs(rnd.nextInt()) % 9] = STATE_CIRCLE;
			}
			
			win = WIN_NONE;
			
			repaint();
			
			return true;
		}

		int index = x / cellw + y / cellh * 3;
		
		if(state[index] == STATE_EMPTY)
		{
			state[index] = STATE_CROSS;
			
			index = aiMove(state);
			
			if(index >= 0)
			{
				state[index] = STATE_CIRCLE;
			}
			
			win = checkWin(state);
		}
		
		repaint();
		
		return true;
	}
	
	private int aiMove(int[] state)
	{
		int i;
		boolean flag;
		
		for(i = 0; i < 9; i++)
		{
			if(state[i] != STATE_EMPTY)
			{
				continue;
			}
			
			state[i] = STATE_CIRCLE;
			flag = checkWin(state, STATE_CIRCLE);
			state[i] = STATE_EMPTY;
			
			if(flag)
			{
				return i;
			}
		}
		
		for(i = 0; i < 9; i++)
		{
			if(state[i] != STATE_EMPTY)
			{
				continue;
			}
			
			state[i] = STATE_CROSS;
			flag = checkWin(state, STATE_CROSS);
			state[i] = STATE_EMPTY;
			
			if(flag)
			{
				return i;
			}
		}
		
		flag = false;
		
		for(i = 0; i < 9; i++)
		{
			if(state[i] == STATE_EMPTY)
			{
				flag = true;
				break;
			}
		}
		
		if(!flag)
		{
			return -1;
		}
		
		do
		{
			i = Math.abs(rnd.nextInt()) % 9;
		}
		while(state[i] != STATE_EMPTY);
		
		return i;
	}
	
	private int checkWin(int[] state)
	{
		if(checkWin(state, STATE_CROSS))
		{
			return WIN_CROSS;
		}
		else if(checkWin(state, STATE_CIRCLE))
		{
			return WIN_CIRCLE;
		}
		else
		{
			boolean empty = false;
			
			for(int i = 0; i < 9; i++)
			{
				if(state[i] == STATE_EMPTY)
				{
					empty = true;
					break;
				}
			}
			
			if(empty)
			{
				return WIN_NONE;
			}
			else
			{
				return WIN_DRAW;
			}
		}
	}
	
	private boolean checkWin(int[] state, int player)
	{
		int x, y, index;
		boolean win;
		
		for(x = 0; x < 3; x++)
		{
			win = true;
			
			for(y = 0; y < 3; y++)
			{
				index = x + y * 3;
				
				if(state[index] != player)
				{
					win = false;
					break;
				}
			}
			
			if(win)
			{
				return true;
			}
		}
		
		for(y = 0; y < 3; y++)
		{
			win = true;
			
			for(x = 0; x < 3; x++)
			{
				index = x + y * 3;
				
				if(state[index] != player)
				{
					win = false;
					break;
				}
			}
			
			if(win)
			{
				return true;
			}
		}
		
		win = true;
		
		for(x = 0, y = 0; x < 3 && y < 3; x++, y++)
		{
			index = x + y * 3;
			
			if(state[index] != player)
			{
				win = false;
				break;
			}
		}
		
		if(win)
		{
			return true;
		}
		
		win = true;
		
		for(x = 0, y = 2; x < 3 && y >= 0; x++, y--)
		{
			index = x + y * 3;
			
			if(state[index] != player)
			{
				win = false;
				break;
			}
		}
		
		return win;
	}

	public void paint(Graphics g)
	{
		g.setColor(fgcolor);
		
		g.drawLine(cellw, 0, cellw, h);
		g.drawLine(cellw << 1, 0, cellw << 1, h);
		
		g.drawLine(0, cellh, w, cellh);
		g.drawLine(0, cellh << 1, w, cellh << 1);
		
		int x, y, index;
		
		for(x = 0; x < 3; x++)
		{
			for(y = 0; y < 3; y++)
			{
				index = x + y * 3;
				
				if(state[index] == STATE_CROSS && win != WIN_CIRCLE)
				{
					g.drawLine(cellw * x + (cellw >>> 2), cellh * y + (cellh >>> 2), cellw * (x + 1) - (cellw >>> 2), cellh * (y + 1) - (cellh >>> 2));
					g.drawLine(cellw * (x + 1) - (cellw >>> 2), cellh * y + (cellh >>> 2), cellw * x + (cellw >>> 2), cellh * (y + 1) - (cellh >>> 2));
				}
				else if(state[index] == STATE_CIRCLE && win != WIN_CROSS)
				{
					g.drawOval(cellw * x + (cellw >>> 2), cellh * y + (cellh >>> 2), cellw >>> 1, cellh >>> 1);
				}
			}
		}
	}
}