项目目标:
- 绘制游戏界面,且实现重绘功能
- 绘制棋子(使棋子放在棋盘交点处)
- 黑白交替,保存棋子,判断输赢
- 实现开始和悔棋功能
绘制界面
public class WuZi {
public void initUI(){
MyFrame jf=new MyFrame();
//利用类MyFrame继承JFrame来实现重绘功能
jf.setSize(1500,900);
jf.setTitle("五子棋");
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(3);
FlowLayout flow= new FlowLayout();
jf.setLayout(flow);
DrawMouse mouse=new DrawMouse();
String[]arr= {"开始","悔棋"};
//添加功能按钮
for(int i=0;i<arr.length;i++) {
JButton jb=new JButton(arr[i]);
jb.setPreferredSize(new Dimension(100,50));
jb.addActionListener(mouse);
jf.add(jb);
}
jf.addMouseListener(mouse);
jf.setVisible(true);
Graphics g=jf.getGraphics();
///画笔一定要声明在窗体设置可见以后
mouse.g=g;
jf.chess=mouse.chess;
//将mouse中的chess数组传给jf中的chess数组中
//chess是Chess类的数组,作用是存储已下棋子,便于重绘和判断输赢
}
public static void main(String[] args)
{
WuZi p=new WuZi();
p.initUI();
}
创建Chess类保存棋子及利用paint方法实现重绘功能
public class Chess {
int x;
int y;
boolean col;
//col为true时为黑棋,为false时为白棋
Chess(int x,int y,boolean col){
this.x=x;
this.y=y;
this.col=col;
}
public void paint(Graphics g) {
if(col) {
g.setColor(new Color(0,0,0));
g.fillOval(x-25, y-25, 50, 50);
} else {
g.setColor(new Color(250,250,250));
g.fillOval(x-25, y-25, 50, 50);
}
}
}
public class DrawMouse implements MouseListener,ActionListener{
Graphics g;
Chess[] chess=new Chess[130];
int index=0;
int x1,y1;
boolean col=true;
//coltrue为黑棋,false为白棋
int[][] table=new int[11][11];
//利用table来保存,0为未下,1为黑棋,2为白棋
String buttonName;
boolean whiteWin=false;
boolean blackWin=false;
public void actionPerformed(ActionEvent e) {
buttonName=e.getActionCommand();
if(buttonName.equals("悔棋")&&index>0) {
index--;
int X=(chess[index].x-50)/50;
int Y=(chess[index].y-250)/50;
table[Y][X]=0;
chess[index]=null;
//将chess对象回收
buttonName="开始";
}
}
public void mouseClicked(MouseEvent e) {
if(blackWin||whiteWin)return;
if(buttonName.equals("开始")) {
x1=e.getX();
y1=e.getY();
if(x1>=25&&x1<=575&&y1<=775&&y1>=225) {
x1=(x1+25)/50*50;
y1=(y1+25)/50*50;
//处理点击的坐标,使其处于最近的棋盘交点
boolean ret=false;
for(int i=0;chess[i]!=null;i++) {
if(chess[i].x==x1&&chess[i].y==y1) {
ret=true;
//判断是否点击位置有已下过的棋子
break;
}
}
if(ret) {
return;
}
chess[index++]=new Chess(x1,y1,col);
//保存棋子信息
if(col) {
g.setColor(new Color(0,0,0));
g.fillOval(x1-25, y1-25, 50, 50);
} else {
g.setColor(new Color(250,250,250));
g.fillOval(x1-25, y1-25, 50, 50);
}
if(col) {
int X=(x1-50)/50;
int Y=(y1-250)/50;
table[Y][X]=1;
} else {
int X=(x1-50)/50;
int Y=(y1-250)/50;
table[Y][X]=2;
}
if(win(table)==1) blackWin=true;
else if(win(table)==2) whiteWin=true;
col=!col;
//改换另一种颜色棋子下棋
} else {
}
}
if(blackWin) {
g.setFont(new Font("仿宋",Font.BOLD,40));
g.setColor(Color.BLACK);
g.drawString("Black Win!!!", 600, 400);
return;
}
if(whiteWin) {
g.setFont(new Font("仿宋",Font.BOLD,40));
g.setColor(Color.BLACK);
g.drawString("White Win!!!", 600, 400);
return;
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
输赢判定算法
public static int win(int[][]table) {
int dx[]= {0,1,1,1,0,-1,-1,-1};
int dy[]= {1,1,0,-1,-1,-1,0,1};
//分别对应八个方向
for(int i=0;i<11;i++) {
for(int j=0;j<11;j++) {
if(table[j][i]==0)continue;
for(int k=0;k<8;k++) {
int counts=0;
int X=i;
int Y=j;
for(int m=0;m<4;m++) {
//每一个方向判断四次每次判断成功则counts++,最后counts为4则该种颜色棋子获胜
X+=dx[k];
Y+=dy[k];
if(X<0||X>10||Y<0||Y>10)continue;
if(table[j][i]==table[Y][X]) counts++;
}
if(counts==4) {
if(table[j][i]==1) return 1;
if(table[j][i]==2) return 2;
}
}
}
}
return 0;
}
MyFrame类实现重绘功能
public class MyFrame extends JFrame{
Chess[] chess;
public void paint(Graphics g) {
super.paint(g);
for (int i = 0; i <=10; i++) {
g.drawLine(50, 250+i*50, 550, 250+i*50);
}
for (int i = 0; i <=10; i++) {
g.drawLine(50+i*50, 250,50+i*50 , 750);
}
for(int i=0;chess[i]!=null;i++) {
chess[i].paint(g);
}
}
}
效果图
点击开始键,正常开始游戏
点击悔棋键(两次)后
最终结果