一个简单的JAVA五子棋

参照书本写了一个很简单的五子棋程序


主要有如下功能:

1、初始化棋盘initBoard()

2、下棋play()

未完成的功能:

1、没有实现棋子AI

2、没有实现连机

3、UI可以继续优化

个人感觉五子棋只有在判断输赢的算法上稍微需要思考一下,别的地方都可以参考书本或者网络自己完成。


具体如下:

1、首先定义一些常量和变量

	// 定义一个二维数组来充当棋盘
	private static String[][] board;
    //五个棋子即赢
	private final int WIN_COUNT = 5;
	// 棋盘大小
	public static final int BOARD_SIZE = 15;
	//棋盘,黑棋,白棋和选择框图标
	BufferedImage table;
	BufferedImage black;
	BufferedImage white;
	BufferedImage selected;   
	//棋盘像素
	private final int TABLE_WIDTH = 535;
	private final int TABLE_HEIGHT = 536;
	//棋盘坐标的像素值和棋盘数组之间的比率
	private final int RATE = TABLE_WIDTH / BOARD_SIZE;
	//棋盘坐标的像素值和棋盘数组之间的偏移距离
	private final int X_OFFSET = 5;
	private final int Y_OFFSET = 6;  
	//游戏窗口
	JFrame f = new JFrame("五子棋");
	//棋盘对应的Canvas组件
	ChessBoard chessBoard = new ChessBoard();
	//当前选中点坐标
	private int selectedX = -1;
	private int selectedY = -1;

2、初始化棋盘

	public void initBoard() throws IOException {
		table = ImageIO.read(new File("image/board.jpg"));
		black = ImageIO.read(new File("image/black.gif"));
		white = ImageIO.read(new File("image/white.gif"));
		selected = ImageIO.read(new File("image/selected.gif"));

		// 初始化棋盘数组
		board = new String[BOARD_SIZE][BOARD_SIZE];
		// 把每个元素赋值为“十”
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				board[i][j] = "十";
			}
		}

		chessBoard.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));
		f.add(chessBoard);
		f.pack();
		f.setVisible(true);
	}

3、下棋

public void play() {
		chessBoard.addMouseListener(new MouseAdapter() {
			@Override
			//用户点击事件转换成棋子坐标
			public void mouseClicked(MouseEvent e) {
				int xPos = (e.getX() - X_OFFSET) / RATE;
				int yPos = (e.getY() - Y_OFFSET) / RATE;
				if (board[xPos][yPos] != "●" && board[xPos][yPos] != "○") {
					board[xPos][yPos] = "●";
				}
				
				//电脑随机生成坐标,这里可以优化算法,做出AI,我自己写的比较简单,就用随机函数 实现了下。
				int[] computerPosArr = computerPlay();
				board[computerPosArr[0]][computerPosArr[1]] = "○";

				chessBoard.repaint();

				if (isWin(xPos, yPos, "●")) {
				//	System.out.println("black win");
					JOptionPane.showMessageDialog(null, "黑棋获得了胜利");
				}
				if (isWin(xPos, yPos, "○")) {
				//	System.out.println("black win");
					JOptionPane.showMessageDialog(null, "白棋获得了胜利");
				}
			}

			@Override
		public void mouseExited(MouseEvent e) {
				selectedX = -1;
				selectedY = -1;
				// chessBoard.repaint();
			}
		});

		chessBoard.addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			//当鼠标移动时候,改变选中点坐标
			public void mouseMoved(MouseEvent e) {
				selectedX = (e.getX() - X_OFFSET) / RATE;
				selectedY = (e.getY() - Y_OFFSET) / RATE;
				chessBoard.repaint();
			}
		});
	}

4、电脑的随机下棋

	public int[] computerPlay() {
		int posX = (int) (Math.random() * (BOARD_SIZE - 1));
		int posY = (int) (Math.random() * (BOARD_SIZE - 1));
	
		while (board[posX][posY] != "十") {
			posX = (int) (Math.random() * (BOARD_SIZE - 1));
			posY = (int) (Math.random() * (BOARD_SIZE - 1));
		}
		int[] result = { posX, posY };
		return result;
	}

5、判断输赢

	
	public boolean isWin(int posX, int posY, String ico) {
		// 直线起点的X坐标
		int startX = 0;
		// 直线起点Y坐标
		int startY = 0;
		// 直线结束pX坐标
		int endX = BOARD_SIZE - 1;
		// 直线结束Y坐标
		int endY = BOARD_SIZE - 1;
		// 同条直线上相邻棋子累积数
		int sameCount = 0;
		int temp = 0;

		// 计算起点的最小X坐标与Y坐标
		temp = posX - WIN_COUNT + 1;
		startX = temp < 0 ? 0 : temp;
		temp = posY - WIN_COUNT + 1;
		startY = temp < 0 ? 0 : temp;
		// 计算终点的最大X坐标与Y坐标
		temp = posX + WIN_COUNT - 1;
		endX = temp > BOARD_SIZE - 1 ? BOARD_SIZE - 1 : temp;
		temp = posY + WIN_COUNT - 1;
		endY = temp > BOARD_SIZE - 1 ? BOARD_SIZE - 1 : temp;
		// 从左到右方向计算相同相邻棋子的数目
		String[][] board = Gobang.getBoard();
		for (int i = startY; i < endY; i++) {
			if (board[posX][i] == ico && board[posX][i + 1] == ico) {
				sameCount++;
			} else if (sameCount != WIN_COUNT - 1) {
				sameCount = 0;
			}
		}
		if (sameCount == 0) {
			// 从上到下计算相同相邻棋子的数目
			for (int i = startX; i < endX; i++) {
				if (board[i][posY] == ico && board[i + 1][posY] == ico) {
					sameCount++;
				} else if (sameCount != WIN_COUNT - 1) {
					sameCount = 0;
				}
			}
		}
		if (sameCount == 0) {
			// 从左上到右下计算相同相邻棋子的数目
			int j = startY;
			for (int i = startX; i < endX; i++) {
				if (j < endY) {
					if (board[i][j] == ico && board[i + 1][j + 1] == ico) {
						sameCount++;
					} else if (sameCount != WIN_COUNT - 1) {
						sameCount = 0;
					}
					j++;
				}
			}
		}

		if (sameCount == 0) {
			// 从左上下到右上计算相同相邻棋子的数目
			int j = endY;
			for (int i = startX; i < endX; i++) {
				if (j > startY) {
					if (board[i][j] == ico && board[i + 1][j - 1] == ico) {
						sameCount++;
					} else if (sameCount != WIN_COUNT - 1) {
						sameCount = 0;
					}
					j--;
				}
			}
		}

		return sameCount >= WIN_COUNT - 1 ? true : false;
	}

6、画棋盘

	public class ChessBoard extends JPanel {
		@Override
		public void paint(Graphics g) {
			g.drawImage(table, 0, 0, null);
			if (selectedX >= 0 && selectedY >= 0) {
				g.drawImage(selected, selectedX * RATE + X_OFFSET, selectedY
						* RATE + Y_OFFSET, null);
				for (int i = 0; i < BOARD_SIZE; i++) {
					for (int j = 0; j < BOARD_SIZE; j++) {
						if (board[i][j].equals("●")) {
							g.drawImage(black, i * RATE + X_OFFSET, j * RATE
									+ Y_OFFSET, null);
						}
						if (board[i][j].equals("○")) {
							g.drawImage(white, i * RATE + X_OFFSET, j * RATE
									+ Y_OFFSET, null);
						}
					}
				}
			}

		}
	}
7、主函数main

	
	public static void main(String args[]) throws IOException{
		Gobang	gobang=new Gobang();
		gobang.initBoard();
		gobang.play();						
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值