象棋小程序2-棋子移动

本文详细解析了象棋小程序中棋子的移动规则,包括炮、车、马、象、士帅和卒的移动逻辑。对于炮和车,它们的移动规则相同,主要检查移动路径上是否有其他棋子。马和象的移动需要考虑绊腿情况,而士帅只能在田字格内移动。卒的移动则区分了前进和侧移,过河后的卒还可以横向移动。每个棋子的移动方法都详细阐述了坐标判断和绊子规则,实现了符合象棋规则的棋子移动操作。
摘要由CSDN通过智能技术生成

首先为对于炮和车的移动

之所以将二者结合在一起是因为它们的移动方式完全一致,完成了其中一个的移动方法的书写,另外一个方法可以直接调用完成后的该方法.

public void cannonRule(ChessMainBehavior play, ChessMainBehavior playQ[], MouseEvent me, List<ChessRegret> chessRegretList, int man){
        //方法为炮的规则参数1为棋子是谁2所有的棋子作为参数3鼠标事件得到鼠标的点击4列表用于悔棋时记录移动地方5具体是谁走
        int count=0;//记录移动中间有几个棋子
        int cx=me.getX();
        int cy=me.getY()+30;//cx与cy(cy加30为工具栏的高度)分别得到鼠标点击的横纵坐标
        if(cx-play.getX()>=0 &&cx-play.getX()<57){//判断条件是保证为纵向移动其x坐标必须在这个范围内play的getx与gety方法得到的是play图像的左上角横纵坐标
            //这个for循环是为了找到当点击的格子满足和要移动的棋子的x轴相加的坐标范围时对应的是该x范围内的哪一个格子for循环内的i就是该格子对应的y坐标
            for(int i=56;i<=569;i+=57){
                //真正判别点击的点是哪一个格子的条件
                if(cy-i>=0 && cy-i<57){//若满足则得到该cy坐标所对应的是哪个格子
                    //遍历32个棋子
                    for(int j=0;j<32;j++){
                        //判断是否有棋子在要移动棋子的行上面
                        if(playQ[j].getX()==play.getX() &&play.getName()!=playQ[j].getName()&&playQ[j].isVisible()){
                            for(int k=i;k<play.getY();k+=57){//这是代表鼠标点击的位置在要移动棋子的上面(57为格子的大小)
                                //如果在该棋子x轴坐标上的棋子的y轴坐标在鼠标点击的位置与要移动棋子的中间时
                                if(playQ[j].getY()==k){
                                    //令记录中间有多少棋子的变量加一
                                    count++;
                                }
                            }
                            for(int k=play.getY();k<i;k+=57){//这是代表鼠标点击的位置在要移动棋子的下面(57为格子的大小)
                                //具体分析和上方一致
                                if(playQ[j].getY()==k){
                                    count++;
                                }
                            }
                        }
                    }
                    if(count==0){//中间无任何棋子
                        ChessRegret chessRegret=new ChessRegret();
                        chessRegret.man=man;
                        chessRegret.cx=play.getX();
                        chessRegret.cy=play.getY();//此处的x与y都是移动前的棋子的x与y坐标
                        chessRegretList.add(chessRegret);//将移动前的相关信息填入用于悔棋的参数列表中
                        play.setBounds(play.getX(),i,55,55);//i是与鼠标点击的位置恰好对应的格子的左上角的y坐标,将棋子移动到该位置
                        play.playSounds();//移动时放出声音
                        return;//至此上下移动就完成了(不吃棋子的情况)
                    }
                }
            }
        }
        //同上方一致,实现对于炮的左右移动的判断分析过程基本一致
        if(me.getY()-play.getY()+30>=0 && me.getY()-play.getY()+30<57){
            for(int i=24;i<480;i+=57){
                if(me.getX()-i>=0 && me.getX()-i<57){
                    for(int j=0;j<32;j++){
                        if(playQ[j].getY()==play.getY()&&play.getName()!=playQ[j].getName()&&playQ[j].died==false){
                            for(int k=i;k<play.getX();k+=57){
                                if(playQ[j].getX()==k){
                                    count++;
                                }
                            }
                            for(int k=play.getX();k<i;k+=57){
                                if(playQ[j].getX()==k){
                                    count++;
                                }
                            }
                        }
                    }
                    if(count==0){
                        ChessRegret chessRegret=new ChessRegret();
                        chessRegret.man=man;
                        chessRegret.cx=play.getX();
                        chessRegret.cy=play.getY();
                        chessRegretList.add(chessRegret);
                        play.setBounds(i,play.getY(),55,55);
                        //播放声音
                        play.playSounds();
                        return;
                    }
                }
            }
        }
    }
    public void cannoRule(ChessMainBehavior play, ChessMainBehavior playQ[], MouseEvent me, List<ChessRegret> chessRegretList, int man){
        //车棋子的移动方法与炮一致所以直接调用炮的移动方法即可
        cannonRule(play,playQ,me,chessRegretList,man);
    }

首先对于炮的移动规则方法为cannonRule()五个参数的具体意义注释已写,首先明白对于某个棋子实际上为一个55*55的JLabel类的矩形框架,且由getx与gety方法得到的坐标是位于左上角的坐标.对于炮的移动规则是检测从移动的炮到点击位置之间是否有其它棋子如果有不进行移动没有则直接移动

定义的cx与cy为鼠标点击位置的x与y+30坐标,count=0是为了记录点击位置与移动棋子之间其它棋子的数目,先进行纵向移动的判断,注意此时鼠标点击的区域应该和移动的炮的位置处于同一个x区域内,因为鼠标不可能准确点击一个点来实现移动所以必须为一个区域,又一个格子大小为57,故而当cx-play.getx()即鼠标点击的x坐标与要移动的炮(实际为左上角坐标)的x坐标要满足>=0<57就可视为在同一个格子内,之后对于i的循环是为了找到该鼠标点击位置真正所处于的格子的y坐标,下方的if语句就是判断过程,此时就得到了鼠标点击位置所处的格子的左上角位置的x与y坐标,之后遍历32个棋子,分两种情况进行讨论,如果点击的格子在炮的上方以及点击格子在炮的下方,不论哪种情况,均是查看32个棋子中是否有棋子在二者之间,若有令count++;当32个棋子遍历结束后就得到了炮与点击的格子之间是否有其它棋子,通过count==0若满足就进行移动其中的chessRegert是存储移动之前的炮的位置以及编号信息便于悔棋时恢复,再将该信息加入悔棋状态结点的列表chessRegertList中其中列表中的最后一项元素就是最近一次操作的棋子移动或吃子前的状态.之后直接调用play.setBounds(x,y,55,55)其中的x与y就是鼠标所点击的格子的位置,55代表棋子的长与宽,之后结束该方法,即结束一次炮的移动操作.

按照上方的分析类似地就可得出,炮的左右移动的代码分析.

在一开始就说炮和车的移动规则一模一样因此对于车的移动规则cannoRule(移动方法参数都一致)的内容就是调用cannonRule()方法,将cannoRule方法的形参作为实参传递给它即可。

之后对于马和象的移动,之所以将二者练习到一起,因为二者都要考虑绊腿的情况,象为绊象腿马则为绊马腿,若有绊腿的情况则不能进行移动

public void horseRule(ChessMainBehavior play, ChessMainBehavior playQ[], MouseEvent me, List<ChessRegret> chessRegretList, int man){//马的移动规则方法//具体参数意义同炮的移动方法是一致的
        int ex=0,ey=0,move=0;//ex与ey分别为鼠标点击的目标点的x与y坐标move用来判断是否拌马腿
        ex=me.getX();
        ey=me.getY()+30;//同样30为工具栏的高度
        if(play.getX()-ex>0 && play.getX()-ex<=57 &&play.getY()-ey>=59 &&play.getY()-ey<=114){//为马走棋中的左上情况
            //满足左上情况时看是否绊马腿了即看马腿位置是否有一个棋子
            for(int i=0;i<32;i++){
                if(playQ[i].died==false && playQ[i].getX()==play.getX() && playQ[i].getY()-play.getY()==-57){//若满足则表示存在绊马腿操作
                    //如果某棋子未死(被吃)且该棋子与要移动的马的x轴坐标一致而其y轴坐标正好在马的上一个格子即马腿位置
                    move=1;
                    break;//发现绊马腿了退出循环
                }
            }
            if(move==0){
                ChessRegret chessRegret=new ChessRegret();//便于之后的悔棋操作
                //将移动前马的相关状态存入该chessRegret变量中便于悔棋后恢复
                chessRegret.man=man;
                chessRegret.cx=play.getX();
                chessRegret.cy=play.getY();
                chessRegretList.add(chessRegret);
                play.setBounds(play.getX()-57,play.getY()-114,55,55);//即不存在绊马脚的操作就进行马的左上移动
            }
        }
        //以左上情况为基础可以类似地写出其它7种马将移动的情况
        //右上坐标点
        if (ex - play.getX() > 0 && play.getX() - ex <= 57 && play.getY() - ey >= 59 && play.getY() - ey <= 114) {
            for(int i = 0; i < 32; ++i) {
                if (playQ[i].isVisible() && playQ[i].getX() == play.getX() && playQ[i].getY() - play.getY() == -57) {
                
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光的样子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值