Java课程设计——五子棋

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;

public class ChessBoard extends JPanel implements MouseListener {
	public static int 边界距离 = 30;// 距离边缘的距离
	public static int 间距 = 35;// 两条线之间的间距
	public static int ROWS = 4;// 行数
	public static int COLS = 4;// 列数
	Point[] chessList = new Point[(ROWS + 1) * (COLS + 1)];// 初始化数组
	boolean isBlack = true;// 默认开始是黑棋先下
	boolean gameOver = false;// 游戏是否结束
	int chessCount;// 当前棋盘的棋子个数
	int xIndex, yIndex;// 当前刚下棋子的索引

	public ChessBoard() {
		setBackground(Color.PINK);// 设置背景颜色
		addMouseListener(this);// 添加事件监听器
		addMouseMotionListener(new MouseMotionListener() {

			
			public void mouseMoved(MouseEvent e) {
				int x1 = (e.getX() - 边界距离 + 间距 / 2) / 间距;
				int y1 = (e.getY() - 边界距离 + 间距 / 2) / 间距;// 将鼠标单击的坐标位置转化为网格索引
				if (x1 < 0 || x1 > ROWS || y1 < 0 || y1 > COLS || gameOver|| findChess(x1, y1)) {// 游戏已经结束,不能下;落在棋盘外,不能下;x,y位置已经有棋子存在,不能下
					setCursor(new Cursor(Cursor.DEFAULT_CURSOR));// 设置成默认形状
				} 
			}

			
			public void mouseDragged(MouseEvent e) {
			}
		});
	}

	/* 绘制 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);// 画棋盘
		for (int i = 0; i <= ROWS; i++) {// 画横线
			g.drawLine(边界距离, 边界距离 + i * 间距, 边界距离 + COLS* 间距, 边界距离 + i * 间距);
		}
		for (int i = 0; i <= COLS; i++) {// 画直线
			g.drawLine(边界距离 + i * 间距, 边界距离, 边界距离 + i * 间距,边界距离 + ROWS * 间距);
		}
		/* 画棋子 */
		for (int i = 0; i < chessCount; i++) {
			int xPos = chessList[i].getX() * 间距 + 边界距离;// 网格交叉的x坐标
			int yPos = chessList[i].getY() * 间距 + 边界距离;// 网格交叉的y坐标
			g.setColor(chessList[i].getColor());// 设置颜色
			g.fillOval(xPos - Point.ZHIJING / 2, yPos - Point.ZHIJING / 2,Point.ZHIJING, Point.ZHIJING);
			if (i == chessCount - 1) {
				g.setColor(Color.red);// 标记最后一个棋子四周为红色
				g.drawRect(xPos - Point.ZHIJING / 2,yPos - Point.ZHIJING / 2, Point.ZHIJING,Point.ZHIJING);
			}
		}
	}

	
	public void mousePressed(MouseEvent e) {// 鼠标按键在组件上按下时调用
		if (gameOver)// 游戏已经结束,不能下
			return;
		String colorName = isBlack ? "黑棋" : "白棋";
		xIndex = (e.getX() - 边界距离 + 间距 / 2) / 间距;
		yIndex = (e.getY() - 边界距离 + 间距 / 2) / 间距;// 将鼠标单击的坐标位置转化为网格索引
		if (xIndex < 0 || xIndex > ROWS || yIndex < 0 || yIndex > COLS)// 棋子落在棋盘外,不能下
			return;
		if (findChess(xIndex, yIndex))// x,y位置已经有棋子存在,不能下
			return;

		Point ch = new Point(xIndex, yIndex, isBlack ? Color.black : Color.white);
		chessList[chessCount++] = ch;
		repaint();// 通知系统重新绘制
		if (isWin()) {
			String msg = String.format("恭喜,%s赢~", colorName);
			JOptionPane.showMessageDialog(this, msg);
			gameOver = true;
		} else if (chessCount == (COLS + 1) * (ROWS + 1)) {
			String msg = String.format("平局");
			JOptionPane.showMessageDialog(this, msg);
			gameOver = true;
		}
		isBlack = !isBlack;
	}

	
	public void mouseClicked(MouseEvent e) {// 鼠标按键在组件上单击(按下并释放)时调用
	}

	
	public void mouseReleased(MouseEvent e) {// //鼠标按键在组件上释放时调用
	}

	
	public void mouseEntered(MouseEvent e) {// 鼠标进入组件时调用
	}

	
	public void mouseExited(MouseEvent e) {// 鼠标离开组件时调用
	}

	private boolean findChess(int x, int y) {//寻找棋子
		for (Point c : chessList) {
			if (c != null && c.getX() == x && c.getY() == y)
				return true;
		}
		return false;
	}

	/* 左右寻找 */
	private boolean isWin() {
		int continueCount = 1;// 连续棋子的个数
		for (int x = xIndex - 1; x >= 0; x--) {// 横向向左寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, yIndex, c) != null) {
				continueCount++;
			} else
				break;
		}
		for (int x = xIndex + 1; x <= ROWS; x++) {// 横向向右寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, yIndex, c) != null) {
				continueCount++;
			} else
				break;
		}
		if (continueCount >= 5) {// 判断记录数大于等于五,即表示此方获胜
			return true;
		} else
			continueCount = 1;
		//上下寻找
		for (int y = yIndex - 1; y >= 0; y--) {// 纵向向上寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(xIndex, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		for (int y = yIndex + 1; y <= ROWS; y++) {// 纵向向下寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(xIndex, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		if (continueCount >= 5) {// 判断记录数大于等于五,即表示此方获胜
			return true;
		} else
			continueCount = 1;
		//左下到右上对角线寻找
		for (int x = xIndex + 1, y = yIndex - 1; y >= 0 && x <= COLS; x++, y--) {// 右上寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		for (int x = xIndex - 1, y = yIndex + 1; y <= ROWS && x >= 0; x--, y++) {// 左下寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		if (continueCount >= 5) {// 判断记录数大于等于五,即表示此方获胜
			return true;
		} else
			continueCount = 1;
		//右下到左上对角线寻找
		for (int x = xIndex - 1, y = yIndex - 1; y >= 0 && x >= 0; x--, y--) {// 左上寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		for (int x = xIndex + 1, y = yIndex + 1; y <= ROWS && x <= COLS; x++, y++) {// 右下寻找
			Color c = isBlack ? Color.black : Color.white;
			if (getChess(x, y, c) != null) {
				continueCount++;
			} else
				break;
		}
		if (continueCount >= 5) {// 判断记录数大于等于五,即表示此方获胜
			return true;
		} else
			continueCount = 1;
		return false;
	}
	
	
	private Point getChess(int xIndex, int yIndex, Color color) {
		for (Point c : chessList) {
			if (c != null && c.getX() == xIndex && c.getY() == yIndex&& c.getColor() == color)
				return c;
		}
		return null;
	}

	public void restartGame() {// 清除棋子
		for (int i = 0; i < chessList.length; i++)
			chessList[i] = null;
		/* 恢复游戏相关的变量值 */
		isBlack = true;
		gameOver = false;// 游戏是否结束
		chessCount = 0;// 当前棋盘的棋子个数
		repaint();
	}

	public void goback() {
		if (chessCount == 0)
			return;
		chessList[chessCount - 1] = null;
		chessCount--;
		if (chessCount > 0) {
			xIndex = chessList[chessCount - 1].getX();
			yIndex = chessList[chessCount - 1].getY();
		}
		isBlack = !isBlack;
		repaint();
	}

	//排版
	public Dimension getPreferredSize() {
		return new Dimension(边界距离 * 2 + 间距 * COLS, 边界距离 * 2+ 间距 * ROWS);
	}

}

import java.awt.*;
public class Point {
	private int x;
	private int y;
	private Color color;
	public static int ZHIJING = 32;
	
	public Point(int x,int y,Color c){
		this.x=x;
		this.y=y;
		color=c;
	}
	public int getX(){
		return x;
	}
	public int getY(){
		return y;
	}
	public Color getColor(){
		return color;
	}
}

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class StartChessJFrame extends JFrame {
	private ChessBoard chessBoard;// 面板
	private Panel toolbar;// 工具条面板
	private Button startButton;
	private Button backButton;
	private Button exitButton;

	public StartChessJFrame() {
		setTitle("五子棋");
		chessBoard = new ChessBoard();
		MyItemListener lis = new MyItemListener();// 初始化按钮事件监听器内部类
		toolbar = new Panel();
		startButton = new Button("重新开始");
		backButton = new Button("悔棋");
		exitButton = new Button("退出");
		toolbar.setLayout(new GridLayout(0, 1));// 布局
		toolbar.add(backButton);
		toolbar.add(startButton);
		toolbar.add(exitButton);
		startButton.addActionListener(lis);
		backButton.addActionListener(lis);
		exitButton.addActionListener(lis);// 按钮注册监听事件
		add(toolbar, BorderLayout.WEST);
		add(chessBoard);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
	}

	private class MyItemListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			Object obj = e.getSource();// 获取事件源
			if (obj == startButton) {
				
				chessBoard.restartGame();
			} else if (obj == exitButton) {
				System.exit(0);// 结束
			} else if (obj == backButton) {
				if (!chessBoard.gameOver)// 游戏结束时不能撤销
					chessBoard.goback();
			}
		}
	}

	public static void main(String[] args) {
		StartChessJFrame f = new StartChessJFrame();// 创建主框架
		f.setVisible(true);// 显示
	}
}
  • 15
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁月漫长_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值