Java之简单人机五子棋(一)

继上周实现了C++控制台版的五子棋之后,这周开始学习Java,顺便花了两三天时间,做出了一直想做的图形化界面的五子棋小游戏。同时在原来C++控制台程序的基础上对AI的算法进行了一定修正,修复了一些bug,并加入了悔棋的功能
C++五子棋系列传送门:
C++之简单五子棋的设计思路
C++之简单五子棋的语言设计实现
C++简单五子棋的AI设计及实现
五子棋的算法规则和类的设计在C++相关中讲过了,所以现在主要总结一下如何转成图形化界面。由于第一次接触java,顶层设计做的不是很好,还是带有浓厚的面向过程的设计风格,勉强合格吧。
效果如下
界面
这里写图片描述
这里写图片描述
界面主要使用swing组件搭建,具体如下:

  • MyChessBoard :面板类,继承JPanel类。主要用来实现存储棋盘信息,记录下棋过程和显示棋局。考虑到各个组件都要对棋盘进行操作,所以对棋局进行记录操作的相关函数和变量均设为静态类成员。具体包括:

    • 存储棋盘信息的15*15二维数组chess[][],用0代表空,1代表白,2代表黑;
    • 记录最近两步走棋信息的2*2二维数组lastChess[][],用于悔棋;
    • 悔棋操作函数reDo(),将lastChess数组中存储的坐标处的棋子标记为空,然后调用repaint()进行重绘;
    • 标志棋盘是否为空的布尔变量isEmpty
    • 负责接收坐标,更新棋盘信息的函数record(int,int);
    • clearBoard()函数负责对棋盘进行清除,并初始化相关变量;

    除此之外,在构造函数中对各变量进行初始化,lastChess[][]初始化为全变量-1,有棋子落子时在record函数里对其进行更新,采用队列的数据结构,存储落子的坐标。
    重写父类的paintComponent用来完成棋盘和棋子的绘制。
    setChess(int,int,int)函数用来接收鼠标点击的坐标和当前所下的棋子颜色,通过点击坐标计算出落子坐标,调用record函数进行记录,调用repaint函数进行重绘。

//面板,用来打印15*15的棋盘和当前在棋盘上的棋子,提供一个15*15的int数组,标记每个节点处的棋子状态
class MyChessBoard extends JPanel{
   
    protected BufferedImage bg = null;
    static public int[][] chess ;//0为空,1为白,2为黑
    static protected int [][] lastChess = {
  {-1,-1},{-1,-1}};
    static protected boolean isEmpty = true;
    static public void record(int x,int y) {
        lastChess[1][0] =  lastChess[0][0];
        lastChess[1][1] = lastChess[0][1];
        lastChess[0][0] = x;
        lastChess[0][1] = y;
        ChessGame.reserve();
        MyControlBoard.redo = false;
        MyControlBoard.undo.setText("Undo");
        isEmpty = false;
    }
    // default constructor
    public MyChessBoard(){
        super();
        lastChess[0][0] = -1;
        lastChess[0][1] = -1;
        lastChess[1][0] = -1;
        lastChess[1][1] = -1;
        chess = new int[15][15];
        for(int i =0;i < 15;i++) {
            for(int j = 0;j < 15;j++) {
                chess[i][j] = 0;
            }
        }
        try {  
            bg = ImageIO.read(new File("D:\\administrator-\\Documents\\eclipse-workspace\\practice\\src\\Windows\\renju.png"));  
        }catch(Exception e) {  
            e.printStackTrace();  
        }
        repaint();
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(new Color(222,184,135));
        Graphics2D g1 = (Graphics2D)g;

        //add background
        g1.drawImage(bg, 0, 0,getWidth(),getHeight(), null);    

        //draw chess board
        g1.setColor(Color.red);
        BasicStroke seg = new BasicStroke(2,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
        g1.setStroke(seg);
        int width = getWidth();
        int height = getHeight();
        int vgap = height/16;
        int hgap = width/16;
        for(int i = 1;i<16;i++) {
            g1.drawLine(hgap, i*vgap, 15*hgap, i*vgap);
            g1.drawLine(i*hgap,vgap , i*hgap, 15*vgap);
        }

        //draw chess
        int chessWidth = hgap*3/4;
        int chessHeight = vgap*3/4;
        for(int i = 0;i < 15;i++) {
            for(int j = 0;j < 15;j++) {
                if(chess[i][j] == 2) {
                    g1.setColor(Color.BLACK);
                    g1.fillOval((1+j)*hgap-chessWidth/2,(1+i)*vgap-chessHeight/2,chessWidth, chessHeight);
                
  • 15
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值