/* */ //appletを使うため import java.applet.*; //AWTを使うため import java.awt.*; //イベント駆動関係のクラスを用いるため import java.awt.event.*; public class Othello extends Applet implements ActionListener{ //変数の準備-------------------------------- MyCanvas myCanvas; Button resetButton; Choice levelChoice; Button passButton; //初期化-------------------------------- public void init(){ //GUI部品の配置 myCanvas = new MyCanvas(); Panel panel1 = new Panel(); panel1.setLayout(new FlowLayout()); panel1.add(resetButton = new Button("New Game")); resetButton.addActionListener(this); panel1.add(levelChoice = new Choice()); levelChoice.addItem("黒先Level1"); levelChoice.addItem("白先Level1"); levelChoice.addItem("黒先Level2"); levelChoice.addItem("白先Level2"); levelChoice.addItem("黒先Level3"); levelChoice.addItem("白先Level3"); levelChoice.addItem("黒先Level4"); levelChoice.addItem("白先Level4"); Panel panel2 = new Panel(); panel2.setLayout(new FlowLayout()); panel2.add(passButton = new Button("Pass")); passButton.addActionListener(this); setLayout(new BorderLayout()); add(panel1,"North"); add(myCanvas,"Center"); add(panel2,"South"); setVisible(true); } //ActioinListener関連の実装-------------------------------- public void actionPerformed(ActionEvent ae){ String s = ae.getActionCommand(); //New Game ボタン実装 if(s.compareTo("New Game")==0){ //コマの初期化 myCanvas.initBlockArray(myCanvas.block); myCanvas.passnum=0; //level別の設定 if(levelChoice.getSelectedIndex()==0){//暫定 myCanvas.turn=1; myCanvas.level=1; } else if(levelChoice.getSelectedIndex()==1){ myCanvas.turn=2; myCanvas.level=1; } else if(levelChoice.getSelectedIndex()==2){ myCanvas.turn=1; myCanvas.level=2; } else if(levelChoice.getSelectedIndex()==3){ myCanvas.turn=2; myCanvas.level=2; } else if(levelChoice.getSelectedIndex()==4){ myCanvas.turn=1; myCanvas.level=3; } else if(levelChoice.getSelectedIndex()==5){ myCanvas.turn=2; myCanvas.level=3; } else if(levelChoice.getSelectedIndex()==6){ myCanvas.turn=1; myCanvas.level=4; } else if(levelChoice.getSelectedIndex()==7){ myCanvas.turn=2; myCanvas.level=4; } myCanvas.repaint(); } //Pass ボタン実装 if((myCanvas.turn==1)&&(s.compareTo("Pass")==0)){ myCanvas.passnum++; myCanvas.turn=2; myCanvas.repaint(); } } } class MyCanvas extends Canvas implements MouseListener{ //field Block[][] block = new Block[8][8]; SearchDirection sd = new SearchDirection();//Reverse実行時どの方向を裏返すか int turn=0;//ターン int score1=2,score2=2;//得点 int level;//サーチレベル int place=0;//COMの手の補助変数 int passnum = 0;//連続パス回数 //ブロック配列の初期化-------------------------------- void initBlockArray(Block[][] bl){ int i,j; int valuedata[][] = {{400,40,100,70,70,100,40,400},{40,15,30,20,20,30,15,40}, {100,30,40,30,30,40,30,100},{70,20,30,30,30,30,20,70}, {70,20,30,30,30,30,20,70},{100,30,40,30,30,40,30,100}, {40,15,30,20,20,30,15,40},{400,40,100,70,70,100,40,400}}; for(i=0;i<8;i++){ for(j=0;j<8;j++){ bl[i][j] = new Block(valuedata[i][j]); } } bl[3][3].state=1; bl[3][4].state=2; bl[4][3].state=2; bl[4][4].state=1; } //コンストラクタ-------------------------------- public MyCanvas(){ //Canvasクラスのコンストラクタの呼び出し super(); setSize(500,520); setBackground(new Color(52,152,52)); //blockの初期化 initBlockArray(block); //イベントドリブン関連付け addMouseListener(this); } //描画-------------------------------- public void paint(Graphics g){ int i,j;//インクリメント用 //盤面準備 g.setColor(new Color(0,0,0)); for(i=0;i<=8;i++){ g.drawLine(i*60+10,30,i*60+10,509); g.drawLine(10,i*60+30,489,i*60+30); } //得点カウント scoreCount(); //終了判定 if(passnum==2) turn=3; //コメント描画 Font f1 = g.getFont(); Font f2 = new Font(f1.getName(),f1.getStyle(),16); g.setFont(f2); //デバッグ用 //g.drawString("passnum:"+passnum,15,140); g.drawString("黒:"+score1+" 白:"+score2,15,20); if(turn==1){ g.drawString("あなたの番です.",275,20); } else if(turn==2){ g.drawString("コンピュータの番です.",275,20); } else if(turn==0){ g.drawString("New Game を押してください.",275,20); } else if(turn==3){ if(score1>score2){ g.drawString("あなたの勝ちです.",275,20); } else if(score1=8)){} else if((y<0)||(y>=8)){} //本処理-------------------------------- else if(putable1(x,y,block)==1){ //プレイヤーの手 execute1(x,y,block); passnum=0; repaint(); turn=2; } } else if(turn==2){ if(level==1) place=search2L1(block); else if(level==2) place=search2L2(block); else if(level==3) place=search2L3(block); else if(level==4) place=search2L4(block); if(place==99){ passnum++; turn=1; } else{ execute2((int)(place/8),place%8,block); passnum=0; } repaint(); turn=1; } else{ //何もしない } } public void scoreCount(){ int i,j; score1=0; score2=0; for(i=0;i<8;i++){ for(j=0;j<8;j++){ if(block[i][j].state==1) score1++; else if(block[i][j].state==2) score2++; } } } public void mouseEntered(MouseEvent me){} public void mouseExited(MouseEvent me){} public void mousePressed(MouseEvent me){} public void mouseReleased(MouseEvent me){} //黒を配置できるかどうか,不可能なら0,可能なら1を返す public int putable1(int x,int y,Block[][] bl){ int i,j,ans; ans=0; //Step0 sd.upleft=0;sd.left=0;sd.downleft=0;sd.down=0; sd.downright=0;sd.right=0;sd.upright=0;sd.up=0; //Step1 if(bl[x][y].state!=0){ return 0; } //Step2 各方向へのサーチ //左上 if((x>=2)&&(y>=2)){ i=x-1;j=y-1; if(block[i][j].state==2){ while(((i>=1)&&(j>=1))&&(bl[i][j].state!=0)){ i--;j--; if(bl[i][j].state==1){ sd.upleft=1; ans=1; } } } } //左 if(x>=2){ i=x-1;j=y; if(bl[i][j].state==2){ while((i>=1)&&(bl[i][j].state!=0)){ i--; if(bl[i][j].state==1){ sd.left=1; ans=1; } } } } //左下 if((x>=2)&&(y<=5)){ i=x-1;j=y+1; if(block[i][j].state==2){ while(((i>=1)&&(j<=6))&&(bl[i][j].state!=0)){ i--;j++; if(bl[i][j].state==1){ sd.downleft=1; ans=1; } } } } //下 if(y<=5){ i=x;j=y+1; if(block[i][j].state==2){ while((j<=6)&&(bl[i][j].state!=0)){ j++; if(bl[i][j].state==1){ sd.down=1; ans=1; } } } } //右下 if((x<=5)&&(y<=5)){ i=x+1;j=y+1; if(bl[i][j].state==2){ while(((i<=6)&&(j<=6))&&(bl[i][j].state!=0)){ i++;j++; if(bl[i][j].state==1){ sd.downright=1; ans=1; } } } } //右 if(x<=5){ i=x+1;j=y; if(bl[i][j].state==2){ while((i<=6)&&(bl[i][j].state!=0)){ i++; if(bl[i][j].state==1){ sd.right=1; ans=1; } } } } //右上 if((x<=5)&&(y>=2)){ i=x+1;j=y-1; if(bl[i][j].state==2){ while(((i<=6)&&(j>=1))&&(bl[i][j].state!=0)){ i++;j--; if(bl[i][j].state==1){ sd.upright=1; ans=1; } } } } //上 if(y>=2){ i=x;j=y-1; if(bl[i][j].state==2){ while((j>=1)&&(bl[i][j].state!=0)){ j--; if(bl[i][j].state==1){ sd.up=1; ans=1; } } } } //結果報告 return ans; } //白を配置できるかどうか,不可能なら0,可能なら1を返す public int putable2(int x,int y,Block[][] bl){ int i,j,ans; ans=0; //Step0 sd.upleft=0;sd.left=0;sd.downleft=0;sd.down=0; sd.downright=0;sd.right=0;sd.upright=0;sd.up=0; //Step1 if(bl[x][y].state!=0){ return 0; } //Step2 各方向へのサーチ //左上 if((x>=2)&&(y>=2)){ i=x-1;j=y-1; if(bl[i][j].state==1){ while(((i>=1)&&(j>=1))&&(bl[i][j].state!=0)){ i--;j--; if(bl[i][j].state==2){ sd.upleft=1; ans=1; } } } } //左 if(x>=2){ i=x-1;j=y; if(bl[i][j].state==1){ while((i>=1)&&(bl[i][j].state!=0)){ i--; if(bl[i][j].state==2){ sd.left=1; ans=1; } } } } //左下 if((x>=2)&&(y<=5)){ i=x-1;j=y+1; if(bl[i][j].state==1){ while(((i>=1)&&(j<=6))&&(bl[i][j].state!=0)){ i--;j++; if(bl[i][j].state==2){ sd.downleft=1; ans=1; } } } } //下 if(y<=5){ i=x;j=y+1; if(bl[i][j].state==1){ while((j<=6)&&(bl[i][j].state!=0)){ j++; if(bl[i][j].state==2){ sd.down=1; ans=1; } } } } //右下 if((x<=5)&&(y<=5)){ i=x+1;j=y+1; if(bl[i][j].state==1){ while(((i<=6)&&(j<=6))&&(bl[i][j].state!=0)){ i++;j++; if(bl[i][j].state==2){ sd.downright=1; ans=1; } } } } //右 if(x<=5){ i=x+1;j=y; if(bl[i][j].state==1){ while((i<=6)&&(bl[i][j].state!=0)){ i++; if(bl[i][j].state==2){ sd.right=1; ans=1; } } } } //右上 if((x<=5)&&(y>=2)){ i=x+1;j=y-1; if(bl[i][j].state==1){ while(((i<=6)&&(j>=1))&&(bl[i][j].state!=0)){ i++;j--; if(bl[i][j].state==2){ sd.upright=1; ans=1; } } } } //上 if(y>=2){ i=x;j=y-1; if(bl[i][j].state==1){ while((j>=1)&&(bl[i][j].state!=0)){ j--; if(bl[i][j].state==2){ sd.up=1; ans=1; } } } } //どの方向もダメ return ans; } //黒手に対する裏返し操作 public void reverse1(int x,int y,Block[][] bl){ int i,j; if(sd.upleft==1){ i=x-1;j=y-1; while(bl[i][j].state==2){ bl[i][j].state=1; i--;j--; } } if(sd.left==1){ i=x-1;j=y; while(bl[i][j].state==2){ bl[i][j].state=1; i--; } } if(sd.downleft==1){ i=x-1;j=y+1; while(bl[i][j].state==2){ bl[i][j].state=1; i--;j++; } } if(sd.down==1){ i=x;j=y+1; while(bl[i][j].state==2){ bl[i][j].state=1; j++; } } if(sd.downright==1){ i=x+1;j=y+1; while(bl[i][j].state==2){ bl[i][j].state=1; i++;j++; } } if(sd.right==1){ i=x+1;j=y; while(bl[i][j].state==2){ bl[i][j].state=1; i++; } } if(sd.upright==1){ i=x+1;j=y-1; while(bl[i][j].state==2){ bl[i][j].state=1; i++;j--; } } if(sd.up==1){ i=x;j=y-1; while(bl[i][j].state==2){ bl[i][j].state=1; j--; } } } //白手に対する裏返し操作 public void reverse2(int x,int y,Block[][] bl){ int i,j; if(sd.upleft==1){ i=x-1;j=y-1; while(bl[i][j].state==1){ bl[i][j].state=2; i--;j--; } } if(sd.left==1){ i=x-1;j=y; while(bl[i][j].state==1){ bl[i][j].state=2; i--; } } if(sd.downleft==1){ i=x-1;j=y+1; while(bl[i][j].state==1){ bl[i][j].state=2; i--;j++; } } if(sd.down==1){ i=x;j=y+1; while(bl[i][j].state==1){ bl[i][j].state=2; j++; } } if(sd.downright==1){ i=x+1;j=y+1; while(bl[i][j].state==1){ bl[i][j].state=2; i++;j++; } } if(sd.right==1){ i=x+1;j=y; while(bl[i][j].state==1){ bl[i][j].state=2; i++; } } if(sd.upright==1){ i=x+1;j=y-1; while(bl[i][j].state==1){ bl[i][j].state=2; i++;j--; } } if(sd.up==1){ i=x;j=y-1; while(bl[i][j].state==1){ bl[i][j].state=2; j--; } } } //黒の手の実行 public void execute1(int x,int y,Block[][] bl){ if(x==12) return;//パス対策 else{ putable1(x,y,bl); bl[x][y].state=1; reverse1(x,y,bl); } } //白の手の実行 public void execute2(int x,int y,Block[][] bl){ if(x==12) return; else{ putable2(x,y,bl); bl[x][y].state=2; reverse2(x,y,bl); } } //白が手を評価する public int evaluate2(Block[][] bl){ int score = 0; int i,j; for(i=0;i<8;i++){ for(j=0;j<8;j++){ if(bl[i][j].state==1) score-=bl[i][j].value; if(bl[i][j].state==2) score+=bl[i][j].value; } } return score; } //黒が手を評価する public int evaluate1(Block[][] bl){ int score = 0; int i,j; for(i=0;i<8;i++){ for(j=0;j<8;j++){ if(bl[i][j].state==2) score-=bl[i][j].value; if(bl[i][j].state==1) score+=bl[i][j].value; } } return score; } //白が手をサーチする public int search2L1(Block[][] bl){ int score,hscore; hscore=-9999; int ansx = 0,ansy = 0; int i,j,k,l; Block calblock[][] = new Block[8][8]; initBlockArray(calblock); //手をサーチする for(i=0;i<8;i++){ for(j=0;j<8;j++){ //calblockを初期化 for(k=0;k<8;k++){ for(l=0;l<8;l++){ calblock[k][l].state = bl[k][l].state; } } if(putable2(i,j,calblock)==0){ } else{ execute2(i,j,calblock); score=evaluate2(calblock); if(hscorehscore){ hscore=score; ansx=i;ansy=j; } } } } if(hscore==-9999) return 99; else return (ansx*8+ansy); } //黒が3手サーチする public int search1L2(Block[][] bl){ int score,hscore; hscore=-9999; int ansx = 0,ansy = 0; int i,j,k,l; int place; Block calblock[][] = new Block[8][8]; initBlockArray(calblock); //手をサーチする for(i=0;i<8;i++){ for(j=0;j<8;j++){ //calblockを初期化 for(k=0;k<8;k++){ for(l=0;l<8;l++){ calblock[k][l].state = bl[k][l].state; } } //置けない場所は排除 if(putable1(i,j,calblock)==0){ } //置ける場所 else{ execute1(i,j,calblock); place=search2L1(calblock); execute2((int)(place/8),place%8,calblock); place=search1L1(calblock); execute1((int)(place/8),place%8,calblock); score=evaluate1(calblock); if(score>hscore){ hscore=score; ansx=i;ansy=j; } } } } if(hscore==-9999) return 99; else return (ansx*8+ansy); } //白が5手サーチする public int search2L3(Block[][] bl){ int score,hscore; hscore=-9999; int ansx = 0 , ansy = 0; int i,j,k,l; int place; Block calblock[][] = new Block[8][8]; initBlockArray(calblock); //手をサーチする for(i=0;i<8;i++){ for(j=0;j<8;j++){ //calblockを初期化 for(k=0;k<8;k++){ for(l=0;l<8;l++){ calblock[k][l].state = bl[k][l].state; } } if(putable2(i,j,calblock)==0){ } else{ execute2(i,j,calblock); place=search1L2(calblock); execute1((int)(place/8),place%8,calblock); place=search2L2(calblock); execute2((int)(place/8),place%8,calblock); place=search1L1(calblock); execute1((int)(place/8),place%8,calblock); place=search2L1(calblock); execute2((int)(place/8),place%8,calblock); score=evaluate2(calblock); if(score>hscore){ hscore=score; ansx=i;ansy=j; } } } } if(hscore==-9999) return 99; else return (ansx*8+ansy); } //黒が5手サーチする public int search1L3(Block[][] bl){ int score,hscore; hscore=-9999; int ansx = 0 , ansy = 0; int i,j,k,l; int place; Block calblock[][] = new Block[8][8]; initBlockArray(calblock); //手をサーチする for(i=0;i<8;i++){ for(j=0;j<8;j++){ //calblockを初期化 for(k=0;k<8;k++){ for(l=0;l<8;l++){ calblock[k][l].state = bl[k][l].state; } } if(putable1(i,j,calblock)==0){ } else{ execute1(i,j,calblock); place=search2L2(calblock); execute2((int)(place/8),place%8,calblock); place=search1L2(calblock); execute1((int)(place/8),place%8,calblock); place=search2L1(calblock); execute2((int)(place/8),place%8,calblock); place=search1L1(calblock); execute1((int)(place/8),place%8,calblock); score=evaluate1(calblock); if(score>hscore){ hscore=score; ansx=i;ansy=j; } } } } if(hscore==-9999) return 99; else return (ansx*8+ansy); } //白が7手サーチする public int search2L4(Block[][] bl){ int score,hscore; hscore=-9999; int ansx = 0 , ansy = 0; int i,j,k,l; int place; Block calblock[][] = new Block[8][8]; initBlockArray(calblock); //手をサーチする for(i=0;i<8;i++){ for(j=0;j<8;j++){ //calblockを初期化 for(k=0;k<8;k++){ for(l=0;l<8;l++){ calblock[k][l].state = bl[k][l].state; } } if(putable2(i,j,calblock)==0){ } else{ execute2(i,j,calblock); place=search1L3(calblock); execute1((int)(place/8),place%8,calblock); place=search2L3(calblock); execute2((int)(place/8),place%8,calblock); place=search1L2(calblock); execute1((int)(place/8),place%8,calblock); place=search2L2(calblock); execute2((int)(place/8),place%8,calblock); place=search1L1(calblock); execute1((int)(place/8),place%8,calblock); place=search2L1(calblock); execute2((int)(place/8),place%8,calblock); score=evaluate2(calblock); if(score>hscore){ hscore=score; ansx=i;ansy=j; } } } } if(hscore==-9999) return 99; else return (ansx*8+ansy); } } class Block{ int state; int value; public Block(int v){ state = 0; value = v; } } class SearchDirection{ int upleft,left,downleft,down,downright,right,upright,up; public SearchDirection(){ upleft=0; left=0; downleft=0; down=0; downright=0; right=0; upright=0; up=0; } }