//Checkers_game
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Checkers_game extends Applet implements ActionListener,MouseListener,Runnable{
int r=25; //駒の半径
int d=2*r; //駒の直径
int[][] s=new int [8][8]; //各マス目の状態を決める変数
int[][] xc=new int [8][8]; //各マス目の中心座標
int[][] yc=new int [8][8];
int x,y,a,b,c,m=0,n=0,f,flag=1;
int passcount;
int sfx,sfy,stx,sty,jx,jy;
Button reset=new Button("RESET"); //RESETボタン
Button turn=new Button("COMPUTER"); //パスボタン
Label message=new Label();
Image offimage;
Graphics offgraphics;
Thread kicker;
boolean comp,pre,jum,sin,you_win,you_lose;
public void init() {
setLayout(null);
setBackground(Color.green);
turn.setBounds(550,400,100,30);
add(turn);
turn.addActionListener(this);
reset.setBounds(550,500,100,30);
add(reset);
reset.addActionListener(this);
addMouseListener(this);
message.setBounds(550,300,200,50);
message.setText(null);
add(message);
showStatus(null);
offimage=createImage(getWidth(),getHeight());
offgraphics=offimage.getGraphics();
int data[]={-5,-1,-5,0,-5,1,-5,1,-1,-5,-1,-5,0,-5,1,-5,15};
int i=0;
for(y=0; y<=7; ++y) {
for(x=0; x<=7; ++x) {
int j = data[i++];
if(j != 15) s[x][y] = j;
else{
i=0;
s[x][y] = data[i++];
}
}
}
comp=false;
kicker=null;
you_win=false;
you_lose=false;
passcount=0;
}
public void update(Graphics g){
paint(g);
}
public void mousePressed(MouseEvent me){
double X = me.getX();
double Y = me.getY();
//クリックされた駒を探す
x=(int)(Y-100)/d;
y=(int)(X-50)/d;
if(x<0||x>7||y<0||y>7){}
if(!comp){
if(s[x][y]==1){
for(a=0;a<8;a++){
for(b=0;b<8;b++){
f=(s[a][b]!=100&&s[a][b]!=200)?1:0;
flag*=f;
}
}
if(flag!=0) select(1,x,y);
flag=1;
}
if(s[x][y]==2){
for(a=0;a<8;a++){
for(b=0;b<8;b++){
f=(s[a][b]!=100&&s[a][b]!=200)?1:0;
flag*=f;
}
}
if(flag!=0) select(2,x,y);
flag=1;
}
if(s[x][y]==0){
if(s[m][n]==10&&x-m==-1&&Math.abs(y-n)==1){
step(1,x,y);
repaint();
comp=true;
start();
}
if(s[m][n]==20&&Math.abs(x-m)==1&&Math.abs(y-n)==1){
step(2,x,y);
repaint();
comp=true;
start();
}
if((s[m][n]==10||s[m][n]==100)&&x-m==-2&&Math.abs(y-n)==2&&(s[(x+m)/2][(y+n)/2]==-1||s[(x+m)/2][(y+n)/2]==-2)){
jump(1,x,y);
repaint();
}
if((s[m][n]==20||s[m][n]==200)&&Math.abs(x-m)==2&&Math.abs(y-n)==2&&(s[(x+m)/2][(y+n)/2]==-1||s[(x+m)/2][(y+n)/2]==-2)){
jump(2,x,y);
repaint();
}
}
}//if(!comp)
}
public void select(int i,int x,int y){
m=x;
n=y;
s[x][y]=i*10;
for(int a=0;a<8;a++){
for(int b=0;b<8;b++){
if(s[a][b]==10&&(a!=x||b!=y)) s[a][b]=1;
if(s[a][b]==20&&(a!=x||b!=y)) s[a][b]=2;
}
}
repaint();
}
public void step(int i,int x,int y){
removeMouseListener(this);
s[x][y]=i;
s[m][n]=0;
if(x==0) s[x][y]=2;
repaint();
m=0;
n=0;
}
public void jump(int i,int x,int y){
int jumpable,sum_jumpable;
removeMouseListener(this);
s[x][y]=i*100;
if(x==0) s[x][y]=200;
s[m][n]=0;
s[(x+m)/2][(y+n)/2]=0;
repaint();
m=x;
n=y;
if(s[m][n]==100){
sum_jumpable=0;
for(b=-1;b<=1;b+=2){
if(m-2<0||n+2*b<0||n+2*b>7) jumpable=0;
else jumpable=(s[m-2][n+2*b]==0&&(s[m-1][n+b]==-1||s[m-1][n+b]==-2))? 1:0;
sum_jumpable+=jumpable;
}
if(sum_jumpable==0){
s[m][n]=1;
m=0;
n=0;
repaint();
comp=true;
start();
}
else{
message.setText("連続ジャンプもできます");
addMouseListener(this);
}
}
if(s[m][n]==200){
sum_jumpable=0;
for(a=-1;a<=1;a+=2){
for(b=-1;b<=1;b+=2){
if(m+2*a<0||m+2*a>7||n+2*b<0||n+2*b>7) jumpable=0;
else jumpable=(s[m+2*a][n+2*b]==0&&(s[m+a][n+b]==-1||s[m+a][n+b]==-2))? 1:0;
sum_jumpable+=jumpable;
}
}
if(sum_jumpable==0){
s[m][n]=2;
m=0;
n=0;
repaint();
comp=true;
start();
}
else{
message.setText("連続ジャンプもできます");
addMouseListener(this);
}
}
}
public void paint(Graphics g){
offgraphics.setColor(new Color(50,25,0));
offgraphics.fillRect(25,75,450,450);
for(x=0; x<=7; x++){
for(y=0; y<=7; ++y){
int xc=(y+1)*d+r; //円の中心
int yc=(x+2)*d+r;
int X1[]={xc,xc+3,xc,xc-3}; //成駒表示のための多角形の頂点座標列
int Y1[]={yc+15,yc,yc-15,yc};
int X2[]={xc,xc+17,xc,xc-17};
int Y2[]={yc+3,yc,yc-3,yc};
int X3[]={xc-15,xc,xc+3,xc+15,xc,xc-3};
int Y3[]={yc-15,yc-3,yc,yc+15,yc+3,yc};
int X4[]={xc+15,xc+3,xc,xc-15,xc-3,xc};
int Y4[]={yc-15,yc,yc+3,yc+15,yc,yc-3};
if(s[x][y]==1){ //人(普通の駒)
offgraphics.setColor(new Color(160,105,32));
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.black);
offgraphics.fillOval(xc-r,yc-r,d,d);
}
if(s[x][y]==10||s[x][y]==100){
offgraphics.setColor(Color.yellow);
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.black);
offgraphics.fillOval(xc-r,yc-r,d,d);
}
if(s[x][y]==-1){ //コンピュータ(普通の駒)
offgraphics.setColor(new Color(160,105,32));
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.white);
offgraphics.fillOval(xc-r,yc-r,d,d);
}
if(s[x][y]==2){ //人(成駒)
offgraphics.setColor(new Color(160,105,32));
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.black);
offgraphics.fillOval(xc-r,yc-r,d,d);
offgraphics.setColor(Color.gray);
offgraphics.fillPolygon(X1,Y1,4);
offgraphics.fillPolygon(X2,Y2,4);
offgraphics.fillPolygon(X3,Y3,6);
offgraphics.fillPolygon(X4,Y4,6);
}
if(s[x][y]==20||s[x][y]==200){
offgraphics.setColor(Color.yellow);
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.black);
offgraphics.fillOval(xc-r,yc-r,d,d);
offgraphics.setColor(Color.gray);
offgraphics.fillPolygon(X1,Y1,4);
offgraphics.fillPolygon(X2,Y2,4);
offgraphics.fillPolygon(X3,Y3,6);
offgraphics.fillPolygon(X4,Y4,6);
}
if(s[x][y]==-2){ //コンピュータ(成駒)
offgraphics.setColor(new Color(160,105,32));
offgraphics.fillRect(xc-r,yc-r,d,d);
offgraphics.setColor(Color.white);
offgraphics.fillOval(xc-r,yc-r,d,d);
offgraphics.setColor(Color.gray);
offgraphics.fillPolygon(X1,Y1,4);
offgraphics.fillPolygon(X2,Y2,4);
offgraphics.fillPolygon(X3,Y3,6);
offgraphics.fillPolygon(X4,Y4,6);
}
if(s[x][y]==-5){
offgraphics.setColor(new Color(228,200,130));
offgraphics.fillRect(xc-r,yc-r,d,d);
}
if(s[x][y]==0){
offgraphics.setColor(new Color(160,105,32));
offgraphics.fillRect(xc-r,yc-r,d,d);
}
}
}
if(you_win){
message.setText(null);
offgraphics.setFont(new Font("Dialog",Font.PLAIN,30));
offgraphics.setColor(Color.blue);
offgraphics.drawString("***YOU WIN***",500,200);
}
if(you_lose){
message.setText(null);
offgraphics.setFont(new Font("Dialog",Font.PLAIN,30));
offgraphics.setColor(Color.blue);
offgraphics.drawString("**YOU LOSE**",500,200);
}
g.drawImage(offimage,0,0,this);
}
public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==reset){
init();
repaint();
}
if(ae.getSource()==turn){
passcount+=1;
if(passcount<4){
removeMouseListener(this);
for(x=0;x<8;x++){
for(y=0;y<8;y++){
for(int i=1;i<=2;i++){
if(s[x][y]==i*10||s[x][y]==i*100) s[x][y]=i;
}
}
}
repaint();
comp=true;
start();
m=0;
n=0;
addMouseListener(this);
}
else message.setText("パスは3回までです");
}
}
public void mouseClicked(MouseEvent me){}
public void mouseReleased(MouseEvent me){}
public void mouseEntered(MouseEvent me){}
public void mouseExited(MouseEvent me){}
public void Computer(){
boolean step1=true,step2=true,step3=true,djump=false;
if(step1){
for(int j=0;j<8;j++){
for(int i=0;i<8;i++){
pre=prevent_jump(i,j);
if(pre){
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
repaint();
return;
}else continue;
}
}
step1=false;
}
if(!step1){
for(int i=7;i>=0;i--){
for(int j=0;j<8;j++){
jum=c_jump(i,j);
if(jum){
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
repaint();
djump=jum;
while(djump){
jum=c_jump(jx,jy);
if(jum){
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
repaint();
}else djump=false;
}
int player=0;
for(y=0;y<=7;y++) {
for(x=0;x<=7;x++) {
if(sign(s[x][y])==1) player++;
}
}
if(player==0) you_lose=true;
return;
}
}
}
step2=false;
}
if(!step2){
sfx = -5;
for(int j=0;j<8;j++){
for(int i=0;i<8;i++){
sin=single(i,j);
if(sin){
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
repaint();
return;
}else continue;
}
}
step3=false;
}
if(!step3){
if(sfx!=-5){
step_comp(sfx,sfy,stx,sty);
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
repaint();
}else{
you_win=true;
return;
}
sfx=sfy=stx=sty=-5;
return ;
}
}
/*プレーヤーのジャンプから逃げる又はそれを妨げる*/
public boolean prevent_jump(int i,int j){
if (sign(s[i][j]) == 1){
if ((legal_move(i,j,i-2,j-2)) && (prevent(i-2,j-2,i-1,j-1))) return true;
if ((legal_move(i,j,i-2,j+2)) && (prevent(i-2,j+2,i-1,j+1))) return true;
}
if (s[i][j] == 2){
if ((legal_move(i,j,i+2,j+2)) && (prevent(i+2,j+2,i+1,j+1))) return true;
if ((legal_move(i,j,i+2,j-2)) && (prevent(i+2,j-2,i+1,j-1))) return true;
}
return false;
}
/*逃げる又は妨げる*/
public boolean prevent(int enx,int eny,int sx,int sy){
int i = enx;
int j = eny;
boolean escape=possible(sx,sy);
if (escape) return true;
if(!escape&&!(i-1<0||j-1<0||i+1>7||j+1>7)){
if (sign(s[i-1][j+1])==-1 && legal_move(i-1,j+1,i,j)) {
step_comp(i-1,j+1,i,j);
return true;
} else if (sign(s[i-1][j-1])==-1 && legal_move(i-1,j-1,i,j)) {
step_comp(i-1,j-1,i,j);
return true;
} else if (s[i+1][j+1]==-2 && legal_move(i+1,j+1,i,j)) {
step_comp(i+1,j+1,i,j);
return true;
} else if (s[i+1][j-1]==-2 && legal_move(i+1,j-1,i,j)) {
step_comp(i+1,j-1,i,j);
return true;
}
} return false;
}
/*プレーヤー駒をとる*/
public boolean c_jump(int i,int j) {
if (s[i][j] == -2){ //成駒
if (legal_move(i,j,i-2,j+2)){
jx=i-2;
jy=j+2;
jump_comp(i,j,i-2,j+2);
return true;
}
if (legal_move(i,j,i-2,j-2)){
jx=i-2;
jy=j-2;
jump_comp(i,j,i-2,j-2);
return true;
}
}
if (sign(s[i][j]) == -1){ //普通駒と成駒
if (legal_move(i,j,i+2,j+2)){
jx=i+2;
jy=j+2;
jump_comp(i,j,i+2,j+2);
return true;
}
if (legal_move(i,j,i+2,j-2)){
jx=i+2;
jy=j-2;
jump_comp(i,j,i+2,j-2);
return true;
}
}
return false;
}
/*前進又は後退*/
public boolean single(int i,int j) {
if(s[i][j] == -2){ //成駒
if(legal_move(i,j,i-1,j+1)){
sfx = i;
sfy = j;
stx = i-1;
sty = j+1;
if(check(i,j,i-1,j+1)){ //4方向チェック
step_comp(i,j,i-1,j+1);
return true;
}
}
if(legal_move(i,j,i-1,j-1)){
sfx = i;
sfy = j;
stx = i-1;
sty = j-1;
if(check(i,j,i-1,j-1)){ //4方向チェック
step_comp(i,j,i-1,j-1);
return true;
}
}
}
if(sign(s[i][j]) == -1){ //普通駒と成駒
if(legal_move(i,j,i+1,j+1)){
sfx = i;
sfy = j;
stx = i+1;
sty = j+1;
if(check(i,j,i+1,j+1)){ //4方向チェック
step_comp(i,j,i+1,j+1);
return true;
}
}
if(legal_move(i,j,i+1,j-1)){
sfx = i;
sfy = j;
stx = i+1;
sty = j-1;
if(check(i,j,i+1,j-1)){ //4方向チェック
step_comp(i,j,i+1,j-1);
return true;
}
}
}
return false;
}
/*移動後の駒の4方向をチェック*/
public boolean check(int fx,int fy,int tx,int ty){
int i = tx;
int j = ty;
int nw,ne,sw,se;
if (i>0 && j<7) nw = s[i-1][j+1]; else nw = -5;
if (i>0 && j>0) ne = s[i-1][j-1]; else ne = -5;
if (i<7 && j<7) sw = s[i+1][j+1]; else sw = -5;
if (i<7 && j>0) se = s[i+1][j-1]; else se = -5;
if((sign(se)==1)&&(fx==i-1)&&(fy==j+1)) return false;
if((sign(sw)==1)&&(fx==i-1)&&(fy==j-1)) return false;
if((ne==2)&&(fx==i+1)&&(fy==j+1)) return false;
if((nw==2)&&(fx==i+1)&&(fy==j-1)) return false;
if ((nw==0) && (sign(se)==1)) return false;
if ((ne==0) && (sign(sw)==1)) return false;
if ((sw==0) && (ne==2)) return false;
if ((se==0) && (nw==2)) return false;
return true;
}
public void step_comp(int fx,int fy,int tx,int ty){
if(tx==7) s[tx][ty]=-2;
else s[tx][ty]=s[fx][fy];
s[fx][fy]=0;
return;
}
public void jump_comp(int fx,int fy,int tx,int ty){
s[(fx+tx)/2][(fy+ty)/2]=0;
if(tx==7) s[tx][ty]=-2;
else s[tx][ty]=s[fx][fy];
s[fx][fy]=0;
return;
}
public boolean possible(int h,int k){
jum=c_jump(h,k);
sin=single(h,k);
if(jum) return true;
if(sin) return true;
else return false;
}
/*進めるかを調べる*/
public boolean legal_move(int fx,int fy,int tx,int ty){
if (tx<0 || fx<0 || ty<0 || fy<0 || tx>7 || fx>7 || ty>7 || fy>7) return false;
int piece = sign(s[fx][fy]);
int disx = tx-fx;
int disy = ty-fy;
if(s[tx][ty]!=0) return false;
if((Math.abs(disx) == 2)&&(piece!=-sign(s[fx+sign(disx)][fy+sign(disy)]))) return false;
if((piece==s[fx][fy]) && (piece==sign(disx))) return false;
else return true;
}
/*COM駒かPLAYER駒か調べる*/
public int sign(int num){
if(num<0){
num=-1;
return num;
}
if(num>0){
num=1;
return num;
}
num=0;
return num;
}
public void start(){
if(kicker==null){
kicker=new Thread(this);
kicker.start();
}
}
public void stop(){
kicker=null;
}
public void run(){
Thread thisThread=Thread.currentThread();
while(kicker==thisThread){
if(comp){
message.setText("コンピュータの番です");
Computer();
repaint();
message.setText("あなたの番です");
addMouseListener(this);
}
comp=false;
kicker=null;
}
}
}