/*サンプログラム[gomoku.java]*/
import java.awt.*;
import java.util.Random;
public class gomoku extends java.applet.Applet implements Runnable {
Image banmen;
Graphics dr_ban;
Choice sente,gote,lan;
Font f;
FontMetrics fm;
Panel pn,pn2,pn3;
Label siro,kuro,mes;
Button bt,bt2;
Checkbox speed;
int i,i2,i3,j,n,waku_x,waku_y,turn=1,lastX,lastY,r,mesn;
int koma[][]=new int [16][16]; /* 石の配置情報 */
int score[][]=new int [16][16];
int kuhakux[]=new int [6];
int kuhakuy[]=new int [6];
int kohox[]=new int [256];
int kohoy[]=new int [256];
boolean game=false,cpu=false,flg_paint,cpu_turn=false,waku=false;
boolean cpuVScpu,draw,stopped;
String st[]=new String[7]; /*メッセージ文字列*/
Color waku_color;
Random rnd=new Random();
Thread runner=null;
public void start(){
resize(420,400);
banmen=createImage(256,256); /*部品作成*/
dr_ban=banmen.getGraphics();
sente=new Choice();
gote=new Choice();
lan=new Choice();
pn=new Panel();
pn2=new Panel();
pn3=new Panel();
siro=new Label();
kuro=new Label();
mes=new Label();
bt=new Button();
bt2=new Button();
speed=new Checkbox("cpu wait",null,false);
speed.setBackground(Color.orange);
f=new Font("TimesRoman",Font.PLAIN,12); /*ラベル・選択メニューFont*/
sente.setFont(f);
gote.setFont(f);
lan.setFont(f);
siro.setFont(f);
kuro.setFont(f);
mes.setFont(f);
sente.addItem("Human"); /*ラベル・選択メニューのテキスト定義*/
sente.addItem("Computer");
gote.addItem("Human");
gote.addItem("Computer");
gote.select(1);
lan.addItem("Japanese");
lan.addItem("English");
kuro.setText("\u5148\u624b\uff08\u9ed2\uff09");
kuro.setBackground(Color.orange);
siro.setText("\u5f8c\u624b\uff08\u767d\uff09");
siro.setBackground(Color.orange);
st[0]="\u30b9\u30bf\u30fc\u30c8\u30dc\u30bf\u30f3\u3067\u958b\u59cb\u3067\u3059";
st[1]="\u9ed2\u306e\u756a\u3067\u3059";
st[2]="\u767d\u306e\u756a\u3067\u3059";
st[3]="\u9ed2\u306e\u52dd\u3061\uff01\uff01";
st[4]="\u767d\u306e\u52dd\u3061\uff01\uff01";
st[5]="\u5f15\u304d\u5206\u3051\uff01\uff01";
st[6]="\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044";
mes.setText(st[0]);
mes.setBackground(Color.orange);
mesn=0;
f=new Font("TimesRoman",Font.BOLD,16); /*ボタンの文字*/
bt.setFont(f);
bt2.setFont(f);
bt.setLabel("Start");
bt2.setLabel("Stop");
setBackground(Color.orange); /*アプレットの背景をオレンジにする*/
sente.setBackground(Color.white);/*選択メニューの背景を白にする*/
gote.setBackground(Color.white);
lan.setBackground(Color.white);
bt.setBackground(Color.lightGray);
bt2.setBackground(Color.lightGray);
this.setLayout((LayoutManager)null); /*部品を配置*/
add(pn);
add(pn2);
add(pn3);
pn.reshape(0,8,400,48);
pn2.reshape(0,328,400,32);
pn3.reshape(32,368,240,24);
pn.setLayout(new FlowLayout(FlowLayout.CENTER,4,4));
pn2.setLayout(new FlowLayout(FlowLayout.CENTER,16,3));
pn3.setLayout(new FlowLayout());
pn.add(kuro);
pn.add(sente);
pn.add(siro);
pn.add(gote);
pn2.add(bt);
pn2.add(bt2);
pn2.add(speed);
pn2.add(lan);
pn3.add(mes);
bt2.enable(false);
mesn=0;
banmenClear();/*盤を描く*/
stopped=false;
if (runner==null){
runner=new Thread(this);
runner.start();
}
}
public void stop() {
mes.setText(st[6]); /* 終了メッセージ表示 */
if (runner!=null) { /*終了時にスレッド破棄*/
runner.stop();
runner=null;
}
}
public void banmenClear(){
int i,j;
dr_ban.setColor(Color.green); /*盤面イメージをクリア*/
dr_ban.fillRect(0,0,256,256);
dr_ban.setColor(Color.black);
for (i=0;i<16;i++) /*碁盤の目を描く*/
dr_ban.drawLine(i*16+8,8,i*16+8,248);
for (i=0;i<16;i++)
dr_ban.drawLine(8,i*16+8,248,i*16+8);
}
public void ishi_haiti(int x,int y) { /*石を置く*/
koma[x][y]=turn;
lastX=x;
lastY=y;
if (turn==1){
dr_ban.setColor(Color.black);
dr_ban.fillOval(1+x*16,1+y*16,13,13);
}
if (turn==-1) {
dr_ban.setColor(Color.white);
dr_ban.fillOval(1+x*16,1+y*16,13,13);
dr_ban.setColor(Color.gray);
dr_ban.drawOval(1+x*16,1+y*16,13,13);
}
}
public boolean mouseMove(Event evt,int x,int y){
int xx,yy;
if (x<20 || x>275 ||y<68 ||y>319) /*マウスカーソルは盤面の中か?*/
return false; /*外なら何もしないでリターン*/
xx=(int)((x-20)/16);
yy=(int)((y-68)/16);
if (koma[xx][yy]==0 && game==true && !cpuVScpu) /*石を置ける状態か?*/
waku_color=Color.blue; /*おける状態なら枠の色は青*/
else
waku_color=Color.red; /*そうでなければ赤*/
waku_x=18+xx*16; /*枠を描くアプレットの座標*/
waku_y=66+yy*16;
waku=true; /*枠をアプレットに描く*/
repaint();
return true;
}
public boolean mouseDown(Event evt,int x,int y){
int xx,yy;
if (x<20 || x>276 ||y<68 ||y>320 ||!game) /*カーソルは盤面の中か?*/
return false; /*外なら何もしないでリターン*/
if (cpu_turn || !flg_paint || cpuVScpu) /*石を置けない状態ならリターン*/
return false;
xx=(int)((x-20)/16); /*マウスカーソルの位置を盤面の座標に変換*/
yy=(int)((y-68)/16);
if (koma[xx][yy]==0) { /*カーソルの位置に石がなければ*/
ishi_haiti(xx,yy); /*石を置く*/
lastX=xx;
lastY=yy;
hantei(turn); /*もし勝負がついたならゲーム終了*/
turn=-turn;
flg_paint=false; /*再描画フラグを設定*/
repaint();
if (cpu)
cpu_turn=true;
}
return true;
}
public void run() { /*スレッド本体*/
while (runner!=null) {
if (cpu_turn && flg_paint && !stopped) {/*対コンピュータなら*/
cpuTurn(); /*コンピュータが石を配置*/
hantei(turn); /*もし勝負がついたならゲーム終了*/
turn=-turn;
repaint();
cpu_turn=false; /*コンピュータの番終了*/
}
if (cpuVScpu && flg_paint &&!stopped) {
cpuTurn();
hantei(turn);
flg_paint=false;
repaint();
turn=-turn;
}
}
}
public boolean action(Event evt,Object what) {
int saki,ato;
if (evt.target==bt){ /*スタートボタン*/
if (game) /*現在ゲーム中なら無効*/
return false;
cpu=false;
cpuVScpu=false;
for (i=0;i<16;i++) /*石の配置情報をクリア*/
for (j=0;j<16;j++)
koma[j][i]=0;
banmenClear();
turn=1;
saki=sente.getSelectedIndex();
ato=gote.getSelectedIndex();
if (saki==1 && ato==0){ /*コンピュータ先手*/
cpu=true;
j=Math.abs(rnd.nextInt()) % 3+7;
i=Math.abs(rnd.nextInt()) % 3+7;
ishi_haiti(j,i);
turn=-1;
}
if (saki==0 && ato==1)
cpu=true;
game=true;
cpu_turn=false;
bt.enable(false);
bt2.enable(true);
sente.enable(false);
gote.enable(false);
if (saki==1 && ato==1)
cpuVScpu=true;
repaint();
return true;
}
if (evt.target==bt2){ /*クリアボタン*/
game=false;
cpuVScpu=false;
turn=1;
bt.enable(true);
bt2.enable(false);
sente.enable(true);
gote.enable(true);
mesn=0;
repaint();
return true;
}
if (evt.target==lan) { /* 表示言語選択メニュー */
if (lan.getSelectedIndex()==0) { /* 日本語表示 */
st[0]="\u30b9\u30bf\u30fc\u30c8\u30dc\u30bf\u30f3";
st[0]=st[0]+"\u3067\u958b\u59cb\u3067\u3059";
st[1]="\u9ed2\u306e\u756a\u3067\u3059";
st[2]="\u767d\u306e\u756a\u3067\u3059";
st[3]="\u9ed2\u306e\u52dd\u3061\uff01\uff01";
st[4]="\u767d\u306e\u52dd\u3061\uff01\uff01";
st[5]="\u5f15\u304d\u5206\u3051\uff01\uff01";
st[6]="\u66f4\u65b0\u3057\u3066\u304f\u3060\u3055\u3044";
kuro.setText("\u5148\u624b\uff08\u9ed2\uff09");
siro.setText("\u5f8c\u624b\uff08\u767d\uff09");
} else if (lan.getSelectedIndex()==1) { /* 英語表示 */
st[0]="Push Start Button!!";
st[1]="Black's Turn";
st[2]="White's Turn";
st[3]="Black Win!!";
st[4]="White Win!!";
st[5]="Draw!!";
st[6]="Please Reload!!";
kuro.setText("Black");
siro.setText("White");
}
repaint();
return true;
}
return false;
}
public void sikou(int isi) { /*コンピュータの思考(盤面評価)*/
int n0,n1,aite;
int kati=15000,hissi=1000,sanren=500,mittu=100,futatu=10; /*点数*/
int kati2=12000,hissi2=500,sanren2=200,mittu2=80,futatu2=10;
for (i=0;i<16;i++) { /* 横に走査 */
for(i2=0;i2<12;i2++) {
n1=0;
n0=0;
aite=0;
for (j=i2;jmax)
max=score[j][i];
n=0;
for (i=0;i<16;i++) /*最高点の手を選択*/
for (j=0;j<16;j++)
if (score[j][i]==max) {
kohox[n]=j;
kohoy[n]=i;
n++;
}
if (n==0)
return false;
n=Math.abs(rnd.nextInt()) % n;
ishi_haiti(kohox[n],kohoy[n]);/*最高点の中から1つを実行*/
return true;
}
public void hantei(int v){ /*石が5つ並んでいるかの判定*/
byte n1,n2,n3,n4;
draw=true;
for (i=0;i<16;i++) /* すべてのマスに石があれば引き分け */
for (j=0;j<16;j++)
if (koma[j][i]==0)
draw=false;
if (draw) /* 引き分けならゲーム終了 */
game_end();
for (i=0;i<16;i++){
n1=0;
for (j=0;j<15;j++){
if (koma[j][i]==v && koma[j+1][i]==v){ /*横方向*/
n1++;
if (n1>=4)
game_end();
} else
n1=0;
}
}
for (i=0;i<16;i++){
n2=0;
n3=0;
n4=0;
for (j=0;j<15;j++){
if (koma[i][j]==v && koma[i][j+1]==v){ /*縦方向*/
n2++;
if (n2>=4)
game_end();
} else
n2=0;
if ((i+j)<15){ /*斜め右下方向*/
if (koma[i+j][j]==v && koma[i+j+1][j+1]==v) {
n3++;
if (n3>=4)
game_end();
} else
n3=0;
if (koma[j][i+j]==v && koma[j+1][i+j+1]==v) {
n4++;
if (n4>=4)
game_end();
} else
n4=0;
}
}
}
for (i=15;i>3;i--) { /*斜め左下方向(横に走査)*/
n3=0;
for (j=0;j<15;j++)
if ((i-j)>0 && j<15)
if (koma[i-j][j]==v && koma[i-j-1][j+1]==v) {
n3++;
if (n3>=4)
game_end();
} else
n3=0;
}
for (i=0;i<12;i++){ /*斜め左下方向(縦に走査)*/
n4=0;
for (j=15;j>0;j--)
if ((15-j+i)<15 && j>0)
if (koma[j][15-j+i]==v && koma[j-1][15-j+i+1]==v) {
n4++;
if (n4>=4)
game_end();
} else
n4=0;
}
}
public void game_end(){ /* ゲーム終了 */
game=false;
cpuVScpu=false;
bt.enable(true);
sente.enable(true);
gote.enable(true);
if (turn==1) /*どちらが勝ったのか?*/
mesn=3;
else
mesn=4;
if (draw)
mesn=5;
if (!draw){
dr_ban.setColor(Color.red); /*勝負がついた場所(石)を赤く囲む*/
dr_ban.fillRect(lastX*16,lastY*16,16,16);
if (koma[lastX][lastY]==1)
dr_ban.setColor(Color.black);
if (koma[lastX][lastY]==-1)
dr_ban.setColor(Color.white);
dr_ban.fillOval(1+lastX*16,1+lastY*16,13,13);
}
bt2.enable(false);
repaint();
}
public void paint(Graphics g){
if (turn==1){ /*ターン表示*/
g.setColor(Color.black);
if (game==true)
mesn=1;
}
else {
g.setColor(Color.white);
if (game==true)
mesn=2;
}
if (!game)
g.setColor(Color.orange);
g.fillOval(280,64,24,24);
mes.setText(st[mesn]); /*メッセージ表示*/
g.drawImage(banmen,16,64,this); /*盤面イメージ表示*/
if (waku){ /* 盤面上のカーソル枠を表示 */
g.setColor(waku_color);
g.drawRect(waku_x,waku_y,11,11);
}
flg_paint=true;
}
public void update(Graphics g){
paint(g);
}
}