Java游戏开发 —— 象棋

Java游戏开发 —— 象棋_第1张图片

公司来活了,忙,暂时没空写完象棋AI这块,等以后再完善吧!

引言:

        象棋的代码实现有点复杂,尤其是计算机的AI算法,在网上找了很多资料,费了好半天劲才弄明白其实现的原理,真的挺开阔思路的,很有意思!

思路:
        1、创建主窗口,加载菜单及游戏面板。

        2、在游戏面板中初始化各种参数,并建立各种功能组件。

       3、利用标签图像做棋子,并结合paint()函数。

        4、利用mouseMoved()鼠标移动函数设置落子指示器的位置。

        5、利用mouseClicked()鼠标单击函数来判断是否可以下棋,由哪方来下,判断是否平局或胜利。如果是人机对战要计算电脑要下棋的最佳位置。

        6、游戏结束,收尾,准备下一局。

代码: 

Java游戏开发 —— 象棋_第2张图片

图片位置与包位置平齐,因为我装载图片时是从类路径开始取,取绝对路径是不认可的。

 

 本游戏用的是JDK1.8,编码UTF-8;

        共有4个类,Chess.java是游戏入口类。GameFrame.java是主窗口类。GamePanel.java是游戏面板类。GameLogic.java是游戏逻辑类。先一口气把所有的代码贴上来再说。

        1、Chess.java 游戏入口类

package com.game.chess;

/**
 * 功能:中国象棋
* 作者:我是小木鱼(Lag)
*/ 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;

/**
 * 功能:游戏窗口
* 作者:我是小木鱼(Lag)
*/ public class GameFrame extends JFrame implements ActionListener { private static final long serialVersionUID = -3812892829859080331L; /** 游戏面板 */ private GamePanel gamePanel; /** * 功能:构造函数
*/ 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); } } /** * 功能:事件监听
*/ @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;

/**
 * 功能:游戏面板
* 作者:我是小木鱼(Lag)
*/ 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]; /** * 棋子信息数组
* index -> 棋子索引
* color -> 棋子颜色(0-黑棋,255-红棋)
* type -> 棋子类型(rook、horse、elephant、guard、king、cannon、soldier)
* name -> 棋子名字(黑车、黑马、黑象、黑士、黑将、黑炮、黑卒、红兵、红炮、红车、红马、红相、红仕、红帅)
* number -> 棋子小标号(如卒1卒2中的1与2)
* direction -> 棋子方向(T-上方,B-下方)
* oldOldRow -> 棋子大上次行位置
* oldOldColumn -> 棋子大上次列位置
* oldRow -> 棋子上次行位置
* oldColumn -> 棋子上次列位置
* newRow -> 棋子本次行位置
* newColumn -> 棋子本次列位置
* dead -> 棋子是否处于死亡状态(T-死亡,F-活着)
* oldEatIndex -> 上次被其吃棋子下标
* eatIndex -> 本次被其吃棋子下标
*/ @SuppressWarnings("unchecked") //数组不支持泛型 Map[] 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> listChess = new ArrayList>(); /** 移动线路图信息 */ List> listMove = new ArrayList>(); /** 组合框控件 */ private JComboBox 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 firstClickChess = null; /** * 落子指示器
* row -> 行坐标
* column -> 列坐标
* show -> 是否显示(0-不显示,1-显示)
* color -> 颜色(0-黑,255-红)
*/ Map mapPointerChess = new HashMap(); /** * 移动指示器
* row -> 行坐标
* column -> 列坐标
* show -> 是否显示(0-不显示,1-显示)
* color -> 颜色(-1-默认,0-黑,255-红)
*/ Map mapPointerMove = new HashMap(); /** 判断游戏是否结束(true-结束,false-未结束) */ boolean isGameOver = true; /** * 功能:构造函数
*/ 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(); } /** * 功能:加载图片
* 备注:考虑Jar包问题,所以图片路径用URL格式
*/ 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 */ 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(); } /** * 功能:布局棋子
*/ private void initChess() { //先按默认设置棋子信息(玩家执红:红方在下,黑方在上) for(int index=0;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列,Y->行) for(int index=0;index * 参数: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(); 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); //最高层 } } /** * 功能:右边功能区布局
*/ 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(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(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(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); } /** * 功能:绘图
*/ @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 0) { g2D.setColor(Color.BLUE); for(int i=0;i 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); } } } /** * 功能:开始新游戏
*/ public void newGame() { //初始化游戏 this.initGame(); //设置控件状态 this.setComponentState(true); //设置游戏结束标识 this.isGameOver = false; //电脑先手 if(this.fightType == 0 && this.playFirst == 2) { this.gameLogic.computerPlay(); } } /** * 功能:悔棋
*/ public void undo() { this.gameLogic.undo(); } /** * 功能:投降
*/ public void surrender() { if(this.isGameOver){return;} JOptionPane.showMessageDialog(null,"啥,认输了,还能再有点出息不!"); this.isGameOver = true; this.setComponentState(false); this.jlb_blackStateText.setText("已结束"); this.jlb_redStateText.setText("已结束"); } /** * 功能:功能监听
*/ @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(); } } /** * 功能:鼠标点击事件监听
*/ @Override public void mouseClicked(MouseEvent e) { this.gameLogic.mouseClicked(e); } /** * 功能:鼠标移动事件监听
*/ @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;

/**
 * 功能:游戏逻辑
* 作者:我是小木鱼(Lag)
*/ public class GameLogic { /** 游戏面板 */ GamePanel gamePanel; /** 最大搜索深度 */ int Maxdepth = 2; Map mapNextChess = new HashMap(); public GameLogic(GamePanel _gamePanel) { this.gamePanel = _gamePanel; } /** * 功能:得到X像素所对应的列坐标
*/ 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像素所对应的行坐标
*/ 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; } /** * 功能:判断下一步是红棋下还是黑棋下
*/ private int getNextChessColor() { int chessColor = -1; //得到上一步信息 if(this.gamePanel.listChess.size() > 0) { Map 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; } /** * 功能:将军提示
*/ private void check() { //全体循环,不知道将哪头的军 for(int i=0;i 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(); } /** * 功能:判断棋子是否可以放到目标位置
* 参数:_mapChess -> 棋子
* 参数:_newRow -> 目标行位置
* 参数:_newColumn -> 目标列位置
* 备注:点空位或对方棋子上,已方棋子略
*/ private boolean isAbleToMove(Map _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 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 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; } /** * 功能:将下完的棋子信息复制一份存储到下棋列表中,悔棋用
* 备注:因为是对象引用,所以必须复制b
*/ private void addList(Map _mapChess) { Map map = new HashMap(); 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); } /** * 功能:悔棋具体步骤
*/ private void undoStep() { if(this.gamePanel.isGameOver){return;} if(this.gamePanel.listChess.size() < 1){return;} //得到最后一步棋信息 Map 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); } /** * 功能:悔棋
*/ public boolean undo() { int index,color,oldRow,oldColumn; Map 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; } /** * 功能:对当前局面进行估分
* 备注:若电脑下的棋则(电脑分-玩家分),反之(玩家分-电脑分)
*/ 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 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 */ 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= 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; //返回最大值 } /** * 功能:轮到电脑下棋了
*/ 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(); } /** * 功能:得到某棋子的可移动路线图
*/ private void getMoveRoute(Map _mapChess) { this.gamePanel.listMove.clear(); //懒得分类挑,反正电脑计算快 for(int row=0;row map = new HashMap(); map.put("row",row); map.put("column",column); this.gamePanel.listMove.add(map); } } } } /** * 功能:判断游戏是否结束
*/ 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; } /** * 功能:棋子移动到新位置
*/ private void moveTo(Map _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; } /** * 功能:鼠标单击事件
*/ 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; } } } } } } } /** * 功能:鼠标移动事件
*/ 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(); } } } }

详解: 
 

运行: 
        

下载: 

网盘链接:https://pan.baidu.com/s/1pZIvRxpUZ6-1_4WOtlGiVw 提取码:1y3w
        

感言: 
 

你可能感兴趣的:(Java小游戏合集,java,游戏开发)