使用java做出围棋或者五子棋


话不多说,先上主界面,如下:



相信大家都能出看来,主界面由一个按钮,三给个xtfile以及一个围棋盘(也就是灰色那部分)构成。

玩法:单击左键下棋子,双击吃棋子, 右击悔棋子

这部分代码如下:


super("围棋对弈");
chess = new ChessBoard();
button = new JButton("重新开局");
txt1 = new JTextField("请下黑棋",10);
txt2 = new JTextField(10);
txt3 = new JTextField(10);

setBounds(600,400,500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setVisible(true);

add(button);
add(txt1);
add(txt2);
add(txt3);
add(chess);
其中重新开局最为简单,直接重绘棋盘界面即可,所以增加按钮事件。如下:

button.addActionListener(this);


public void actionPerformed(ActionEvent e) {
if(e.getSource() == button) {
chess.repaint();
}
}


我这里的棋盘界面是单独弄了一个chess类,如下:


class ChessBoard extends Canvas{

public ChessBoard() {
setSize(400,400);
setBackground(Color.gray);
        
}

}


@Override
public void paint(Graphics g) {
super.paint(g);
for(int i=0;i<=20;i++) {
g.drawLine(0, 0+i*20, 400, 0+i*20);
}

for(int j=0;j<=20;j++) {
g.drawLine(0+j*20, 0, 0+j*20,400);
}

}







从主窗口传来信号,确定下画棋子的位置
public void setLoaction(int x,int y,boolean flag,boolean flag2) {
this.x = x;
this.y = y;
    paintChess(x,y,flag,flag2);

}

 

根据地址画一个棋子
 


public  void paintChess(int x,int y,boolean flag,boolean flag2) { 
g = this.getGraphics();

if(flag2) {
g.setColor(Color.gray);
System.out.println("我是悔棋"+flag);
}else if(!flag && (!flag2)) {
g.setColor(Color.white);
System.out.println("我是白棋"+flag+"--"+flag2);
}else if(flag && (!flag2)) {
g.setColor(Color.black);
System.out.println("我是黑棋"+flag+"--"+flag2);
}

g.fillOval(x, y, 10, 10);
}
 


那么接下来就要进入正题了,实现1://单击左击下棋子

那肯定必不可少的就是鼠标点击事件了:(我这里的鼠标事件采用匿名内部类实现,当然其小伙伴,也可以直接写一个适配器类去实现,这里我就不多说了)

这个判断就是判断是否是鼠标左击(

这里还要判断你要你要下棋子的地方是否已近有过了棋子,这里我使用的是TreeMap<Integer,Integer> ,正好2个位置(x,y),键我设置为x,   值我设置为Y,还有一点需要注这里要使用存储按顺序的Map,因为你后面会用(在右击悔棋那里)

e.getModifiers() & InputEvent.BUTTON1_MASK)!=0

遍历存储棋子的Treemap查询这个位置是有棋子,如果没有那么hasChess 给true(默认是fasle),如果没有就根据鼠标的坐标直接在棋盘上画出棋子   ,再把你画棋子的位子存储道treemap里面


chess.addMouseListener(new MouseListener() {

public void mouseClicked(MouseEvent e) {
//左击下棋子
if( (e.getModifiers() & InputEvent.BUTTON1_MASK)!=0){
hasChess = false;
Iterator iterator = previousLoacation.keySet().iterator();                
            while (iterator.hasNext()) {    
             Integer key = (Integer) iterator.next();
             Integer value = previousLoacation.get(key);
             if(key.equals(e.getX()) && value.equals(e.getY()) ) {
            txt2.setText("此处已有棋子");
            hasChess = true;
                 } 
            }
}
        
 if(!hasChess) {
chess.paintChess(e.getX(),e.getY(),flag,false);
}



previousLoacation.put(e.getX(), e.getY());
            
}




public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}

});

如果你下的位置有棋子,那么txt2文本框会显示(此处已有棋子),如下图



 

接下来就是双击吃棋子,这部分是比较简单的,值需要判断鼠标点击次数是否为二即可,如果点击次数为二,那么文本对话框显示失去棋子的一方的信息,这里的flag的作用是(//flag为true下黑棋  否则下白棋),haschess的作用是判断下棋子的位置是否已近有棋子了(hasChess 默认为false


 
//双击吃棋子
if(e.getClickCount()==2) {
if(flag) {
txt3.setText("白方失去一颗棋子");
}else {
txt3.setText("黑方失去一颗棋子");
}
hasChess = false;

}


效果图如下:



 

下面这里是处理我我这里代码众多bug中一个抓狂,(处理如果在有棋子的地方按了一下,防止出现连续(请出黑棋子 或者 请出白棋子)



            if(!hasChess) {
             flag = !flag;
             if(flag) {
             txt2.setText(" ");
             txt1.setText("请下黑棋");
             }else {
             txt1.setText("请下白棋");
             txt2.setText(" ");
             }
            }


 

对于悔棋那部分就需要用到我之前提到的treemap了,因为treemap,存储的时候是按照顺序的,她的最后一个就是上一个棋子的位置

只要将那个位置颜色消掉,并且再treemap中,把那个坐标删除即可!并且再txt文本中显示悔棋的信息。



//右击晦棋子
if( (e.getModifiers() & InputEvent.BUTTON3_MASK)!=0) {

int x = previousLoacation.lastKey();
int y = previousLoacation.lastEntry().getValue();

previousLoacation.remove(previousLoacation.lastKey());
System.out.println(x+y);
chess.paintChess(x,y,true,true);
if(flag) {
txt3.setText("白方悔棋一颗");
}else {
txt3.setText("黑方悔棋一颗");
}

}



好了,我现在只写了围棋最简单的部分,对于下棋位置只能在横线与纵线的焦点出下,围棋的算法判断(吃掉被围住的棋子)那部分

还没有写,其实,对于只能在焦点出下棋子,也写很简单的,只是需要自己去一个个试,确定每个焦点位置的范围,然后再判断棋手下棋子的位置,再函数内部,改变棋子的位置即可!



最最难的就是如何判断被棋子围住,吃掉被围住的棋子,其实博主有一些想法,不过太麻烦了,以后有时间再更新把!

 
(其中也有许多小bug,不过那都不是事,可以慢慢弄,毕竟大体框架已经出来了). 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值