//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; } } }