引言:
象棋的代码实现有点复杂,尤其是计算机的AI算法,在网上找了很多资料,费了好半天劲才弄明白其实现的原理,真的挺开阔思路的,很有意思!
思路:
1、创建主窗口,加载菜单及游戏面板。
2、在游戏面板中初始化各种参数,并建立各种功能组件。
3、利用标签图像做棋子,并结合paint()函数。
4、利用mouseMoved()鼠标移动函数设置落子指示器的位置。
5、利用mouseClicked()鼠标单击函数来判断是否可以下棋,由哪方来下,判断是否平局或胜利。如果是人机对战要计算电脑要下棋的最佳位置。
6、游戏结束,收尾,准备下一局。
代码:
图片位置与包位置平齐,因为我装载图片时是从类路径开始取,取绝对路径是不认可的。
本游戏用的是JDK1.8,编码UTF-8;
共有4个类,Chess.java是游戏入口类。GameFrame.java是主窗口类。GamePanel.java是游戏面板类。GameLogic.java是游戏逻辑类。先一口气把所有的代码贴上来再说。
1、Chess.java 游戏入口类
package com.game.chess;
/**
* 功能:中国象棋<br>
* 作者:我是小木鱼(Lag)<br>
*/
public class Chess
{
public static void main(String[] args)
{
new GameFrame();
}
}
2、GameFrame.java 主窗口类。
package com.game.chess;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
/**
* 功能:游戏窗口<br>
* 作者:我是小木鱼(Lag)<br>
*/
public class GameFrame extends JFrame implements ActionListener
{
private static final long serialVersionUID = -3812892829859080331L;
/** 游戏面板 */
private GamePanel gamePanel;
/**
* 功能:构造函数<br>
*/
public GameFrame()
{
try
{
//菜单
JMenuBar jmb_gobang = new JMenuBar();
JMenu jm_game = new JMenu("游戏");
jm_game.setFont(new Font("微软雅黑",Font.PLAIN,12));
JMenuItem jmi_game_new = jm_game.add("新游戏");
jmi_game_new.setFont(new Font("微软雅黑",Font.PLAIN,12));
jmi_game_new.addActionListener(this);
jmi_game_new.setActionCommand("new");
JMenuItem jmi_game_undo = jm_game.add("悔棋");
jmi_game_undo.setFont(new Font("微软雅黑",Font.PLAIN,12));
jmi_game_undo.addActionListener(this);
jmi_game_undo.setActionCommand("undo");
JMenuItem jmi_surrender = jm_game.add("认输");
jmi_surrender.setFont(new Font("微软雅黑",Font.PLAIN,12));
jmi_surrender.addActionListener(this);
jmi_surrender.setActionCommand("surrender");
jm_game.addSeparator();
JMenuItem jmi_game_exit = jm_game.add("退出");
jmi_game_exit.setFont(new Font("微软雅黑",Font.PLAIN,12));
jmi_game_exit.addActionListener(this);
jmi_game_exit.setActionCommand("exit");
jmb_gobang.add(jm_game);
JMenu jm_help = new JMenu("帮助");
jm_help.setFont(new Font("微软雅黑",Font.PLAIN,12));
JMenuItem jmi_help_about = jm_help.add("关于");
jmi_help_about.setFont(new Font("微软雅黑",Font.PLAIN,12));
jmi_help_about.addActionListener(this);
jmi_help_about.setActionCommand("about");
jmb_gobang.add(jm_help);
this.setJMenuBar(jmb_gobang);
//面板
this.gamePanel = new GamePanel();
this.add(this.gamePanel);
//显示
this.setTitle("中国象棋");
this.setLayout(null);
this.setSize(666,620);
this.setResizable(false);
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);
System.exit(0);
}
}
/**
* 功能:事件监听<br>
*/
@Override
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
if("new".equals(command))
{
this.gamePanel.newGame();
}
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,"我是小木鱼(Lag)","提示",JOptionPane.INFORMATION_MESSAGE);
}
}
}
3、GamePanel.java 游戏面板类
package com.game.chess;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.BorderFactory;
/**
* 功能:游戏面板<br>
* 作者:我是小木鱼(Lag)<br>
*/
public class GamePanel extends JPanel implements MouseListener,MouseMotionListener,ActionListener
{
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];
/**
* 棋子信息数组<br>
* 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>();
/**
* 移动指示器<br>
* row -> 行坐标<br>
* column -> 列坐标<br>
* show -> 是否显示(0-不显示,1-显示)<br>
* color -> 颜色(-1-默认,0-黑,255-红)<br>
*/
Map<String,Integer> mapPointerMove = new HashMap<String,Integer>();
/** 判断游戏是否结束(true-结束,false-未结束) */
boolean isGameOver = true;
/**
* 功能:构造函数<br>
*/
public GamePanel()
{
//与主窗口大小保持一致,并设置背景色(去掉菜单高度)
this.setSize(666,560);
this.setLayout(null);
//设置象棋面板
this.panelChess = new JLayeredPane();
this.panelChess.setBounds(0,0,504,558);
this.panelChess.setLayout(null);
this.add(this.panelChess);
//加载图片
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); //最底层
//建立棋子标签
this.createChess();
//右边功能区布局
this.option();
//游戏逻辑
this.gameLogic = new GameLogic(this);
//初始化游戏
this.initGame();
}
/**
* 功能:加载图片<br>
* 备注:考虑Jar包问题,所以图片路径用URL格式<br>
*/
private void loadImage()
{
try
{
//棋盘图片
this.imageIconChessBoard = new ImageIcon(new ImageIcon(this.getClass().getResource("/resource/chess/chessBoard.png")).getImage().getScaledInstance(this.panelChess.getWidth(),this.panelChess.getHeight(),Image.SCALE_SMOOTH)); //缩放图片来适应标签大小
//棋子图片
for(int i=0;i<this.imageIconChess.length;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)); //缩放图片来适应标签大小
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* 功能:初始化游戏<br>
*/
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.BLACKCHESS)
{
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();
}
/**
* 功能:布局棋子<br>
*/
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("oldOldColumn","-1");
this.mapChess[index].put("oldRow","-1");
this.mapChess[index].put("oldColumn","-1");
this.mapChess[index].put("dead","F");
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 > 10 && index < 16) //黑卒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","9");
this.mapChess[index].put("newColumn",Integer.toString(index - 23));
}
}
//如果玩家执黑则坐标反过来
if(this.chessColor == this.BLACKCHESS)
{
//棋子信息对调(行变abs(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);
}
}
/**
* 功能:设置控件状态<br>
* 参数:true-新开局;false-未开局<br>
*/
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);
}
}
/**
* 功能:建立棋子标签<br>
*/
private void createChess()
{
for(int index=0;index<this.labelChess.length;index++)
{
this.labelChess[index] = new JLabel();
this.labelChess[index].setName(Integer.toString(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[1]);
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","黑将");
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); //最高层
}
}
/**
* 功能:右边功能区布局<br>
*/
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){}
}
4、GameLogic.java 游戏逻辑类。
package com.game.chess;
import java.util.Map;
import java.util.HashMap;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.event.MouseEvent;
/**
* 功能:游戏逻辑<br>
* 作者:我是小木鱼(Lag)<br>
*/
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();
}
}
}
}