码迷,mamicode.com
首页 > 其他好文 > 详细

五子棋游戏源码

时间:2014-12-29 21:36:02      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:java   eclipse   源码   五子棋   界面   


技术分享

这是五子棋的最终效果图,棋盘以及棋子均是程序作图。下边奉献个人的源代码。

GoBangGUI.java 这个源文件主要是界面的实现

package game.gobang;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class GoBangGUI extends JFrame{
	private JPanel mainframe;
	private GoBangBoard board;
	private JPanel control;
	private GridLayout grid;
	private BorderLayout border;
	private JButton start;
	private JButton end;
	private JLabel label;
	private int row;
	private int column;
	private Gobang gobang;
	private MouseAdapter mouselistener;
	private boolean flag;
	private boolean ok;
	private ActionListener actionlistener;
	
	public GoBangGUI(){
		this("GoBang Game", 10, 10);
	}
	public GoBangGUI(String title, int row, int column){
		super(title);
//		this.setUndecorated(true);
		this.row = row;
		this.column = column;
		this.flag = false;
		this.ok = false;
		initial();
		setSize(600, 600);
		this.setResizable(false);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLocationByPlatform(true);
		this.setVisible(true);
		this.requestFocus();
	}

	private void initial() {
		createComponent();
		layOut();
		listener();	
	}
	private void createComponent() {
		mainframe = new JPanel();
		control = new JPanel();
		border = new BorderLayout();
		grid = new GridLayout();
		start = new JButton("Start");
		label = new JLabel();
		gobang = new Gobang(row, column);
		board = new GoBangBoard(gobang, row, column);
		end = new JButton("Exit");
//		gobang.getData()[0][0] = GobangColor.WHITE;
	}
	private void layOut() {
		this.getContentPane().add(mainframe);
//		setBackpicture();
//		mainframe.setBackground(Color.yellow);
		mainframe.setLayout(border);
		mainframe.add(board, BorderLayout.CENTER);
//		board.setBounds(0, 0, 500, 500);
		mainframe.add(control, BorderLayout.EAST);
		Box ve = Box.createVerticalBox();
		ve.add(start);
		ve.add(Box.createVerticalStrut(50));
		end.setSize(start.getWidth(), start.getHeight());
		ve.add(end);
		control.add(ve);
	}
	private void setBackpicture() {
		ImageIcon a = new ImageIcon("/home/qcq/1.jpg");
		JLabel p = new JLabel(a);
		p.setBounds(0, 0, a.getIconWidth(), a.getIconHeight());
		this.getLayeredPane().add(p, Integer.MIN_VALUE);	
	}
	/*
	 * 判断鼠标落入棋盘窗格的位置索引 (x, y)为当前鼠标的坐标。
	 */
	private Place judgePlace(int indexx, int indexy, int x, int y, int squre){
		for (int i = 0; i < row; i++){
			for (int j = 0; j < column; j++){
				if (x >= indexx + j * squre && x <= indexx + (j + 1) * squre
						&&y >= indexy + i * squre && y <= indexy + (i + 1) * squre){
					return new Place(i, j);
				} 
			}
		}
		return null;
	}
	private void listener() {
		mouselistener = new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				int x = e.getX();
				int y = e.getY();
				/*
				 * (25, 10) is a special coordinate. the board draw begins here,
				 * when the board added to the this JFrame the begin change to
				 * (25, 10 + 25), However, I do not know why. just keep it;
				 * */
				if (ok){
					Place temp = judgePlace(25, 10, x, y, board.getSqure());
					System.out.println(temp);
					if (flag){
						if (!gobang.check(temp.getX(), temp.getY())){
							JOptionPane.showMessageDialog(mainframe, "Change another place");
						} else {
							gobang.setChess(temp.getX(), temp.getY(), GobangColor.WHITE);
							repaint();
							if (gobang.isSuccess(new Place(0, 0), new Place(row - 1, column - 1), GobangColor.WHITE)){
	//							JOptionPane.showMessageDialog(mainframe, "The white player is win");
								int choice = JOptionPane.showConfirmDialog(mainframe, "The white player is win", "DO you want try again", 
										JOptionPane.YES_NO_OPTION);
								if (choice == JOptionPane.YES_OPTION){
									gobang.initial();
									ok = false;
									repaint();
								}
							}
							flag = false;
						}
						
					} else {
						if (!gobang.check(temp.getX(), temp.getY())){
							JOptionPane.showMessageDialog(mainframe, "Change another place");
						} else {
							gobang.setChess(temp.getX(), temp.getY(), GobangColor.BLACK);
							repaint();
							if (gobang.isSuccess(new Place(0, 0), new Place(row - 1, column - 1), GobangColor.BLACK)){
	//							JOptionPane.showMessageDialog(mainframe, "The black player is win");
								int choice = JOptionPane.showConfirmDialog(mainframe, "The black player is win", "DO you want try again", 
										JOptionPane.YES_NO_OPTION);
								if (choice == JOptionPane.YES_OPTION){
									gobang.initial();
									ok = false;
									repaint();
								}
							}
							flag = true;
						}	
					}	
				} else {
					JOptionPane.showMessageDialog(mainframe, "please start the game");
				}
			}
		};
		actionlistener = new ActionListener() {	
			@Override
			public void actionPerformed(ActionEvent e) {
				if (((JButton)(e.getSource())).getText().equals("Start")){
					ok = true;
				} else if (((JButton)(e.getSource())).getText().equals("Exit")){
					System.exit(0);
				}
			}
		};
		board.addMouseListener(mouselistener);
		start.addActionListener(actionlistener);
		end.addActionListener(actionlistener);
	}

	public static void main(String[] args) {
		GoBangGUI game = new GoBangGUI(null, 20, 20);
	}

}

GoBangBoard.java本文件是棋盘的绘图

package game.gobang;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;

import javax.swing.JPanel;

public class GoBangBoard extends JPanel {
	private Gobang gobang;
	private int row;
	private int column;
	private int squre;
	
	public GoBangBoard() {
		//this.setBounds(x, y, width, height);
	}
	public GoBangBoard(Gobang gobang, int row, int column){
		this.gobang = gobang;
		this.column = column;
		this.row = row;
	}
	
	public int getSqure(){
		return squre;
	}
	
	public void paint(Graphics g){
		Graphics2D gg = (Graphics2D)g;
		squre = (this.getWidth() - 50) / Math.max(row, column);
		/**
		 * from the point (25, 10) draw the game's background.
		 * */
		/*
		 * below draw the background gird.
		 * */
		int x = 25;
		int y = 10;
		gg.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_ROUND, 
				BasicStroke.JOIN_ROUND, 1.0f,new float[]{5f, 5f},0f));
		gg.setColor(Color.blue);
		for (int i = 0; i < row; i++){
			for (int j = 0; j < column; j++){
				gg.drawRect(x + j * squre, y + i * squre, squre, squre);
			}
		}
		for (int i = 0; i < gobang.getData().length; i++){
			for (int j = 0; j < gobang.getData()[i].length; j++){
				if (GobangColor.WHITE == gobang.getData()[i][j]){
					gg.setColor(Color.blue);
					gg.fillOval(x + j * squre, y + i * squre, squre, squre);
				} else if (GobangColor.BLACK == gobang.getData()[i][j]){
					gg.setColor(Color.BLACK);
					gg.fillOval(x + j * squre, y + i * squre, squre, squre);
				}
			}
		}
		
		gg.setStroke(new BasicStroke(5f));
		gg.setColor(Color.blue);
		gg.drawRect(x - 1, y - 1, squre * column + 2, squre * row + 2);
		gg.dispose();
		
	}
}
GobangColor.java 本文件是棋子颜色的枚举定义。

package game.gobang;

public enum GobangColor {
	BLACK,
	WHITE,
	NULL
}

Placejava 本文件是关于棋子位置的定义

package game.gobang;

/**
 * here lays the snake's body coordinate information.
 * */
public class Place {
	private int x;
	private int y;
	public Place(){
		this(0, 0);
	}
	public Place(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	@Override
	public String toString() {
		return "Place [x=" + x + ", y=" + y + "]";
	}
	public void setY(int y) {
		this.y = y;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Place other = (Place) obj;
		if (x != other.x)
			return false;
		if (y != other.y)
			return false;
		return true;
	}
}

Gobang.java本文件是五子棋实现的核心逻辑代码

package game.gobang;

import java.util.Scanner;

/**
 * Question 19、利用二维数组实现五子棋下棋功能
 * */
public class Gobang {
	

	private GobangColor[][] data;
	private int row = 10;
	private int column = 10;

	public Gobang() {
		/*
		 * The default checkerboard is 10 * 10 boxes;
		 * */
		this(10, 10);
		initial();
	}
	/*
	 * Initial the Game
	 * */
	public void initial(){
		for (int i = 0; i < row; i++){
			for (int j = 0; j < column; j++){
				data[i][j] = GobangColor.NULL;
			}
		}
	}
	
	/*
	 * The piece move
	 * */
	public void setChess(int row, int column,GobangColor color){
		data[row][column] = color;
	}
	
	public Gobang(int row, int column){
		/*
		 * set the Chess squre to row * line
		 * */
		this.row = row;
		this.column = column;
		data = new GobangColor[row][];
		for (int i = 0; i < row; i++){
			data[i] = new GobangColor[column];
		}
		initial();
	}
	public GobangColor[][] getData() {
		return data;
	}
	public void setData(GobangColor[][] data) {
		this.data = data;
	}
	public int getRow() {
		return row;
	}
	public void setRow(int row) {
		this.row = row;
	}
	public int getColumn() {
		return column;
	}
	public void setColumn(int column) {
		this.column = column;
	}
	/*
	 * print out the current checkerboard
	 * */
	public void printCheckerBoard(){
		/*
		 * print out the chessboard layout
		 * */
		for (GobangColor[] i: data){
			for (GobangColor j : i){
				System.out.print(j.toString() + " ");
			}
			System.out.println();	
		}
	}
	/*
	 * verify the input data to insure the piece is in the range
	 * and not put this piece in the history place
	 * 验证棋子在合适的位置上
	 * */
	public boolean check(int x, int y){
		if (x < 0 || x >= row || y < 0 || y >= column){
			System.out.println("The input is error");
			System.out.println("The input should from(0, 0) to (" + (x - 1) + "," + (y - 1) + ")");
			return false;
		}
		if (GobangColor.NULL != data[x][y]){
			System.out.println("This place already has one piece!");
			return false;
		}
		return true;
	}
	
	/*
	 * judge if successed, The parameter x and y
	 * is the range which need to be scanning.
	 * The Scanning range can zoom in a range which is a circle(a square)
	 * center in current move, radius is 5.
	 * 扫描棋盘看是不是有棋子获胜,可以优化扫描方案,将扫描的范围局限于一个以落子处为中心
	 * 5为半径的棋盘(isSucess的重载方法实现这一个思想)。
	 */
	public boolean isSuccess(Place x, Place y, GobangColor color){
		boolean flag = false;
		int counter = 0;
		label:
		for (int i = (int) x.getX(); i <= (int)y.getX(); i++){
			for (int j = (int)x.getY(); j <= (int)y.getY(); j++){
				/*
				 * scanning the [x,y] range in 4 directions.
				 * */
				
				// check the horizontal
				counter = 0;
				if (j + 4 <= (int)y.getY()){
					for (int index = j; index <= j + 4; index++){
						if (color == data[i][index]){
							counter++;
						}
					}
				}
				if (5 == counter){
					flag = true;
					break label;
				}
				// check the vertical
				counter = 0;
				if (i + 4 <= (int)y.getX()){
					for (int index = i; index <= i + 4; index++){
						if (color == data[index][j]){
							counter++;
						}
					}
				}
				if (5 == counter){
					flag = true;
					break label;
				
				}
				//check the dig line
				counter = 0;
				if ((i + 4 <= (int)y.getX()) && (j + 4 <= (int)y.getY())){
					for (int indexX = i, indexY = j; indexX <= i + 4 ;indexX++, indexY++){
						if (color == data[indexX][indexY]){
							counter++;
						}
					}
				}
				if (5 == counter){
					flag = true;
					break label;
				}
				//check the reverse dig line
				counter = 0;
				if ((i + 4 <= (int)y.getX()) && (j - 4 >= (int)x.getY())){
					for (int indexX = i, indexY = j; indexX <= i + 4;indexX++, indexY--){
						if (color == data[indexX][indexY]){
							counter++;
						}
					}
				}
				if (5 == counter){
					flag = true;
					break label;
				}
			}
		}
		
		return flag;
		 
	}
	/*
	 * 这是一个重载的方法,与上一个方法不同的是没有使用扫描来实现判定
	 * 而是基于落子的地方,来基于四个方向进行计数判断。
	 * */
	public boolean isSuccess(Place x, GobangColor color){
		boolean flag = false;
		/*
		 * horizontal direction 
		 * */
		int counter = 0;
		for (int i = x.getY(); i >= Math.min(x.getY() - 4, row); i--){
			if (color == data[x.getX()][i]){
				counter++;
			}else{
				break;
			}
		}
		for (int i = x.getY() + 1; i <= Math.min(x.getY() + 4, column - 1); i++){
			if (color == data[x.getX()][i]){
				counter++;
			}else{
				break;
			}
		}
		if (5 == counter){
			flag = true;
		}
		/*
		 * vertical direction
		 * */
		counter = 0;
		for (int i = x.getX(); i >= Math.min(x.getX() - 4, row); i--){
			if (color == data[i][x.getY()]){
				counter++;
			}else{
				break;
			}
		}
		for (int i = x.getY() + 1; i <= Math.min(x.getY() + 4, column - 1); i++){
			if (color == data[i][x.getY()]){
				counter++;
			}else{
				break;
			}
		}
		if (5 == counter){
			flag = true;
		}
		/*
		 * diagonal direction
		 * */
		counter = 0;
		for (int i = x.getX(), j = x.getY(); i >= Math.min(x.getX() - 4, row)
				&& j >= Math.min(x.getY() - 4, row); i--, j--){
			if (color == data[i][j]){
				counter++;
			}else{
				break;
			}
		}
		for (int i = x.getX() + 1, j = x.getY() + 1; i <= Math.min(x.getX() + 4, column - 1)
				&& j <= Math.min(x.getY() + 4, column - 1); i++, j++){
			if (color == data[i][j]){
				counter++;
			}else{
				break;
			}
		}
		if (5 == counter){
			flag = true;
		}
		/*
		 * reverse diagonal direction
		 * */
		counter = 0;
		for (int i = x.getX(), j = x.getY(); i <= Math.min(x.getX() + 4, column - 1)
				&& j >= Math.min(x.getY() - 4, row); i++, j--){
			if (color == data[i][j]){
				counter++;
			}else{
				break;
			}
		}
		for (int i = x.getX() + 1, j = x.getY() + 1; i >= Math.min(x.getX() - 4, row)
				&& j <= Math.min(x.getY() + 4, column - 1); i--, j++){
			if (color == data[i][j]){
				counter++;
			}else{
				break;
			}
		}
		if (5 == counter){
			flag = true;
		}
		return flag;
	}
	/*
	 * The actual game start here, where black first, white second,
	 * we can optimize the game which  do not call
	 * the method isSuccess in the first segment. such as 8 moves.
	 * and we can narrow the scanning the range to a square just talk above.
	 * */
	public void playChess(){
		Scanner in = new Scanner(System.in);
		Place x = new Place(0, 0);
		Place y = new Place(row - 1, column - 1);
		label:
		while (true){
			//The input should like 1,2
			while (in.hasNext()){
				
				String[] str = in.next().split(",");
				int indexX = Integer.valueOf(str[0]);
				int indexY = Integer.valueOf(str[1]);
				if (!check(indexX, indexY)){
					System.out.println("please input again");
					continue;
				}else{
					setChess(indexX, indexY, GobangColor.BLACK);
					printCheckerBoard();
//					if (isSuccess(x, y, GobangColor.BLACK)){
					if (isSuccess(new Place(indexX, indexY), GobangColor.BLACK)){
						System.out.println("The Black is win");
						break label;
					}
					break;
				}
			}
			while (in.hasNext()){
				String[] str = in.next().split(",");
				int indexX = Integer.valueOf(str[0]);
				int indexY = Integer.valueOf(str[1]);
				if (!check(indexX, indexY)){
					System.out.println("please input again");
					continue;
				}else{
					setChess(indexX, indexY, GobangColor.WHITE);
					printCheckerBoard();
//					if (isSuccess(x, y, GobangColor.WHITE)){
					if (isSuccess(new Place(indexX, indexY), GobangColor.WHITE)){
						System.out.println("The White is win");
						
						break label;
					}
					break;
				}
			}	
		}
		in.close();
	}

	public static void main(String[] args) {
		Gobang chess = new Gobang();
		chess.playChess();
	}

}


五子棋游戏源码

标签:java   eclipse   源码   五子棋   界面   

原文地址:http://blog.csdn.net/u011233383/article/details/42242331

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!