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