java五子棋人机.doc
介绍:这是一款很简单的人机对战五子棋,只实现了简单的防守功能,适合刚开始设计五子棋的朋友参考。程序执行结果:框架程序:package wuziqi;import java.awt.BorderLayout;import java.awt.Color;import javax.swing.JFrame;/* * 五子棋 */public class MainFrame extends JFrame public static void main(String args) MainPanel panel = new MainPanel();MainFrame frame = new MainFrame("五子棋");frame.setSize(680,680); panel.setBackground(Color.LIGHT_GRAY);frame.add(panel,BorderLayout.CENTER);panel.addMouseListener(panel);frame.setVisible(true);frame.setDefaultCloseOperation(3);frame.setLocationRelativeTo(null); public MainFrame() super(); public MainFrame(String str) super(str); 面板设计:package wuziqi;import java.awt.*;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;/* * JFrame中的层次分布及相对关系是:最底层是:JRootPane; * 第二层是:JlayerPane;最上层就是ContentPane,也正是我们常说的内容面板。 * 所以一般我们拖放的控件就是在ContentPane层上。 */import javax.swing.JOptionPane;/* * 五子棋的面板设计 */public class MainPanel extends Panel implements MouseListener private static final int COLUMN = 16;/ 列数private static final int ROW = 16;/ 行数private static final int GAP = 40;/ 间距private static boolean isBlack = true; / 判断是否是黑棋private static int click_X; / 点击时候的x坐标private static int click_Y; / 点击时候的y坐标private char allChess = new charROWCOLUMN; / 存下了旗子的位置public MainPanel() super();for (int i = 0; i < allChess.length; i+) for (int j = 0; j < allChessi.length; j+) allChessij = '*' / 初始化数组allChess,*表示没有棋子存在/* 画棋盘要放在paint(Graphics g)里面 */public void paint(Graphics g) for (int i = 0; i < ROW; i+) / 划横线g.setColor(Color.BLACK); / 画线为黑色,g.drawLine(20, 20 + i * GAP, 640 - 20, 20 + i * GAP);/ 棋盘间隔分布for (int i = 0; i < COLUMN; i+) / 划纵线g.setColor(Color.BLACK);g.drawLine(20 + i * GAP, 20, 20 + i * GAP, 640 - 20); / 棋盘间隔分布/ 画棋子 w表示白棋 b表示黑棋for (int i = 0; i < allChess.length; i+) / allChess.length是行数for (int j = 0; j < allChessi.length; j+) / allChessi.length是列数if (allChessij = 'w') g.setColor(Color.WHITE);g.fillOval(5 + i * 40, 5 + j * 40, 30, 30);if (allChessij = 'b') g.setColor(Color.BLACK);g.fillOval(5 + i * 40, 5 + j * 40, 30, 30);/ 判断黑棋是否已经有连续连在一起了,有则开始拦截public void isCon(int x,int y)char ch = allChessxy;/* 横向判断 */int RLastX = x;/ 横向判断有多少个连在一起了while (RLastX >= 0 && allChessRLastXy = ch) RLastX-;int LRLastX=RLastX; /标记最左边的位置int RNum = 0;/ 统计横向相同的棋子数RLastX+;while (RLastX < allChess.length&& allChessRLastXy = ch) RNum+;RLastX+;/* 纵向判断 */ 横向判断有多少个连在一起了int LLastY = y;while (LLastY >= 0 && allChessxLLastY = ch) LLastY-;int LLLastY=LLastY;/标记最上面棋盘的位置int LNum = 0;/ 统计纵向相同的棋子数LLastY+;while ( LLastY < allChessx.length&& allChessxLLastY = ch) LLastY+;LNum+;/* 左下右上判断 */int LDLastX = x;int RULastY = y;/ 横向判断有多少个连在一起了while (LDLastX >= 0 && RULastY < allChessx.length&& allChessLDLastXRULastY = ch) LDLastX-;RULastY+;int LLDLastX=LDLastX;/记录左下方棋盘的x坐标int DRULastY=RULastY;/记录左下方棋盘的y坐标int LDNum = 0;LDLastX+;RULastY-;while (RULastY >= 0&& LDLastX < allChess.length&& allChessLDLastXRULastY = ch) LDNum+;LDLastX+;RULastY-;/* 左上右下判断 */int RULastX = x;int LDLastY = y;/ 横向判断有多少个连在一起了while (RULastX >= 0 && LDLastY >= 0 && allChessRULastXLDLastY = ch) RULastX-;LDLastY-;int LRULastX=RULastX;/记录左上棋子的横坐标int ULDLastY=LDLastY;/记录左上棋子的横坐标int RUNum = 0;RULastX+;LDLastY+;while (RULastX >= 0 && RULastX < allChess.length&& LDLastY < allChessx.length&& allChessRULastXLDLastY = ch) RULastX+;LDLastY+;RUNum+;/取最大值也就是最危险的状况int max=0;if(max<RNum) max=RNum;if(max<LNum) max=LNum;if(max<LDNum) max=LDNum;if(max<RUNum) max=RUNum;/在最危险的地方放置棋子if(max=RNum)if(max=1)if(x>0)allChessx-1y='w'isBlack=true;return;elseif(allChessx+1y='*')allChessx+1y='w'isBlack=true;return;elsedo x = (int) (Math.round(float) (Math.random() * 15);y = (int) (Math.round(float) (Math.random() * 15); while(allChessxy != '*'); allChessxy = 'w'/ 令棋盘(x,y)设置为白棋 isBlack = true; isBlack=true;return;elseif(allChessLRLastXy='*')allChessLRLastXy='w'isBlack=true;return;else if(allChessRLastXy='*')allChessRLastXy='w'isBlack=true;return;/上下判断else if(max=LNum)if(allChessxLLLastY='*')/最上方的棋盘是否是空的allChessxLLLastY='w'isBlack=true;return;else if(allChessxLLastY='*')/最下方棋盘是否为空allChessxLLastY='w'isBlack=true;return;/左上右下else if(max=LDNum)if(allChessLLDLastXDRULastY='*')/最上方的棋盘是否是空的allChessLLDLastXDRULastY='w'isBlack=true;return;else if(allChessLDLastXRULastY='*')/最下方棋盘是否为空allChessLDLastXRULastY='w'isBlack=true;return;/左下右上else if(max=RUNum)if(allChessLRULastXULDLastY='*')/最上方的棋盘是否是空的allChessLRULastXULDLastY='w'isBlack=true;return;else if(allChessRULastXLDLastY='*')/最下方棋盘是否为空allChessRULastXLDLastY='w'isBlack=true;return;/ 判断是否为5个相同的棋子,是返回true,否返回falsepublic boolean isWin(int x, int y, boolean isColor) char ch = allChessxy;/* 横向判断 */int RLastX = x;/ 横向判断是否到达5个相同的棋子,先向左回溯相同颜色,再向右搜索是否有连续5个while (RLastX >= 0 && allChessRLastXy = ch) RLastX-;int RNum = 0;/ 统计横向相同的棋子数RLastX+;int itemRLastx = RLastX + 5;while (RLastX < itemRLastx && RLastX < allChess.length&& allChessRLastXy = ch) RNum+;RLastX+;/* 纵向判断 */ 纵向判断是否到达5个相同的棋子,先向上回溯连续的同一颜色棋子,再向下连续搜索5颗棋子看是否连续int LLastY = y;while (LLastY >= 0 && allChessxLLastY = ch) LLastY-;int LNum = 0;/ 统计纵向相同的棋子数LLastY+;int itemLLastY = LLastY + 5;while (LLastY < itemLLastY && LLastY < allChessx.length&& allChessxLLastY = ch) LLastY+;LNum+;/* 左下右上判断 */int LDLastX = x;int RULastY = y;/ 往左下回溯相同颜色的旗子,再往右上连续搜索5颗看看是否颜色相同while (LDLastX >= 0 && RULastY < allChessx.length&& allChessLDLastXRULastY = ch) LDLastX-;RULastY+;int LDNum = 0;LDLastX+;RULastY-;int itemLDLastX = LDLastX + 5;while (LDLastX < itemLDLastX && RULastY >= 0&& LDLastX < allChess.length&& allChessLDLastXRULastY = ch) LDNum+;LDLastX+;RULastY-;/* 左上右下判断 */int RULastX = x;int LDLastY = y;/ 往左上回溯相同颜色的旗子,再往右下连续搜索5颗看看是否颜色相同while (RULastX >= 0 && LDLastY >= 0 && allChessRULastXLDLastY = ch) RULastX-;LDLastY-;int RUNum = 0;RULastX+;LDLastY+;int itemLDLastY = LDLastY + 5;while (RULastX >= 0 && RULastX < allChess.length&& LDLastY < itemLDLastY && LDLastY < allChessx.length&& allChessRULastXLDLastY = ch) RULastX+;LDLastY+;RUNum+;if (RNum = 5 | LNum = 5 | RUNum = 5 | LDNum = 5) return true;return false;Overridepublic void mouseClicked(MouseEvent e) / 鼠标按下时候画出棋子public void mousePressed(MouseEvent e) / 鼠标点击事件处理过程/ 获取点击位置坐标int click_x = e.getX();int click_y = e.getY();/* * 返回x最接近的整数,如果x的小数部分大于等于0.5,返回值是大于x的最小整数, 否则round函数返回小于等于x的最大整数 */int chess_x = Math.round(float) (click_x - 20) / GAP);int chess_y = Math.round(float) (click_y - 20) / GAP);click_X = chess_x; / 获得点击后的横坐标click_Y = chess_y; / 获得点击后的纵坐标/ 玩家执黑棋if (isBlack = true && allChesschess_xchess_y = '*') allChesschess_xchess_y = 'b'/ 令棋盘(x,y)设置为黑棋isBlack = false;repaint();if (isWin(chess_x, chess_y, isBlack) if (isBlack) / 弹出对话框JOptionPane.showMessageDialog(null, "白棋赢了");System.exit(0); else JOptionPane.showMessageDialog(null, "黑棋赢了");System.exit(0);if (isBlack = false) / 防止再次点击已有棋子区域时下了白棋isCon(chess_x, chess_y);/* * do chess_x = (int) (Math.round(float) (Math.random() * 15); * chess_y = (int) (Math.round(float) (Math.random() * 15); * System.out.println(chess_x + " " + chess_y); while * (allChesschess_xchess_y != '*'); * System.out.println(allChesschess_xchess_y); * allChesschess_xchess_y = 'w'/ 令棋盘(x,y)设置为白棋 isBlack = true; * * /* if(isBlack=false&&allChesschess_xchess_y='*') * allChesschess_xchess_y = 'w' isBlack = true; /令棋盘(x,y)设置为白棋 * */ 刷新页面repaint();if (isWin(chess_x, chess_y, isBlack) if (isBlack) / 弹出对话框JOptionPane.showMessageDialog(null, "白棋赢了"); else JOptionPane.showMessageDialog(null, "黑棋赢了");public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e)