Java编写五子棋小游戏
代码如下:
package org.liky.game.frame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class FiveChessFrame extends JFrame implements MouseListener {
Integer width=Toolkit.getDefaultToolkit().getScreenSize().width;
Integer height=Toolkit.getDefaultToolkit().getScreenSize().height;
Integer x=0;
Integer y=0;
int[][] allChess=new int[19][19];
boolean isBlack=true;
boolean canPlay=true;
String message="黑方先行";
BufferedImage bgImage=null;
public FiveChessFrame() {
this.setTitle("五子棋");
this.setSize(500,500);
this.setLocation((width-500)/2,(height-500)/2);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addMouseListener(this);
try {
bgImage=ImageIO.read(new File("c:/image/game.jpg"));
} catch (IOException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
this.setVisible(true);
}
public void paint(Graphics g) {
BufferedImage bi=new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB);
Graphics g2=bi.createGraphics();
g2.drawImage(bgImage, 0, 20,this);
g2.setFont(new Font("黑体",Font.BOLD,20));
g2.drawString("游戏信息:"+message, 30, 60);
g2.setFont(new Font("黑体",Font.BOLD,15));
g2.drawString("开始游戏", 400, 90);
g2.setFont(new Font("宋体",0,14));
g2.drawString("黑方时间:", 30, 470);
g2.drawString("白方时间:", 260, 470);
g2.drawRect(400, 70, 70, 30);
//绘制
for(Integer i=0;i<19;i++) {
g2.drawLine(10, 70+20*i, 370, 70+20*i);
g2.drawLine(10+20*i, 70, 10+20*i, 430);
}
g2.fillOval(68, 128, 4, 4);
g2.fillOval(188, 128, 4, 4);
g2.fillOval(308, 128, 4, 4);
g2.fillOval(68, 248, 4, 4);
g2.fillOval(188, 248, 4, 4);
g2.fillOval(308, 248, 4, 4);
g2.fillOval(68, 368, 4, 4);
g2.fillOval(188, 368, 4, 4);
g2.fillOval(308, 368, 4, 4);
//绘制棋子
//x=(x-10)/20*20+10; //是为了取得交叉点的坐标
//y=(y-70)/20*20+70;
// //黑子
//g.fillOval(x-7, y-7, 14, 14);
// //白子
//g.setColor(Color.BLACK);
//g.fillOval(x-7, y-7, 14, 14);
//g.setColor(Color.BLACK);
//g.drawOval(x-7, y-7, 14, 14);
for(int i=0;i<19;i++) {
for(int j=0;j<19;j++) {
if(allChess[i][j]==1) {
Integer tempX=i*20+10;
Integer tempY=j*20+70;
g2.fillOval(tempX-7, tempY-7, 14, 14);
}
if(allChess[i][j]==2) {
Integer tempX=i*20+10;
Integer tempY=j*20+70;
g2.setColor(Color.white);
g2.fillOval(tempX-7, tempY-7, 14, 14);
g2.setColor(Color.black);
g2.drawOval(tempX-7, tempY-7, 14, 14);
}
}
}
g.drawImage(bi, 0, 0, this);
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
if(canPlay) {
System.out.println("X:"+e.getX());
System.out.println("Y:"+e.getY());
x=e.getX();
y=e.getY();
if(x>=10&&x<=370&&y>=70&&y<=430) {
x=(x-10)/20;
y=(y-70)/20;
if(allChess[x][y]==0) {
if(isBlack==true) {
allChess[x][y]=1;
isBlack=false;
message="轮到白方";
}else {
allChess[x][y]=2;
isBlack=true;
message="轮到黑方";
}
//判断
boolean winFlag = this.checkWin();
if (winFlag == true) {
JOptionPane.showMessageDialog(this, "游戏结束,"
+ (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜!");
canPlay = false;
}
}else {JOptionPane.showMessageDialog(this, "当前位置已经有棋子!");}
this.repaint();
}
}
if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 70
&& e.getY() <= 100) {
int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");
if (result == 0) {
// 现在重新开始游戏
// 重新开始所要做的操作:1)把棋盘清空,allChess数组中全部数据归0;
// 2)游戏相关信息显示初始化
// 3)将下一步下棋改为黑方
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 19; j++) {
allChess[i][j] = 0;
}
}
// 另一种方式 allChess=new int[19][19]
message = "黑方先行";
isBlack = true;
this.repaint();
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根
}
private boolean checkWin() {
boolean flag=false;
int color=allChess[x][y];
int count=this.checkCount(1, 0, color);
if(count>=5) {flag=true;}
else {
count=this.checkCount(0, 1, color);
if(count>=5) {flag=true;}
else {
count=this.checkCount(1, -1, color);
if(count>=5) {flag=true;}
else {
count=this.checkCount(1, 1, color);
if(count>=5) {flag=true;}
}
}
}
return flag;
}
private int checkCount(int xChange,int yChange,int color) {
int count=1;
int tempX=xChange;
int tempY=yChange;
while((x + xChange >= 0 && x + xChange <= 18 && y + yChange >= 0
&& y + yChange <= 18
&& color == allChess[x + xChange][y + yChange])) {
count++;
if(xChange!=0)
xChange++;
if(yChange!=0) {
if(yChange>0)
yChange++;
else {yChange--;}
}}
xChange=tempX;
yChange=tempY;
while(x - xChange >= 0 && x - xChange <= 18 && y - yChange >= 0
&& y - yChange <= 18
&& color == allChess[x - xChange][y - yChange]) {
count++;
if(xChange!=0)
xChange++;
if(yChange!=0) {
if(yChange>0)
yChange++;
else {yChange--;}
}
}
return count;
}
}
测试类
package org.liky.game.test;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.liky.game.frame.FiveChessFrame;
public class Test {
public static void main(String[] args) {
//MyChessFrame jf=new MyChessFrame();
//JOptionPane.showMessageDialog(jf, "我的信息");
//Integer result=JOptionPane.showConfirmDialog(jf, "xx");
//System.out.print(result);
//String n=JOptionPane.showInputDialog("22");
//sSystem.out.print(n);
FiveChessFrame ff=new FiveChessFrame();
}
}
运行结果
点击开始游戏
主要难点:
1.每一步棋的保存:使用二维数组来模仿19*19的棋盘,等于0时无棋,等于1时黑棋,等于2时白旗。
2.五子连成时的判断:每下落一个棋子时判断它的周围是否连成五子,从它的上下、左右、两斜方向共4个方向判断。