面向对象程序设计(Java)课程设计——五子棋小游戏

目录

一、团队成员及任务

二、项目简介

三、功能设计图

 四、运行结果截图

五、核心源码

六、课程设计感想与展望


一、团队成员及任务

队长:管俊杰  计科(智能)22-1 202203200037

负责模块:界面设置中paint方法,功能中的双人对战功能和人机对战功能,以及判断游戏输赢的算法。

Java课程设计——五子棋游戏(个人)_The_God_Tree的博客-CSDN博客

组员:

李启帆 计科(智能)22-1 202203200036

负责模块:登录注册的功能与界面设置,创建容器面板以及棋盘和棋子的绘制。

面向对象程序设计(Java)课程设计——五子棋小游戏 中注册登录模块的实现。_Solar_487的博客-CSDN博客

马林飞 计科(智能)22-1 202203200031

负责模块:界面设置中的创建提示区域、放置按钮和JLabel组件,以及实现基本功能中的悔棋、重开、结束游戏功能。

二、项目简介

本项目由我们三人合作完成,实现了登录注册功能,每次打开需要先进行注册,需要创建账号密码。注册完成后回到登录界面,输入注册的账号密码便可以进入游戏。进入游戏后可以选择双人对战以及人机对战功能,人机对战还可以选择棋子颜色。同时还有悔棋、重开功能,以及结束本次游戏的按键。棋子进行了消除锯齿的优化,使棋子看起来更加圆润。

三、功能设计图

 四、运行结果截图

 

 

 

 

 

 

五、核心源码

Signin.java


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class Signin extends JFrame  {

    ArrayList<User>list = new ArrayList<User>();
    private Button loginButton;
    private Button signinButton;

    String ID;
    String password;

    int flag=0;

    private void addUser(ArrayList<User> list,String ID){

        //安全校验  没有 => return -1,可以添加 ;有 => 新输入
        String sid=ID;

        //将sid设为全局变量
        while(true){
            int index= getIndex(list,sid);
            if(index==-1){
                break;
            }else{
                tishi_zhucecunzai();
                flag=1;
                break;
            }
        }
        int index= getIndex(list,sid);
        if(index==-1){
            String Password=password;
            //创建用户实体对象
            User user = new User(ID,password);
            //将用户对象放入集合统一管理
            list.add(user);
            flag=0;
        }

    }


    private int getIndex(ArrayList<User>list,String sid){
        int index=-1;
        for(int i=0;i<list.size();i++){
            //得到集合中每一个用户对象
            User user = list.get(i);
            //拿到用户对象的id与sid比较
            String id= user.getID();
            if(sid.equals(id)){
                index = i;
            }
        }
        return index;
    }

    private int getpasswordIndex(ArrayList<User>list,String sid){
        int index=-2;
        for(int i=0;i<list.size();i++){
            //得到集合中每一个用户对象
            User user = list.get(i);
            //拿到用户对象的id与sid比较
            String password= user.getPassword();
            if(sid.equals(password)){
                index = i;
            }
        }
        return index;
    }


    void tishi_dengluchuowu(){
        JFrame t1=new JFrame();
        t1.setTitle("提示弹窗");
        t1.setSize(400,180);
        t1.setLocation(1050,600);
        t1.setResizable(false);
        t1.setVisible(true);
        t1.setLayout(null);
        t1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel s=new JLabel("账号不存在或密码错误");
        s.setBounds(120, 10, 200, 100);
        JButton bt=new JButton("确认");
        bt.setBounds(150,80,70,30);

        t1.add(s);
        t1.add(bt);

        bt.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                t1.setVisible(false);
            }
        });

    }
    void tishi_zhucebutong(){
        JFrame t2=new JFrame();
        t2.setTitle("提示弹窗");
        t2.setSize(400,200);
        t2.setLocation(1050,600);
        t2.setResizable(false);
        t2.setVisible(true);
        t2.setLayout(null);
        t2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel s=new JLabel("您两次输入的密码不同,请重新输入。");
        s.setBounds(100, 10, 220, 100);
        JButton bt=new JButton("确认");
        bt.setBounds(150,80,70,30);

        t2.add(s);
        t2.add(bt);

        bt.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                t2.setVisible(false);
            }
        });

    }
    void tishi_zhucecunzai(){
        JFrame t3=new JFrame();
        t3.setTitle("提示弹窗");
        t3.setSize(400,200);
        t3.setLocation(1050,600);
        t3.setResizable(false);
        t3.setVisible(true);
        t3.setLayout(null);
        t3.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel s=new JLabel("已存在相同账号,请重新输入账号");
        s.setBounds(100, 10, 220, 100);
        JButton bt=new JButton("确认");
        bt.setBounds(150,80,70,30);

        t3.add(s);
        t3.add(bt);

        bt.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                t3.setVisible(false);
            }
        });

    }
    void tishi_zhucechenggong(){
        JFrame t4=new JFrame();
        t4.setTitle("提示弹窗");
        t4.setSize(400,200);
        t4.setLocation(1050,600);
        t4.setResizable(false);
        t4.setVisible(true);
        t4.setLayout(null);
        t4.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel s=new JLabel("注册成功");
        s.setBounds(159, 10, 200, 100);
        JButton bt=new JButton("确认");
        bt.setBounds(150,80,70,30);

        t4.add(s);
        t4.add(bt);

        bt.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                t4.setVisible(false);
            }
        });

    }

    void tishi_kong(){
        JFrame t5=new JFrame();
        t5.setTitle("提示弹窗");
        t5.setSize(400,200);
        t5.setLocation(1050,600);
        t5.setResizable(false);
        t5.setVisible(true);
        t5.setLayout(null);
        t5.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel s=new JLabel("账号或密码不能为空");
        s.setBounds(125, 10, 200, 100);
        JButton bt=new JButton("确认");
        bt.setBounds(150,80,70,30);

        t5.add(s);
        t5.add(bt);

        bt.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                t5.setVisible(false);
            }
        });
    }






    public void setSigninFrame(){

        JFrame f1=new JFrame();
        JFrame zhuce=new JFrame();
        f1.setTitle("登录界面");
        f1.setSize(500,400);
        f1.setLocation(1000,500);
        f1.setBackground(Color.white);
        f1.setResizable(false);
        f1.setVisible(true);
        f1.setLayout(null);
        f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//默认关闭操作//

        JLabel l1=new JLabel("欢迎使用本程序");
        l1.setBounds(200, 20, 100, 20);    //这里表示对l1标签在窗口中的位置。
        JLabel l2=new JLabel("注册页面");
        l2.setBounds(200,20,500,50);
        JLabel l3=new JLabel("请输入账号");
        l3.setBounds(50,80,300,20);
        JLabel l4=new JLabel("请输入密码");
        l4.setBounds(50,120,300,20);
        JLabel l5=new JLabel("请确认密码");
        l5.setBounds(50,160,300,20);//注册界面文本显示
        JLabel l6=new JLabel("账号");
        l6.setBounds(50,80,300,20);
        JLabel l7=new JLabel("密码");
        l7.setBounds(50,120,300,20);
        JLabel l8=new JLabel("账号不存在或密码错误");
        l8.setBounds(50,200,300,20);
        JLabel l9=new JLabel("您两次输入的密码不同,请重新输入。");
        l9.setBounds(50,200,300,20);

        JButton bt1 = new JButton("登录");
        bt1.setBounds(70, 250, 120, 20);
        JButton bt2 = new JButton("注册");
        bt2.setBounds(290, 250, 120, 20);
        JButton bt3=new JButton("确认");
        bt3.setBounds(90, 250, 80, 20);
        JButton bt4=new JButton("返回");
        bt4.setBounds(310, 250, 80, 20);//注册界面按钮设置

        JTextField text1 = new JTextField();
        JTextField text2 = new JTextField();
        JTextField text3 = new JTextField();
        JTextField text4 = new JTextField();
        JTextField text5 = new JTextField();
        text1.setBounds(150, 80, 300, 20);
        text2.setBounds(150, 120, 300, 20);
        text3.setBounds(150, 160, 300, 20);//注册界面文本框设置
        text4.setBounds(150, 80, 300, 20);
        text5.setBounds(150, 120, 300, 20);//登录界面文本框设置

        f1.add(l1);
        f1.add(l6);
        f1.add(l7);
        f1.add(bt1);
        f1.add(bt2);
        f1.add(text4);
        f1.add(text5);

        bt1.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                String text4a = text4.getText();
                String text5a = text5.getText();
                ID=text4a;
                password=text5a;
                int index1=getIndex(list,ID);
                int index2=getpasswordIndex(list,password);

                if(text4a.equals("")||text5a.equals("")){
                    tishi_kong();
                }else {
                    if(index2==index1){
                        JFrame jf = new JFrame("五子棋小游戏");
                        jf.add(new TablePanel());
                        jf.pack();  //自动适配大小
                        jf.setLocationRelativeTo(null);     //居中
                        jf.setResizable(true); //可调整大小
                        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //按×关闭
                        jf.setVisible(true);    //是否可见
                        f1.setVisible(false);
                    }else{
                        tishi_dengluchuowu();
                    }
                }


            }
        });

        bt2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                f1.setVisible(false);
                zhuce.setTitle("注册窗口");
                zhuce.setLayout(null);
                zhuce.setSize(500,350);
                zhuce.setLocation(1000,500);//注册界面窗口设置
                zhuce.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                zhuce.setVisible(true);

                zhuce.add(text1);
                zhuce.add(text2);
                zhuce.add(text3);
                zhuce.add(bt3);
                zhuce.add(bt4);
                zhuce.add(l2);
                zhuce.add(l3);
                zhuce.add(l4);
                zhuce.add(l5);
            }
        });

        bt3.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                String text1a = text1.getText();
                String text2a = text2.getText();
                String text3a = text3.getText();
                if(text1a.equals("")||text2a.equals("")){
                    tishi_kong();
                }else if(text2a.equals(text3a)){
                    ID=text1a;
                    password=text2a;
                    addUser(list,ID);
                    if(flag==0){
                        setSigninFrame();
                        tishi_zhucechenggong();
                        zhuce.setVisible(false);
                    }

                } else{
                    tishi_zhucebutong();
                }
            }
        });

        bt4.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                zhuce.setVisible(false);
                setSigninFrame();
            }
        });

    }

}


 User.java

public class User {
    String ID;
    String password;

    public User(String id, String password) {
        this.ID=id;
        this.password=password;
    }

    public void setID(String ID){

        this.ID=ID;
    }
    public void setPassword(String password){

        this.password=password;
    }

    public String getID(){
        return ID;
    }

    public String getPassword(){
        return password;
    }
}

 Frame.java

public class Frame {
    public static void main(String[] args) {

       Signin a=new Signin();
       a.setSigninFrame();

    }
}
TablePanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Vector;

public class TablePanel extends JPanel {

    //设置Panel的大小
    final int TABLE_WIDTH = 800;
    final int TABLE_HEIGHT = 600;

    final int NUM = 15;//棋盘线的条数,标准棋盘为15*15
    final int OFFSET_X = 30;  //棋盘左上角相对于panel左上角的偏移量(棋盘的起始位置)
    final int OFFSET_Y = 80;
    final int SP = 34; //棋盘每条线的间隔
    final int RECT_SIZE = 6;    //棋盘上五个提示点的位置
    final int OVAL_SIZE = 32;   //棋子的大小
    int[][] table = new int[NUM][NUM];  //二维数字记录棋盘上每个位置上的棋子 (0无棋子  1白子  2黑子)
    int step;
    int oval_type = 2; //所要下的棋子的颜色 1白 2黑

    int mouse_X;
    int mouse_Y;

    int select_X = -10;
    int select_Y = -10;

    //定义一个Vector,存储每次下的位置,来实现悔棋功能
    Vector<Integer> last_xy = new Vector<>();

    boolean isWin;  //是否赢

    int isStart;    //是否开始游戏 0未开始 1 2 3

    int robot_x;
    int robot_y;

    BasicStroke bs; //定义画笔宽度(因为不止一个方法用,就定义在外面)

    SpringLayout springLayout = new SpringLayout(); //设置springLayout布局,方便按钮位置的部署

    Dimension buttonSize = new Dimension(180, 35);    //设置按钮大小
    //设置字体的形状
    Font font1 = new Font("楷体", Font.PLAIN, 30);
    Font font2 = new Font("华文新魏", Font.PLAIN, 20);
    Font font3 = new Font("华文琥珀", Font.PLAIN, 50);
    Font font4 = new Font("微软雅黑", Font.PLAIN, 35);
    //定义一系列button和label
    JLabel titleLabel = new JLabel("五子棋");
    JLabel selectLabel = new JLabel("游戏类型:");
    JButton rrBtn = new JButton("双人对战");
    JButton rjbBtn = new JButton("人机对战.持黑");
    JButton rjwBtn = new JButton("人机对战.持白");
    JLabel elseLabel = new JLabel("其他设置:");
    JButton regretBtn = new JButton("悔棋");
    JButton restartBtn = new JButton("重新开始");
    JButton endBtn = new JButton("结束游戏");

    public TablePanel() {
        setLayout(springLayout);    //设置弹性布局方式
        setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT)); //设置组件的首选大小
        setBackground(Color.lightGray); //设置背景颜色亮灰色
        initBtn();  //初始化按钮
        init(); //初始化一些属性
        isStart = 0;
        addMouseListener(mouseAdapter); //添加鼠标监听
        addMouseMotionListener(mouseAdapter);
    }
    //初始化一些属性
    private void init() {
        //初始化二维数组
        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM; j++) {
                table[i][j] = 0;
            }
        }

        //初始化step
        step = 0;

        isWin = false;

        oval_type = 2;

        //初始化list
        last_xy.clear();
    }

    @Override
    public void paint(Graphics g) {
        //定义一个Graphics2D消除棋子锯齿,使棋子更加圆润
        Graphics2D gg = (Graphics2D) g;
        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
        //棋盘
        initPaint(g, gg);
        //棋子
        ovalPaint(gg);
        //提示框
        sidePaint(gg);
    }

    private void ovalPaint(Graphics2D gg) {
        //画棋子
        //每次点击后,会刷新一下棋盘,根据table的值画黑或白字

        //画实体棋子
        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM; j++) {
                int x = OFFSET_X + SP * i - OVAL_SIZE / 2;
                int y = OFFSET_Y + SP * j - OVAL_SIZE / 2;
                if (table[i][j] == 2) {
                    gg.setColor(Color.BLACK);
                    gg.fillOval(x, y, OVAL_SIZE, OVAL_SIZE);
                } else if (table[i][j] == 1) {
                    gg.setColor(Color.WHITE);
                    gg.fillOval(x, y, OVAL_SIZE, OVAL_SIZE);
                } else if (table[i][j] == 3) {
                    gg.setColor(Color.RED);
                    gg.drawOval(x, y, OVAL_SIZE, OVAL_SIZE);
                }
            }
        }

        if (isWin) {//赢了就把选择框隐藏起来
            select_X = -10;
            select_Y = -10;
        } else {
            bs = new BasicStroke(1);       // 画笔宽度为1
            gg.setStroke(bs);
            //画选择框
            gg.setColor(Color.RED);
            gg.drawOval(OFFSET_X + SP * select_X - OVAL_SIZE / 2,
                    OFFSET_Y + SP * select_Y - OVAL_SIZE / 2,
                    OVAL_SIZE, OVAL_SIZE);
        }
    }

    //画棋盘
    private void initPaint(Graphics g, Graphics2D gg) {
        super.paint(g);
        //画棋盘的线
        g.setColor(Color.BLACK);
        for (int i = 0; i < NUM; i++) {
            g.drawLine(OFFSET_X + SP * i, OFFSET_Y, OFFSET_X + SP * i, OFFSET_Y + SP * (NUM - 1));
        }
        for (int i = 0; i < NUM; i++) {
            g.drawLine(OFFSET_X, OFFSET_Y + SP * i, OFFSET_X + SP * (NUM - 1), OFFSET_Y + SP * i);
        }

        //加点点缀
        //五个定位的小方块
        g.fillRect(OFFSET_X + SP * 3 - RECT_SIZE / 2, OFFSET_Y + SP * 3 - RECT_SIZE / 2, RECT_SIZE, RECT_SIZE);
        g.fillRect(OFFSET_X + SP * 11 - RECT_SIZE / 2, OFFSET_Y + SP * 3 - RECT_SIZE / 2, RECT_SIZE, RECT_SIZE);
        g.fillRect(OFFSET_X + SP * 3 - RECT_SIZE / 2, OFFSET_Y + SP * 11 - RECT_SIZE / 2, RECT_SIZE, RECT_SIZE);
        g.fillRect(OFFSET_X + SP * 11 - RECT_SIZE / 2, OFFSET_Y + SP * 11 - RECT_SIZE / 2, RECT_SIZE, RECT_SIZE);
        g.fillRect(OFFSET_X + SP * 7 - RECT_SIZE / 2, OFFSET_Y + SP * 7 - RECT_SIZE / 2, RECT_SIZE, RECT_SIZE);
        //再加几条粗一点的线
        bs = new BasicStroke(3);       // 画笔宽度为5
        gg.setStroke(bs);
        gg.drawRect(OFFSET_X - 7, OFFSET_Y - 7, (NUM - 1) * SP + 14, (NUM - 1) * SP + 14);
        bs = new BasicStroke(2);
        gg.setStroke(bs);
        for (int i = 1; i < NUM; i = i + 4) {
            gg.drawLine(OFFSET_X + SP * i, OFFSET_Y, OFFSET_X + SP * i, OFFSET_Y + SP * (NUM - 1));
        }
        for (int i = 1; i < NUM; i = i + 4) {
            gg.drawLine(OFFSET_X, OFFSET_Y + SP * i, OFFSET_X + SP * (NUM - 1), OFFSET_Y + SP * i);
        }
    }

    //画侧面(右上角)的提示框
    private void sidePaint(Graphics2D gg) {
        if (isStart != 0) {
            //开始游戏时
            if (isWin) {
                //赢了后
                gg.setColor((oval_type == 1 ? Color.black : Color.white));
                gg.setFont(font3);
                gg.drawString((oval_type == 1 ? "黑方赢" : "白方赢"), 520, 170);
            } else {
                //没赢之前
                gg.setColor(Color.red);
                gg.setFont(font4);
                gg.drawString("轮到:", 520, 105);

                if (oval_type == 2) {
                    gg.setColor(Color.black);
                } else if (oval_type == 1) {
                    gg.setColor(Color.white);
                }
                gg.drawString((oval_type == 2 ? "黑方" : "白方"), 530, 150);
                gg.fillOval(610, 125, 40, 40);

                gg.setColor(Color.red);
                gg.drawString("步数:", 520, 200);
                gg.setColor(Color.black);
                gg.drawString(step + "", 620, 200);
            }
        } else {
            gg.setColor(Color.RED);
            gg.setFont(font4);
            gg.drawString("请选择游戏类型", 525, 150);

        }
    }

    private void initBtn() {
        //将button和label设置各自的属性
        selectLabel.setFont(font1);
        rrBtn.setPreferredSize(buttonSize);
        rrBtn.setFont(font2);
        rjbBtn.setPreferredSize(buttonSize);
        rjbBtn.setFont(font2);
        rjwBtn.setPreferredSize(buttonSize);
        rjwBtn.setFont(font2);
        elseLabel.setFont(font1);
        regretBtn.setPreferredSize(buttonSize);
        regretBtn.setFont(font2);
        restartBtn.setPreferredSize(buttonSize);
        restartBtn.setFont(font2);
        endBtn.setPreferredSize(buttonSize);
        endBtn.setFont(font2);
        titleLabel.setFont(font3); // 标题

        //给按钮加上监听
        rrBtn.addActionListener(actionListener);
        rjbBtn.addActionListener(actionListener);
        rjwBtn.addActionListener(actionListener);
        regretBtn.addActionListener(actionListener);
        restartBtn.addActionListener(actionListener);
        endBtn.addActionListener(actionListener);

        //将其放入
        add(selectLabel);
        add(rrBtn);
        add(rjbBtn);
        add(rjwBtn);
        add(elseLabel);
        add(regretBtn);
        add(restartBtn);
        add(endBtn);
        add(titleLabel);

        //设置各自的位置,使用弹性布局

        //将标题放置到中位置
        int offsetX = Spring.width(titleLabel).getValue() / 2;
        springLayout.putConstraint(SpringLayout.WEST, titleLabel, -offsetX,
                SpringLayout.HORIZONTAL_CENTER, this);
        springLayout.putConstraint(SpringLayout.NORTH, titleLabel, 10, SpringLayout.NORTH, this);


        springLayout.putConstraint(SpringLayout.WEST, selectLabel, 525,
                SpringLayout.WEST, this);
        springLayout.putConstraint(SpringLayout.NORTH, selectLabel, 260, SpringLayout.NORTH, this);

        springLayout.putConstraint(SpringLayout.WEST, rrBtn, 5,
                SpringLayout.WEST, selectLabel);
        springLayout.putConstraint(SpringLayout.NORTH, rrBtn, 5, SpringLayout.SOUTH, selectLabel);

        springLayout.putConstraint(SpringLayout.WEST, rjbBtn, 0,
                SpringLayout.WEST, rrBtn);
        springLayout.putConstraint(SpringLayout.NORTH, rjbBtn, 5, SpringLayout.SOUTH, rrBtn);

        springLayout.putConstraint(SpringLayout.WEST, rjwBtn, 0,
                SpringLayout.WEST, rjbBtn);
        springLayout.putConstraint(SpringLayout.NORTH, rjwBtn, 5, SpringLayout.SOUTH, rjbBtn);

        springLayout.putConstraint(SpringLayout.WEST, elseLabel, 0,
                SpringLayout.WEST, selectLabel);
        springLayout.putConstraint(SpringLayout.NORTH, elseLabel, 10, SpringLayout.SOUTH, rjwBtn);

        springLayout.putConstraint(SpringLayout.WEST, regretBtn, 5,
                SpringLayout.WEST, elseLabel);
        springLayout.putConstraint(SpringLayout.NORTH, regretBtn, 5, SpringLayout.SOUTH, elseLabel);

        springLayout.putConstraint(SpringLayout.WEST, restartBtn, 0,
                SpringLayout.WEST, regretBtn);
        springLayout.putConstraint(SpringLayout.NORTH, restartBtn, 5, SpringLayout.SOUTH, regretBtn);

        springLayout.putConstraint(SpringLayout.WEST, endBtn, 0,
                SpringLayout.WEST, restartBtn);
        springLayout.putConstraint(SpringLayout.NORTH, endBtn, 5, SpringLayout.SOUTH, restartBtn);

        regretBtn.setEnabled(false);
        restartBtn.setEnabled(false);
        endBtn.setEnabled(false);
    }

    ActionListener actionListener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            JButton jButton = (JButton) e.getSource();
            String text = jButton.getText();
            if ("重新开始".equals(text)) {
                init();

                if(isStart==3){
                    machine();
                    step++;
                    table[robot_x][robot_y] = 2;
                    oval_type = 1;
                }
                regretBtn.setEnabled(false);
                restartBtn.setEnabled(false);
            } else if ("悔棋".equals(text)) {
                int x = last_xy.get(last_xy.size() - 2);
                int y = last_xy.get(last_xy.size() - 1);
                table[x][y] = 0;
                last_xy.remove(last_xy.size() - 2);
                last_xy.remove(last_xy.size() - 1);
                oval_type = oval_type % 2 + 1;
                if (isStart == 2 || isStart == 3) {
                    x = last_xy.get(last_xy.size() - 2);
                    y = last_xy.get(last_xy.size() - 1);
                    table[x][y] = 0;
                    last_xy.remove(last_xy.size() - 2);
                    last_xy.remove(last_xy.size() - 1);
                    oval_type = oval_type % 2 + 1;
                }

                if (oval_type == 2||isStart==3) {
                    step--;
                }
                if (isWin) {
                    isWin = false;
                }
                if (last_xy.size() == 0) {
                    regretBtn.setEnabled(false);
                    restartBtn.setEnabled(false);
                }
            } else if ("结束游戏".equals(text)) {
                isStart = 0;
                init();
                rrBtn.setEnabled(true);
                rjbBtn.setEnabled(true);
                rjwBtn.setEnabled(true);
                regretBtn.setEnabled(false);
                restartBtn.setEnabled(false);
                endBtn.setEnabled(false);
            } else {
                //上面三个按钮
                if ("双人对战".equals(text)) {
                    isStart = 1;
                } else if ("人机对战.持黑".equals(text)) {
                    isStart = 2;
                } else if ("人机对战.持白".equals(text)) {
                    isStart = 3;
                    machine();
                    step++;
                    table[robot_x][robot_y] = 2;
                    oval_type = 1;
                }
                rrBtn.setEnabled(false);
                rjbBtn.setEnabled(false);
                rjwBtn.setEnabled(false);
                endBtn.setEnabled(true);
            }
            repaint();
        }
    };

    MouseAdapter mouseAdapter = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            //赢的时候不能用
            if (!isWin) {
                if (isStart == 1) {
                    //来判断是否在棋盘内
                    if (e.getX() > OFFSET_X - OVAL_SIZE / 2 && e.getX() < OFFSET_X + (NUM - 1) * SP + OVAL_SIZE / 2
                            && e.getY() > OFFSET_Y - OVAL_SIZE / 2 && e.getY() < OFFSET_Y + (NUM - 1) * SP + OVAL_SIZE / 2) {

                        //将坐标转换为二维数组的i和j
                        mouse_X = (e.getX() - OFFSET_X + OVAL_SIZE / 2) / SP;
                        mouse_Y = (e.getY() - OFFSET_Y + OVAL_SIZE / 2) / SP;
                        if (table[mouse_X][mouse_Y] == 0) {
                            table[mouse_X][mouse_Y] = oval_type;
                            if (oval_type == 2) {
                                oval_type = 1;
                                step++; //根据黑棋下的次数来增加总步数
                            } else if (oval_type == 1) {
                                oval_type = 2;
                            }
                            last_xy.add(mouse_X);
                            last_xy.add(mouse_Y);
                            //如果下了棋子,才能使用悔棋和重新游戏的按钮

                            restartBtn.setEnabled(true);
                            regretBtn.setEnabled(true);

                            judge(oval_type % 2 + 1, mouse_X, mouse_Y);

                        }
                        repaint();
                    }
                } else if (isStart == 2) {

                    if (e.getX() > OFFSET_X - OVAL_SIZE / 2 && e.getX() < OFFSET_X + (NUM - 1) * SP + OVAL_SIZE / 2
                            && e.getY() > OFFSET_Y - OVAL_SIZE / 2 && e.getY() < OFFSET_Y + (NUM - 1) * SP + OVAL_SIZE / 2) {
                        mouse_X = (e.getX() - OFFSET_X + OVAL_SIZE / 2) / SP;
                        mouse_Y = (e.getY() - OFFSET_Y + OVAL_SIZE / 2) / SP;
                        if (table[mouse_X][mouse_Y] == 0) {
                            table[mouse_X][mouse_Y] = 2;
                            oval_type = 1;
                            last_xy.add(mouse_X);
                            last_xy.add(mouse_Y);
                            repaint();
                            judge(2, mouse_X, mouse_Y);
                            if (!isWin) {
                                machine();
                                table[robot_x][robot_y] = 1;
                                oval_type = 2;
                                judge(1, robot_x, robot_y);
                                last_xy.add(robot_x);
                                last_xy.add(robot_y);
                            }
                            step++;
                            restartBtn.setEnabled(true);
                            regretBtn.setEnabled(true);
                        }
                    }
                } else if (isStart == 3) {
                    if (e.getX() > OFFSET_X - OVAL_SIZE / 2 && e.getX() < OFFSET_X + (NUM - 1) * SP + OVAL_SIZE / 2
                            && e.getY() > OFFSET_Y - OVAL_SIZE / 2 && e.getY() < OFFSET_Y + (NUM - 1) * SP + OVAL_SIZE / 2) {
                        mouse_X = (e.getX() - OFFSET_X + OVAL_SIZE / 2) / SP;
                        mouse_Y = (e.getY() - OFFSET_Y + OVAL_SIZE / 2) / SP;
                        if (table[mouse_X][mouse_Y] == 0) {
                            table[mouse_X][mouse_Y] = 1;
                            oval_type = 2;
                            last_xy.add(mouse_X);
                            last_xy.add(mouse_Y);
                            repaint();
                            judge(1, mouse_X, mouse_Y);
                            if (!isWin) {
                                machine();
                                table[robot_x][robot_y] = 2;
                                oval_type = 1;
                                judge(2, robot_x, robot_y);
                                last_xy.add(robot_x);
                                last_xy.add(robot_y);
                            }
                            step++;
                            restartBtn.setEnabled(true);
                            regretBtn.setEnabled(true);
                        }
                    }
                }
            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            if (!isWin) {
                if (isStart > 0) {
                    if (e.getX() > OFFSET_X - OVAL_SIZE / 2 && e.getX() < OFFSET_X + (NUM - 1) * SP + OVAL_SIZE / 2
                            && e.getY() > OFFSET_Y - OVAL_SIZE / 2 && e.getY() < OFFSET_Y + (NUM - 1) * SP + OVAL_SIZE / 2) {
                        select_X = (e.getX() - OFFSET_X + OVAL_SIZE / 2) / SP;
                        select_Y = (e.getY() - OFFSET_Y + OVAL_SIZE / 2) / SP;

                    } else {
                        select_X = -10;
                        select_Y = -10;
                    }
                }
            }
            repaint();
        }
    };

    //判断谁赢,扫描整个棋盘,来判断是否连成五个
    private void judge(int type, int x, int y) {
        //传入参数,来判断是黑(2)或白(1)子

        int sum=0;
        //判断四个方向
        //1.左 右
        {
            int k = x - 1;
            while (k >= 0) {
                if (table[k][y] == type) {
                    sum++;
                } else {
                    break;
                }
                k--;
            }
        }
        for (int k = x + 1; k < NUM; k++) {
            if (table[k][y] == type) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            isWin = true;
            return;
        }

        //2.上 下
        sum = 0;
        for (int k = y - 1; k >= 0; k--) {
            if (table[x][k] == type) {
                sum++;
            } else {
                break;
            }
        }
        for (int k = y + 1; k < NUM; k++) {
            if (table[x][k] == type) {
                sum++;
            } else {
                break;
            }
        }
        if (sum >= 4) {
            isWin = true;
            return;
        }

        //3。左上 右下
        sum = 0;
        for (int i = x - 1, j = y - 1; i >= 0 && j >= 0; i--, j--) {
            if (table[i][j] == type) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = x + 1, j = y + 1; i < NUM && j < NUM; i++, j++) {
            if (table[i][j] == type)
                sum++;
            else {
                break;
            }
        }
        if (sum >= 4) {
            isWin = true;
            return;
        }

        //3。右上 左下
        sum = 0;
        for (int i = x - 1, j = y + 1; i >= 0 && j < NUM; i--, j++) {
            if (table[i][j] == type) {
                sum++;
            } else {
                break;
            }
        }
        for (int i = x + 1, j = y - 1; i < NUM && j >= 0; i++, j--) {
            if (table[i][j] == type)
                sum++;
            else {
                break;
            }
        }
        if (sum >= 4) {
            isWin = true;
            //return;
        }
    }


    //自动下棋的方法
    private void machine() {
        //传入棋子种类,判断颜色
        int[][] ts = new int[NUM][NUM]; //来记录每个点上的得分

        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM; j++) {
                ts[i][j] = 0;
            }
        }

        int wn; //白色个数
        int bn; //黑色个数

        //分4种情况
        //横向
        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM - 4; j++) {
                wn = 0;
                bn = 0;
                //5个
                for (int k = j; k < j + 5; k++) {
                    if (table[i][k] == 1) {
                        wn++;
                    } else if (table[i][k] == 2) {
                        bn++;
                    }
                }
                for (int k = j; k < j + 5; k++) {
                    if (table[i][k] == 0) {
                        ts[i][k] += score(wn, bn);
                    }
                }
            }
        }

        //纵向
        for (int j = 0; j < NUM; j++) {
            for (int i = 0; i < NUM - 4; i++) {
                wn = 0;
                bn = 0;
                for (int k = i; k < i + 5; k++) {
                    if (table[k][j] == 1) {
                        wn++;
                    } else if (table[k][i] == 2) {
                        bn++;
                    }
                }
                for (int k = i; k < i + 5; k++) {
                    if (table[k][i] == 0) {
                        ts[k][i] += score(wn, bn);
                    }
                }
            }
        }

        //左上 右下
        for (int i = 0; i < NUM - 4; i++) {
            for (int j = 0; j < NUM - 4; j++) {
                wn = 0;
                bn = 0;
                for (int ki = i, kj = j; ki < i + 5; ki++, kj++) {
                    if (table[ki][kj] == 1) {
                        wn++;
                    } else if (table[ki][kj] == 2) {
                        bn++;
                    }
                }
                for (int ki = i, kj = j; ki < i + 5; ki++, kj++) {
                    if (table[ki][kj] == 0) {
                        ts[ki][kj] += score(wn, bn);
                    }
                }
            }
        }

        //右上 左下
        for (int i = 4; i < NUM; i++) {
            for (int j = 0; j < NUM - 4; j++) {
                wn = 0;
                bn = 0;
                for (int ki = i, kj = j; kj < j + 5; ki--, kj++) {
                    if (table[ki][kj] == 1) {
                        wn++;
                    } else if (table[ki][kj] == 2) {
                        bn++;
                    }
                }
                for (int ki = i, kj = j; kj < j + 5; ki--, kj++) {
                    if (table[ki][kj] == 0) {
                        ts[ki][kj] += score(wn, bn);
                    }
                }
            }
        }

        Vector<Integer> vv = new Vector<>();
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM; j++) {
                if (ts[i][j] > max) {
                    max = ts[i][j];
                }
            }
        }
        for (int i = 0; i < NUM; i++) {
            for (int j = 0; j < NUM; j++) {
                if (ts[i][j] == max) {
                    vv.add(i);
                    vv.add(j);
                }
            }
        }
        Random random = new Random();
        int r = random.nextInt(vv.size() / 2);
        robot_x = vv.get(r * 2);
        robot_y = vv.get(r * 2 + 1);
        vv.clear();
    }

    private int score(int wh, int bl) {
        if (wh > 0 && bl > 0) {
            return 0;
        }
        if (wh == 0 && bl == 0) {
            return 7;
        }
        if (wh == 1) {
            return 35;
        }
        if (wh == 2) {
            return 800;
        }
        if (wh == 3) {
            return 15000;
        }
        if (wh == 4) {
            return 800000;
        }
        if (bl == 1) {
            return 15;
        }
        if (bl == 2) {
            return 400;
        }
        if (bl == 3) {
            return 1800;
        }
        if (bl == 4) {
            return 100000;
        }
        return -1;
    }
}

六、课程设计感想与展望

  通过团队十几天的努力,感觉收获颇丰,加强了对所学知识的巩固。不足之处是因能力有限,登陆注册没有使用数据库,所以每次打开都需要重新注册再登录。同时,界面设计有些简陋,只实现了这些基本功能。但通过参考和借鉴,实现了人机互动功能是团队的一大进步。

参考博客:五子棋小游戏 java版(代码+详细注释)_java五子棋游戏代码_逗呵呵的博客-CSDN博客

五元组评价算法实现简易五子棋【人工智能】_五子棋五元组算法_YouthUpward的博客-CSDN博客

  • 6
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值