java实现的五子棋

创建一个简单的五子棋游戏,带GUI界面。不多说,上代码。首先上的是五子棋模型。这个模型提供简单的放置棋子,判断是否五子相连,也就是是否赢了。代码如下所示。

/**game five in a row
 * */
public class FiveInARowModel {
	public static final int EMPTY=0;//no chessman
	public static final int BLACK=1;//black chessman
	public static final int WHITE=2;//white chessman
	private int[][]board;
	private int lastPutRow,lastPutCol;
	public FiveInARowModel(int dimension){
		board=new int[dimension][dimension];
		clear();
	}
	public int getDimension(){
		return board.length;
	}
	public int getChessman(int row,int col){
		return board[row][col];
	}
	public boolean isEmpty(int row,int col){
		return EMPTY==getChessman(row, col);
	}
	public boolean isFull(){
		for(int k=0;k<board.length;++k)
			for(int j=0;j<board.length;++j)
				if(isEmpty(k, j))
					return false;
		return true;
	}
	public void clear(){
		//board=new int[board.length][board.length];
		for(int k=0;k<board.length;++k)
			for(int j=0;j<board.length;++j)
				board[k][j]=EMPTY;
		lastPutRow=lastPutCol=-1;
	}
	/**@return last position of the chessman put on the board
	 * */
	public int[]getLastPut(){
		return new int[]{lastPutRow,lastPutCol};
	}
	public boolean trySetChessman(int row,int col,int chessman){
		if(!isEmpty(row, col))
			return false;
		if(chessman!=BLACK&&chessman!=WHITE)
			return false;
		board[row][col]=chessman;
		//lastPutRow=row;
		//lastPutCol=col;
		boolean win= checkWin(row, col);
		board[row][col]=EMPTY;
		return win;
	}
	/**put a chessman on the board
	 * @param row row of position to put chessman
	 * @param col column of position to put chessman
	 * @param chessman type of chessman to put
	 * @return true if the putter wins
	 * */
	public boolean setChessman(int row,int col,int chessman) throws Exception{
		if(!isEmpty(row, col))
			throw new Exception("Non-empty position!");
		if(chessman!=BLACK&&chessman!=WHITE)
			throw new Exception("Invalid chessman");
		board[row][col]=chessman;
		lastPutRow=row;
		lastPutCol=col;
		return checkWin(row, col);
	}
	//chech whether five chessmans in a line
	private boolean checkWin(int row,int col){
		//left->right
		int chessman=getChessman(row, col);
		int selfChessManNum=1;
		for(int left=col-1;
				left>=0&&getChessman(row, left)==chessman;
				--left,++selfChessManNum);
		for(int right=col+1;
				right<getDimension()&&getChessman(row, right)==chessman;
				++right,++selfChessManNum);
		if(selfChessManNum>=5)
			return true;
		//up->down
		selfChessManNum=1;
		for(int up=row-1;
				up>=0&&getChessman(up,col)==chessman;
				--up,++selfChessManNum);
		for(int down=row+1;
				down<getDimension()&&getChessman(down,col)==chessman;
				++down,++selfChessManNum);
		if(selfChessManNum>=5)
			return true;
		//left-up->right-down
		selfChessManNum=1;
		for(int left=col-1,up=row-1;
				left>=0&&up>=0&&getChessman(up, left)==chessman;
				--left,--up,++selfChessManNum);
		for(int right=col+1,down=row+1;
				right<getDimension()&&down<getDimension()&&getChessman(down, right)==chessman;
				++right,++down,++selfChessManNum);
		if(selfChessManNum>=5)
			return true;
		//right-up->left-down
		selfChessManNum=1;
		for(int left=col-1,down=row+1;
				left>=0&&down<getDimension()&&getChessman(down, left)==chessman;
				--left,++down,++selfChessManNum);
		for(int right=col+1,up=row-1;
				right<getDimension()&&up>=0&&getChessman(up, right)==chessman;
				++right,--up,++selfChessManNum);
		if(selfChessManNum>=5)
			return true;
		return false;
	}
}
接着是计算机玩家的代码。这里只是个简单的框架,只做最简单的判断,首先看是否有四子相连,则直接赢棋,否则就是下子堵另一方。

import java.util.Random;

//
public class ComputerPlayer {
	private FiveInARowModel board;
	private int chessman;
	public ComputerPlayer(FiveInARowModel board,int chessman){
		this.board=board;
		this.chessman=chessman;
	}
	/**
	 * put a chessman on board
	 * @return true if computer wins
	 * */
	public boolean play(){
		int[]anotherPlayerPut=board.getLastPut();
		if(anotherPlayerPut[0]<0){
			try {
				board.setChessman(board.getDimension()/2, board.getDimension()/2, chessman);
			} catch (Exception e) {
			}
			return false;
		}
		int row=anotherPlayerPut[0],col=anotherPlayerPut[1];
		int nearRow=-1,nearCol=-1,dis=2*board.getDimension();
		//search a position if player can win
		for(int k=0;k<board.getDimension();++k)
			for(int j=0;j<board.getDimension();++j)
				if(board.isEmpty(k, j)){
					if(Math.abs(k-row)+Math.abs(j-col)<dis){
						nearCol=j;
						nearRow=k;
						dis=Math.abs(k-row)+Math.abs(j-col);
					}
					if(board.trySetChessman(k, j, chessman)){
						try {
							return board.setChessman(k, j, chessman);
						} catch (Exception e) {
							//impossible to get here
							return false;
						}
					}
				}
		//
		//left->right
		//check whether another player has more than 3 chessman in a row
		if(checkLeftToRight(row, col))
			return false;
		if(checkUpToDown(row, col))
			return false;
		if(checkLeftUpToRightDown(row, col))
			return false;
		if(checkLeftDownToRightUp(row, col))
			return false;
		//choose a position randomly
		try {
			board.setChessman(nearRow, nearCol, chessman);
		} catch (Exception e) {
		}
		return false;
	}
	private boolean checkLeftToRight(int row,int col){
		return check(row,col,0,1);
	}
	private boolean checkUpToDown(int row,int col){
		return check(row,col,1,0);
	}
	private boolean checkLeftUpToRightDown(int row,int col){
		return check(row,col,1,1);
	}
	private boolean checkLeftDownToRightUp(int row,int col){
		return check(row,col,-1,1);
	}
	//check chessmans in a line. If more than 3 chessmans in a row, then blocked it
	private boolean check(int row,int col,int drow,int dcol){
		int startRow=row-drow,startCol=col-dcol,
				endRow=row+drow,endCol=col+dcol;
		int chessman=board.getChessman(row, col);
		int sameChessNum=1;
		while(startRow>=0&&startCol>=0&&board.getChessman(startRow, startCol)==chessman){
			startRow-=drow;
			startCol-=dcol;
			++sameChessNum;
		}
		while(endRow<board.getDimension()
				&&endCol<board.getDimension()
				&&board.getChessman(endRow, endCol)==chessman){
			endRow+=drow;
			endCol+=dcol;
			++sameChessNum;
		}
		if(sameChessNum>=3){//more than 3  chessman in a row
			if(startRow>=0&&startCol>=0&&board.isEmpty(startRow, startCol)){
				try {
					board.setChessman(startRow, startCol, this.chessman);
					return true;
				} catch (Exception e) {
				}
			}else if(endRow<board.getDimension()
					&&endCol<board.getDimension()&&board.isEmpty(endRow, endCol)){
				try {
					board.setChessman(endRow, endCol, this.chessman);
					return true;
				} catch (Exception e) {
				}
			}
		}
		return false;
	}
}

然后创建一个棋盘面板。显示棋局,设置好鼠标事件处理。

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;

import javax.swing.JOptionPane;
import javax.swing.JPanel;


public class BoardPanel extends JPanel {
	public static final int WIDTH=600;
	public static final int HEIGHT=600;
	private static int MARGIN=20;
	private FiveInARowModel board;//chessman board
	private ComputerPlayer computerPlayer;
	public BoardPanel(FiveInARowModel board){
		this.board=board;
		computerPlayer=new ComputerPlayer(board, FiveInARowModel.BLACK);
		this.setBackground(Color.WHITE);
		addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				Point p=e.getPoint();
				int row,col;
				int dim=BoardPanel.this.board.getDimension();
				int cellWidth=(getWidth()-2*MARGIN)/dim;
				if(p.y>=MARGIN&&p.y<MARGIN+dim*cellWidth&&
						p.x>=MARGIN&&p.x<MARGIN+dim*cellWidth){
					row=(p.y-MARGIN)/cellWidth;
					col=(p.x-MARGIN)/cellWidth;
					if(!BoardPanel.this.board.isEmpty(row, col))
						return;
					try {
						//user put a chessman
						boolean win=BoardPanel.this.board.setChessman(row, col, FiveInARowModel.WHITE);
						BoardPanel.this.drawChessman(row, col);
						if(win){//user wins
							JOptionPane.showMessageDialog(BoardPanel.this, "You win!");
							BoardPanel.this.board.clear();
							BoardPanel.this.repaint();
						}else if(BoardPanel.this.board.isFull()){//full
							JOptionPane.showMessageDialog(BoardPanel.this, "No empty cell!");
							BoardPanel.this.board.clear();
							BoardPanel.this.repaint();
						}else{
							//computer put a chessman
							win=computerPlayer.play();
							int[]last=BoardPanel.this.board.getLastPut();
							row=last[0];
							col=last[1];
							BoardPanel.this.drawChessman(row, col);
							if(win){//computer wins
								JOptionPane.showMessageDialog(BoardPanel.this, "Computer win!");
								BoardPanel.this.board.clear();
								BoardPanel.this.repaint();
							}else if(BoardPanel.this.board.isFull()){
								JOptionPane.showMessageDialog(BoardPanel.this, "No empty cell!");
								BoardPanel.this.board.clear();
								BoardPanel.this.repaint();
							}
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				}
			}
		});
	}
	public int getWidth() {
		return WIDTH;
	}
	public int getHeight() {
		return HEIGHT;
	}
	public void paint(Graphics g) {
		Graphics2D g2d=(Graphics2D) g;
		//fill white back ground
		g2d.setColor(Color.CYAN);
		g2d.fillRect(0, 0, WIDTH, HEIGHT);
		//write tip
		g2d.setColor(Color.BLACK);
		g2d.drawString("Computer", MARGIN, MARGIN*2/3);
		FontMetrics fm=g2d.getFontMetrics();
		Rectangle2D rect=fm.getStringBounds("Computer", g2d);
		int r=MARGIN-2;
		g2d.drawOval(MARGIN+(int)rect.getWidth()+r, 0, r, r);
		g2d.fillOval(MARGIN+(int)rect.getWidth()+r, 0, r, r);
		
		g2d.drawString("User", WIDTH/2, MARGIN*2/3);
		rect=fm.getStringBounds("User", g2d);
		g2d.drawOval(WIDTH/2+(int)rect.getWidth()+r, 0, r, r);
		g2d.setColor(Color.WHITE);
		g2d.fillOval(WIDTH/2+(int)rect.getWidth()+r, 0, r, r);
		
		//draw background of board
		int cellWidth=(getWidth()-2*MARGIN)/board.getDimension();
		g2d.setColor(Color.GRAY);
		g2d.fillRect(MARGIN, MARGIN, 
				cellWidth*board.getDimension(), cellWidth*board.getDimension());
		//draw lines
		g2d.setColor(Color.BLACK);
		for(int k=0;k<board.getDimension()+1;++k){
			g2d.drawLine(MARGIN+k*cellWidth, MARGIN, 
					MARGIN+k*cellWidth, MARGIN+cellWidth*board.getDimension());
			g2d.drawLine(MARGIN, MARGIN+k*cellWidth, 
					MARGIN+cellWidth*board.getDimension(), MARGIN+k*cellWidth);
		}
		for(int k=0;k<board.getDimension();++k){
			for(int j=0;j<board.getDimension();++j)
				drawChessman(k, j);
		}
	}
	private void drawChessman(int row,int col){
		int chessman=board.getChessman(row, col);
		if(chessman!=FiveInARowModel.BLACK&&chessman!=FiveInARowModel.WHITE)
			return;
		int x,y;
		int cellWidth=(getWidth()-2*MARGIN)/board.getDimension();
		x=MARGIN+col*cellWidth;
		y=MARGIN+row*cellWidth;
		Graphics2D g2d=(Graphics2D) this.getGraphics();
		int pad=2;
		Color color=chessman==FiveInARowModel.BLACK?Color.BLACK:Color.WHITE;
		g2d.setColor(color);
		g2d.fillOval(x+pad, y+pad, cellWidth-2*pad, cellWidth-2*pad);
	}
}

接着就是创建一个主窗口,将棋盘放在中央。

import java.awt.BorderLayout;

import javax.swing.JFrame;


public class MainFrame extends JFrame {
	public MainFrame() {
		FiveInARowModel board=new FiveInARowModel(19);
		BoardPanel panel=new BoardPanel(board);
		getContentPane().add(panel,BorderLayout.CENTER);
		setSize(panel.getWidth(),10+panel.getHeight());
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

}

终于,到了主函数了。

public class Main {
	public static void main(String[]args){
		MainFrame mf=new MainFrame();
		mf.setVisible(true);
	}

}
好了。看看结果吧。这是初始界面。

接着是下棋的界面。



好了,最后是用户赢了。


总体就是这样了,代码很简单。主要就是计算机的智能太低了,不过显然这是可以改进的。当然了,五子棋模型类也需要改进,毕竟现在不支持退回。

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值