您的位置:首页 > 编程语言 > Java开发

java实现的五子棋

2015-11-28 19:41 609 查看
创建一个简单的五子棋游戏,带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);
}

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



接着是下棋的界面。



好了,最后是用户赢了。



总体就是这样了,代码很简单。主要就是计算机的智能太低了,不过显然这是可以改进的。当然了,五子棋模型类也需要改进,毕竟现在不支持退回。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java 五子棋 界面