Java学习之路--GUI编程--象棋
package com.gui.chess;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
//2023.4.4/4.5/4.6 Gui编程 中国象棋游戏的练习 回顾多线程和GUi知识,算法实现练习 Gui编程知识点回顾(Awt,Swing)等等
//游戏主窗口类 这一个类是功能类,主要就是画游戏的窗口实现,功能模块设计,事件监听,鼠标监听,Gui编程-Swing框架下的组件复习回顾,Gui编程布局复习,图标复习等等
public class GameFrame extends JFrame implements ActionListener {//游戏窗口类继承JFrame类,实现ActionListener接口
private static final long serialVersionUID = -3812892829859080331L;//定义程序序列化ID
/*
*资料查询补充:
*1、这句话的意思是定义程序序列化ID
2、什么是序列化?
Serializable,Java的一个接口,用来完成java的序列化和反序列化操作的;
任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。也可以用管道来传输到系统的其他程序中;
java序列化是指把java对象转换为字节序列的过程,而java反序列化是指把字节序列恢复为java对象的过程
3、序列化id (serialVersionUID)
序列化ID,相当于身份认证,主要用于程序的版本控制,保持不同版本的兼容性,在程序版本升级时避免程序报出版本不一致的错误。
如果定义了private static final long serialVersionUID = 1L,那么如果你忘记修改这个信息,而且你对这个类进行修改的话,这个类也能被进行反序列化,而且不会报错。一个简单的概括就是,如果你忘记修改,那么它是会版本向上兼容的。
如果没有定义一个名为serialVersionUID,类型为long的变量,Java序列化机制会根据编译的class自动生成一个serialVersionUID,即隐式声明。这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID 。此时如果对某个类进行修改的话,那么版本上面是不兼容的,就会出现反序列化报错的情况。
4、在实际的开发中,重新编译会影响项目进度部署,所以我们为了提高开发效率,不希望通过编译来强制划分软件版本,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。
*/
/*
*游戏面板
*/
private GamePanel gamePanel;//定义私有的游戏面板类变量
/*
*功能:构造函数
*/
public GameFrame() {
try {
//菜单
JMenuBar jMenuBar_goBang = new JMenuBar();//创建菜单栏对象JMenuBar
JMenu jMenu_game = new JMenu("游戏");//创建菜单对象JMenu,名称为“游戏”
jMenu_game.setFont(new Font("微软雅黑",Font.PLAIN,12));//设置菜单对象“游戏”的字体(字体样式,字体大小)
JMenuItem jMenuItem_game_new = jMenu_game.add("新游戏");//添加菜单项(标题)JMenuItem(标题名称 “新游戏”)到菜单栏对象中
jMenuItem_game_new.setFont(new Font("微软雅黑", Font.PLAIN,12));//设置菜单标题“新游戏”的字体(字体样式,字体大小)
jMenuItem_game_new.addActionListener(this);//将菜单项(标题)为“新游戏”的添加到事件监听里面,()里的this代表jMenuItem_game_new
jMenuItem_game_new.setActionCommand("new");//ava中 Swing 包中的 setActionCommand(String ActionCommand)
//设置一个属性(new)的字符串值,然后通过在actionPerformed(ActionEvent e)方法里通过if(e.getActioncommand.equals("改变"))判断点击这个菜单标题发生的事件
JMenuItem jMenuItem_game_undo = jMenu_game.add("悔棋");//创建菜单项(标题)对象jMenuItem_game_undo(名称"悔棋")并将它添加到菜单对象中()
jMenuItem_game_undo.setFont(new Font("微软雅黑", Font.PLAIN,12));//设置菜单标题“悔棋”的字体(字体样式,字体大小)
jMenuItem_game_undo.addActionListener(this);//将菜单项(标题)为“悔棋”的添加到事件监听里面
jMenuItem_game_undo.setActionCommand("undo");//设置一个属性的字符串值,在后面方法里判断点击这个菜单标题发生的事件
JMenuItem jMenuItem_surrender = jMenu_game.add("认输");//以下备注和上面类似,就不做解释了
jMenuItem_surrender.setFont(new Font("微软雅黑",Font.PLAIN,12));
jMenuItem_surrender.addActionListener(this);
jMenuItem_surrender.setActionCommand("surrender");
jMenu_game.addSeparator();//其作用就是在菜单(JMenu)中填加的菜单项(JMenuItem)之间产生一个分割线
JMenuItem jMenuItem_game_exit = jMenu_game.add("退出");//注释同上
jMenuItem_game_exit.setFont(new Font("微软雅黑",Font.PLAIN,12));
jMenuItem_game_exit.addActionListener(this);
jMenuItem_game_exit.setActionCommand("exit");
jMenuBar_goBang.add(jMenu_game);
JMenu jMenu_help = new JMenu("帮助");
jMenu_help.setFont(new Font("微软雅黑",Font.PLAIN,12));
JMenuItem jMenuItem_help_about = jMenu_help.add("关于");
jMenuItem_help_about.setFont(new Font("微软雅黑",Font.PLAIN,12));
jMenuItem_help_about.addActionListener(this);
jMenuItem_help_about.setActionCommand("about");
jMenuBar_goBang.add(jMenu_help);
this.setJMenuBar(jMenuBar_goBang);
//游戏面板
this.gamePanel = new GamePanel();
this.add(this.gamePanel);
//显示
this.setTitle("中国象棋");//设置窗口标题(名称)为“中国象棋”
this.setLayout(null);//设置布局为空,即没有布局
this.setSize(666,620);//设置窗口的大小
this.setResizable(false);//设置此窗口是否可由用户调整大小 false(不能) true(可以)
this.setLocationRelativeTo(null);//设置窗口相对位置,水平居中
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口
this.setVisible(true);//设置可见性
}catch (Exception e){
JOptionPane.showMessageDialog(this,"程序出现异常错误,即将退出!\r\n\r\n" + e.toString(), "提示", JOptionPane.ERROR_MESSAGE);//接下一行注释
//利用JOptionPane创建JDialog,实现对话框的自动关闭
System.exit(0);
}
}
/*
*功能:事件监听
*/
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();//这个方法返回的是事件源组件的“命令” , 这个“命令” 实际上就是事件源组件上的“Label(标签)字符串”
if ("new".equals(command)){
this.gamePanel.newGame();//这里这三句注释掉是因为调用的这三个方法写在GamePanel类里面的,GamePanel还没写,后面写了记得取消注释
}else if ("undo".equals(command)){
this.gamePanel.undo();
}else if("surrender".equals(command))
{
this.gamePanel.surrender();
}
else if("exit".equals(command))
{
System.exit(0);
}
else if("about".equals(command))
{
JOptionPane.showMessageDialog(this,"我是cdc","提示",JOptionPane.INFORMATION_MESSAGE);
}
}
}
//
package com.gui.chess;
import java.util.Map;
import java.util.HashMap;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.event.MouseEvent;
/*
*2023.4.4/4.5/4.6/4.7/4.8/4.9
* Gui编程 中国象棋 游戏逻辑实现
* 功能:游戏逻辑类
* 这一个类主要就是写游戏的算法实现,逻辑实现,游戏中棋子怎么走,怎么计算路径等等
*/
public class GameLogic
{
/** 游戏面板 */
GamePanel gamePanel;
/** 最大搜索深度 */
int Maxdepth = 2;
Map<String,String> mapNextChess = new HashMap<String,String>();
public GameLogic(GamePanel _gamePanel)
{
this.gamePanel = _gamePanel;
}
/**
* 功能:得到X像素所对应的列坐标<br>
*/
private int getColumn(int x)
{
//先判断靠哪列近些
int column = (x - this.gamePanel.gridsLeftX + this.gamePanel.gridSize / 2) / this.gamePanel.gridSize;
//再判断是否在有效范围内
int posX = this.gamePanel.gridsLeftX + column * this.gamePanel.gridSize;
if(x > (posX - this.gamePanel.chessSize / 2) && x < (posX + this.gamePanel.chessSize / 2)){}
else
{
column = -1;
}
return column;
}
/**
* 功能:得到Y像素所对应的行坐标<br>
*/
private int getRow(int y)
{
//先判断靠哪行近些
int row = (y - this.gamePanel.gridsTopY + this.gamePanel.gridSize / 2) / this.gamePanel.gridSize;
//再判断是否在有效范围内
int posY = this.gamePanel.gridsTopY + row * this.gamePanel.gridSize;
if(y > (posY - this.gamePanel.chessSize / 2) && y < (posY + this.gamePanel.chessSize / 2)){}
else
{
row = -1;
}
return row;
}
/**
* 功能:判断下一步是红棋下还是黑棋下<br>
*/
private int getNextChessColor()
{
int chessColor = -1;
//得到上一步信息
if(this.gamePanel.listChess.size() > 0)
{
Map<String,String> mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);
if(Integer.parseInt(mapLast.get("color")) == this.gamePanel.BLACKCHESS)
{
chessColor = this.gamePanel.REDCHESS;
}
else
{
chessColor = this.gamePanel.BLACKCHESS;
}
}
else
{
if(this.gamePanel.fightType == 0) //人机对战
{
if(this.gamePanel.playFirst == 1) //玩家先手
{
chessColor = this.gamePanel.chessColor;
}
else //电脑先手(这是不想赢啊)
{
if(this.gamePanel.chessColor == this.gamePanel.BLACKCHESS)
{
chessColor = this.gamePanel.REDCHESS;
}
else
{
chessColor = this.gamePanel.BLACKCHESS;
}
}
}
else //人人对战
{
chessColor = this.gamePanel.chessColor;
}
}
return chessColor;
}
/**
* 功能:将军提示<br>
*/
private void check()
{
//全体循环,不知道将哪头的军
for(int i=0;i<this.gamePanel.mapChess.length;i++)
{
this.getMoveRoute(this.gamePanel.mapChess[i]);
for(int j=0;j<this.gamePanel.listMove.size();j++)
{
Map<String,Integer> map = this.gamePanel.listMove.get(j);
int index = this.gamePanel.chessBoradState[map.get("row")][map.get("column")];
if(index != -1 && "king".equals(this.gamePanel.mapChess[index].get("type")))
{
JOptionPane.showMessageDialog(null,"将军,十万火急!");
break;
}
}
}
this.gamePanel.listMove.clear();
this.gamePanel.repaint();
}
/**
* 功能:判断棋子是否可以放到目标位置<br>
* 参数:_mapChess -> 棋子<br>
* 参数:_newRow -> 目标行位置<br>
* 参数:_newColumn -> 目标列位置<br>
* 备注:点空位或对方棋子上,已方棋子略<br>
*/
private boolean isAbleToMove(Map<String,String> _mapChess,int _newRow,int _newColumn)
{
int oldRow = -1; //移动前行位置
int oldColulmn = -1; //移动前列位置
int index = -1; //目标索引
String type = ""; //棋子类型
String direction = ""; //棋子方向(T-上方,B-下方)
//死亡棋子不能移动
if("T".equals(_mapChess.get("dead"))){return false;}
oldRow = Integer.parseInt(_mapChess.get("newRow"));
oldColulmn = Integer.parseInt(_mapChess.get("newColumn"));
type = _mapChess.get("type");
direction = _mapChess.get("direction");
index = this.gamePanel.chessBoradState[_newRow][_newColumn];
//不能吃自己伙的棋子
if(index != -1 && Integer.parseInt(this.gamePanel.mapChess[index].get("color")) == Integer.parseInt(_mapChess.get("color"))){return false;}
//不能吃自身
if(oldRow == _newRow && oldColulmn == _newColumn) {return false;}
if("king".equals(type)) //将帅
{
//不能出九宫
if((_newRow > 2 && _newRow < 7) || _newColumn < 3 || _newColumn > 5){return false;}
//一次只能走一格
if(Math.abs(_newRow - oldRow) > 1 || Math.abs(_newColumn - oldColulmn) > 1){return false;}
//不能走斜线
if((_newRow - oldRow) * (_newColumn - oldColulmn) != 0){return false;}
//将帅不能露脸
if(index != -1 && "king".equals(this.gamePanel.mapChess[index].get(type)) && oldColulmn == _newColumn) //目标棋子是将帅并且在同一列上
{
//判断中间是否有棋子
int count = 0;
int min = Math.min(oldRow,_newRow);
int max = Math.max(oldRow,_newRow);
for(int row=min+1;row<max;row++)
{
if(this.gamePanel.chessBoradState[row][_newColumn] != -1){count++;}
}
if(count == 0){return false;}
}
}
else if("guard".equals(type)) //士仕
{
//不能出九宫
if((_newRow > 2 && _newRow < 7) || _newColumn < 3 || _newColumn > 5){return false;}
//一次只能走一格
if(Math.abs(_newRow - oldRow) > 1 || Math.abs(_newColumn - oldColulmn) > 1){return false;}
//不能走横线或竖线
if((_newRow - oldRow) * (_newColumn - oldColulmn) == 0){return false;}
}
else if("elephant".equals(type)) //象相
{
//不能越界
if("T".equals(direction))
{
if(_newRow > 4){return false;}
}
else
{
if(_newRow < 5){return false;}
}
//不能走横线或竖线
if((_newRow - oldRow) * (_newColumn - oldColulmn) == 0){return false;}
//一次只能走二格
if(Math.abs(_newRow - oldRow) != 2 || Math.abs(_newColumn - oldColulmn) != 2){return false;}
//是否堵象眼
if(this.gamePanel.chessBoradState[Math.min(oldRow,_newRow) + 1][Math.min(oldColulmn,_newColumn) + 1] != -1){return false;}
}
else if("horse".equals(type)) //马(8种跳法,4种别腿)
{
//必须走日字格
if( Math.abs((_newRow - oldRow)) * Math.abs((_newColumn - oldColulmn)) != 2){return false;}
//向上跳
if(_newRow - oldRow == -2)
{
if(this.gamePanel.chessBoradState[oldRow - 1][oldColulmn] != -1){return false;}
}
//向下跳
if(_newRow - oldRow == 2)
{
if(this.gamePanel.chessBoradState[oldRow + 1][oldColulmn] != -1){return false;}
}
//向左跳
if(_newColumn - oldColulmn == -2)
{
if(this.gamePanel.chessBoradState[oldRow][oldColulmn - 1] != -1){return false;}
}
//向右跳
if(_newColumn - oldColulmn == 2)
{
if(this.gamePanel.chessBoradState[oldRow][oldColulmn + 1] != -1){return false;}
}
}
else if("rook".equals(type)) //车
{
//不能走斜线
if((_newRow - oldRow) * (_newColumn - oldColulmn) != 0){return false;}
//竖走
if(_newColumn == oldColulmn)
{
//判断中间是否有棋子
int min = Math.min(oldRow,_newRow);
int max = Math.max(oldRow,_newRow);
for(int row=min+1;row<max;row++)
{
if(this.gamePanel.chessBoradState[row][_newColumn] != -1){return false;}
}
}
//横走
if(_newRow == oldRow)
{
//判断中间是否有棋子
int min = Math.min(oldColulmn,_newColumn);
int max = Math.max(oldColulmn,_newColumn);
for(int column=min+1;column<max;column++)
{
if(this.gamePanel.chessBoradState[_newRow][column] != -1){return false;}
}
}
}
else if("cannon".equals(type)) //炮
{
int count = 0;
//不能走斜线
if((_newRow - oldRow) * (_newColumn - oldColulmn) != 0){return false;}
//竖走
if(_newColumn == oldColulmn)
{
//判断中间是否有棋子
int min = Math.min(oldRow,_newRow);
int max = Math.max(oldRow,_newRow);
for(int row=min+1;row<max;row++)
{
if(this.gamePanel.chessBoradState[row][_newColumn] != -1){count++;}
}
}
//横走
if(_newRow == oldRow)
{
//判断中间是否有棋子
int min = Math.min(oldColulmn,_newColumn);
int max = Math.max(oldColulmn,_newColumn);
for(int column=min+1;column<max;column++)
{
if(this.gamePanel.chessBoradState[_newRow][column] != -1){count++;}
}
}
//开始判断是否可以移动或吃棋子
if(count > 1)
{
return false;
}
else if(count == 1)
{
if(this.gamePanel.chessBoradState[_newRow][_newColumn] == -1){return false;} //打空炮的不要
}
else
{
if(this.gamePanel.chessBoradState[_newRow][_newColumn] != -1){return false;}
}
}
else if("soldier".equals(type)) //卒兵
{
//不能走斜线
if((_newRow - oldRow) * (_newColumn - oldColulmn) != 0){return false;}
//一次只能走一格
if(Math.abs(_newRow - oldRow) > 1 || Math.abs(_newColumn - oldColulmn) > 1){return false;}
//小卒过河不回头
if("T".equals(direction)) //上方
{
if(oldRow > 4) //过河了
{
if(_newRow < oldRow){return false;} //不许向后退
}
else
{
if(_newColumn == oldColulmn && _newRow > oldRow){} //只能往前走
else
{
return false;
}
}
}
else //下方
{
if(oldRow < 5) //过河了
{
if(_newRow > oldRow){return false;} //不许向后退
}
else
{
if(_newColumn == oldColulmn && _newRow < oldRow){} //只能往前走
else
{
return false;
}
}
}
}
return true;
}
/**
* 功能:将下完的棋子信息复制一份存储到下棋列表中,悔棋用<br>
* 备注:因为是对象引用,所以必须复制b<br>
*/
private void addList(Map<String,String> _mapChess)
{
Map<String,String> map = new HashMap<String,String>();
map.put("index",_mapChess.get("index"));
map.put("color",_mapChess.get("color"));
map.put("type",_mapChess.get("type"));
map.put("name",_mapChess.get("name"));
map.put("number",_mapChess.get("number"));
map.put("direction",_mapChess.get("direction"));
map.put("oldOldRow",_mapChess.get("oldOldRow"));
map.put("oldOldColumn",_mapChess.get("oldOldColumn"));
map.put("oldRow",_mapChess.get("oldRow"));
map.put("oldColumn",_mapChess.get("oldColumn"));
map.put("newRow",_mapChess.get("newRow"));
map.put("newColumn",_mapChess.get("newColumn"));
map.put("dead",_mapChess.get("dead"));
map.put("oldEatIndex",_mapChess.get("oldEatIndex"));
map.put("eatIndex",_mapChess.get("eatIndex"));
this.gamePanel.listChess.add(map);
}
/**
* 功能:悔棋具体步骤<br>
*/
private void undoStep()
{
if(this.gamePanel.isGameOver){return;}
if(this.gamePanel.listChess.size() < 1){return;}
//得到最后一步棋信息
Map<String,String> mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);
int index = Integer.parseInt(mapLast.get("index"));
int oldOldRow = Integer.parseInt(mapLast.get("oldOldRow"));
int oldOldColumn = Integer.parseInt(mapLast.get("oldOldColumn"));
int oldRow = Integer.parseInt(mapLast.get("oldRow"));
int oldColumn = Integer.parseInt(mapLast.get("oldColumn"));
int newRow = Integer.parseInt(mapLast.get("newRow"));
int newColumn = Integer.parseInt(mapLast.get("newColumn"));
int oldEatIndex = Integer.parseInt(mapLast.get("oldEatIndex"));
int eatIndex = Integer.parseInt(mapLast.get("eatIndex"));
//开始退回
this.gamePanel.mapChess[index].put("newRow",Integer.toString(oldRow));
this.gamePanel.mapChess[index].put("newColumn",Integer.toString(oldColumn));
this.gamePanel.mapChess[index].put("oldRow",Integer.toString(oldOldRow));
this.gamePanel.mapChess[index].put("oldColumn",Integer.toString(oldOldColumn));
this.gamePanel.mapChess[index].put("oldOldRow","-1");
this.gamePanel.mapChess[index].put("oldOldColumn","-1");
this.gamePanel.mapChess[index].put("dead","F");
this.gamePanel.mapChess[index].put("eatIndex",Integer.toString(oldEatIndex));
this.gamePanel.mapChess[index].put("oldEatIndex","-1");
this.gamePanel.labelChess[index].setBounds(this.gamePanel.gridsLeftX + oldColumn * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.gridsTopY + oldRow * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.chessSize,this.gamePanel.chessSize);
this.gamePanel.chessBoradState[oldRow][oldColumn] = index;
//判断是否吃棋子了
if(eatIndex == -1) //未吃棋子
{
this.gamePanel.chessBoradState[newRow][newColumn] = -1;
}
else //吃棋子了,给我吐出来
{
this.gamePanel.mapChess[eatIndex].put("dead","F");
this.gamePanel.labelChess[eatIndex].setBounds(this.gamePanel.gridsLeftX + newColumn * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.gridsTopY + newRow * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.chessSize,this.gamePanel.chessSize);
this.gamePanel.chessBoradState[newRow][newColumn] = eatIndex;
}
this.gamePanel.listChess.remove(this.gamePanel.listChess.size() - 1);
}
/**
* 功能:悔棋<br>
*/
public boolean undo()
{
int index,color,oldRow,oldColumn;
Map<String,String> mapLast = null;
if(this.gamePanel.isGameOver){return false;}
if(this.gamePanel.listChess.size() < 1){return false;}
//得到最后一步棋信息
mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 1);
index = Integer.parseInt(mapLast.get("index"));
color = Integer.parseInt(mapLast.get("color"));
oldRow = Integer.parseInt(mapLast.get("oldRow"));
oldColumn = Integer.parseInt(mapLast.get("oldColumn"));
if(this.gamePanel.fightType == 0) //人机对战(只有玩家才会悔棋,电脑才不会这么耍赖)
{
//人机要同时悔2步棋,所以要得到倒数第二步棋信息
if(this.gamePanel.listChess.size() < 2)
{
JOptionPane.showMessageDialog(null,"禁止悔棋!","提示",JOptionPane.INFORMATION_MESSAGE);
return false;
}
mapLast = this.gamePanel.listChess.get(this.gamePanel.listChess.size() - 2);
index = Integer.parseInt(mapLast.get("index"));
color = Integer.parseInt(mapLast.get("color"));
oldRow = Integer.parseInt(mapLast.get("oldRow"));
oldColumn = Integer.parseInt(mapLast.get("oldColumn"));
//判断玩家是否可以悔棋
if(this.gamePanel.chessColor == this.gamePanel.BLACKCHESS) //玩家执黑
{
if(this.gamePanel.blackUndoNum == 0)
{
JOptionPane.showMessageDialog(null,"黑棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);
return false;
}
this.gamePanel.blackUndoNum--;
}
else
{
if(this.gamePanel.redUndoNum == 0)
{
JOptionPane.showMessageDialog(null,"红棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);
return false;
}
this.gamePanel.redUndoNum--;
}
this.undoStep(); //电脑悔一步
this.undoStep(); //玩家悔一步
}
else
{
//判断是否可以悔棋
if(color == this.gamePanel.REDCHESS)
{
if(this.gamePanel.redUndoNum == 0)
{
JOptionPane.showMessageDialog(null,"红棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);
return false;
}
this.gamePanel.redUndoNum--;
}
else
{
if(this.gamePanel.blackUndoNum == 0)
{
JOptionPane.showMessageDialog(null,"黑棋的悔棋次数已经全部用完了!","提示",JOptionPane.INFORMATION_MESSAGE);
return false;
}
this.gamePanel.blackUndoNum--;
}
this.undoStep(); //玩家悔一步
}
//重新生成落子指示器
this.gamePanel.mapPointerChess.put("row",oldRow);
this.gamePanel.mapPointerChess.put("column",oldColumn);
this.gamePanel.mapPointerChess.put("color",color);
this.gamePanel.mapPointerChess.put("show",1);
this.gamePanel.isFirstClick = false;
this.gamePanel.firstClickChess = this.gamePanel.mapChess[index];
//显示移动路线图
this.getMoveRoute(this.gamePanel.firstClickChess);
//更新提示
this.gamePanel.jlb_blackUndoText.setText("剩"+gamePanel.blackUndoNum+"次");
this.gamePanel.jlb_redUndoText.setText("剩"+gamePanel.redUndoNum+"次");
if(color == this.gamePanel.REDCHESS)
{
this.gamePanel.jlb_redStateText.setText("已下完");
this.gamePanel.jlb_blackStateText.setText("已选棋");
}
else
{
this.gamePanel.jlb_redStateText.setText("已选棋");
this.gamePanel.jlb_blackStateText.setText("已下完");
}
//刷新
this.gamePanel.repaint();
return true;
}
/**
* 功能:对当前局面进行估分<br>
* 备注:若电脑下的棋则(电脑分-玩家分),反之(玩家分-电脑分)<br>
*/
private int evaluation(int[][] _chessBoradMap)
{
//基础分
final int BASE_ROOK = 500;
final int BASE_HORSE = 350;
final int BASE_ELEPHANT = 250;
final int BASE_GUARD = 250;
final int BASE_KING = 10000;
final int BASE_CANNON = 350;
final int BASE_SOLDIER = 100;
//灵活分(每多一个可走位置的相应加分)
final int FLEXIBLE_ROOK = 6;
final int FLEXIBLE_HORSE = 12;
final int FLEXIBLE_ELEPHANT = 1;
final int FLEXIBLE_GUARD = 1;
final int FLEXIBLE_KING = 0;
final int FLEXIBLE_CANNON = 6;
final int FLEXIBLE_SOLDIER = 15;
//其他
int score = 0; //总评估分数
int redScore = 0; //红旗评估分数
int blackScore = 0; //黑棋评估分数
//判断该谁下棋
int nextColor = this.getNextChessColor();
//所有棋子循环
for(int m=0;m<this.gamePanel.mapChess.length;m++)
{
//如果该棋子死亡则略过
if("T".equals(this.gamePanel.mapChess[m].get("dead"))) {continue;}
//得到相关参数
String type = this.gamePanel.mapChess[m].get("type");
int color = Integer.parseInt(this.gamePanel.mapChess[m].get("color"));
String direction = this.gamePanel.mapChess[m].get("direction");
int newRow = Integer.parseInt(this.gamePanel.mapChess[m].get("newRow"));
int newColumn = Integer.parseInt(this.gamePanel.mapChess[m].get("newColumn"));
//加基础分
if("rook".equals(type)) //车
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_ROOK;
}
else
{
redScore = redScore + BASE_ROOK;
}
}
else if("horse".equals(type)) //马
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_HORSE;
}
else
{
redScore = redScore + BASE_HORSE;
}
}
else if("elephant".equals(type)) //象相
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_ELEPHANT;
}
else
{
redScore = redScore + BASE_ELEPHANT;
}
}
else if("guard".equals(type)) //士仕
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_GUARD;
}
else
{
redScore = redScore + BASE_GUARD;
}
}
else if("king".equals(type)) //将帅
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_KING;
}
else
{
redScore = redScore + BASE_KING;
}
}
else if("cannon".equals(type)) //炮
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_CANNON;
}
else
{
redScore = redScore + BASE_CANNON;
}
}
else if("soldier".equals(type)) //卒兵
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_SOLDIER;
}
else
{
redScore = redScore + BASE_SOLDIER;
}
}
//加过河分
if("soldier".equals(type)) //卒兵
{
int riverScore = 0;
if("T".equals(direction)) //上方
{
if(newRow > 4 && newRow < 9) //过河了(不要最底框那行)
{
riverScore = 70;
if(newRow >= 6)
{
if(newColumn >= 2 && newColumn <= 6)
{
if(newRow >= 7 && newRow <=8 && newColumn >= 3 && newColumn <= 5)
{
riverScore = riverScore + 50;
}
else
{
riverScore = riverScore + 40;
}
}
}
}
}
else //下方
{
if(newRow > 0 && newRow < 5) //过河了(不要最顶框那行)
{
riverScore = 70;
if(newRow <= 3)
{
if(newColumn >= 2 && newColumn <= 6)
{
if(newRow >= 1 && newRow <=2 && newColumn >= 3 && newColumn <= 5)
{
riverScore = riverScore + 50;
}
else
{
riverScore = riverScore + 40;
}
}
}
}
}
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + riverScore;
}
else
{
redScore = redScore + riverScore;
}
}
//该棋子可以走的位置
for(int row=0;row<this.gamePanel.gridRows;row++)
{
for(int column=0;column<this.gamePanel.gridColumns;column++)
{
if(this.isAbleToMove(this.gamePanel.mapChess[m],row,column))
{
//加适应分
if("rook".equals(type)) //车
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_ROOK;
}
else
{
redScore = redScore + FLEXIBLE_ROOK;
}
}
else if("horse".equals(type)) //马
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_HORSE;
}
else
{
redScore = redScore + FLEXIBLE_HORSE;
}
}
else if("elephant".equals(type)) //象相
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_ELEPHANT;
}
else
{
redScore = redScore + FLEXIBLE_ELEPHANT;
}
}
else if("guard".equals(type)) //士仕
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_GUARD;
}
else
{
redScore = redScore + FLEXIBLE_GUARD;
}
}
else if("king".equals(type)) //将帅
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_KING;
}
else
{
redScore = redScore + FLEXIBLE_KING;
}
}
else if("cannon".equals(type)) //炮
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_CANNON;
}
else
{
redScore = redScore + FLEXIBLE_CANNON;
}
}
else if("soldier".equals(type)) //卒兵
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + FLEXIBLE_SOLDIER;
}
else
{
redScore = redScore + FLEXIBLE_SOLDIER;
}
}
//加威胁分(默认再加一遍基础分)
int index = this.gamePanel.chessBoradState[row][column];
if(index != -1)
{
String type1 = this.gamePanel.mapChess[index].get("type");
if("rook".equals(type1)) //车
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_ROOK;
}
else
{
redScore = redScore + BASE_ROOK;
}
}
else if("horse".equals(type1)) //马
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_HORSE;
}
else
{
redScore = redScore + BASE_HORSE;
}
}
else if("elephant".equals(type1)) //象相
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_ELEPHANT;
}
else
{
redScore = redScore + BASE_ELEPHANT;
}
}
else if("guard".equals(type1)) //士仕
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_GUARD;
}
else
{
redScore = redScore + BASE_GUARD;
}
}
else if("king".equals(type1)) //将帅
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_KING;
}
else
{
redScore = redScore + BASE_KING;
}
}
else if("cannon".equals(type1)) //炮
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_CANNON;
}
else
{
redScore = redScore + BASE_CANNON;
}
}
else if("soldier".equals(type1)) //卒兵
{
if(color == this.gamePanel.BLACKCHESS)
{
blackScore = blackScore + BASE_SOLDIER;
}
else
{
redScore = redScore + BASE_SOLDIER;
}
}
}
}
}
}
}
//计算总分
if(nextColor == this.gamePanel.REDCHESS)
{
score = blackScore - redScore;
}
else
{
score = redScore - blackScore;
}
return score;
}
/**
* 功能:负极大值算法<br>
*/
private int negaMax(int[][] _chessBoradMap,int _depth)
{
int value;
int bestValue = -9999999;
//有事,程序还有好多漏洞,暂时未完善,也没写α与β剪枝,等有空再完善。
//if(this.gameOver())return evaluation(this.gamePanel.chessBoradState); //胜负已分,返回估值,有问题
System.out.println("_depth="+_depth);
//叶子节点
if(_depth == 0)
{
return this.evaluation(this.gamePanel.chessBoradState); //调用估值函数,返回估值
}
//生成每一步走法
int nextColor = this.getNextChessColor();
System.out.println("nextColor="+nextColor);
for(int i=0;i<this.gamePanel.mapChess.length;i++)
{
//判断该谁下棋
if(Integer.parseInt(this.gamePanel.mapChess[i].get("color")) != nextColor)
{
continue;
}
//判断是否可以下棋
for(int row=0;row<this.gamePanel.gridRows;row++)
{
for(int column=0;column<this.gamePanel.gridColumns;column++)
{
if(this.isAbleToMove(this.gamePanel.mapChess[i],row,column))
{
this.moveTo(this.gamePanel.mapChess[i],row,column);
//递归搜索子节点
value = this.negaMax(this.gamePanel.chessBoradState, _depth - 1);
//判断最大值
if(value >= bestValue)
{
bestValue = value;
if(_depth == this.Maxdepth)
{
this.mapNextChess.put("index",""+i);
this.mapNextChess.put("newRow",row+"");
this.mapNextChess.put("newColumn",column+"");
}
}
//恢复原来位置
this.undoStep();
}
}
}
}
return bestValue; //返回最大值
}
/**
* 功能:轮到电脑下棋了<br>
*/
public void computerPlay()
{
int value;
value = this.negaMax(this.gamePanel.chessBoradState,Maxdepth);
int index = Integer.parseInt(this.mapNextChess.get("index"));
int newRow = Integer.parseInt(this.mapNextChess.get("newRow")) ;
int newColumn = Integer.parseInt(this.mapNextChess.get("newColumn")) ;
System.out.println("value="+value);
System.out.println("index="+index);
System.out.println("newRow="+newRow);
System.out.println("newColumn="+newColumn);
this.moveTo(this.gamePanel.mapChess[index],newRow,newColumn);
//落子指示器
this.gamePanel.mapPointerChess.put("row",newRow);
this.gamePanel.mapPointerChess.put("column",newColumn);
this.gamePanel.mapPointerChess.put("show",1);
this.gamePanel.mapPointerChess.put("color",this.gamePanel.computerChess);
this.gamePanel.repaint();
}
/**
* 功能:得到某棋子的可移动路线图<br>
*/
private void getMoveRoute(Map<String,String> _mapChess)
{
this.gamePanel.listMove.clear();
//懒得分类挑,反正电脑计算快
for(int row=0;row<this.gamePanel.gridRows;row++)
{
for(int column=0;column<this.gamePanel.gridColumns;column++)
{
if(this.isAbleToMove(_mapChess,row,column))
{
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("row",row);
map.put("column",column);
this.gamePanel.listMove.add(map);
}
}
}
}
/**
* 功能:判断游戏是否结束<br>
*/
private boolean gameOver()
{
if(this.gamePanel.fightType == 0) //人机对战
{
if("T".equals(this.gamePanel.mapChess[4].get("dead"))) //黑将被吃
{
if(this.gamePanel.computerChess == this.gamePanel.BLACKCHESS)
{
JOptionPane.showMessageDialog(null,"恭喜,你终于赢电脑一把了!");
}
else
{
JOptionPane.showMessageDialog(null,"我去,你怎么连电脑都输啊!","提示",JOptionPane.ERROR_MESSAGE);
}
return true;
}
if("T".equals(this.gamePanel.mapChess[27].get("dead"))) //红帅被吃
{
if(this.gamePanel.computerChess == this.gamePanel.BLACKCHESS)
{
JOptionPane.showMessageDialog(null,"我去,你怎么连电脑都输啊!","提示",JOptionPane.ERROR_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null,"恭喜,你终于赢电脑一把了!");
}
return true;
}
}
else //人人对战
{
if("T".equals(this.gamePanel.mapChess[4].get("dead"))) //黑将被吃
{
JOptionPane.showMessageDialog(null,"恭喜,红棋赢了!");
return true;
}
if("T".equals(this.gamePanel.mapChess[27].get("dead"))) //红帅被吃
{
JOptionPane.showMessageDialog(null,"恭喜,黑棋赢了!");
return true;
}
}
return false;
}
/**
* 功能:棋子移动到新位置<br>
*/
private void moveTo(Map<String,String> _mapChess,int _newRow,int _newColumn)
{
//判断是移动还是吃子
int newIndex = this.gamePanel.chessBoradState[_newRow][_newColumn];
if(newIndex != -1) //吃子
{
//目标棋子清除
this.gamePanel.mapChess[newIndex].put("dead","T");
this.gamePanel.labelChess[newIndex].setBounds(this.gamePanel.gridsLeftX + -2 * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.gridsTopY + -2 * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.chessSize,this.gamePanel.chessSize);
}
//新棋子占位
int index = Integer.parseInt(_mapChess.get("index"));
_mapChess.put("oldOldRow",_mapChess.get("oldRow"));
_mapChess.put("oldOldColumn",_mapChess.get("oldColumn"));
_mapChess.put("oldRow",_mapChess.get("newRow"));
_mapChess.put("oldColumn",_mapChess.get("newColumn"));
_mapChess.put("newRow",Integer.toString(_newRow));
_mapChess.put("newColumn",Integer.toString(_newColumn));
_mapChess.put("oldEatIndex",_mapChess.get("eatIndex"));
_mapChess.put("eatIndex",Integer.toString(newIndex));
this.addList(_mapChess);
this.gamePanel.labelChess[index].setBounds(this.gamePanel.gridsLeftX + _newColumn * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.gridsTopY + _newRow * this.gamePanel.gridSize - this.gamePanel.chessSize/2,this.gamePanel.chessSize,this.gamePanel.chessSize);
this.gamePanel.chessBoradState[Integer.parseInt(_mapChess.get("oldRow"))][Integer.parseInt(_mapChess.get("oldColumn"))] = -1;
this.gamePanel.chessBoradState[_newRow][_newColumn] = index;
this.gamePanel.isFirstClick = true;
}
/**
* 功能:鼠标单击事件<br>
*/
public void mouseClicked(MouseEvent e)
{
if(this.gamePanel.isGameOver){return;}
if(e.getButton() == MouseEvent.BUTTON1) //鼠标左键点击
{
if(e.getSource() == this.gamePanel.labelChessBorad) //点击到棋盘上
{
//第一次点击无效
if(this.gamePanel.isFirstClick){return;}
//判断位置(将X与Y由像素改为相应的行列坐标)
int row = this.getRow(e.getY());
int column = this.getColumn(e.getX());
if(row >= 0 && row < 10 && column >= 0 && column < 9) //第二次点击
{
//要移动棋子了
if(this.isAbleToMove(this.gamePanel.firstClickChess,row,column))
{
this.moveTo(this.gamePanel.firstClickChess,row,column);
//取消移动路线图
this.gamePanel.listMove.clear();
//落子指示器
this.gamePanel.mapPointerChess.put("row",row);
this.gamePanel.mapPointerChess.put("column",column);
this.gamePanel.mapPointerChess.put("show",1);
//更新提示
if(Integer.parseInt(gamePanel.firstClickChess.get("color")) == this.gamePanel.BLACKCHESS)
{
this.gamePanel.jlb_redStateText.setText("思考中");
this.gamePanel.jlb_blackStateText.setText("已下完");
}
else
{
this.gamePanel.jlb_redStateText.setText("已下完");
this.gamePanel.jlb_blackStateText.setText("思考中");
}
this.gamePanel.repaint();
//判断是否将军
this.check();
//如果是人机对战,机器要回应啊
if(this.gamePanel.fightType == 0) //人机对战
{
this.computerPlay();
if(this.gamePanel.computerChess == this.gamePanel.BLACKCHESS)
{
this.gamePanel.jlb_blackStateText.setText("已下完");
this.gamePanel.jlb_redStateText.setText("思考中");
}
else
{
this.gamePanel.jlb_redStateText.setText("已下完");
this.gamePanel.jlb_blackStateText.setText("思考中");
}
//判断游戏是否结束
if(this.gameOver())
{
this.gamePanel.isGameOver = true;
this.gamePanel.setComponentState(false);
this.gamePanel.jlb_blackStateText.setText("已结束");
this.gamePanel.jlb_redStateText.setText("已结束");
return;
}
}
}
}
else
{
return;
}
}
else //点到棋子上
{
JLabel label = (JLabel)e.getSource();
int index = Integer.parseInt(label.getName());
int row = Integer.parseInt(this.gamePanel.mapChess[index].get("newRow"));
int column = Integer.parseInt(this.gamePanel.mapChess[index].get("newColumn"));
//判断第几次点击
if(this.gamePanel.isFirstClick) //第一次(必须点击到该下棋方的棋子上)
{
if(Integer.parseInt(this.gamePanel.mapChess[index].get("color")) != this.getNextChessColor()){return;}
//画个落子指示器并记录下第一次点击对象
this.gamePanel.mapPointerChess.put("row",row);
this.gamePanel.mapPointerChess.put("column",column);
this.gamePanel.mapPointerChess.put("show",1);
this.gamePanel.mapPointerChess.put("color",Integer.parseInt(this.gamePanel.mapChess[index].get("color")));
this.gamePanel.firstClickChess = this.gamePanel.mapChess[index];
this.gamePanel.isFirstClick = false;
this.gamePanel.repaint();
if(Integer.parseInt(this.gamePanel.mapChess[index].get("color")) == this.gamePanel.BLACKCHESS)
{
this.gamePanel.jlb_redStateText.setText("等待中");
this.gamePanel.jlb_blackStateText.setText("已选棋");
}
else
{
this.gamePanel.jlb_redStateText.setText("已选棋");
this.gamePanel.jlb_blackStateText.setText("等待中");
}
//显示移动路线图
this.getMoveRoute(this.gamePanel.firstClickChess);
this.gamePanel.repaint();
}
else //第二次点击
{
//点击到该下棋方的棋子上则还算是第一次
if(Integer.parseInt(this.gamePanel.mapChess[index].get("color")) == this.getNextChessColor())
{
this.gamePanel.mapPointerChess.put("row",row);
this.gamePanel.mapPointerChess.put("column",column);
this.gamePanel.mapPointerChess.put("show",1);
this.gamePanel.firstClickChess = this.gamePanel.mapChess[index];
this.gamePanel.isFirstClick = false;
this.getMoveRoute(this.gamePanel.firstClickChess); //显示移动路线图
this.gamePanel.repaint();
}
else //要吃棋子了
{
if(this.isAbleToMove(this.gamePanel.firstClickChess,row,column)) //这个可以吃
{
this.moveTo(this.gamePanel.firstClickChess,row,column);
//取消移动路线图
this.gamePanel.listMove.clear();
//落子指示器
this.gamePanel.mapPointerChess.put("row",row);
this.gamePanel.mapPointerChess.put("column",column);
this.gamePanel.mapPointerChess.put("show",1);
if(Integer.parseInt(gamePanel.firstClickChess.get("color")) == this.gamePanel.BLACKCHESS)
{
this.gamePanel.jlb_redStateText.setText("思考中");
this.gamePanel.jlb_blackStateText.setText("已下完");
}
else
{
this.gamePanel.jlb_redStateText.setText("已下完");
this.gamePanel.jlb_blackStateText.setText("思考中");
}
this.gamePanel.repaint();
//判断是否将军
this.check();
}
//判断游戏是否结束
if(this.gameOver())
{
this.gamePanel.isGameOver = true;
this.gamePanel.setComponentState(false);
this.gamePanel.jlb_blackStateText.setText("已结束");
this.gamePanel.jlb_redStateText.setText("已结束");
return;
}
//判断双方是否战平(这个不行啊)
//如果是人机对战,机器要回应啊
if(this.gamePanel.fightType == 0) //人机对战
{
this.computerPlay();
if(this.gamePanel.computerChess == this.gamePanel.BLACKCHESS)
{
this.gamePanel.jlb_blackStateText.setText("已下完");
this.gamePanel.jlb_redStateText.setText("思考中");
}
else
{
this.gamePanel.jlb_redStateText.setText("已下完");
this.gamePanel.jlb_blackStateText.setText("思考中");
}
//判断游戏是否结束
if(this.gameOver())
{
this.gamePanel.isGameOver = true;
this.gamePanel.setComponentState(false);
this.gamePanel.jlb_blackStateText.setText("已结束");
this.gamePanel.jlb_redStateText.setText("已结束");
return;
}
}
}
}
}
}
}
/**
* 功能:鼠标移动事件<br>
*/
public void mouseMoved(MouseEvent e)
{
int row = -1;
int column = -1;
int index = -1;
if(this.gamePanel.isGameOver){return;}
//得到行列位置
if(e.getSource() == this.gamePanel.labelChessBorad) //在棋盘上移动
{
row = this.getRow(e.getY());
column = this.getColumn(e.getX());
}
else //在棋子上移动
{
JLabel label = (JLabel)e.getSource();
index = Integer.parseInt(label.getName());
row = Integer.parseInt(this.gamePanel.mapChess[index].get("newRow"));
column = Integer.parseInt(this.gamePanel.mapChess[index].get("newColumn"));
}
//判断是否在棋盘内部移动
if(row >= 0 && row < 10 && column >= 0 && column < 9)
{
//清除落子指示器(先不显示)
this.gamePanel.mapPointerMove.put("show",0);
if(this.gamePanel.chessBoradState[row][column] == -1) //移动到棋盘上
{
this.gamePanel.mapPointerMove.put("row",row);
this.gamePanel.mapPointerMove.put("column",column);
this.gamePanel.mapPointerMove.put("show",1);
this.gamePanel.mapPointerMove.put("color",-1);
}
else //移动到棋子上
{
//第一次点击处理
if(this.gamePanel.isFirstClick)
{
//下棋方显示移动显示器,非下棋方不显示移动指示器
if(Integer.parseInt(this.gamePanel.mapChess[index].get("color")) == this.getNextChessColor())
{
this.gamePanel.mapPointerMove.put("row",row);
this.gamePanel.mapPointerMove.put("column",column);
this.gamePanel.mapPointerMove.put("show",1);
this.gamePanel.mapPointerMove.put("color",-1);
}
}
else //第二次点击处理
{
this.gamePanel.mapPointerMove.put("row",row);
this.gamePanel.mapPointerMove.put("column",column);
this.gamePanel.mapPointerMove.put("show",1);
this.gamePanel.mapPointerMove.put("color",-1);
}
}
this.gamePanel.repaint();
}
else //点棋盘外边了
{
if(this.gamePanel.mapPointerMove.get("show") == 1)
{
this.gamePanel.mapPointerMove.put("show",0);
this.gamePanel.repaint();
}
}
}
}
//
package com.gui.chess;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//2023.4.4/4.5/4.6/4.7/4.8/4.9 Gui编程 中国象棋游戏的练习 回顾多线程和GUi知识,算法实现练习 Gui编程知识点回顾(Awt,Swing)等等
//游戏面板类 这一个类是功能类,主要就是画游戏的界面,功能模块设计,事件监听,鼠标监听,Gui编程-Swing框架下的组件复习回顾,Gui编程布局复习,图标复习等等
public class GamePanel extends JPanel implements MouseListener, MouseMotionListener, ActionListener {//游戏面板类继承JPanel类,实现鼠标监听接口,鼠标运动监听接口,事件监听接口
private static final long serialVersionUID = 1353029267562430095L;
/** 游戏逻辑 */
private GameLogic gameLogic;
/** 网格行数 */
final int gridRows = 10;
/** 网格列数 */
final int gridColumns = 9;
/** 网格尺寸 */
final int gridSize = 52;
/** 网格宽度 */
final int gridsWidth = gridSize * (gridColumns - 1);
/** 网格高度 */
final int gridsHeight = gridSize * (gridRows - 1);
/** 网格左上角X坐标 */
final int gridsLeftX = 42;
/** 网格左上角Y坐标 */
final int gridsTopY = 42;
/** 象棋面板(要分层,否则棋盘标签压棋子标签) */
private JLayeredPane panelChess;
/** 棋盘标签 */
JLabel labelChessBorad;
/** 棋盘图片 */
private ImageIcon imageIconChessBoard;
/** 棋盘状态信息(-1->无棋,其他数字->棋子信息数组的下标) */
int[][] chessBoradState = new int[gridRows][gridColumns];
/** 棋子尺寸 */
final int chessSize = 44;
/** 棋子标签 */
JLabel[] labelChess = new JLabel[32];
/**
* 棋子信息数组
* index -> 棋子索引<br>
* color -> 棋子颜色(0-黑棋,255-红棋)<br>
* type -> 棋子类型(rook、horse、elephant、guard、king、cannon、soldier)<br>
* name -> 棋子名字(黑车、黑马、黑象、黑士、黑将、黑炮、黑卒、红兵、红炮、红车、红马、红相、红仕、红帅)<br>
* number -> 棋子小标号(如卒1卒2中的1与2)<br>
* direction -> 棋子方向(T-上方,B-下方)<br>
* oldOldRow -> 棋子大上次行位置<br>
* oldOldColumn -> 棋子大上次列位置<br>
* oldRow -> 棋子上次行位置<br>
* oldColumn -> 棋子上次列位置<br>
* newRow -> 棋子本次行位置<br>
* newColumn -> 棋子本次列位置<br>
* dead -> 棋子是否处于死亡状态(T-死亡,F-活着)<br>
* oldEatIndex -> 上次被其吃棋子下标<br>
* eatIndex -> 本次被其吃棋子下标<br>
*/
@SuppressWarnings("unchecked") //数组不支持泛型
Map<String,String>[] mapChess = new Map[32];
/** 棋子图片 */
private ImageIcon[] imageIconChess = new ImageIcon[14];
/** 红棋标识 */
final int REDCHESS = 255;
/** 黑棋标识 */
final int BLACKCHESS = 0;
/** 对战方式(0-人机对战,1-人人对战) */
int fightType ;
/** 先手选择(1-玩家先手,2-电脑先手) */
int playFirst ;
/** 红黑选择(255-玩家执红,0-玩家执黑) */
int chessColor ;
/** 电脑棋子颜色 */
int computerChess = -1 ;
/** 玩家棋子颜色 */
int playerChess = -1 ;
/** 红棋悔棋数 */
int redUndoNum = 30;
/** 黑棋悔棋数 */
int blackUndoNum = 30;
/** 全部下棋信息 */
List<Map<String,String>> listChess = new ArrayList<Map<String,String>>();
/** 移动线路图信息 */
List<Map<String,Integer>> listMove = new ArrayList<Map<String,Integer>>();
/** 组合框控件 */
private JComboBox<String> jcb_fightType,jcb_playFirst,jcb_chessColor;
/** 按钮控件 */
private JButton jb_new,jb_undo,jb_surrender;
/** 标签控件 */
JLabel jlb_blackUndoText,jlb_blackStateText,jlb_redUndoText,jlb_redStateText;
/** Logo图片 */
private ImageIcon imageIconLogo;
/** 是否第一次点击 */
boolean isFirstClick = true;
/** 第一次点击棋子 */
Map<String,String> firstClickChess = null;
/**
* 落子指示器<br>
* row -> 行坐标<br>
* column -> 列坐标<br>
* show -> 是否显示(0-不显示,1-显示)<br>
* color -> 颜色(0-黑,255-红)<br>
*/
Map<String,Integer> mapPointerChess = new HashMap<String,Integer>();//1.
/**
* 移动指示器<br>
* row -> 行坐标<br>
* column -> 列坐标<br>
* show -> 是否显示(0-不显示,1-显示)<br>
* color -> 颜色(-1-默认,0-黑,255-红)<br>
*/
Map<String,Integer> mapPointerMove = new HashMap<String,Integer>();//2. 1,2这两句没有调用到,排查
/** 判断游戏是否结束(true-结束,false-未结束) */
boolean isGameOver = true;
/**
* 功能:构造函数
*/
public GamePanel(){
//与主窗口大小保持一致,并设置背景颜色(去掉菜单高度)
this.setSize(666,560);//设置面板大小
this.setLayout(null);//设置布局为空
//设置象棋面板
this.panelChess = new JLayeredPane();//创建象棋面板对象为层级面板(JLayeredPane)
this.panelChess.setBounds(0,0,504,558);//设置象棋面板位置和面板大小
this.panelChess.setLayout(null);//设置象棋面板布局为空
this.add(this.panelChess);//将象棋面板添加到JLayeredPane中
//加载图片
this.loadImage();
//设置棋盘背景图片
this.labelChessBorad = new JLabel();//创建棋盘背景的标签对象
this.labelChessBorad.setBounds(0,0,this.panelChess.getWidth(),this.panelChess.getHeight());//设置棋盘背景标签对象的位置和(根据棋盘大小)来确定棋盘背景的大小
this.labelChessBorad.setIcon(this.imageIconChessBoard); //设置棋盘背景的图片标签
this.labelChessBorad.addMouseListener(this);//将棋盘背景对象添加到鼠标监听事件中
this.labelChessBorad.addMouseMotionListener(this);//将棋盘背景对象添加到鼠标运动(行为)监听事件中
this.panelChess.add(this.labelChessBorad, JLayeredPane.DEFAULT_LAYER);//将棋盘背景对象添加到棋盘面板对象中,位置层级数组为0,即没有标记第几层,DEFAULT_LAYER:Z_order的Layer数值为0
//建立棋子标签
this.createChess();//这一行只是调用创建棋子的方法
//右边功能区布局
this.option();
//游戏逻辑
this.gameLogic = new GameLogic(this);//创建游戏逻辑对象,调用GameLogic(游戏逻辑类)类
//初始化游戏
this.initGame();
}
/**
* 功能:加载图片
*/
private void loadImage(){
try {
//棋盘图片
this.imageIconChessBoard = new ImageIcon(new ImageIcon(this.getClass().getResource("resource/chess/chessBoard.png")).getImage());//获得棋盘背景的图片资源,棋盘背景图片被放在了图片图标里面
//棋子图片
for(int i=0; i<this.imageIconChess.length; i++)//循环,从棋子图标中取每一个不同的棋子图标,棋子图标中还存在棋子图标,则i++,直到取完为止
{
this.imageIconChess[i] = new ImageIcon(new ImageIcon(this.getClass().getResource("resource/chess/chess"+i+".png")).getImage().getScaledInstance(this.chessSize,this.chessSize,Image.SCALE_SMOOTH));//缩放图片来适应标签大小-接下一行
//取得棋子图片资源放到图片图标中,缩放图片来适应棋子图标的大小
}
//Logo图片
this.imageIconLogo = new ImageIcon(new ImageIcon(this.getClass().getResource("resource/chess/logo.png")).getImage().getScaledInstance(100,50, Image.SCALE_SMOOTH));//缩放图片来适应标签大小-接下一行
//取得Logo图片的资源放到图片图标中,缩放图片来适应棋子图标的大小
}catch (Exception e){
e.printStackTrace();
}
}
/**
*功能:初始化游戏
*/
private void initGame(){
//重新设置参数
this.isGameOver = true;
//清空下棋与移动线路图列表
this.listChess.clear();
this.listMove.clear();
//指示器初始化
this.mapPointerChess.put("row", -1);
this.mapPointerChess.put("column", -1);
this.mapPointerChess.put("show", 0);
this.mapPointerChess.put("color", -1);
this.mapPointerMove.put("row", -1);
this.mapPointerMove.put("column", -1);
this.mapPointerMove.put("show", 0);
this.mapPointerMove.put("color", -1);
//对战方式
if ("人人对战".equals(this.jcb_fightType.getSelectedItem().toString())){
this.fightType = 1;
}else {
this.fightType = 0;
}
//先手选择
if ("电脑先手".equals(this.jcb_playFirst.getSelectedItem().toString())){
this.playFirst = 2;
}else {
this.playFirst = 1;
}
//红黑选择
if ("玩家执黑".equals(this.jcb_chessColor.getSelectedItem().toString())){
this.chessColor = this.BLACKCHESS;
}else {
this.chessColor = this.REDCHESS;
}
//电脑与玩家棋子颜色
if (this.fightType == 0){
if (this.chessColor == this.REDCHESS){
this.playerChess = this.BLACKCHESS;
this.computerChess = this.REDCHESS;
}else {
this.playerChess = this.REDCHESS;
this.computerChess = this.BLACKCHESS;
}
}
//悔棋数初始化
this.redUndoNum = 30;
this.blackUndoNum = 30;
//设置控件状态
this.setComponentState(false);
//初始化棋子(默认我方棋子在下方)
this.initChess();
}
/**
* 功能:布局棋子
*/
private void initChess(){
//先默认设置棋子信息(玩家执红;红方在下,黑方在上)
for (int index = 0; index < this.mapChess.length; index++){
this.mapChess[index].put("index", Integer.toString(index));
this.mapChess[index].put("oldOldRow", "-1");//放上一次行的的
this.mapChess[index].put("oldRow", "-1");//放上一回合的行坐标到集合中
this.mapChess[index].put("oldColumn", "-1");//放上一回合的列坐标到集合中
this.mapChess[index].put("dead", "F");//放死亡的棋子到map集合中
this.mapChess[index].put("oldEatIndex", "-1");//放上一回合吃掉的棋子到集合中
this.mapChess[index].put("eatIndex", "-1");//放上一回合吃掉的棋子到集合中
if (index < 9){ //黑车马象士将象马车 --按照这个顺序将棋子一一摆放好
this.mapChess[index].put("direction", "T");//所放的棋子是上方棋盘的
this.mapChess[index].put("newRow", "0");
this.mapChess[index].put("newColumn", Integer.toString(index));
}else if (index == 9){//黑炮1
this.mapChess[index].put("direction", "T");
this.mapChess[index].put("newRow", "2");
this.mapChess[index].put("newColumn", "1");
}else if (index == 10){//黑炮2
this.mapChess[index].put("direction", "T");
this.mapChess[index].put("newRow", "2");
this.mapChess[index].put("newColumn", "7");
}else if (index >= 16 && index < 21){//黑卒n
this.mapChess[index].put("direction", "T");
this.mapChess[index].put("newRow", "3");
this.mapChess[index].put("newColumn", Integer.toString(2 * index - 22));
}else if (index >= 16 && index < 21){//红兵n
this.mapChess[index].put("direction", "B");
this.mapChess[index].put("newRow", "6");
this.mapChess[index].put("newColumn", Integer.toString(2 * index - 32));
}else if (index == 21){//红炮1
this.mapChess[index].put("direction", "B");
this.mapChess[index].put("newRow", "7");
this.mapChess[index].put("newColumn", "1");
}else if (index == 22){//红炮2
this.mapChess[index].put("direction", "B");
this.mapChess[index].put("newRow", "7");
this.mapChess[index].put("newColumn", "7");
}else if (index > 22 && index < 32){//红车马相士帅士相马车 --按照这个顺序依次摆放好棋子
this.mapChess[index].put("direction", "B");
this.mapChess[index].put("newRow", "0");
this.mapChess[index].put("newColumn", Integer.toString(index - 23));
}
}
//如果玩家执黑则坐标反过来
if (this.chessColor == this.BLACKCHESS){
//棋子信息对调(行变(9 -行),列不变)
for (int index = 0; index < this.mapChess.length; index++){
int row = Integer.parseInt(this.mapChess[index].get("newRow"));
this.mapChess[index].put("newRow", Integer.toString(Math.abs(9 - row)));
if ("T".equals(this.mapChess[index].get("direction"))){
this.mapChess[index].put("direction", "B");
}else {
this.mapChess[index].put("direction", "T");
}
}
}
//清空棋盘状态信息
for (int row = 0; row < this.chessBoradState.length; row++){
for (int column = 0; column < this.chessBoradState[0].length; column++){
this.chessBoradState[row][column] = -1;
}
}
//再根据棋子状态信息设置棋盘状态信息
for (int index = 0; index < this.mapChess.length; index++){
int row = Integer.parseInt(this.mapChess[index].get("newRow"));
int column = Integer.parseInt(this.mapChess[index].get("newColumn"));
this.chessBoradState[row][column] = index;
}
//重新布局棋子(x -> 列,y -> 行)
for (int index = 0; index < this.mapChess.length; index++){
int row = Integer.parseInt(this.mapChess[index].get("newRow"));
int column = Integer.parseInt(this.mapChess[index].get("newColumn"));
this.labelChess[index].setBounds(this.gridsLeftX + column * this.gridSize - this.chessSize/2, this.gridsTopY + row * this.gridSize - this.chessSize/2, this.chessSize, this.chessSize);
}
}
/**
* 功能:设置控件状态
* 参数:true -新开局, false -未开局
*/
public void setComponentState(boolean _flag){
if (_flag){//新游戏已经开始了
this.jcb_fightType.setEnabled(false);
this.jcb_playFirst.setEnabled(false);
this.jcb_chessColor.setEnabled(false);
this.jb_new.setEnabled(false);
this.jb_undo.setEnabled(true);
this.jb_surrender.setEnabled(true);
}else {//新游戏还未开始
this.jcb_fightType.setEnabled(true);
this.jcb_playFirst.setEnabled(true);
this.jcb_chessColor.setEnabled(true);
this.jb_new.setEnabled(true);
this.jb_undo.setEnabled(false);
this.jb_surrender.setEnabled(false);
}
}
/**
* 功能:建立棋子标签
*/
private void createChess() {
for (int index = 0; index < this.labelChess.length; index++){
this.labelChess[index] = new JLabel();//创建棋子标签对象
this.labelChess[index].setName(Integer.toString(index));//根据index(棋子的索引,第一第二第三...)设置棋子的名字
this.mapChess[index] = new HashMap<String, String>();//创建集合对象,将棋子标签放到集合里面
if (index == 0){//黑车1
this.labelChess[index].setIcon(this.imageIconChess[4]);
this.mapChess[index].put("color", "0");
this.mapChess[index].put("type", "rook");
this.mapChess[index].put("name", "黑车");
this.mapChess[index].put("number", "1");
}else if (index == 8){//黑车2
this.labelChess[index].setIcon(this.imageIconChess[4]);
this.mapChess[index].put("color", "0");
this.mapChess[index].put("type", "rook");
this.mapChess[index].put("name", "黑车");
this.mapChess[index].put("number", "2");
}else if (index == 1){//黑马1
this.labelChess[index].setIcon(this.imageIconChess[3]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","horse");
this.mapChess[index].put("name","黑马");
this.mapChess[index].put("number","1");
}else if (index == 7){//黑马2
this.labelChess[index].setIcon(this.imageIconChess[3]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","horse");
this.mapChess[index].put("name","黑马");
this.mapChess[index].put("number","2");
}else if (index == 2){//黑象1
this.labelChess[index].setIcon(this.imageIconChess[2]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","elephant");
this.mapChess[index].put("name","黑象");
this.mapChess[index].put("number","1");
}else if (index == 6){//黑象2
this.labelChess[index].setIcon(this.imageIconChess[2]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","elephant");
this.mapChess[index].put("name","黑象");
this.mapChess[index].put("number","2");
}else if (index == 3){//黑士1
this.labelChess[index].setIcon(this.imageIconChess[3]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","guard");
this.mapChess[index].put("name","黑士");
this.mapChess[index].put("number","1");
}else if (index == 5){//黑士2
this.labelChess[index].setIcon(this.imageIconChess[1]);
this.mapChess[index].put("color","0");
this.mapChess[index].put("type","guard");
this.mapChess[index].put("name","黑士");
this.mapChess[index].put("number","2");
}else if (index == 4){//黑将
this.labelChess[index].setIcon(this.imageIconChess[0]);
this.mapChess[index].put("color", "0");
this.mapChess[index].put("type", "king");
this.mapChess[index].put("name", "0");
this.mapChess[index].put("number", "");
}else if (index == 9 || index == 10){//黑炮n
this.labelChess[index].setIcon(this.imageIconChess[5]);
this.mapChess[index].put("color", "0");
this.mapChess[index].put("type", "cannon");
this.mapChess[index].put("name", "黑炮");
this.mapChess[index].put("number", Integer.toString(index - 8));
}else if (index > 10 && index < 16){//黑卒n
this.labelChess[index].setIcon(this.imageIconChess[6]);
this.mapChess[index].put("color", "0");
this.mapChess[index].put("type", "soldier");
this.mapChess[index].put("name", "黑卒");
this.mapChess[index].put("number", Integer.toString(index - 10));
}else if (index >= 16 && index < 21) {//红兵n
this.labelChess[index].setIcon(this.imageIconChess[13]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","soldier");
this.mapChess[index].put("name","红兵");
this.mapChess[index].put("number",Integer.toString(index - 15));
} else if (index == 21 || index == 22) {//红炮n
this.labelChess[index].setIcon(this.imageIconChess[12]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","cannon");
this.mapChess[index].put("name","红炮");
this.mapChess[index].put("number",Integer.toString(index - 20));
} else if (index == 23) {//红车1
this.labelChess[index].setIcon(this.imageIconChess[11]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","rook");
this.mapChess[index].put("name","红车");
this.mapChess[index].put("number","1");
} else if (index == 31) {//红车2
this.labelChess[index].setIcon(this.imageIconChess[11]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","rook");
this.mapChess[index].put("name","红车");
this.mapChess[index].put("number","2");
} else if (index == 24) {//红马1
this.labelChess[index].setIcon(this.imageIconChess[10]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","horse");
this.mapChess[index].put("name","红马");
this.mapChess[index].put("number","1");
} else if (index == 30) {//红马2
this.labelChess[index].setIcon(this.imageIconChess[10]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","horse");
this.mapChess[index].put("name","红马");
this.mapChess[index].put("number","2");
} else if (index == 25) {//红相1
this.labelChess[index].setIcon(this.imageIconChess[9]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","elephant");
this.mapChess[index].put("name","红相");
this.mapChess[index].put("number","1");
} else if (index == 29) {//红相2
this.labelChess[index].setIcon(this.imageIconChess[9]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","elephant");
this.mapChess[index].put("name","红相");
this.mapChess[index].put("number","2");
} else if (index == 26) {//红仕1
this.labelChess[index].setIcon(this.imageIconChess[8]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","guard");
this.mapChess[index].put("name","红仕");
this.mapChess[index].put("number","1");
} else if (index == 28) {//红仕2
this.labelChess[index].setIcon(this.imageIconChess[8]);
this.mapChess[index].put("color","255");
this.mapChess[index].put("type","guard");
this.mapChess[index].put("name","红仕");
this.mapChess[index].put("number","2");
} else if (index == 27) {//红帅
this.labelChess[index].setIcon(this.imageIconChess[7]);
this.mapChess[index].put("color", "255");
this.mapChess[index].put("type", "king");
this.mapChess[index].put("name", "红帅");
this.mapChess[index].put("number", "");
}
this.labelChess[index].addMouseListener(this);
this.labelChess[index].addMouseMotionListener(this);
this.panelChess.add(this.labelChess[index],JLayeredPane.DRAG_LAYER);
}
}
/**
*功能:右边功能区布局
*/
private void option()
{
//logo图片
JLabel labelLogo = new JLabel(this.imageIconLogo);
labelLogo.setBounds(this.panelChess.getWidth() + 20,4,100,50);
this.add(labelLogo);
//对战方式
JLabel jlb_fightType = new JLabel("对战方式:");
jlb_fightType.setFont(new Font("微软雅黑",Font.PLAIN,12));
jlb_fightType.setBounds(this.panelChess.getWidth() + 22,60,100,24);
this.add(jlb_fightType);
this.jcb_fightType = new JComboBox<String>(new String[]{"人机对战","人人对战"});
this.jcb_fightType.setBackground(Color.WHITE);
this.jcb_fightType.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jcb_fightType.setBounds(this.panelChess.getWidth() + 22,90,100,24);
this.add(this.jcb_fightType);
//谁先手
JLabel jlb_playFirst = new JLabel("先手选择:");
jlb_playFirst.setBounds(this.panelChess.getWidth() + 22,120,100,24);
jlb_playFirst.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.add(jlb_playFirst);
this.jcb_playFirst = new JComboBox<String>(new String[]{"玩家先手","电脑先手"});
this.jcb_playFirst.setBackground(Color.WHITE);
this.jcb_playFirst.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jcb_playFirst.setBounds(this.panelChess.getWidth() + 22,150,100,24);
this.add(this.jcb_playFirst);
//谁执红
JLabel jlb_chessColor = new JLabel("红黑选择:");
jlb_chessColor.setBounds(this.panelChess.getWidth() + 22,180,100,24);
jlb_chessColor.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.add(jlb_chessColor);
this.jcb_chessColor = new JComboBox<String>(new String[]{"玩家执红","玩家执黑"});
this.jcb_chessColor.setBackground(Color.WHITE);
this.jcb_chessColor.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jcb_chessColor.setBounds(this.panelChess.getWidth() + 22,210,100,24);
this.jcb_chessColor.addActionListener(this);
this.jcb_chessColor.setActionCommand("chessColor");
this.add(this.jcb_chessColor);
//按钮
this.jb_new = new JButton("开始游戏");
this.jb_new.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jb_new.setBounds(this.panelChess.getWidth() + 22,250,100,30);
this.jb_new.setActionCommand("newGame");
this.jb_new.addActionListener(this);
this.add(this.jb_new);
this.jb_undo = new JButton("我要悔棋");
this.jb_undo.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jb_undo.setBounds(this.panelChess.getWidth() + 22,295,100,30);
this.jb_undo.setActionCommand("undo");
this.jb_undo.addActionListener(this);
this.jb_undo.setEnabled(false);
this.add(this.jb_undo);
this.jb_surrender = new JButton("我认输了");
this.jb_surrender.setFont(new Font("微软雅黑",Font.PLAIN,12));
this.jb_surrender.setBounds(this.panelChess.getWidth() + 22,340,100,30);
this.jb_surrender.setActionCommand("surrender");
this.jb_surrender.addActionListener(this);
this.jb_surrender.setEnabled(false);
this.add(this.jb_surrender);
//红棋提示
JPanel groupBoxRed = new JPanel();
groupBoxRed.setLayout(null);
groupBoxRed.setBackground(this.getBackground());
groupBoxRed.setBounds(this.panelChess.getWidth() + 22,380,100,80);
groupBoxRed.setBorder(BorderFactory.createTitledBorder("红棋"));
this.add(groupBoxRed);
JLabel jlb_whiteUndo = new JLabel("悔棋:");
jlb_whiteUndo.setFont(new Font("微软雅黑",Font.PLAIN,12));
jlb_whiteUndo.setBounds(10,16,40,30);
groupBoxRed.add(jlb_whiteUndo);
this.jlb_redUndoText = new JLabel("剩"+Integer.toString(this.redUndoNum)+"次");
this.jlb_redUndoText.setFont(new Font("微软雅黑",Font.BOLD,12));
this.jlb_redUndoText.setForeground(Color.darkGray);
this.jlb_redUndoText.setBounds(44,16,50,30);
groupBoxRed.add(this.jlb_redUndoText);
JLabel jlb_whiteState = new JLabel("状态:");
jlb_whiteState.setFont(new Font("微软雅黑",Font.PLAIN,12));
jlb_whiteState.setBounds(10,44,40,30);
groupBoxRed.add(jlb_whiteState);
this.jlb_redStateText = new JLabel("未开始");
this.jlb_redStateText.setFont(new Font("微软雅黑",Font.BOLD,12));
this.jlb_redStateText.setForeground(Color.darkGray);
this.jlb_redStateText.setBounds(44,44,50,30);
groupBoxRed.add(this.jlb_redStateText);
//黑棋提示
JPanel groupBoxBlack = new JPanel();
groupBoxBlack.setLayout(null);
groupBoxBlack.setBackground(this.getBackground());
groupBoxBlack.setBounds(this.panelChess.getWidth() + 22,465,100,80);
groupBoxBlack.setBorder(BorderFactory.createTitledBorder("黑棋"));
this.add(groupBoxBlack);
JLabel jlb_blackUndo = new JLabel("悔棋:");
jlb_blackUndo.setFont(new Font("微软雅黑",Font.PLAIN,12));
jlb_blackUndo.setBounds(10,16,40,30);
groupBoxBlack.add(jlb_blackUndo);
this.jlb_blackUndoText = new JLabel("剩"+Integer.toString(this.blackUndoNum)+"次");
this.jlb_blackUndoText.setFont(new Font("微软雅黑",Font.BOLD,12));
this.jlb_blackUndoText.setForeground(Color.darkGray);
this.jlb_blackUndoText.setBounds(44,16,50,30);
groupBoxBlack.add(this.jlb_blackUndoText);
JLabel jlb_blackState = new JLabel("状态:");
jlb_blackState.setFont(new Font("微软雅黑",Font.PLAIN,12));
jlb_blackState.setBounds(10,44,40,30);
groupBoxBlack.add(jlb_blackState);
this.jlb_blackStateText = new JLabel("未开始");
this.jlb_blackStateText.setFont(new Font("微软雅黑",Font.BOLD,12));
this.jlb_blackStateText.setForeground(Color.darkGray);
this.jlb_blackStateText.setBounds(44,44,50,30);
groupBoxBlack.add(this.jlb_blackStateText);
}
/**
* 功能:绘图<br>
*/
@Override
public void paint(Graphics g)
{
//调用父类,让其做一些事前的工作,如刷新屏幕等
super.paint(g);
//因为要画一些特殊效果,所以要用Graphics2D
Graphics2D g2D = (Graphics2D)g;
//开始画棋盘
String[] tip = {" 0"," 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9"}; //行列坐标,有利于编程是查看定位
g2D.setColor(Color.black);
for(int row=0;row<this.gridRows;row++)
{
//g2D.drawLine(this.gridsLeftX,this.gridsTopY + row * this.gridSize,this.gridsLeftX + this.gridsWidth,this.gridsTopY + row * this.gridSize);
g2D.drawString(tip[row],this.gridsLeftX - 30,this.gridsTopY + 4 + row * this.gridSize);
}
for(int column=0;column<this.gridColumns;column++)
{
//g2D.drawLine(this.gridsLeftX + column * this.gridSize,this.gridsTopY,this.gridsLeftX + column * this.gridSize,this.gridsTopY + this.gridsHeight);
g2D.drawString(tip[column],this.gridsLeftX - 2 + column * this.gridSize,this.gridsTopY - 20);
}
//画移动指示器
if(this.mapPointerMove.get("show") == 1)
{
if(this.mapPointerMove.get("color") == this.BLACKCHESS)
{
g2D.setColor(Color.BLACK);
}
else if(this.mapPointerMove.get("color") == this.REDCHESS)
{
g2D.setColor(Color.RED);
}
else
{
g2D.setColor(Color.GREEN);
}
g2D.setStroke(new BasicStroke(3.5f));
//先以交叉点为中心取到指示器周围的4个角坐标
//中心点坐标
int x = this.gridsLeftX + this.mapPointerMove.get("column") * this.gridSize;
int y = this.gridsTopY + this.mapPointerMove.get("row") * this.gridSize;
//左上角坐标,并向下向右画线
int x1 = x - this.chessSize / 2;
int y1 = y - this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);
g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);
//右上角坐标,并向下向左画线
x1 = x + this.chessSize / 2;
y1 = y - this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);
g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);
//左下角坐标,并向上向右画线
x1 = x - this.chessSize / 2;
y1 = y + this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);
g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);
//右下角坐标,并向上向左画线
x1 = x + this.chessSize / 2;
y1 = y + this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);
g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);
//System.out.println("("+this.mapPointerChess.get("x")+","+this.mapPointerChess.get("y")+")");
}
//画落子指示器
if(this.mapPointerChess.get("show") == 1)
{
if(this.mapPointerChess.get("color") == this.BLACKCHESS)
{
g2D.setColor(Color.BLACK);
}
else
{
g2D.setColor(Color.RED);
}
g2D.setStroke(new BasicStroke(3.5f));
//先以交叉点为中心取到指示器周围的4个角坐标
//中心点坐标
int x = this.gridsLeftX + this.mapPointerChess.get("column") * this.gridSize;
int y = this.gridsTopY + this.mapPointerChess.get("row") * this.gridSize;
//左上角坐标,并向下向右画线
int x1 = x - this.chessSize / 2;
int y1 = y - this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);
g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);
//右上角坐标,并向下向左画线
x1 = x + this.chessSize / 2;
y1 = y - this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 + this.chessSize / 4);
g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);
//左下角坐标,并向上向右画线
x1 = x - this.chessSize / 2;
y1 = y + this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);
g2D.drawLine(x1,y1,x1 + this.chessSize / 4,y1);
//右下角坐标,并向上向左画线
x1 = x + this.chessSize / 2;
y1 = y + this.chessSize / 2;
g2D.drawLine(x1,y1,x1,y1 - this.chessSize / 4);
g2D.drawLine(x1,y1,x1 - this.chessSize / 4,y1);
//System.out.println("("+this.mapPointerChess.get("x")+","+this.mapPointerChess.get("y")+")");
}
//画可移动线路图
if(this.listMove.size() > 0)
{
g2D.setColor(Color.BLUE);
for(int i=0;i<this.listMove.size();i++)
{
Map<String,Integer> map = this.listMove.get(i);
int row = map.get("row");
int column = map.get("column");
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); //消除画图锯齿
g2D.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT); //追求速度或质量
g2D.fillArc(this.gridsLeftX + column * this.gridSize - 5,this.gridsTopY + row * this.gridSize - 5,10,10,0,360);
}
}
}
/**
* 功能:开始新游戏<br>
*/
public void newGame()
{
//初始化游戏
this.initGame();
//设置控件状态
this.setComponentState(true);
//设置游戏结束标识
this.isGameOver = false;
//电脑先手
if(this.fightType == 0 && this.playFirst == 2)
{
this.gameLogic.computerPlay();
}
}
/**
* 功能:悔棋<br>
*/
public void undo()
{
this.gameLogic.undo();
}
/**
* 功能:投降<br>
*/
public void surrender()
{
if(this.isGameOver){return;}
JOptionPane.showMessageDialog(null,"啥,认输了,还能再有点出息不!");
this.isGameOver = true;
this.setComponentState(false);
this.jlb_blackStateText.setText("已结束");
this.jlb_redStateText.setText("已结束");
}
/**
* 功能:功能监听<br>
*/
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if("newGame".equals(command)) {
this.newGame();
} else if("undo".equals(command)) {
this.undo();
} else if("surrender".equals(command)) {
this.surrender();
} else if("chessColor".equals(command)) {
if("玩家执黑".equals(this.jcb_chessColor.getSelectedItem().toString()))
{
this.chessColor = this.BLACKCHESS;
}
else
{
this.chessColor = this.REDCHESS;
}
this.initChess();
}
}
/**
* 功能:鼠标点击事件监听<br>
*/
@Override
public void mouseClicked(MouseEvent e) {
this.gameLogic.mouseClicked(e);
}
/**
* 功能:鼠标移动事件监听<br>
*/
@Override
public void mouseMoved(MouseEvent e) {
this.gameLogic.mouseMoved(e);
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
}
}
//
package com.gui.chess;
/*
2023.4.4/4.5/4.6/4.7/4.8
中国象棋的主程序类 借鉴作者CSDN--我是小木鱼
*/
public class Chess {
public static void main(String[] args) {
//启动程序
new GameFrame();
}
}
__EOF__

本文作者:CaiDingChao
本文链接:https://www.cnblogs.com/CaiDingChao/p/17718092.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/CaiDingChao/p/17718092.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!