Java象棋

我首先定义了一个棋子类,该类保存棋子的一些信息


public class Stone
{

    int _row;//行
    int _col;//列
    TYPE _type;//类型
    boolean _dead;//生存状态
    boolean _red;//是否是红方
    int _id;
    
    public Stone()
    {
	
    }
   

    static enum TYPE{CHE, MA, PAO, BING, JIANG, SHI, XIANG};

    //用来后面初始化每一颗棋子信息
    class Pos{
    	int row,col;
    	TYPE type;
		public Pos(int row, int col, TYPE type) {
			super();
			this.row = row;
			this.col = col;
			this.type = type;
		}
    };
    
    
    void init(int id)//用以初始化红方棋子
    {
    
    	Pos [] pos = new Pos[] {
    			new Pos(0, 0, TYPE.CHE),
    			new Pos(0, 1, TYPE.MA),
    		    new Pos(0, 2, TYPE.XIANG),
    		    new Pos(0, 3, TYPE.SHI),
    		    new Pos(0, 4, TYPE.JIANG),
    		    new Pos(0, 5, TYPE.SHI),
    		    new Pos(0, 6, TYPE.XIANG),
    		    new Pos(0, 7, TYPE.MA),
    		    new Pos(0, 8, TYPE.CHE),

    		    new Pos(2, 1, TYPE.PAO),
    		    new Pos(2, 7, TYPE.PAO),
    		    new Pos(3, 0, TYPE.BING),
    		    new Pos(3, 2, TYPE.BING),
    		    new Pos(3, 4, TYPE.BING),
    		    new Pos(3, 6, TYPE.BING),
    		    new Pos(3, 8, TYPE.BING),
    	};
    	
    	//把信息正式赋给
    	if(id < 16)
        {
            this._col = pos[id].col;
            this._row = pos[id].row;
            this._type = pos[id].type;
        }
        else
        {
            this._col = 8-pos[id-16].col;
            this._row = 9-pos[id-16].row;
            this._type = pos[id-16].type;
        }

        this._dead = false;
        this._red = id<16;
    }
    
    
    void rotate()//初始化黑方棋子
    {
    	this._col = 8-this._col;
        this._row = 9-this._row;
    }
    

    String name()
    {
    	switch(this._type)
        {
        case CHE:
            return "车";
        case MA:
            return "马";
        case PAO:
            return "炮";
        case BING:
            return "兵";
        case JIANG:
            return "将";
        case SHI:
            return "士";
        case XIANG:
            return "相";
        }
        return "错误";
    }

}


棋子的基本信息处理好后,我开始画棋盘了,后面我还会对棋盘类进行功能扩充


import java.awt.*;
import java.awt.event.PaintEvent;
import java.util.Vector;

import javax.swing.Painter;

import org.w3c.dom.css.Rect;

public class Board extends Frame{
	Stone [] _s;
    int _r;//棋子的半径
    boolean _bSide;
    //Vector<Step> _steps;//保存步骤
    int _selectid;//被选中的棋子id
    boolean _bRedTurn;//是否轮到红棋
    Point START;
    
    public Board(String title)
    {
       super(title); 
       _s = new Stone[33];
       for(int i = 0;i < 32;++i)
    	   _s[i] = new Stone();
       _r = 20;
       START = new Point(_r+20,_r+50);
       setSize(_r*28+1, _r*25+1);
       setVisible(true);
       initChess(true);
          
    }
    
    void initChess(boolean bRedSide)//初始化
    {
    	
    	for(int i=0; i<32; ++i)
        {
            _s[i].init(i);
        }
    	
        if(bRedSide)
        {
            for(int i=0; i<32; ++i)
            {
            	_s[i].rotate();
            }
        }

        _selectid = -1;
        _bRedTurn = true;
        _bSide = bRedSide;
        update(null);
    }

    public void paint(Graphics g)
    {
    	
        drawPlate(g);
        drawPlace(g);
        //画棋子
        for(int i=0; i<32; i++)
        {
            drawStone(g, i);
        }
    }
    
    
    //画棋盘
  	void drawPlate(Graphics g)
  	{
  	    for(int i=0; i<10; ++i) //画竖线
  	    {
  	    	Graphics2D g2 = (Graphics2D)g;
  	        if(i==0 || i==9)
  	        {
  				g2.setStroke(new BasicStroke(3.0f));
  	            g2.setColor(Color.black);
  	        }
  	        else
  	        {
  	        	  //g是Graphics对象
  				g2.setStroke(new BasicStroke(1.0f));
  	            g2.setColor(Color.black);
  	        }
  	        g2.drawLine(center(i, 0).x,center(i, 0).y, center(i, 8).x,center(i, 8).y);
  	    }

  	    
  	    for(int i=0; i<9; ++i) //画横线
  	    {
  	    	g.setColor(Color.black);
  	        if(i==0 || i==8)
  	        {
  	        	Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  				g2.setStroke(new BasicStroke(3.0f));
  	            g2.setColor(Color.black);
  	            g2.drawLine(center(0, i).x,center(0, i).y, center(9, i).x,center(9, i).y);
  	        }
  	        else
  	        {
  	        	Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  				g2.setStroke(new BasicStroke(1.0f));
  	            g2.setColor(Color.black);
  	            g2.drawLine(center(0, i).x,center(0, i).y, center(4, i).x,center(4, i).y);
  	            g2.drawLine(center(5, i).x,center(5, i).y, center(9, i).x,center(9, i).y);
  	        }
  	    }
  	}


  	//画宫殿
  	void drawPlace(Graphics g)
  	{
  		Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  		g2.setStroke(new BasicStroke(3.0f));
          g2.setColor(Color.black);
  	    g2.drawLine(center(0, 3).x,center(0, 3).y, center(2, 5).x,center(2, 5).y);
  	    g2.drawLine(center(2, 3).x,center(2, 3).y, center(0, 5).x, center(0, 5).y);

  	    g2.drawLine(center(9, 3).x,center(9, 3).y, center(7, 5).x,center(7, 5).y);
  	    g2.drawLine(center(7, 3).x,center(7, 3).y, center(9, 5).x,center(9, 5).y);
  	}
  	
    Point center(int row, int col)
    {
          Point pt = new Point(_r*col*2, _r*row*2);
          return new Point(pt.x+START.x,pt.y+START.y);
    }

    
    void drawStone(Graphics g, int id)//绘制棋子
    {
    	boolean flag = true;
    	boolean isRed = true;
    	if(isDead(id)) return;

        Color color;
        if(red(id)) isRed = true;
        else isRed = false;
        if(isRed)
            g.setColor(Color.red);
        else
        	g.setColor(Color.black);
        if(id == _selectid) flag = false;
        else flag = true;

        Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
		g2.setStroke(new BasicStroke(3.0f));
        //画棋子的边框
        g2.drawOval(cell(id).x,cell(id).y,cell(id).width,cell(id).height);
        if(flag)
        {
        	g.setColor(Color.yellow);
        }
        else
        	g.setColor(Color.gray);
        //填充棋子颜色
        g.fillOval(cell(id).x,cell(id).y,cell(id).width,cell(id).height);
        
        //填充文字
        g.setFont(new Font("隶书", Font.PLAIN, 27));
        if(isRed)
            g.setColor(Color.red);
        else
        	g.setColor(Color.black);
        g.drawString(_s[id].name(),cell(id).x+5,cell(id).y+25);
        System.out.println("hello");
        
    }
    
    Point center(int id)
    {
    	return center(_s[id]._row, _s[id]._col);
    }
    
    boolean red(int id)
    {
    	return _s[id]._red;
    }
    
    
    boolean isDead(int id)//判断是否被吃
    {
    	if(id == -1) return true;
        return _s[id]._dead;	
    }
    
    boolean Select(int id)
    {
    	return _bRedTurn == _s[id]._red;
    }

    
    Point topLeft(int row, int col)
    {
    	return new Point(center(row, col).x-_r,center(row, col).y-_r);
    }
    
    Point topLeft(int id)
    {
    	return new Point(center(id).x-_r,center(id).y-_r);
    }
    
    Rectangle cell(int row, int col)
    {
    	return new Rectangle(topLeft(row, col).x,topLeft(row, col).y, _r*2-1, _r*2-1);
    }
    
    //返回的是棋子的大小和位置
    Rectangle cell(int id)
    {
    	return new Rectangle(topLeft(id).x,topLeft(id).y, _r*2-1, _r*2-1);
    }
    
}

 这里为了增加悔棋功能(Step.java)


public class Step {
	int _moveid;//移动棋子的id
    int _killid;//即将被杀死棋子的id
    int _rowFrom;//起始位置
    int _colFrom;
    int _rowTo;//要到达的位置
    int _colTo;
}

下面就是对象棋逻辑代码的编写了,首先我们需要一个点击事件来监听,然后把鼠标点击处的坐标传给getRowCol得到其行列号,注意这里有一点很巧妙(我通过行列和坐标的关系,把坐标转化为行列,然后来查找象棋的id属性),下面是象棋的逻辑代码思路

public void mousePressed(MouseEvent ev)// 接口方法,负责鼠标拖动棋子走棋过程中的动作响应
	{
    	if(ev.getButton() != MouseEvent.BUTTON1)
        {
            return;
        }
    	
        click(ev.getPoint());
	}
   

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Enter");
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Exited");
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Released");
	}

	void click(Point pt)
    {
    	int row = 0, col = 0;
    	Point p;
        p = getClickRowCol(pt, row, col);
        if(p == null)
        {
        	row = -1;
        	col = -1;
        }
        	
        else
        {
        	row = p.x; col = p.y;
        	System.out.println("Before pos->x"+p.x+"  pos->y"+p.y);
        }
        
        int id = getChessId(row, col);
        System.out.println("Before chess->id "+id);
        System.out.println("------------------------------------");
        click(id, row, col);
    }
    
    int getChessId(int row, int col)
    {
        for(int i=0; i<32; ++i)
        {
            if(_s[i]._row == row && _s[i]._col == col && !isDead(i))
                return i;
        }
        return -1;
    }
    
    //获取点击点的行列
    Point getClickRowCol(Point pt, int row, int col)
    {
        for(row=0; row<=9; ++row)
        {
            for(col=0; col<=8; ++col)
            {
                Point distance = new Point(center(row, col).x-pt.x,center(row, col).y-pt.y);
                if(distance.x * distance.x + distance.y * distance.y < _r* _r)
                    return new Point(row,col);
            }
        }
        return null;
    }
    
    void click(int id, int row, int col)
    {
    	if(this._selectid == -1)
        {
            trySelectStone(id);
        }
        else
        {
            tryMoveStone(id, row, col);
        }
    }
    
    void trySelectStone(int id)
    {
        if(id == -1)
            return;

         //是否符合当前方棋子
        if(_bRedTurn != _s[id]._red) return;

        _selectid = id;
        //重绘事件
        repaint();
    }

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
    
    //尝试移动棋子
    void tryMoveStone(int killid, int row, int col)
    {
        //选择了同一方棋子,换选中的棋子
        if(killid != -1 && sameColor(killid, _selectid))
        {
            trySelectStone(killid);
            return;
        }

        //判断能否移动
        boolean ret = Move(_selectid, killid, row, col);
        if(ret)
        {
        	System.out.println("killid->id "+killid);
            moveStone(_selectid, killid, row, col);
            _selectid = -1;
            //调用重绘事件
            repaint();
        }
    }
    

     //判断两个棋子是否相同颜色
	boolean sameColor(int id1, int id2)
	{
	      if(id1 == -1 || id2 == -1) return false;
	
	      return red(id1) == red(id2);
	}
	
    boolean Move(int moveid, int killid, int row, int col)
    {
        if(sameColor(moveid, killid)) return false;

        switch (_s[moveid]._type)
        {
        case CHE:
            return MoveChe(moveid, killid, row, col);
            
        case MA:
            return MoveMa(moveid, killid, row, col);
            
        case PAO:
            return MovePao(moveid, killid, row, col);

        case BING:
            return MoveBing(moveid, killid, row, col);

        case JIANG:
            return MoveJiang(moveid, killid, row, col);

        case SHI:
            return MoveShi(moveid, killid, row, col);

        case XIANG:
            return MoveXiang(moveid, killid, row, col);
        }
        return false;
    }
   
    
    Point GetRowCol(int _row, int _col1,int _id)
    {
        return new Point(_s[_id]._row,_s[_id]._col);	
    }
    
    
    boolean MoveJiang(int moveid, int killid, int row, int col)
    {
        if(killid != -1 && _s[killid]._type == Stone.TYPE.JIANG)
            return MoveChe(moveid, killid, row, col);

        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 1 && r != 10) return false;

        if(col < 3 || col > 5) return false;
        if(isBottomSide(moveid))
        {
            if(row < 7) return false;
        }
        else
        {
            if(row > 2) return false;
        }
        return true;
    }

    boolean MoveShi(int moveid, int killid, int row, int col)
    {
        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 11) return false;

        if(col < 3 || col > 5) return false;
        if(isBottomSide(moveid))
        {
            if(row < 7) return false;
        }
        else
        {
            if(row > 2) return false;
        }
        return true;
    }

    boolean MoveXiang(int moveid, int killid, int row, int col)
    {
        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 22) return false;

        int rEye = (row+row1)/2;
        int cEye = (col+col1)/2;
        if(getChessId(rEye, cEye) != -1)
            return false;

        if(isBottomSide(moveid))
        {
            if(row < 4) return false;
        }
        else
        {
            if(row > 5) return false;
        }
        return true;
    }
    
    int getStoneCount(int row1, int col1, int row2, int col2)
    {
        int ret = 0;
        if(row1 != row2 && col1 != col2)
            return -1;
        if(row1 == row2 && col1 == col2)
            return -1;

        if(row1 == row2)
        {
            int min = col1 < col2 ? col1 : col2;
            int max = col1 < col2 ? col2 : col1;
            for(int col = min+1; col<max; ++col)
            {
                if(getChessId(row1, col) != -1) ++ret;
            }
        }
        else
        {
            int min = row1 < row2 ? row1 : row2;
            int max = row1 < row2 ? row2 : row1;
            for(int row = min+1; row<max; ++row)
            {
                if(getChessId(row, col1) != -1) ++ret;
            }
        }

        return ret;
    }


    boolean MoveChe(int moveid, int killid, int row, int col)
    {
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int ret = getStoneCount(row1, col1, row, col);
        if(ret == 0)
            return true;
        return false;
    }
    
    boolean MoveMa(int moveid, int killid, int row, int col)
    {
        //获取移动起始位置的坐标
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int r = relation(row1, col1, row, col);
        if(r != 12 && r != 21)
            return false;

        if(r == 12)
        {
            //判断横着走能否走
            if(getChessId(row1, (col+col1)/2) != -1)
                return false;
        }
        else
        {
            if(getChessId((row+row1)/2, col1) != -1)
                return false;
        }

        return true;
    }

    boolean MovePao(int moveid, int killid, int row, int col)
    {
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int ret = getStoneCount(row, col, row1, col1);
        if(killid != -1)
        {
            if(ret == 1) return true;
        }
        else
        {
            if(ret == 0) return true;
        }
        return false;
    }

        
    boolean MoveBing(int moveid, int killid, int row, int col)
    {
    	Point p;
    	int row1 = 0,col1=0;//需要移动棋子的坐标
        p = GetRowCol(row1, col1, moveid);
        row1 = p.x;col1 = p.y;
        System.out.println("moveid->x:"+row1+" moveid->y:"+col1);
        
        int r = relation(row1, col1, row, col);
        if(r != 1 && r != 10) return false;

        if(isBottomSide(moveid))
        {
            if(row > row1) return false;
            if(row1 >= 5 && row == row1) return false;
        }
        else
        {
            if(row < row1) return false;
            if(row1 <= 4 && row == row1) return false;
        }

        return true;
    }


	boolean isBottomSide(int id)
	{
	    return _bSide == _s[id]._red;
	}

    //判断马是否可以走动
    int relation(int row1, int col1, int row, int col)
    {
        return Math.abs(row1-row)*10+Math.abs(col1-col);
    }

    //移动 棋子
    void moveStone(int moveid, int row, int col)
    {
        _s[moveid]._row = row;
        _s[moveid]._col = col;

        _bRedTurn = !_bRedTurn;
    }
    
    //在移动的过程中杀死棋子
    void moveStone(int moveid, int killid, int row, int col)
    {
        saveStep(moveid, killid, row, col, _steps);

        killStone(killid);
        moveStone(moveid, row, col);
    }

    //保存途径,以便悔棋
    void saveStep(int moveid, int killid, int row, int col, Vector<Step> steps)
    {
    	Point p;
    	int row1 = 0,col1=0;//需要移动棋子的坐标
        p = GetRowCol(row1, col1, moveid);
        row1 = p.x;col1 = p.y;
        
        Step step = new Step();
        step._colFrom = col1;
        step._colTo = col;
        step._rowFrom = row1;
        step._rowTo = row;
        step._moveid = moveid;
        step._killid = killid;
        steps.add(step);
        
    }

    //杀死棋子
    void killStone(int id)
    {
        if(id==-1) return;
        _s[id]._dead = true;
    }

然后我把逻辑和前端页面逻辑合并在Board.java


import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.PaintEvent;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.Painter;

import org.w3c.dom.css.Rect;

public class Board extends Frame implements MouseListener{
	Stone [] _s;
    int _r;//棋子的半径
    boolean _bSide;
    int row1,col1;
    Vector<Step> _steps;//保存步骤
    int _selectid;//被选中的棋子id
    boolean _bRedTurn;//是否轮到红棋
    Point START;
    private Image image;
    private Graphics bg;
    
    public Board(String title)
    {
       super(title); 
       _s = new Stone[33];
       _steps = new Vector();
       for(int i = 0;i < 32;++i)
    	   _s[i] = new Stone();
       _r = 20;
       addMouseListener(this);
       START = new Point(_r+20,_r+50);
       setSize(_r*28+1, _r*25+1);
       setVisible(true);
       initChess(true);
          
    }
    
    void initChess(boolean bRedSide)//初始化
    {
    	
    	for(int i=0; i<32; ++i)
        {
            _s[i].init(i);
        }
    	
        if(bRedSide)
        {
            for(int i=0; i<32; ++i)
            {
            	_s[i].rotate();
            }
        }

        _selectid = -1;
        _bRedTurn = true;
        _bSide = bRedSide;
        //update(null);
    }
   
    public void update(Graphics g)
    {
    	if (image == null)
    	{

    	       image = createImage (this.getSize().width, this.getSize().height);
    	       bg = image.getGraphics ();

    	}
    	
    	bg.setColor(getBackground());
        bg.fillRect(0, 0, this.getSize().width,  this.getSize().height);
        paint(bg);
        g.drawImage(image,0,0,this);
    }
    
    public void paint(Graphics g)
    {
    	
    	drawPlate(g);
        drawPlace(g);
        //画棋子
        for(int i=0; i<32; i++)
        {
            drawStone(g, i);
        }
    }
    
    
    //画棋盘
  	void drawPlate(Graphics g)
  	{
  	    for(int i=0; i<10; ++i) //画竖线
  	    {
  	    	Graphics2D g2 = (Graphics2D)g;
  	        if(i==0 || i==9)
  	        {
  				g2.setStroke(new BasicStroke(3.0f));
  	            g2.setColor(Color.black);
  	        }
  	        else
  	        {
  	        	  //g是Graphics对象
  				g2.setStroke(new BasicStroke(1.0f));
  	            g2.setColor(Color.black);
  	        }
  	        g2.drawLine(center(i, 0).x,center(i, 0).y, center(i, 8).x,center(i, 8).y);
  	    }

  	    
  	    for(int i=0; i<9; ++i) //画横线
  	    {
  	    	g.setColor(Color.black);
  	        if(i==0 || i==8)
  	        {
  	        	Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  				g2.setStroke(new BasicStroke(3.0f));
  	            g2.setColor(Color.black);
  	            g2.drawLine(center(0, i).x,center(0, i).y, center(9, i).x,center(9, i).y);
  	        }
  	        else
  	        {
  	        	Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  				g2.setStroke(new BasicStroke(1.0f));
  	            g2.setColor(Color.black);
  	            g2.drawLine(center(0, i).x,center(0, i).y, center(4, i).x,center(4, i).y);
  	            g2.drawLine(center(5, i).x,center(5, i).y, center(9, i).x,center(9, i).y);
  	        }
  	    }
  	}


  	//画宫殿
  	void drawPlace(Graphics g)
  	{
  		Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
  		g2.setStroke(new BasicStroke(3.0f));
          g2.setColor(Color.black);
  	    g2.drawLine(center(0, 3).x,center(0, 3).y, center(2, 5).x,center(2, 5).y);
  	    g2.drawLine(center(2, 3).x,center(2, 3).y, center(0, 5).x, center(0, 5).y);

  	    g2.drawLine(center(9, 3).x,center(9, 3).y, center(7, 5).x,center(7, 5).y);
  	    g2.drawLine(center(7, 3).x,center(7, 3).y, center(9, 5).x,center(9, 5).y);
  	}
  	
    Point center(int row, int col)
    {
          Point pt = new Point(_r*col*2, _r*row*2);
          return new Point(pt.x+START.x,pt.y+START.y);
    }

    
    void drawStone(Graphics g, int id)//绘制棋子
    {
    	boolean flag = true;
    	boolean isRed = true;
    	if(isDead(id)) return;

        Color color;
        if(red(id)) isRed = true;
        else isRed = false;
        if(isRed)
            g.setColor(Color.red);
        else
        	g.setColor(Color.black);
        if(id == _selectid) flag = false;
        else flag = true;

        Graphics2D g2 = (Graphics2D)g;  //g是Graphics对象
		g2.setStroke(new BasicStroke(3.0f));
        //画棋子的边框
        g2.drawOval(cell(id).x,cell(id).y,cell(id).width,cell(id).height);
        if(flag)
        {
        	g.setColor(Color.yellow);
        }
        else
        	g.setColor(Color.gray);
        //填充棋子颜色
        g.fillOval(cell(id).x,cell(id).y,cell(id).width,cell(id).height);
        
        //填充文字
        g.setFont(new Font("隶书", Font.PLAIN, 27));
        if(isRed)
            g.setColor(Color.red);
        else
        	g.setColor(Color.black);
        g.drawString(_s[id].name(),cell(id).x+5,cell(id).y+25);
        
    }
    
    Point center(int id)
    {
    	return center(_s[id]._row, _s[id]._col);
    }
    
    boolean red(int id)
    {
    	return _s[id]._red;
    }
    
    
    boolean isDead(int id)//判断是否被吃
    {
    	if(id == -1) return true;
        return _s[id]._dead;	
    }
    
    boolean Select(int id)
    {
    	return _bRedTurn == _s[id]._red;
    }

    
    Point topLeft(int row, int col)
    {
    	return new Point(center(row, col).x-_r,center(row, col).y-_r);
    }
    
    Point topLeft(int id)
    {
    	return new Point(center(id).x-_r,center(id).y-_r);
    }
    
    Rectangle cell(int row, int col)
    {
    	return new Rectangle(topLeft(row, col).x,topLeft(row, col).y, _r*2-1, _r*2-1);
    }
    
    //返回的是棋子的大小和位置
    Rectangle cell(int id)
    {
    	return new Rectangle(topLeft(id).x,topLeft(id).y, _r*2-1, _r*2-1);
    }
    
    public void mousePressed(MouseEvent ev)// 接口方法,负责鼠标拖动棋子走棋过程中的动作响应
	{
    	if(ev.getButton() != MouseEvent.BUTTON1)
        {
            return;
        }
    	
        click(ev.getPoint());
	}
   

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Enter");
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Exited");
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		System.out.println("Released");
	}

	void click(Point pt)
    {
    	int row = 0, col = 0;
    	Point p;
        p = getClickRowCol(pt, row, col);
        if(p == null)
        {
        	row = -1;
        	col = -1;
        }
        	
        else
        {
        	row = p.x; col = p.y;
        	System.out.println("Before pos->x"+p.x+"  pos->y"+p.y);
        }
        
        int id = getChessId(row, col);
        System.out.println("Before chess->id "+id);
        System.out.println("------------------------------------");
        click(id, row, col);
    }
    
    int getChessId(int row, int col)
    {
        for(int i=0; i<32; ++i)
        {
            if(_s[i]._row == row && _s[i]._col == col && !isDead(i))
                return i;
        }
        return -1;
    }
    
    //获取点击点的行列
    Point getClickRowCol(Point pt, int row, int col)
    {
        for(row=0; row<=9; ++row)
        {
            for(col=0; col<=8; ++col)
            {
                Point distance = new Point(center(row, col).x-pt.x,center(row, col).y-pt.y);
                if(distance.x * distance.x + distance.y * distance.y < _r* _r)
                    return new Point(row,col);
            }
        }
        return null;
    }
    
    void click(int id, int row, int col)
    {
    	if(this._selectid == -1)
        {
            trySelectStone(id);
        }
        else
        {
            tryMoveStone(id, row, col);
        }
    }
    
    void trySelectStone(int id)
    {
        if(id == -1)
            return;

         //是否符合当前方棋子
        if(_bRedTurn != _s[id]._red) return;

        _selectid = id;
        //重绘事件
        repaint();
    }

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
    
    //尝试移动棋子
    void tryMoveStone(int killid, int row, int col)
    {
        //选择了同一方棋子,换选中的棋子
        if(killid != -1 && sameColor(killid, _selectid))
        {
            trySelectStone(killid);
            return;
        }

        //判断能否移动
        boolean ret = Move(_selectid, killid, row, col);
        if(ret)
        {
        	System.out.println("killid->id "+killid);
            moveStone(_selectid, killid, row, col);
            _selectid = -1;
            //调用重绘事件
            repaint();
        }
    }
    

     //判断两个棋子是否相同颜色
	boolean sameColor(int id1, int id2)
	{
	      if(id1 == -1 || id2 == -1) return false;
	
	      return red(id1) == red(id2);
	}
	
    boolean Move(int moveid, int killid, int row, int col)
    {
        if(sameColor(moveid, killid)) return false;

        switch (_s[moveid]._type)
        {
        case CHE:
            return MoveChe(moveid, killid, row, col);
            
        case MA:
            return MoveMa(moveid, killid, row, col);
            
        case PAO:
            return MovePao(moveid, killid, row, col);

        case BING:
            return MoveBing(moveid, killid, row, col);

        case JIANG:
            return MoveJiang(moveid, killid, row, col);

        case SHI:
            return MoveShi(moveid, killid, row, col);

        case XIANG:
            return MoveXiang(moveid, killid, row, col);
        }
        return false;
    }
   
    
    Point GetRowCol(int _row, int _col1,int _id)
    {
        return new Point(_s[_id]._row,_s[_id]._col);	
    }
    
    
    boolean MoveJiang(int moveid, int killid, int row, int col)
    {
        if(killid != -1 && _s[killid]._type == Stone.TYPE.JIANG)
            return MoveChe(moveid, killid, row, col);

        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 1 && r != 10) return false;

        if(col < 3 || col > 5) return false;
        if(isBottomSide(moveid))
        {
            if(row < 7) return false;
        }
        else
        {
            if(row > 2) return false;
        }
        return true;
    }

    boolean MoveShi(int moveid, int killid, int row, int col)
    {
        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 11) return false;

        if(col < 3 || col > 5) return false;
        if(isBottomSide(moveid))
        {
            if(row < 7) return false;
        }
        else
        {
            if(row > 2) return false;
        }
        return true;
    }

    boolean MoveXiang(int moveid, int killid, int row, int col)
    {
        GetRowCol(row1, col1, moveid);
        int r = relation(row1, col1, row, col);
        if(r != 22) return false;

        int rEye = (row+row1)/2;
        int cEye = (col+col1)/2;
        if(getChessId(rEye, cEye) != -1)
            return false;

        if(isBottomSide(moveid))
        {
            if(row < 4) return false;
        }
        else
        {
            if(row > 5) return false;
        }
        return true;
    }
    
    int getStoneCount(int row1, int col1, int row2, int col2)
    {
        int ret = 0;
        if(row1 != row2 && col1 != col2)
            return -1;
        if(row1 == row2 && col1 == col2)
            return -1;

        if(row1 == row2)
        {
            int min = col1 < col2 ? col1 : col2;
            int max = col1 < col2 ? col2 : col1;
            for(int col = min+1; col<max; ++col)
            {
                if(getChessId(row1, col) != -1) ++ret;
            }
        }
        else
        {
            int min = row1 < row2 ? row1 : row2;
            int max = row1 < row2 ? row2 : row1;
            for(int row = min+1; row<max; ++row)
            {
                if(getChessId(row, col1) != -1) ++ret;
            }
        }

        return ret;
    }


    boolean MoveChe(int moveid, int killid, int row, int col)
    {
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int ret = getStoneCount(row1, col1, row, col);
        if(ret == 0)
            return true;
        return false;
    }
    
    boolean MoveMa(int moveid, int killid, int row, int col)
    {
        //获取移动起始位置的坐标
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int r = relation(row1, col1, row, col);
        if(r != 12 && r != 21)
            return false;

        if(r == 12)
        {
            //判断横着走能否走
            if(getChessId(row1, (col+col1)/2) != -1)
                return false;
        }
        else
        {
            if(getChessId((row+row1)/2, col1) != -1)
                return false;
        }

        return true;
    }

    boolean MovePao(int moveid, int killid, int row, int col)
    {
    	int row1=0,col1=0;
        Point p = GetRowCol(row1, col1, moveid);
        //如果移动的位置上有棋子则不能移动
        row1 = p.x;col1 = p.y;
        int ret = getStoneCount(row, col, row1, col1);
        if(killid != -1)
        {
            if(ret == 1) return true;
        }
        else
        {
            if(ret == 0) return true;
        }
        return false;
    }

        
    boolean MoveBing(int moveid, int killid, int row, int col)
    {
    	Point p;
    	int row1 = 0,col1=0;//需要移动棋子的坐标
        p = GetRowCol(row1, col1, moveid);
        row1 = p.x;col1 = p.y;
        System.out.println("moveid->x:"+row1+" moveid->y:"+col1);
        
        int r = relation(row1, col1, row, col);
        if(r != 1 && r != 10) return false;

        if(isBottomSide(moveid))
        {
            if(row > row1) return false;
            if(row1 >= 5 && row == row1) return false;
        }
        else
        {
            if(row < row1) return false;
            if(row1 <= 4 && row == row1) return false;
        }

        return true;
    }


	boolean isBottomSide(int id)
	{
	    return _bSide == _s[id]._red;
	}

    //判断马是否可以走动
    int relation(int row1, int col1, int row, int col)
    {
        return Math.abs(row1-row)*10+Math.abs(col1-col);
    }

    //移动 棋子
    void moveStone(int moveid, int row, int col)
    {
        _s[moveid]._row = row;
        _s[moveid]._col = col;

        _bRedTurn = !_bRedTurn;
    }
    
    //在移动的过程中杀死棋子
    void moveStone(int moveid, int killid, int row, int col)
    {
        saveStep(moveid, killid, row, col, _steps);

        killStone(killid);
        moveStone(moveid, row, col);
    }

    //保存途径,以便悔棋
    void saveStep(int moveid, int killid, int row, int col, Vector<Step> steps)
    {
    	Point p;
    	int row1 = 0,col1=0;//需要移动棋子的坐标
        p = GetRowCol(row1, col1, moveid);
        row1 = p.x;col1 = p.y;
        
        Step step = new Step();
        step._colFrom = col1;
        step._colTo = col;
        step._rowFrom = row1;
        step._rowTo = row;
        step._moveid = moveid;
        step._killid = killid;
        steps.add(step);
        
    }

    //杀死棋子
    void killStone(int id)
    {
        if(id==-1) return;
        _s[id]._dead = true;
    }

}

这里会有一些小问题,就是会出现闪烁现象,所以为解决这个问题,我采用双缓冲技术

源码地址:

https://pan.baidu.com/s/1ky2rJi1asmnwkHfDI0mkag

密码:jgrs

猜你喜欢

转载自blog.csdn.net/qq_40511966/article/details/85067246
今日推荐