欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java实战:仿QQ游戏大厅五子棋

程序员文章站 2022-05-25 13:52:38
...

本篇主要讲本科时学习Java时写的一个小游戏。五子棋对于锻炼Java初级编程很有帮助。

素材搜集与设计

棋盘

五子棋的游戏算法就不说了,当时写的比较一般。这里讲一讲游戏设计吧。首先是棋盘,我花了一早上用PPT画了个棋盘,主要是不会PS啊。效果如图:
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
画了各种颜色的棋盘,最后再画个棋子:
Java实战:仿QQ游戏大厅五子棋
以及棋子选框:
Java实战:仿QQ游戏大厅五子棋
大功告成!

玩家形象

我觉得QQ大厅的形象挺好看的,就扒下来了一些:
Java实战:仿QQ游戏大厅五子棋
Java实战:仿QQ游戏大厅五子棋
哈哈!

声音

从百度里找了几段短的片段。

聊天窗口

为了防止无聊,从好多人的QQ签名上摘了一些话下来。写了个聊天线程。

代码实现

就一个类从头到尾,全都写在一起了。当时刚学Java,啥也不懂哈。

package chenweiliang;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Time;
import java.util.Calendar;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.management.timer.Timer;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.plaf.metal.MetalIconFactory.FileIcon16;


public class ChessFive {
    //计时开始标志
    private static int timerFlag=0;
    //下棋步数
    private static int steps=0;
    //
    private int highestGrade=0;

    //棋盘、棋子
    BufferedImage table;
    BufferedImage black;
    BufferedImage white;
    BufferedImage playerImg;
    BufferedImage comImg;
    BufferedImage starImg;

    //鼠标选择框
    BufferedImage selected;

    //棋盘大小
    private static int BOARD_SIZE=15;
    //棋盘宽高
    private final int TABLE_WIDTH=612;
    private final int TABLE_HEIGHT=612;
    //棋盘边框
    private final int X_OFFSET=12;
    private final int Y_OFFSET=12;

    //像素与棋盘数组之间的比率
    private final  int rate=(TABLE_WIDTH-X_OFFSET*3)/(BOARD_SIZE);
    //棋子
    private final int CHESS_BLACK=1;
    private final int CHESS_WHITE=2;
    private final int CHESS_NONE=0;
    //静态变量
    static private int[][] board=new int[BOARD_SIZE][BOARD_SIZE];

    //游戏窗口
    JFrame f=new JFrame("五子棋游戏");
    //棋盘
    ChessBoard chessBoard=new ChessBoard();
    //当前点
    private int selectedX=-1;
    private int selectedY=-1;

    //创建菜单
    JMenuBar mb=new JMenuBar();
    JMenu gameMenu=new JMenu("游戏");
    JMenu helpMenu=new JMenu("帮助");
    JMenuItem newGameItem=new JMenuItem("新游戏");
    JMenuItem inforItem=new JMenuItem("统计信息");
    JMenuItem optionItem=new JMenuItem("选项");
    JMenuItem exitItem=new JMenuItem("退出");

    JMenuItem lookHelpItem=new JMenuItem("查看帮助");
    JMenuItem aboutItem=new JMenuItem("关于五子棋");

    //******************创建游戏双方窗口部件*************************
    PlayBoard player=new PlayBoard();
    PlayBoard computer=new PlayBoard();
    JLabel pJLabel=new JLabel("玩家");
    JLabel cJLabel=new JLabel("计算机");
    Box rightBox=new Box(BoxLayout.Y_AXIS);
    //聊天窗口
    JTextField pJField=new JTextField(20);
    JTextArea cJArea=new JTextArea(1,20);
    //计时器
    static JTextField cTime=new JTextField(10);


    //*********************创建选项窗口****************************
    JDialog opJDialog=new JDialog(f,"选项");
    JRadioButtonMenuItem easyItem=new JRadioButtonMenuItem("容易",true);
    JRadioButtonMenuItem middleItem=new JRadioButtonMenuItem("中等",true);

    Box bBox=new Box(BoxLayout.Y_AXIS);


    //*******************主程序初始化******************************
    public void init()throws Exception{
        new File("./data").mkdir();
        File userFile=new File("./data/user.dat");
        File finalFile=new File("./data/final.dat");

        final RandomAccessFile userRaf=new RandomAccessFile(userFile, "rw");
        final RandomAccessFile finalRaf=new RandomAccessFile(finalFile, "rw");
        if(userRaf.length()==0){
            highestGrade=0;
        }
        else{
            highestGrade=userRaf.readInt();
        }

        if(finalRaf.length()!=15*15*4){
            //初始化
            begin();
        }
        else{
            for(int i=0;i<=14;i++)
                for(int j=0;j<=14;j++){
                    board[i][j]=finalRaf.readInt();
            }
        }

        //计算机说话线程
        Thread csThread=new Thread(new ComputerSpeakThread());
        csThread.setDaemon(true);
        csThread.start();

        Thread timerThread=new Thread(new TimerThread());
        timerThread.start();

        //游戏声音
        String separator=System.getProperty("file.separator");
        String preface="file:"+System.getProperty("user.dir")+separator+"sounds"+separator;

        final AudioClip startMusic=Applet.newAudioClip(new URL(preface+"start.wav"));
        final AudioClip downMusic=Applet.newAudioClip(new URL(preface+"down.wav"));
        final AudioClip winMusic=Applet.newAudioClip(new URL(preface+"winning.wav"));
        final AudioClip overMusic=Applet.newAudioClip(new URL(preface+"over.wav"));
        startMusic.play();

        //选项对话框
        opJDialog.setSize(600, 300);
        bBox.add(easyItem);
        bBox.add(middleItem);

        opJDialog.add(bBox);

        //菜单事件
        newGameItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                begin();
                startMusic.play();
            }
        });

        inforItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub

            }
        });

        optionItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                opJDialog.show();
            }
        });

        exitItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });

        lookHelpItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                String[] helpString={"五子棋游戏说明:\n    我方为黑棋,电脑为白棋。\n游戏开始后,我方先走子。\n"
                        +"先使五个棋子连在一起的赢得游戏。\n游戏共有容易、中等两个等级。"
                };
                JOptionPane.showMessageDialog(f, helpString,"关于",1);
            }
        });

        aboutItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                JOptionPane.showMessageDialog(f, "作者:goodluckcwl\n 版本:1.01\n日期:2015.02.13\n联系方式:aaa@qq.com", "关于", 1);
            }
        });

        //读取图
        table=ImageIO.read(new File("./img/table_default.png"));
        black=ImageIO.read(new File("./img/black.png"));
        white=ImageIO.read(new File("./img/white.png"));
        selected=ImageIO.read(new File("./img/selected.png"));
        playerImg=ImageIO.read(new File("./icon/male.gif"));
        comImg=ImageIO.read(new File("./icon/female.gif"));
        starImg=ImageIO.read(new File("./icon/star.png"));



        //设置棋盘为合适大小
        chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));
        //棋盘事件
        chessBoard.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e){
                //将用户鼠标事件转换为棋子坐标
                int xPos=(int)((e.getX()-X_OFFSET)/rate);
                int yPos=(int)((e.getY()-Y_OFFSET)/rate);
                if(board[xPos][yPos]!=CHESS_NONE){
                    return;
                }
                System.out.println(xPos);
                System.out.println(yPos);
                board[xPos][yPos]=CHESS_BLACK;
                downMusic.play();

                chessBoard.repaint();
                //判断是否游戏结束
                Boolean playerWin=new Judgement().judgement(board,xPos,yPos,CHESS_BLACK);
                 System.out.println("win"+playerWin);
                steps++;        
                 //***********************电脑下棋******************************************
                Computer com=new Computer();
                com.checkMode(board,xPos, yPos);
                downMusic.play();
                //判断游戏是否结束
                Boolean comWin=new Judgement().judgement(board,com.getTargetPoint().x,com.getTargetPoint().y,CHESS_WHITE);
                System.out.println("computer win"+comWin);
                chessBoard.repaint();
                if(comWin){
                    overMusic.play();
                    int grade=steps*3-TimerThread.getTimer();
                    String s=grade>highestGrade?("游戏结束!\n计算机赢了!\n最高分:" +grade+"分!"):
                        ("游戏结束!\n计算机赢了!\n最后分数:" +grade+"分!");
                    highestGrade=grade>highestGrade?grade:highestGrade;
                    JOptionPane.showMessageDialog(f, s);

                }
                else if(playerWin){
                    winMusic.play();
                    int grade=10000-TimerThread.getTimer()-steps*10;
                    String s=grade>highestGrade?("游戏结束!\n你赢了!\n最高分:" +grade+"分!"):
                        ("游戏结束!\n你赢了!\n最后分数:" +grade+"分");
                    highestGrade=grade>highestGrade?grade:highestGrade;
                    JOptionPane.showMessageDialog(f, s);
                }

            }

            //鼠标退出棋盘
            public void mouseExited(MouseEvent e){
                selectedX=-1;
                selectedY=-1;
                chessBoard.repaint();
            }
        });



        chessBoard.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseMoved(MouseEvent e) {
                // TODO Auto-generated method stub
                //鼠标移动时改变选中点坐标
                selectedX=e.getX();
                selectedY=e.getY();
                chessBoard.repaint();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        });

        f.addWindowListener(new WindowListener() {

            @Override
            public void windowOpened(WindowEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void windowIconified(WindowEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void windowClosing(WindowEvent e) {
                // TODO Auto-generated method stub
                try {
                    userRaf.seek(0);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                try {
                    userRaf.writeInt(highestGrade);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                try {
                    userRaf.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                try {
                    finalRaf.seek(0);
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                for(int i=0;i<=14;i++)
                    for(int j=0;j<=14;j++){
                        try {
                            finalRaf.writeInt(board[i][j]);
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                    }
                try {
                    finalRaf.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }

            @Override
            public void windowClosed(WindowEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void windowActivated(WindowEvent e) {
                // TODO Auto-generated method stub

            }
        });

        //组装菜单
        gameMenu.add(newGameItem);
        gameMenu.add(inforItem);
        gameMenu.add(optionItem);
        gameMenu.add(exitItem);
        helpMenu.add(lookHelpItem);
        helpMenu.add(aboutItem);
        mb.add(gameMenu);
        mb.add(helpMenu);
        //玩家面板
        player.setImg(playerImg);
        computer.setImg(comImg);
        player.setPreferredSize(new Dimension(200,200));
        computer.setPreferredSize(new Dimension(200,200));
        player.repaint();
        computer.repaint();
        cTime.setEditable(false);
        cTime.setFocusable(false);
        cTime.setBackground(Color.LIGHT_GRAY);
        rightBox.add(cJLabel);
        rightBox.add(computer);

        rightBox.add(cTime);

        rightBox.add(Box.createVerticalStrut(20));
        rightBox.add(cJArea);
        rightBox.add(Box.createVerticalStrut(20));
        rightBox.add(pJLabel);
        rightBox.add(player);       
        rightBox.add(pJField);
        rightBox.add(Box.createVerticalStrut(100));

        f.add(mb,BorderLayout.NORTH);
        f.add(rightBox,BorderLayout.EAST);
        f.add(chessBoard,BorderLayout.CENTER);
        f.pack();
        f.setMaximizedBounds(new Rectangle(f.getWidth(),f.getHeight()));
        f.setVisible(true);
    }

    //*****************开始游戏初始化********************************
    public void begin(){
        timerFlag=1;
        System.out.println("线程数"+Thread.activeCount());
        //每个元素赋值为0
        for(int i=0;i<=BOARD_SIZE-1;i++){
            for(int j=0;j<=BOARD_SIZE-1;j++){
                board[i][j]=CHESS_NONE;
            }
        }
    }

    //判决类
    class Judgement{
        //连在一起的棋子数目
        private int repeat=0;
        private int chessType=CHESS_NONE;
        private Boolean win;

        //相连棋子的起始、结束坐标
        private Point connectBegin=null;
        private Point connectEnd=null;

        //当前棋子的行、列、对角线的起点
        private Point beginPoint=new Point();


        //偏移步长
        private int XOffset=0;
        private int YOffset=0;

        private int yLine[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        private int xLine[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        private int a[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

        private Boolean judgement(int[][]board,int x,int y,int type){
            win=judge(board,x,y,0,5,type)|judge(board,x,y,1,5,type)|
                    judge(board,x,y,2,5,type)|judge(board,x,y,3,5,type);
            return win;
        }

        //*******设置要判决的棋子类型**************************************
        private void setChessType(int type){
            chessType=type;
        }
        //返回相连棋子的起始坐标
        public Point getBeginPoint(){
            return this.connectBegin;
        }
        //返回相连棋子的结束坐标
        public Point getEndPoint(){
            return this.connectEnd;
        }

        //***************************************************************
        //判断在(x,y)坐标所在行、列、斜线上连在一起的棋子的数目
        //设置连在一起的棋子的起始坐标、结束坐标
        //flag:可取0,1,2,3分别代表行、列、正对角线、反对角线
        //type:指定所判断的棋子类型;
        //num:连在一起的棋子数目
        //connectBegin:连在一起的棋子的起始坐标
        //connectEnd:连在一起的棋子的结束坐标
        private Boolean judge(int[][]board,int x,int y,int flag,int num,int type){
            //所下棋子的行线、列线
            for(int i=0;i<=BOARD_SIZE-1;i++){
                yLine[i]=board[x][i];
                xLine[i]=board[i][y];
            }

            //设置棋子类型
            setChessType(type);

            switch(flag){
            //列线
            case 0:
                a=yLine;
                XOffset=0;
                YOffset=1;
                beginPoint=new Point(x,0);
                break;
            //行线
            case 1:
                a=xLine;
                XOffset=1;
                YOffset=0;
                beginPoint=new Point(0,y);
                break;
            //正对角线
            case 2:
                //所下棋子的正对角线
                int xbegin=x<=y?0:x-y;
                int ybegin=y<=x?0:y-x;
                beginPoint=new Point(xbegin,ybegin);
                for(int i=0;xbegin<=BOARD_SIZE-1&&ybegin<=BOARD_SIZE-1;xbegin++,ybegin++,i++){
                    a[i]=board[xbegin][ybegin];
                }
                XOffset=1;
                YOffset=1;
                break;
            default:
                //所下棋子的反对角线
                int xbegin2=x+y<=14?0:x+y-14;
                int ybegin2=x+y>=14?14:x+y;
                beginPoint=new Point(xbegin2,ybegin2);
                for(int i=0;xbegin2<=BOARD_SIZE-1&&ybegin2>=0;xbegin2++,ybegin2--,i++){
                    a[i]=board[xbegin2][ybegin2];
                }
                XOffset=1;
                YOffset=-1;
                break;
            }

            //判决
            for(int i=0;i<=a.length-1;i++){
                if(a[i]!=chessType){
                    continue;
                }
                repeat=0;
                connectBegin=new Point(beginPoint.x+XOffset*i,beginPoint.y+YOffset*i);
                for(int k=i;k<=a.length-1;k++){
                    if(a[k]==chessType){
                        repeat++;
                        System.out.println("repeat"+repeat);
                        if(repeat>=num){
                            System.out.println("a[0]="+a[0]);
                            System.out.println("a[1]="+a[1]);
                            System.out.println("beginPoint.x="+beginPoint.x);
                            System.out.println("beginPoint.y="+beginPoint.y);
                            System.out.println("           k="+k);
                            connectEnd=new Point(beginPoint.x+XOffset*k,beginPoint.y+YOffset*k);
                            System.out.println("num"+num);
                            return true;
                        }
                    }
                    else {
                        System.out.println("else"+k);
                        repeat=0;
                        i=k;
                        break;
                    }
                }
            }
            return false;
        }

        //检查是否有num个棋子相连,若是,则返回建议点坐标;否则返回错误点。
        private Point continuous(int[][]board,int num,int type){
            for(int i=0;i<=BOARD_SIZE-1;i++){

                for(int j=0;j<=BOARD_SIZE-1;j=j+ (i==0?1:15) ){
                    //列
                    if(judge(board, i, j, 0, num, type)){
                        if(isValid(board,getBeginPoint().x,getBeginPoint().y-1))
                            return new Point(getBeginPoint().x,getBeginPoint().y-1);
                        if(isValid(board, getEndPoint().x, getEndPoint().y+1))
                            return new Point(getEndPoint().x,getEndPoint().y+1);
                    }
                    //行
                    if(judge(board,i,j,1,num,type)){
                        if(isValid(board,getBeginPoint().x-1,getBeginPoint().y))
                            return new Point(getBeginPoint().x-1,getBeginPoint().y);
                        if(isValid(board,getEndPoint().x+1,getEndPoint().y))
                            return new Point(getEndPoint().x+1,getEndPoint().y);
                    }
                    //主对角线
                    if(judge(board, i, j, 2, num, type)){
                        if(isValid(board,getBeginPoint().x-1,getBeginPoint().y-1))
                            return new Point(getBeginPoint().x-1,getBeginPoint().y-1);
                        if(isValid(board,getEndPoint().x+1,getEndPoint().y+1))
                            return new Point(getEndPoint().x+1,getEndPoint().y+1);
                    }
                    //反对角线
                    if(judge(board, i, j, 3, num, type)){
                        if(isValid(board,getBeginPoint().x-1,getBeginPoint().y+1))
                            return new Point(getBeginPoint().x-1,getBeginPoint().y+1);
                        if(isValid(board,getEndPoint().x+1,getEndPoint().y-1))
                            return new Point(getEndPoint().x+1,getEndPoint().y-1);
                    }

                }
            }
            return null;
        }

        //检查是否有num个type棋子相连,相连的棋子前后没有其他类型的棋子,若是,则返回建议点坐标;否则返回空指针。
        private Point stepWin(int[][]board,int num,int type){
            for(int i=0;i<=BOARD_SIZE-1;i++){
                for(int j=0;j<=BOARD_SIZE-1;j=j+ (i==0?1:15) ){
                    //列
                    if(judge(board, i, j, 0, num, type)
                        &&isValid(board,getBeginPoint().x,getBeginPoint().y-1)
                        &&isValid(board, getEndPoint().x, getEndPoint().y+1)){
                            return new Point(getBeginPoint().x,getBeginPoint().y-1);                        
                    }
                    //行
                    if(judge(board,i,j,1,num,type)
                        &&isValid(board,getBeginPoint().x-1,getBeginPoint().y)
                        &&isValid(board,getEndPoint().x+1,getEndPoint().y))
                            return new Point(getBeginPoint().x-1,getBeginPoint().y);    

                    //主对角线
                    if(judge(board, i, j, 2, num, type)
                        &&isValid(board,getBeginPoint().x-1,getBeginPoint().y-1)
                        &&isValid(board,getEndPoint().x+1,getEndPoint().y+1))
                        return new Point(getBeginPoint().x-1,getBeginPoint().y-1);

                    //反对角线
                    if(judge(board, i, j, 3, num, type)
                        &&isValid(board,getBeginPoint().x-1,getBeginPoint().y+1)
                        &&isValid(board,getEndPoint().x+1,getEndPoint().y-1))
                            return new Point(getBeginPoint().x-1,getBeginPoint().y+1);


                }
            }

            return null;

        }

        private Boolean isValid(int board[][],int xPos,int yPos){
            return xPos>=0&&xPos<=14&&yPos>=0&&yPos<=14&&board[xPos][yPos]==CHESS_NONE;
        }

    }


    //计算机下棋类
    class Computer{ 
        Computer(){};

        Random random=new Random();
        //计算机下棋坐标
        private  Point targetPoint;
        {
            targetPoint=new Point(0,0);
        }

        public Point getTargetPoint(){
            return this.targetPoint;
        }

        public void randomMode(){
            do{
                targetPoint.x=random.nextInt()%BOARD_SIZE;
                targetPoint.y=random.nextInt()%BOARD_SIZE;
                targetPoint.x=abs(targetPoint.x);
                targetPoint.y=abs(targetPoint.y);
            }while(ChessFive.board[targetPoint.x][targetPoint.y]!=CHESS_NONE);

            ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
        }

        public void followMode(int xPos,int yPos){
            int ch=random.nextInt(4);
            int i=0,j=0;
            switch (ch) {
            case 0:
                i=random.nextInt()%2;
                j=random.nextInt()%2;
                break;
            case 1:
                i=random.nextInt()%2;
                break;
            case 2:
                j=random.nextInt()%2;
                break;
            default:
                break;
            }
            do{
                targetPoint.x=abs((xPos+i)%BOARD_SIZE);
                targetPoint.y=abs((yPos+j)%BOARD_SIZE);
                i++;j--;
                System.out.println("xC"+targetPoint.x);
                System.out.println("yC"+targetPoint.y);
            }while(ChessFive.board[targetPoint.x][targetPoint.y]!=CHESS_NONE);
            ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;          
        }

        public void checkMode(int[][] board,int x,int y){
            Judgement jug=new Judgement();
            //判断白方是否能一步取胜
            if(jug.continuous(board,4,CHESS_WHITE)!=null){
                targetPoint=jug.continuous(board,4,CHESS_WHITE);
                ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
                return ;
            }

            //判断黑方是否能一步取胜
            if(jug.continuous(board, 4, CHESS_BLACK)!=null){
                targetPoint=jug.continuous(board, 4, CHESS_BLACK);
                ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
                return;
            }
            else{
                //黑方无法一步取胜,白方寻找连在一起的3个棋子
                if(jug.continuous(board, 3, CHESS_WHITE)!=null){
                    targetPoint=jug.continuous(board, 3, CHESS_WHITE);
                    ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
                    return;
                }
            }

            //判断黑方是否能两步取胜
            if(jug.stepWin(board, 3, CHESS_BLACK)!=null){
                targetPoint=jug.stepWin(board, 3, CHESS_BLACK);
                ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
                return ;

            }

            //判断黑方是否有三个棋子连在一起
            if(jug.continuous(board, 3, CHESS_BLACK)==null){
                //寻找两个连在一起的白棋
                if(jug.continuous(board, 2, CHESS_WHITE)!=null){
                    targetPoint=jug.continuous(board, 2, CHESS_WHITE);
                    ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;
                    return;
                }
            }

            //防守
            for(int num=4;num>=1;num--){
                System.out.println("num="+num);
                //列
                if(jug.judge(board, x, y,0,num,CHESS_BLACK)){
                    targetPoint.x=x;
                    if(isValid(board,targetPoint.x, jug.getEndPoint().y+1)){
                        targetPoint.y=jug.getEndPoint().y+1;
                        System.out.println("进入列,后");
                        break;
                    }
                    if(isValid(board, targetPoint.x, jug.getBeginPoint().y-1)){
                        targetPoint.y=jug.getBeginPoint().y-1;
                        System.out.println("进入列,前");
                        break;
                    }
                }
                //行
                if(jug.judge(board, x, y,1,num,CHESS_BLACK)){
                    targetPoint.y=y;
                    if(isValid(board,jug.getEndPoint().x+1, targetPoint.y)){
                        targetPoint.x=jug.getEndPoint().x+1;
                        System.out.println("进入行,后");
                        break;
                    }
                    if(isValid(board,jug.getBeginPoint().x-1,targetPoint.y)){
                        targetPoint.x=jug.getBeginPoint().x-1;
                        System.out.println("进入行,前");
                        break;

                    }
                }
                //正对角线
                if(jug.judge(board, x, y, 2, num, CHESS_BLACK)){
                    System.out.println("正对角x,y");
                    System.out.println(jug.getEndPoint().x+1);
                    System.out.println(jug.getEndPoint().y+1);

                    if(isValid(board, jug.getEndPoint().x+1, jug.getEndPoint().y+1)){
                        targetPoint.x=jug.getEndPoint().x+1;
                        targetPoint.y=jug.getEndPoint().y+1;
                        System.out.println("进入正对角,后");
                        break;
                    }
                    if(isValid(board, jug.getBeginPoint().x-1, jug.getBeginPoint().y-1)){
                        targetPoint.x=jug.getBeginPoint().x-1;
                        targetPoint.y=jug.getBeginPoint().y-1;
                        System.out.println("进入正对角,前");
                        break;
                    }
                }
                //反对角线
                if(jug.judge(board, x, y,3, num,CHESS_BLACK)){
                    if(isValid(board,jug.getEndPoint().x+1,jug.getEndPoint().y-1)){
                        targetPoint.x=jug.getEndPoint().x+1;
                        targetPoint.y=jug.getEndPoint().y-1;
                        System.out.println("进入反对角线,后");
                        break;
                    }
                    if(isValid(board,jug.getBeginPoint().x-1,jug.getBeginPoint().y+1)){
                        targetPoint.x=jug.getBeginPoint().x-1;
                        targetPoint.y=jug.getBeginPoint().y+1;
                        System.out.println("进入反对角线,前");
                        break;
                    }
                }
            }
            ChessFive.board[targetPoint.x][targetPoint.y]=CHESS_WHITE;          
        }

        private Boolean isValid(int board[][],int xPos,int yPos){
            return xPos>=0&&xPos<=14&&yPos>=0&&yPos<=14&&board[xPos][yPos]==CHESS_NONE;
        }

        private int abs(int n){
            return n=n<=0?-n:n;
        }

    }

    //棋盘类,绘制棋盘与棋子
    class ChessBoard extends JPanel{
        //重写paint方法
        public void paint(Graphics g){
            //绘制五子棋棋盘
            g.drawImage(table,0,0,null);
            //绘制选中点的红框
            if(selectedX>=0&&selectedY>=0){
                g.drawImage(selected,selectedX-selected.getHeight()/2,
                        selectedY-selected.getWidth()/2,null);
            }

            //遍历数组,绘制棋子
            for(int i=0;i<=BOARD_SIZE-1;i++){
                for(int j=0;j<=BOARD_SIZE-1;j++){
                    if(board[i][j]==CHESS_BLACK){
                        g.drawImage(black, i*rate+X_OFFSET, j*rate+Y_OFFSET, null);
                    }
                    else if(board[i][j]==CHESS_WHITE){
                        g.drawImage(white, i*rate+X_OFFSET, j*rate+Y_OFFSET, null);
                    }

                }
            }
        }
    }

    //玩家面板类,绘制玩家画像
    class PlayBoard extends JPanel{
        private BufferedImage img;
        public void setImg(BufferedImage bufferedImage){
            img=bufferedImage;
        }
        public void paint(Graphics g){
            g.drawImage(img, 0, 0,null);
            g.drawImage(starImg, 110, 80, null);
            g.drawImage(starImg, 120, 80, null);
            g.drawImage(starImg, 130, 80, null);
        }
    }

    //计时线程
    static class TimerThread implements Runnable{
        private static int i=0;
        public void run(){
            while(true){
                timerFlag=0;
                cTime.setText("    游戏时间:"+i+"s");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                i++;
                if(timerFlag==1)
                    i=0;
            }
        }

        static public int getTimer(){
            return i;
        }
    }



    //聊天窗口线程
    class ComputerSpeakThread implements Runnable{
        public void run(){
            String []comS={"正值年少,何不长啸","悟已往之不谏,知来者之可追","得失随缘,心无增减","难过|总不能什么"
                    +"都不努力就\n指望着做得好吧","生活就像蒲公英,看似*,却身不由己","成大事者,不计较一时一事之得失",
                    "但行其事,莫问前程","人就是这样,记不得理所当然的好,\n只记得偶尔的疲惫","暖日生烟,夜凉如水",
                    "踏实做人,认真做事","拆下肋骨当火把","盲学,弃,致用,纯粹","失败只代表你还不够努力",
                    "经世纬国,*志远","行多久,方为执,思多久,方为远"};
            //聊天窗口显示
            Random r=new Random();
            while(true){
                int i=r.nextInt(15);
                cJArea.setText(null);
                cJArea.append(comS[i]);
                cJArea.setFocusable(false);

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String []args)throws Exception{
        new ChessFive().init();
    }
}

游戏效果图

Java实战:仿QQ游戏大厅五子棋

游戏逻辑还是有些问题,存在一些bug。

相关标签: 五子棋