import java.applet.Applet;    
import java.awt.event.*;      
import java.applet.AudioClip; 
import java.awt.*;            
import java.util.*;

public class Sanmoku2 extends Applet implements Runnable,MouseListener{
	private Dimension d;
	private Image offscreen;
	private Graphics grf;
	private final int tateCount = 3;
	private final int yokoCount = 3;
	private final int masuInterval = 5;
	private final int masuWidth = 40;
	private final int masuHeight = 40;
	private int x;
	private int y;
	private int tw;
	private int yw;
	private int [][] radio = {{1,0},{0,1}};
	private int [][] yusen = {{2,1,2},{1,3,1},{2,1,2}};
	private Image haikei;
	private Image masugazou;
	private Image title;
	private Image onradiobutton;
	private Image offradiobutton;
	private Image maru;
	private Image batu;
	private MediaTracker mt;
	private int [][] p = new int[2][2];
	private Masu[][] masu = new Masu[3][3];
	private Banmen banmen;
	private Judge2 judge;
	private boolean startFlg = false;
	private boolean ex1Flg = true;
	private boolean ex2Flg = true;
	Thread thread = null;
	public void init(){
		d = getSize();
		offscreen = createImage(d.width,d.height);
		grf = offscreen.getGraphics();
		tw = (d.height - (masuHeight * tateCount + masuInterval * (tateCount - 1))) / 2;
		yw = (d.width - (masuWidth * yokoCount + masuInterval * (yokoCount - 1))) / 2;
		mt = new MediaTracker(this);
		masugazou = getImage(getCodeBase(),"masu.gif");
		mt.addImage(masugazou,0);
		title = getImage(getCodeBase(),"title.gif");
		mt.addImage(title,0);
		onradiobutton = getImage(getCodeBase(),"radiobotton2.gif");
		mt.addImage(onradiobutton,0);
		offradiobutton = getImage(getCodeBase(),"radiobotton.gif");
		mt.addImage(offradiobutton,0);
		addMouseListener(this);
	}
	public void init2(){
		for(int i = 0;i < tateCount;i++){
			for(int j = 0;j < yokoCount;j++){
				masu[i][j] = new Masu();
			}
		}
		banmen = new Banmen(masu);
		judge = new Judge2(this,banmen);
		
	}
	public void paint(Graphics g){
		update(g);
	}
	public void update(Graphics g){
		if(!mt.checkID(0)){
			g.setColor(Color.black);
			g.drawString("Please wait...",d.width / 4,d.height / 2);
			return;
		}
		grf.setColor(new Color(176,224,230));
		grf.fillRect(0,0,d.width,d.height);
		grf.drawImage(title,78,5,this);
		grf.setColor(Color.blue);
		grf.setFont(new Font("TimesRoman",Font.PLAIN,14));
		grf.drawString("PLAYER1",40,150);
		grf.drawString("PLAYER2",300,150);
		for(int i = 0;i < 2;i++){
			for(int j = 0;j < 2;j++){
				if(j == 0){
					grf.drawString("HUMA",55 + 260 * i,187 + 25 * j);
				}else{
					grf.drawString("COMP",55 + 260 * i,187 + 25 * j);
				}
				if(radio[i][j] == 1){
					grf.drawImage(onradiobutton,30 + i * 260,175 + j * 25,this);
				}else{
					grf.drawImage(offradiobutton,30 + i * 260,175 + j * 25,this);
				}
			}
		}
		for(int i = 0;i < tateCount;i++){
				int x = i * (masuHeight + masuInterval); 
				for(int j = 0;j < yokoCount;j++){
					int y = j * (masuWidth + masuInterval);
					grf.drawImage(masugazou,y + tw,x + yw,this);
				}
		}
		if(startFlg){
			grf.setColor(Color.green);
			for(int i = 0;i < tateCount;i++){
					int x = i * (masuHeight + masuInterval); 
					for(int j = 0;j < yokoCount;j++){
						int y = j * (masuWidth + masuInterval);
						if(masu[i][j].getZyoutai() != -1){
							grf.setColor(Color.white);
							grf.fillRect(y + tw,x + yw,40,40);
							grf.setColor(Color.black);
							if(masu[i][j].getZyoutai() == 0){
								grf.drawString("○",y + tw + 15,x + yw + 25);
							}else{
								grf.drawString("×",y + tw + 15,x + yw + 25);
							}
						}
					}
			}
			int i = judge.winnerReturn();
			if(i != -1){
				startFlg = false;
				if(i == 0){
					grf.drawString("プレーヤー1の勝ちです",135,360);
				}else{
					grf.drawString("プレーヤー2の勝ちです",135,360);
				}
			}
			if(i == -1){
			    if(banmen.allFull()){
					grf.drawString("引き分けです",135,360);
					startFlg = false;
			    }
			}
		}
		
		grf.setColor(new Color(255,255,160));
		grf.fillRect(135,310,135,30);
		grf.setColor(Color.black);
		grf.setFont(new Font("TimesRoman",Font.ITALIC,16));
		grf.drawString("START",165,330);
		g.drawImage(offscreen,0,0,this);
	}
	public void mouseReleased(MouseEvent e){
	}
	public void mousePressed(MouseEvent e){
		for(int i = 0;i < 2;i++){
			for(int j = 0;j < 2;j++){
				if(e.getX() >= 30 + 260 * i && e.getX() <= 46 + 260 * i && e.getY() >= 175 + 25 * j && e.getY() <= 191 + 25 * j){
					radio[i][j] = 1;
					radio[i][1 - j] = 0;
					if(j == 1){
						radio[1 - i][1] = 0;
						radio[1 - i][0] = 1;
					}
					repaint();
					return;
				}
			}
		}
		if(e.getX() >= 135 && e.getX() <= 270 && e.getY() >= 310 && e.getY() <= 340){
			startFlg = true;
			for(int i = 0;i < 2;i++){
				for(int j = 0;j < 2;j++){
					p[i][j] = radio[i][j];
				}
			}
			init2();
			repaint();
			if(p[0][1] == 1){
				computer0();
			}
		}
		if(p[judge.getTeban()][0] == 1){
			for(int i = 0;i < tateCount;i++){
				x = i * (masuHeight + masuInterval);
				for(int j = 0;j < tateCount;j++){
					y = j * (masuWidth + masuInterval);
					if(e.getX() >= y + tw && e.getX() <= y + 40 + tw && e.getY() >= x + yw && e.getY() <= x + yw + 40){
						if(banmen.isPossiblePlace(i,j)){
							banmen.setCheck(i,j,judge.getTeban());
							judge.setTeban(banmen.nextPlayer(judge.getTeban()));
							repaint();
							if(judge.winnerReturn() == -1 && !banmen.allFull()){
								if(p[judge.getTeban()][1] == 1){
									computer0();
								}
							}
						}
					}
				}
			}
		}
	}
	public void mouseExited(MouseEvent e){
	}
	public void mouseEntered(MouseEvent e){
	}
	public void mouseClicked(MouseEvent e){
	}
	public void start(){
		if(thread == null){
			thread = new Thread(this);
			thread.start();
		}
	}
	public void stop(){
		if(thread != null){
			thread.stop();
			thread = null;
		}
	}
	public void run(){
		try{
			mt.waitForID(0);
		}
		catch(InterruptedException e){
			return;
		}
		repaint();
	}
	public void computer0(){
		x = y = -1;
		if(tateCheck(2,0)){
			setCheck();
			return;
		}
		if(yokoCheck(2,0)){
			setCheck();
			return;
		}
		if(leftSlashCheck(2,0)){
			setCheck();
			return;
		}
		if(rightSlashCheck(2,0)){
			setCheck();
			return;
		}
		if(x == -1 && y == -1){
			if(tateCheck(0,2)){
				setCheck();
				return;
			}
			if(yokoCheck(0,2)){
				setCheck();
				return;
			}
			if(leftSlashCheck(0,2)){
				setCheck();
				return;
			}
			if(rightSlashCheck(0,2)){
				setCheck();
				return;
			}
			if(x == -1 && y == -1){
				int value = 2;
				if(exception1Check() || exception2Check()){
					value = 1;
				}
				if(valueCount(2) == 0){
					value = 1;
				}
				if(masu[1][1].getZyoutai() == -1){
					x = y = 1;
				}else{
					x = (int)(Math.random() * 3);
					y = (int)(Math.random() * 3);
					while(masu[x][y].getZyoutai() != -1 || yusen[x][y] != value){
						x = (int)(Math.random() * 3);
						y = (int)(Math.random() * 3);
					}
				}
				setCheck();
			}
		}
	}
	public boolean tateCheck(int z_cnt,int a_cnt){
		for(int i = 0;i < yokoCount;i++){
			if(banmen.tateCount(i,judge.getTeban()) == z_cnt && banmen.tateCount(i,banmen.nextPlayer(judge.getTeban())) == a_cnt){
				for(int j = 0;j < tateCount;j++){
					if(masu[j][i].getZyoutai() == -1){
						x = j;
						y = i;
						return true;
					}
				}
			}
		}
		return false;
	}
	public boolean yokoCheck(int z_cnt,int a_cnt){
		for(int i = 0;i < tateCount;i++){
			if(banmen.yokoCount(i,judge.getTeban()) == z_cnt && banmen.yokoCount(i,banmen.nextPlayer(judge.getTeban())) == a_cnt){
				for(int j = 0;j < yokoCount;j++){
					if(masu[i][j].getZyoutai() == -1){
						x = i;
						y = j;
						return true;
					}
				}
			}
		}
		return false;
	}
	public boolean leftSlashCheck(int z_cnt,int a_cnt){
		if(banmen.leftSlashCount(judge.getTeban()) == z_cnt && banmen.leftSlashCount(banmen.nextPlayer(judge.getTeban())) == a_cnt){
			for(int j = 0;j < tateCount;j++){
				if(masu[j][j].getZyoutai() == -1){
					x = j;
					y = j;
					return true;
				}
			}
		}
		return false;
	}
	public boolean rightSlashCheck(int z_cnt,int a_cnt){
		if(banmen.rightSlashCount(judge.getTeban()) == z_cnt && banmen.rightSlashCount(banmen.nextPlayer(judge.getTeban())) == a_cnt){
			for(int j = 0;j < tateCount;j++){
				if(masu[j][2 - j].getZyoutai() == -1){
					x = j;
					y = 2 - j;
					return true;
				}
			}
		}
		return false;
	}
	public boolean exception1Check(){
		if(masu[0][0].getZyoutai() == banmen.nextPlayer(judge.getTeban())){
			if(masu[1][1].getZyoutai() == judge.getTeban()){
				if(masu[2][2].getZyoutai() == banmen.nextPlayer(judge.getTeban())){
					if(ex1Flg){
						ex1Flg = false;
						return true;
					}
				}
			}
		}
		return false;
	}
	public boolean exception2Check(){
		if(masu[0][2].getZyoutai() == banmen.nextPlayer(judge.getTeban())){
			if(masu[1][1].getZyoutai() == judge.getTeban()){
				if(masu[2][0].getZyoutai() == banmen.nextPlayer(judge.getTeban())){
					if(ex2Flg){
						ex2Flg = false;
						return true;
					}
				}
			}
		}
		return false;
	}	
	public void setCheck(){
		banmen.setCheck(x,y,judge.getTeban());
		judge.setTeban(banmen.nextPlayer(judge.getTeban()));
		repaint();
	}
	public int valueCount(int value){
		int cnt = 0;
		for(int i = 0;i < tateCount;i++){
			for(int j = 0;j < yokoCount;j++){
				if(masu[i][j].getZyoutai() == -1 && yusen[i][j] == value){
					cnt++;
				}
			}
		}
		return cnt;
	}
}
	