使用java的paint方法实现五子棋,使其能实现开始游戏,悔棋,判断输赢等功能。
首先建包,引入swing和awt工具包,通过使用其中的类构建界面应用程序和完成画图。主类继承画图板,设置背景参数,添加 开始游戏 悔棋两个按钮并监听,为了使移动窗口落子不消失,棋盘和棋子要保存重绘,所以把画棋盘,棋子的方法封装到鼠标监听器
import java.awt.*;
import javax.swing.*;
public class GoBangUI extends JFrame{
GoListener gol = new GoListener();
public void ShowUI(){
setTitle("五子棋pro");
setSize(900,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(null);
setLocationRelativeTo(null);
JButton btn1=new JButton("开始游戏");
JButton btn2=new JButton("悔棋");
btn1.setBounds(X + COL * SIZE + SIZE, Y, 95, 35);
btn2.setBounds(X + COL * SIZE + SIZE, Y + 40, 95, 35);
add(btn1);
add(btn2);
btn2.addActionListener(gol);
btn1.addActionListener(gol);
setVisible(true);
addMouseListener(gol);
gol.g=getGraphics();
}
static final int X = 50, Y = 75, SIZE = 40, ROW = 15, COL = 15;
public void paint(Graphics g){
super.paint(g);
gol.drawChessPad();
gol.drawAllChess();
}
public static void main(String[] args){
GoBangUI goBangUI=new GoBangUI();
goBangUI.ShowUI();
}
}
在监听器类中接口鼠标监听器,动作监听器,定义声明数据类型:先创建棋子对象,ChessFlag是棋子颜色,开始游戏后ChessFlag=1时下黑子,然后赋值为2下白子;创建一个数组对象ChessArr【】【】,在棋盘上落子相当于在数组中给相应位置的0赋值为1,2;ChessIndex为下标,表示为落的第几颗子,每次悔棋时就是将最后落的那颗子删去;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class GoListener implements MouseListener, ActionListener{
Graphics g;
int ChessFlag=0;
static final int X = 50, Y = 75, SIZE = 40, ROW = 15, COL = 15;
int[][] ChessArr=new int[ROW+1][COL+1];
Chess[] chesslist=new Chess[ChessArr.length*ChessArr[0].length];
int ChessIndex=0;
当动作监听器监听到获取的按钮上的字符文字时,当字符串等于“开始游戏”,ChessFlag赋值为1开始下黑子并且黑白迭代,按钮字符文本变成“结束游戏”,颜色变为红色;当获取“结束游戏”文本时,重绘棋盘,棋子下标变为0;
当动作监听器监听到获取的按钮上的字符文字等于“悔棋”时,如果场上有棋子(即ChessFlag!=0),如果下标ChessIndex<=0的话会弹出文本框“场上没有棋子!”,场上有棋子的话棋子对象的排列列表赋值给棋子对象,然后最后落下的那颗棋子退还成null,再重绘棋盘和棋子
@Override
public void actionPerformed(ActionEvent e) {
String ac = e.getActionCommand();
JButton btn = (JButton) e.getSource();
if(ac.equals("开始游戏")){
ChessFlag=1;
btn.setText("结束游戏");
btn.setBackground(Color.RED);
} else if (ac.equals("结束游戏")) {
ChessFlag=0;
btn.setText("开始游戏");
btn.setBackground(Color.GREEN);
ChessIndex=0;
drawChessPad();
}
if(ac.equals("悔棋")){
if(ChessFlag!=0){
if(ChessIndex<=0){
JOptionPane.showMessageDialog(null,"场上没有棋子!");
return;
}
Chess chess=chesslist[ChessIndex-1];
chesslist[ChessIndex-1]=null;
ChessIndex--;
drawChessPad();
drawAllChess();
}
}
}
鼠标监听器监听落子的位置得到坐标,当ChessFlag=0时无法落子弹出文本框“游戏未开始,请开始游戏!";定义新变量r,c为棋子在数组中的行和列,当行列值乘尺寸大于棋盘的尺寸则说明落子到棋盘外,弹出文本框"请落子在棋盘内!";在棋盘数组中已赋值的某个位置上再次赋值,则会弹出"此处已有棋子,请选择空位落子!";将ChessFlag和颜色绑定,然后将ChessFlag值放入棋盘数组中;画棋子
@Override
public void mousePressed(MouseEvent e) {
int x=e.getX();
int y=e.getY();
if(ChessFlag==0){
JOptionPane.showMessageDialog(null,"游戏未开始,请开始游戏!");
return;
}
int c=(x-X+SIZE/2)/SIZE;
int r=(y-Y+SIZE/2)/SIZE;
System.out.println(r+" "+c);
if(r>ROW||c>COL||x<X-SIZE/2||y<Y-SIZE/2){
JOptionPane.showMessageDialog(null,"请落子在棋盘内!");
return;
}
if(ChessArr[r][c]!=0){
JOptionPane.showMessageDialog(null,"此处已有棋子,请选择空位落子!");
return;
}
ChessArr[r][c]=ChessFlag;
Chess chess=new Chess(r,c,ChessFlag);
chesslist[ChessIndex++]=chess;
if(ChessFlag==1){
g.setColor(Color.BLACK);
ChessFlag=2;
} else if (ChessFlag==2) {
g.setColor(Color.WHITE);
ChessFlag=1;
}
int chessX=c*SIZE+X-SIZE/2;
int chessY=r*SIZE+Y-SIZE/2;
g.fillOval(chessX,chessY,SIZE,SIZE);
g.setColor(Color.RED);
g.drawString(""+ChessIndex,chessX+SIZE/2,chessY+SIZE/2);
printChessArr();
}
绘制棋盘数组 画棋盘 画棋子方法
private void printChessArr() {
for (int i = 0; i < ChessArr.length; i++) {
for (int j = 0; j < ChessArr[i].length; j++) {
System.out.println(ChessArr[i][j] + " ");
}
System.out.println();
}
}
public void drawChessPad(){
g.setColor(new Color(61,157,31));
g.fillRect(X-SIZE/2,Y-SIZE/2,COL*SIZE+SIZE,ROW*SIZE+SIZE);
g.setColor(Color.BLACK);
for (int i = 0; i <=COL; i++) {
g.drawLine(X,Y+i*SIZE,X+COL*SIZE,Y+i*SIZE);
g.drawLine(X+i*SIZE,Y,X+i*SIZE,Y+ROW*SIZE);
}
}
public void drawAllChess(){
for (int i = 0; i < ChessIndex; i++) {
Chess chess = chesslist[i];
if (chess != null) {
g.setColor(chess.ChessFlag == 1 ? Color.BLACK : Color.WHITE);
int chessX = chess.c * SIZE + X - SIZE / 2;
int chessY = chess.r * SIZE + Y - SIZE / 2;
g.fillOval(chessX, chessY, SIZE, SIZE);
g.setColor(Color.RED);
g.drawString("" + (i + 1), chessX + SIZE / 2, chessY + SIZE / 2);
}
}
}
判断输赢方法:每落一颗子开始从落子的棋盘位置开始分别遍历,向左和向右遍历 向上和向下遍历 向左上和右下遍历 向右下和左上遍历,遍历到同方向相邻的一颗同色棋子则count+1。只要满足count=>5时则可判断最后落子的那方胜利。
//横
int count1=1;int count2=1;int count3=1;int count4=1;
int cnum=ChessArr[r][c];
for (int i = c+1; i < ChessArr[r].length; i++) {
if (ChessArr[r][i] == cnum) {
count1+=1;
}else if (ChessArr[r][i] != cnum) {
break;
}
}
for (int i = c-1; i > ChessArr[r][0]; i--) {
if (ChessArr[r][i] == cnum) {
count1+=1;
}else if (ChessArr[r][i] != cnum) {
break;
}
}
if (count1 >= 5&&ChessFlag==1) {
JOptionPane.showMessageDialog(null,"白子获得胜利!");
return;
}
else if (count1 >= 5&&ChessFlag==2) {
JOptionPane.showMessageDialog(null,"黑子获得胜利!");
return;
}
//纵
for (int i = r+1; i < ChessArr[c].length; i++) {
if (ChessArr[i][c] == cnum) {
count2+=1;
}else if (ChessArr[i][c] != cnum) {
break;
}
}
for (int i = r-1; i > ChessArr[0][c]; i--) {
if (ChessArr[i][c] == cnum) {
count2+=1;
}else if (ChessArr[i][c] != cnum) {
break;
}
if (count2 >= 5&&ChessFlag==1) {
JOptionPane.showMessageDialog(null,"白子获得胜利!");
return;
}
else if (count2 >= 5&&ChessFlag==2) {
JOptionPane.showMessageDialog(null,"黑子获得胜利!");
return;
}
}
//左上到右下
for (int i = c+1 ,j = r+1; i < ChessArr[r].length&& j <ChessArr[c].length ;i++, j++) {
if (ChessArr[j][i] == cnum) {
count3+=1;
}else if (ChessArr[j][i] != cnum) {
break;
}
}
for (int i = c-1 ,j = r-1; i > 0&& j >0 ;i--, j--) {
if (ChessArr[j][i] == cnum) {
count3+=1;
}else if (ChessArr[j][i] != cnum) {
break;
}
}
if (count3 >= 5&&ChessFlag==1) {
JOptionPane.showMessageDialog(null,"白子获得胜利!");
return;
}
else if (count3 >= 5&&ChessFlag==2) {
JOptionPane.showMessageDialog(null,"黑子获得胜利!");
return;
}
//左下到右上
for (int i = c+1 ,j = r-1; i < ChessArr[r].length&& j >0 ;i++, j--) {
if (ChessArr[j][i] == cnum) {
count4+=1;
}else if (ChessArr[j][i] != cnum) {
break;
}
}
for (int i = c-1 ,j = r+1; i > 0&& j <ChessArr[c].length ;i--, j++) {
if (ChessArr[j][i] == cnum) {
count4+=1;
}else if (ChessArr[j][i] != cnum) {
break;
}
}
if (count4 >= 5&&ChessFlag==1) {
JOptionPane.showMessageDialog(null,"白子获得胜利!");
return;
}
else if (count4 >= 5&&ChessFlag==2) {
JOptionPane.showMessageDialog(null,"黑子获得胜利!");
return;
}
if(count1>=5||count2>=5||count3>=5||count4>=5){
ChessArr[chess.r][chess.c] = 0;
drawChessPad();
}
}