rmenu=makeRadioButtonMenuItem(mode[j],target);
if(j==0)//第一个单选按钮默认选中
rmenu.setSelected(true);
//模式二级子菜单中加入单选按钮
modeSubmenu.add(rmenu);
//将按钮加入多选一按钮组
group.add(rmenu);
}
//将模式二级子菜单加入到游戏一级菜单中
menu.add(modeSubmenu);
}else
//创建其它二级子菜单
menu.add(makeMenuItem(items[i],target));
returnmenu;
}
//构造五子棋游戏的菜单项
publicJMenuItemmakeMenuItem(Stringitem,Objecttarget){
JMenuItemr=newJMenuItem(item);
r.addActionListener((ActionListener)target);
returnr;
}
//构造五子棋游戏的单选按钮式菜单项
publicJRadioButtonMenuItemmakeRadioButtonMenuItem(Stringitem,Objecttarget){
JRadioButtonMenuItemr=newJRadioButtonMenuItem(item);
r.addActionListener((ActionListener)target);
returnr;
}
//重新开局
publicvoidpanelInit(intframeCol,intframeRow){
//设置面板中棋盘的行列
MainPanel.setColRow(frameCol,frameRow);
MainPanel.ClearChessMap();
//MainPanel类继承了Jpanel类,Jpanel类有一个repaint方法,在repaint中调用paint方法。
MainPanel.repaint();
}
publicvoidactionPerformed(ActionEvente){
//.getActionCommand()返回和动作相连的命令字符串
Stringarg=e.getActionCommand();
try{
if(arg.equals("Windows"))
//UIManager.setLookAndFeel()设置桌面的外观
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
elseif(arg.equals("Motif"))
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
else
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
//当改变程序的LookAndFeel外观时,通过调用SwingUtilities.updateComponentTreeUI方法来刷新整个UI
SwingUtilities.updateComponentTreeUI(this);
}catch(Exceptionee){}
if(arg.equals("20x15")){//改变棋盘大小
frameCol=20;
frameRow=15;
//设置frame高度、宽度
setSize(frameCol*20+50,frameRow*20+100);
//初始化panel,格子的行列发生变化
panelInit(frameCol,frameRow);
}
if(arg.equals("30x20")){//改变棋盘大小
frameCol=30;
frameRow=20;
//设置frame高度、宽度
setSize(frameCol*20+50,frameRow*20+100);
//初始化panel,格子的行列发生变化
panelInit(frameCol,frameRow);
}
if(arg.equals("40x30")){//改变棋盘大小
frameCol=40;
frameRow=30;
//设置frame高度、宽度
setSize(frameCol*20+50,frameRow*20+100);
//初始化panel,格子的行列发生变化
panelInit(frameCol,frameRow);
}
if(arg.equals("人机对弈")){
GameFrame.manMachine=true;
}
if(arg.equals("人人对弈")){
GameFrame.manMachine=false;
}
if(arg.equals("开局")){
//初始化panel
panelInit(frameCol,frameRow);
}
if(arg.equals("关于"))
JOptionPane.showMessageDialog(this,"五子棋游戏测试版本","关于",0);
if(arg.equals("退出"))
System.exit(0);
}
}
/*
*类MainPanel主要完成如下功能:
*1、构建一个面板,在该面板上画上棋盘;
*2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等)
**/
classMainPanelextendsJPanelimplementsMouseListener{
privateintpanelCol,panelRow;//面板中棋盘的列、行
//棋盘方格的横向、纵向坐标所对应的棋子颜色,
//数组chessMap只有3个值:
1,2,0其中:
1有黑子,2有白子,0没有棋子,
privateint[][]chessMap;
privatebooleanisManDo;//true:
轮到人下,false:
轮到机器下
//根据棋盘行列设定面板的大小
MainPanel(intcol,introw){
panelCol=col;
panelRow=row;
ClearChessMap();//清空棋盘
addMouseListener(this);
}
voidsetColRow(intframeCol,intframeRow){
panelCol=frameCol;
panelRow=frameRow;
}
//构建棋盘
//按照棋盘模式构建棋盘大小
publicvoidClearChessMap(){
isManDo=true;
chessMap=newint[panelCol+1][panelRow+1];
for(inti=0;i<=panelCol;i++){
for(intj=0;j<=panelRow;j++){
chessMap[i][j]=0;//清空棋盘
}
}
}
//
//MainPanel的repaint方法中调用paint方法,重写父类JPanel的paint方法
publicvoidpaint(Graphicsg){
//调用父类Jpanel的paint方法
super.paint(g);
//画棋盘格子
g.setColor(Color.white);//设置画笔颜色灰色
for(inti=0;i<=panelCol;i++)//画panelCol+1条竖线
g.drawLine(20*i+20,20,20*i+20,20*panelRow+20);
for(intj=0;j<=panelRow;j++)//画panelRow+1条横线
g.drawLine(20,20*j+20,20*panelCol+20,20*j+20);
for(intj=0;j<=panelRow;j++){
for(inti=0;i<=panelCol;i++){
intcolor=chessMap[i][j];
intx=20*i+20;
inty=20*j+20;
//画黑色棋子
if(color==1){
g.setColor(Color.black);//设置画笔颜色黑色
g.fillOval(x-8,y-8,16,16);//画实心椭圆(园)
}
//画白色棋子
if(color==2){
g.setColor(Color.gray);//设置画笔颜色灰色
g.drawOval(x-8,y-8,16,16);//画空心椭圆(园)
g.setColor(Color.white);//设置画笔颜色白色
g.fillOval(x-8,y-8,16,16);//画实心椭圆(园)
}
}
}
}
//判断下子的横向、纵向坐标是否越界
publicbooleanoverBorder(intx,inty){
if(x>=panelCol+20||x<0)
returntrue;
returny>=panelRow+20||y<0;
}
//判断(i,j)位置上是否有棋子
publicbooleanchessExist(inti,intj){
if(this.chessMap[i][j]==1||this.chessMap[i][j]==2)
returntrue;
returnfalse;
}
//人在鼠标位置下棋子
publicbooleanmanPlay(intx,inty){
if(overBorder(x,y))//越界
returnfalse;
if(chessExist(x,y))//该位置有棋子
returnfalse;
if(isManDo){
isManDo=false;
this.chessMap[x][y]=1;
}else{
isManDo=true;
this.chessMap[x][y]=2;
}
returntrue;
}
/*计算机下棋
说明:
用穷举法判断每一个坐标点的四个方向的的连成一线的最大棋子数
最后得出棋子数最大值的坐标,下子
*/
publicvoidcomputerPlay(intposition[]){
intmax_black,max_white,max_temp,max=0,max_x=0,max_y=0;
isManDo=true;
for(inti=0;i<=panelCol;i++){
for(intj=0;j<=panelRow;j++){
if(!
chessExist(i,j)){//算法判断是否下子
max_white=checkMax(i,j,2);//判断连成一线白子的最大棋子值
max_black=checkMax(i,j,1);//判断连成一线黑子的最大棋子值
max_temp=Math.max(max_white,max_black);
if(max_temp>max){
max=max_temp;
max_x=i;
max_y=j;
}
}
}
}
chessMap[max_x][max_y]=2;
position[0]=max_x;
position[1]=max_y;
}
//判断八个方向连成一线的最大棋子数
publicintcheckMax(intx,inty,intblack_or_white){
intcount=0,max=0;
intx_temp=x,y_temp=y;
//向右
for(inti=1;i<5;i++){
x_temp=x_temp+1;
if(x_temp>panelCol)
break;
if(this.chessMap[x_temp][y_temp]==black_or_white)
count++;
else
break;
}
//向左
x_temp=x;
for(inti=1;i<5;i++){
x_temp=x_temp-1;
if(x_temp<0)
break;
if(chessMap[x_temp][y_temp]==black_or_white)
count++;
else
break;
}
max=count;
//向上
x_temp=x;
y_temp=y;
count=0;
for(inti=1;i<5;i++){
y_temp=y_temp-1;
if(y_temp<0)
break;
if(chessMap[x_temp][y_temp]==black_or_white)
count++;
else
break;
}
//向下
y_temp=y;
for(inti=1;i<5;i++){
y_temp=y_temp+1;
if(y_temp>panelRow)
break;
if(chessMap[x_temp][y_temp]==black_or_white)
count++;
else
break;
}
if(count>max)
max=count;
//左上
x_temp=x;
y_temp=y;
count=0;
for(inti=1;i<5;i++){
x_temp=x_temp-1;
y_temp=y_temp-1;
if(y_t