轉自:http://www.cnblogs.com/pains/archive/2007/10/07/915966.html
兩年前做的,程式在玩家勝利後會有一點問題,有些棋子還在原來的位置上,那時候沒找出來是什麼原因,現在也不想管它了,拿上來也許對有些朋友有用。不過要 事先說明的是:要在j2sdk1.4.0下才能編譯通過,在更高的版本上就要修改下程式才行,這可不是我的錯,是java的版本相容有問題;最好用個工具 編譯執行它,如:EditPlus(它雖然是個文字編輯工具,但可以編譯執行源程式的,要在工具選單引數選擇裡設定下,當然要有java的sdk了),如 果直接在dos下執行可能圖片載入不上來。
與本部落格中的用flash實現的五子棋的實現原理不同,這個要簡單很多,這個10×10的,標準應該是15×15。
貼個圖(比較醜,不過我想你關心的是程式實現原理。):
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.event.*;
public class wuziqi
{
public static void main(String[] args)
{
SimpleFrame frame=new SimpleFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
class AboutFrame extends JFrame
{
public AboutFrame()
{
setSize(400,300);
setResizable(false);
setTitle("關於");
Toolkit tk=Toolkit.getDefaultToolkit();
Image ff=tk.getImage("false.gif");
setIconImage(ff);
Dimension screenSize=tk.getScreenSize();
setLocation((screenSize.width-400)/2,(screenSize.height-300)/2);
FontPanel fpanel=new FontPanel();
Container con=getContentPane();
con.add(fpanel);
}
}
class FontPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Font f=new Font("宋體",Font.BOLD,22);
g.setFont(f);
g.drawString("五子棋)",10,30);
f=new Font("楷體_GB2312",Font.PLAIN,18);
g.setFont(f);
g.drawString("設計者:Rick carter",10,120);
g.drawString("本程式僅供大家參考及學習,",10,225);
g.drawString("未經本人允許請勿用於任何商業活動!",10,250);
}
}
class SimpleFrame extends JFrame
{
public SimpleFrame()
{
setSize(WIDTH,HEIGHT);
setResizable(false);
setTitle("五子棋(10*10)");
Toolkit tk=Toolkit.getDefaultToolkit();
Image img=tk.getImage("map.gif");
setIconImage(img);
Dimension screenSize=tk.getScreenSize();
setLocation((screenSize.width-WIDTH)/2,(screenSize.height-HEIGHT)/2);
final AboutFrame aboutFrame=new AboutFrame();
ImagePanel panel=new ImagePanel();
Container contentPane=getContentPane();
contentPane.add(panel);
JMenuBar menuBar=new JMenuBar();
setJMenuBar(menuBar);
JMenu gameMenu=new JMenu("遊戲(G)"); //建立遊戲選單
gameMenu.setMnemonic('G');
//建立遊戲子選單及監聽器
JMenuItem replayItem=new JMenuItem("重玩",'R');
replayItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,InputEvent.CTRL_MASK));
replayItem.addActionListener(new AbstractAction("重玩")
{
public void actionPerformed(ActionEvent event)
{
ImagePanel.restart();
}
} );
JMenuItem optionItem=new JMenuItem("選項",'O');
optionItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,InputEvent.CTRL_MASK));
optionItem.addActionListener(new AbstractAction("選項")
{
public void actionPerformed(ActionEvent event)
{
}
} );
JMenuItem exitItem=new JMenuItem("退出",'E');
exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E,InputEvent.CTRL_MASK));
exitItem.addActionListener(new AbstractAction("退出")
{
public void actionPerformed(ActionEvent event)
{
System.exit(0);
}
} );
gameMenu.add(replayItem);
gameMenu.add(optionItem);
gameMenu.addSeparator();
gameMenu.add(exitItem);
menuBar.add(gameMenu);
JMenu helpMenu=new JMenu("幫助(H)"); //建立幫助選單
helpMenu.setMnemonic('H');
//建立幫助子選單及監聽器
JMenuItem aboutItem=new JMenuItem("關於",'A');
aboutItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,InputEvent.CTRL_MASK));
aboutItem.addActionListener(new AbstractAction("關於")
{
public void actionPerformed(ActionEvent event)
{
aboutFrame.show();
}
});
helpMenu.add(aboutItem);
menuBar.add(helpMenu);
}
public static final int WIDTH=560;
public static final int HEIGHT=450;
}
final class ImagePanel extends JPanel
{
public ImagePanel()
{
image=Toolkit.getDefaultToolkit().getImage("map.gif");
green=Toolkit.getDefaultToolkit().getImage("green.gif");
red=Toolkit.getDefaultToolkit().getImage("red.gif");
position=Toolkit.getDefaultToolkit().getImage("position.gif");
ired=Toolkit.getDefaultToolkit().getImage("ired.gif");
MediaTracker tracker=new MediaTracker(this);
tracker.addImage(image,1); //棋盤
tracker.addImage(green,2); //綠棋子
tracker.addImage(red,3); //紅棋子
tracker.addImage(position,4); //滑鼠位置
tracker.addImage(ired,5);
try
{
tracker.waitForID(1);
tracker.waitForID(2);
tracker.waitForID(3);
tracker.waitForID(4);
tracker.waitForID(5);
}
catch(InterruptedException exception)
{}
//註冊監聽器
addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
for(i=0;i<10;i++) //初始化棋盤狀態
for(j=0;j<10;j++)
ball[i][j] = 0;
for(i=0;i<10;i++) //設定水平方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i][count] = true;
ctable[j+k][i][count] = true;
}
count++;
}
for(i=0;i<10;i++) //設定垂直方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[i][j+k][count] = true;
ctable[i][j+k][count] = true;
}
count++;
}
for(i=0;i<6;i++) //設定正對角線方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i+k][count] = true;
ctable[j+k][i+k][count] = true;
}
count++;
}
for(i=0;i<6;i++) //設定反對角線方向的獲勝位置
for(j=9;j>=4;j--)
{
for(k=0;k<5;k++)
{
ptable[j-k][i+k][count] = true;
ctable[j-k][i+k][count] = true;
}
count++;
}
computer = false;
player = true;
}
//繪製窗體皮膚
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int FrameWidth=getWidth();
int FrameHeight=getHeight();
int x=(FrameWidth-400)/2;
int y=FrameHeight-400;
int px=mousex-(mousex-x)%40;
int py=mousey-(mousey-y)%40;
if(px<x)
px=x;
if(py<y)
py=y;
if(px>(x+360))
px=x+360;
if(py>(y+360))
py=y+360;
g.drawImage(image,x,y,null);
g.drawImage(position,px,py,null);
Font f=new Font("楷體_GB2312",Font.BOLD,20);
g.setFont(f);
g.setColor(new Color(204,66,204));
g.drawString("計算機",5,60);
g.setColor(new Color(00,99,00));
g.drawString("玩家",495,60);
g.drawImage(red,20,75,null);
g.drawImage(green,500,75,null);
g.setColor(Color.black);
switch(str)
{
case 0:
g.drawString("你先下!",480,140);
break;
case 1:
g.drawString("等待!",480,140);
break;
case 2:
g.drawString("該你了.",480,140);
break;
case 3:
g.drawString("你嬴了!",480,140);
break;
case 4:
g.drawString("你輸了!",480,140);
break;
case 5:
g.drawString("平 局!",480,140);
break;
}
for(i=0;i<10;i++)
for(j=0;j<10;j++)
{
if(ball[i][j]==1)
{
px=i*40+3+x;
py=j*40+3+y;
g.drawImage(green,px,py,null);
}
if(ball[i][j]==2)
{
px=i*40+3+x;
py=j*40+3+y;
g.drawImage(red,px,py,null);
}
}
g.drawImage(ired,a*40+x+3,b*40+y+3,null);
}
//變數
private Image image;
private Image position;
private Image green;
private Image red;
private Image ired;
private int mousex,mousey;
private JButton replayButton;
private static int ball[][]=new int [10][10];
private static boolean ptable[][][]=new boolean [10][10][192],ctable[][][]=new boolean [10][10][192];
private static int pgrades[][]=new int [10][10],cgrades[][]=new int [10][10],cgrade,pgrade;
private static int win[][]=new int [2][192];
private static int pcount,ccount; //記錄計算機與玩家各下了多少棋子
private static boolean player,computer,start=true,over=false,pwin,cwin,tie;
private static int i,j,k,n,m,count,a=50,b=50;
private static int mat,nat,mde,nde;
private static int str=0;
private class replayAction implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
restart();
}
}
//滑鼠移動事件
private class MouseMotionHandler implements MouseMotionListener
{
public void mouseMoved(MouseEvent event)
{
mousex=event.getX();
mousey=event.getY();
repaint();
}
public void mouseDragged(MouseEvent event) {}
}
//滑鼠點選事件
private class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
mousex=event.getX();
mousey=event.getY();
if(!over)
if(player)
{
int FrameWidth=getWidth();
int FrameHeight=getHeight();
int x=(FrameWidth-400)/2;
int y=FrameHeight-400-5;
if(mousex>x&&mousex<(x+400)&&mousey>y&&mousey<(y+400))
{ m=(int)((mousex-x)/40);
n=(int)((mousey-y)/40);
while(ball[m][n]==0) //如果該棋子為空
{ ball[m][n]=1; //設為玩家的棋子
pcount++;
str=1;
if((ccount==50)&&(pcount==50))
{ tie=true;
over=true;
str=5;
}
for(i=0;i<192;i++)
{
if(ptable[m][n][i]&&win[0][i]!=7)
win[0][i]++;
if(ctable[m][n][i])
{
ctable[m][n][i]=false;
win[1][i]=7; //計算機在第i種獲勝可能中不可能再獲勝,就置為7
}
}
if(!over)
{
for(i=0;i<=1;i++)
for(j=0;j<192;j++)
{
if(win[i][j] == 5)
if(i==0) //玩家獲勝
{
pwin=true;
cwin=false;
over=true;
str=3;
break;
}
else //計算機獲勝
{
cwin=true;
pwin=false;
over=true;
str=4;
break;
}
if(over)
break;
}
}
player=false;
computer=true;
repaint();
if(over)
{
if(tie)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"平局!","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
else
if(pwin)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"恭喜你!你嬴了。","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
else
if(cwin)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"你輸了!","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
restart();
}
}
}
}
//電腦下
computerdo();
}
}
public void computerdo()
{
if(!over)
if(computer)
{
for(i=0;i<=9;i++) //計算玩家在空格子上的獲勝分數
for(j=0;j<=9;j++)
{
pgrades[i][j]=0;
if(ball[i][j]==0)
for(k=0;k<192;k++)
if(ptable[i][j][k])
{
switch(win[0][k])
{
case 1:
pgrades[i][j]+=5;
break;
case 2:
pgrades[i][j]+=50;
break;
case 3:
pgrades[i][j]+=100;
break;
case 4:
pgrades[i][j]+=400;
break;
}
}
}
for(i=0;i<=9;i++) //計算計算機在空格子上的獲勝分數
for(j=0;j<=9;j++)
{
cgrades[i][j]=0;
if(ball[i][j]==0)
for(k=0;k<192;k++)
if(ctable[i][j][k])
{
switch(win[1][k])
{
case 1:
cgrades[i][j]+=5;
break;
case 2:
cgrades[i][j]+=50;
break;
case 3:
cgrades[i][j]+=100;
break;
case 4:
cgrades[i][j]+=400;
break;
}
}
}
if(start) //遊戲開始
{
if(ball[4][4]==0)
{
m = 4;
n = 4;
}
else
{
m = 5;
n = 5;
}
start = false;
}
else
{
for(i=0;i<10;i++)
for(j=0;j<10;j++)
if(ball[i][j]==0)
{
if(cgrades[i][j]>=cgrade)
{
cgrade = cgrades[i][j];
mat = i;
nat = j;
}
if(pgrades[i][j]>=pgrade)
{
pgrade = pgrades[i][j];
mde = i;
nde = j;
}
}
if(pgrade>=cgrade&&pgrade>100) //防守
{
m = mde;
n = nde;
}
else //攻擊
{
m = mat;
n = nat;
}
}
cgrade = 0;
pgrade = 0;
ball[m][n] = 2; //設定為計算機的棋子
a=m;
b=n;
ccount++;
str=2;
if((ccount==50)&&(pcount==50))
{
tie = true;
over = true;
}
for(i=0;i<192;i++)
{
if(ctable[m][n][i] && win[1][i] != 7)
win[1][i]++;
if(ptable[m][n][i])
{
ptable[m][n][i] = false;
win[0][i]=7;
}
}
if(!over)
{
for(i=0;i<=1;i++)
for(j=0;j<192;j++)
{
if(win[i][j]==5)
if(i==0) //玩家獲勝
{
pwin=true;
cwin=false;
over=true;
str=3;
break;
}
else //計算機獲勝
{
cwin=true;
pwin=false;
over=true;
str=4;
break;
}
if(over)
break;
}
}
player=true; //換玩家下
computer=false;
repaint();
if(over)
{
if(tie)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"平局!","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
else
if(pwin)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"恭喜你!你嬴了。","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
else
if(cwin)
JOptionPane.showConfirmDialog(
ImagePanel.this,
"你輸了!","確認資訊",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE);
restart();
}
}
}
public static void restart()
{
for(i=0;i<10;i++)
for(j=0;j<10;j++)
{
pgrades[i][j]=0;
cgrades[i][j]=0;
ball[i][j]=0;
}
count=0;
for(i=0;i<10;i++) //設定水平方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i][count] = true;
ctable[j+k][i][count] = true;
}
count++;
}
for(i=0;i<10;i++) //設定垂直方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[i][j+k][count] = true;
ctable[i][j+k][count] = true;
}
count++;
}
for(i=0;i<6;i++) //設定正對角線方向的獲勝位置
for(j=0;j<6;j++)
{
for(k=0;k<5;k++)
{
ptable[j+k][i+k][count] = true;
ctable[j+k][i+k][count] = true;
}
count++;
}
for(i=0;i<6;i++) //設定反對角線方向的獲勝位置
for(j=9;j>=4;j--)
{
for(k=0;k<5;k++)
{
ptable[j-k][i+k][count] = true;
ctable[j-k][i+k][count] = true;
}
count++;
}
for(i=0;i<=1;i++)
for(j=0;j<192;j++)
win[i][j]=0;
computer=false;
player=true;
str=0;
count=0;
ccount=0;
pcount=0;
start=true;
over=false;
pwin=false;
cwin=false;
tie=false;
a=b=50;
}
}