五子棋大家都玩过,那我们来挑战做个一下简单的五子棋游戏。
软件:eclipse.exe
编程语言:JAVA
首先,制作一个五子棋界面窗口
不多说,直接上代码:
此处用数组加了四个按钮,供后面实现相应功能使用。
画棋盘,横竖线
一开始是想直接用画图的方式划线,然而你会发现你画的线并不会显示出来,为什么呢?这里需要对线重绘。
为了更好对我们棋盘进行调整,我建了一个接口存储一些需要用到的常量的值
然后就可以进行重绘
在paint 里调用画棋盘的方法,重绘线,你可以看到paint里还有调用画棋子的方法,那我们现在就来解决怎么点鼠标下棋的问题吧。
下棋子
创建一个类,首先加鼠标监听器:extends MouseAdapter,
(MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener)接了鼠标监听了
接下来重写点击方法
定义x,y存点击点的横纵坐标,在用g.fillOval(x, y, width, height);函数画棋,简单方法就可以了。
写个构建方法传入Graphics g,在界面类中Graphics g = this.getGraphics();//得到窗体,ChessListener mouse = new ChessListener(g);
this.addMouseListener(mouse);
这样就可以画出棋子了
但是现在有问题发现没?棋子应该下在网格上
黑白棋交替
下过了不能再下
重绘
首先,计算交点,要选择最靠近点击点的交叉点,如果点击的横坐标减去X0的值除以SIZE取余数,若大于二分之一SIZE是不是该选整除的结果加1,若小于二分之一SIZE是不是该直接选整除的结果?答案是肯定的,很好理解。纵坐标类似。(得到的结果只是以左上为原点,x,y单位为1的坐标,还要转换成窗体上的坐标)
定义个棋子计数标志,奇偶数来定义下黑白棋,下一颗棋就加1.再定义个数组记录是否放过棋了,黑白棋区分下,我这里设黑为1,白为2,无棋子没再赋值就是0.
然后再是重绘,在界面类中写。首先要传入事件类中数组的值来判断重绘的是黑白棋,此时应该在构造方法中加数组参数,"传送"数组。
在paint函数里调用它即可。运行结果如下:
接下来还需要干嘛呢?
没错,聪明的孩子肯定知道我们还没做判断输赢!
五子连线即胜,其中我们要判断横竖斜上斜下四个方向是否五颗棋子,大家都懂得规则。
好,新建Win类判断输赢
对一个棋子的横向,右判断同色count加一,不同跳出循环,进行左判断,若count加至5就判断赢,其他三个类同。
再在事件类中写:
Win win = new Win(chessArray);
win.isWin(xx,yy);
将chessArrary数组赋值给Win类的chessA,xx,yy赋值给Win类的x,y
这时候就能判断输赢了,如下:
接下来加悔棋、重开功能
对按钮加监听器
首先事件类中加接口ActionListener,重写actionPerformed抽象方法。重开简单,将棋盘每个交点的黑白数组归零刷新重绘就好,悔棋则需要定义一个数组去存每一次棋的点,然后一样的对该点黑白数组清零刷新,代码:
就这样,人人对战的五子棋就做好了,是不是很激动,赶紧和小伙伴玩起来吧!!!
下一期我们再介绍人机对战中的AI怎么写,自己可以先想想思考下。
下期,我们不见不散!
附上代码:
第一个类:import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ChessBoard extends JFrame implements Config {
private int[][] chess = new int[ROWS][COLUMNS];
private ChessListener mouse = new ChessListener();
public void showUI() {
this.setSize(650, 700);
this.setTitle("五子棋");
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setLayout(new FlowLayout());
this.getContentPane().setBackground(Color.orange);
this.setResizable(false);
String name[] = { "人人对战", "人机对战", "悔棋", "重新开始"};
for (int i = 0; i < name.length; i++) {
JButton jbu = new JButton(name[i]);
jbu.setPreferredSize(new Dimension(90, 30));
this.add(jbu);
jbu.addActionListener(mouse);//事件监听器
}
this.setVisible(true);
Graphics g = this.getGraphics();
mouse.setChessListener(g, chess,this);
this.addMouseListener(mouse);
}
public void paint(Graphics g) {
super.paint(g);//父类
drawChessBroad(g); //画棋盘
paintChess(g);//画棋子
}
public void drawChessBroad(Graphics g) { //画棋盘
for (int i = 0; i < ROWS; i++) {
g.drawLine(X0, Y0 + SIZE * i, X0 + SIZE * (ROWS - 1), Y0 + SIZE * i);
g.drawLine(X0 + SIZE * i, Y0, X0 + SIZE * i, Y0 + SIZE * (COLUMNS - 1));
}
}
private void paintChess(Graphics g){
for (int i = 0; i < chess.length; i++)// 棋子
for (int j = 0; j < chess.length; j++) {
if (chess[i][j] == 1) {
g.fillOval(X0 + i * SIZE - CHESS_SIZE / 2, Y0 + j * SIZE - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
} else if (chess[i][j] == 2) {
g.setColor(Color.WHITE);
g.fillOval(X0 + i * SIZE - CHESS_SIZE / 2, Y0 + j * SIZE - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
}
}
}
public static void main(String[] args) {
ChessBoard cb = new ChessBoard();
cb.showUI();
}
}
第二个类Win:
import javax.swing.JOptionPane;
public class Win {
private int[][] chessA;
public Win(int[][] chess) {
this.chessA = chess;
}
public void isWin(int x, int y) {
//print();
if (Sprow(x,y) >= 5||Spcolumn(x,y) >= 5||Spyoushang( x, y)>=5||Spzuoshang( x, y)>=5) {
if (chessA[x][y] == 1) {
JOptionPane.showMessageDialog(null, "黑棋赢!");
}
if (chessA[x][y] == -1) {
JOptionPane.showMessageDialog(null, "白棋赢!");
}
if (chessA[x][y] == 0) {
JOptionPane.showMessageDialog(null, "赢!");
}
}
}
//public void print() {
//for (int i = 0; i < chessA.length; i++) {
//for (int j = 0; j < chessA.length; j++) {
//System.out.print(chessA[j][i] + " ");
//}
//System.out.println();
//}
//System.out.println();
//}
public int Sprow(int x, int y) {
//System.out.println("x = " + x + " y = " + y );
int count = 0;
//System.out.print(chessA[x][y] + " ");
for(int i=x+1;i
if(chessA[x][y] == chessA[i][y]){
count++;
//System.out.println("count = "+count);
}if(chessA[x][y] != chessA[i][y]){
break;
}
}
//向左
for(int i=x;i>=0;i--){
if(chessA[x][y] == chessA[i][y]){
count++;
System.out.println("count2 = "+count);
}if(chessA[x][y] != chessA[i][y]){
break;
}
}
return count;
}
public int Spcolumn(int x, int y) {
//System.out.println("x = " + x + " y = " + y );
int count = 0;
//System.out.print(chessA[x][y] + " ");
for(int i=y+1;i
if(chessA[x][y] == chessA[x][i]){
count++;
//System.out.println("count = "+count);
}if(chessA[x][y] != chessA[x][i]){
break;
}
}
//向左
for(int i=y;i>=0;i--){
if(chessA[x][y] == chessA[x][i]){
count++;
System.out.println("count2 = "+count);
}else{
break;
}
}
return count;
}
public int Spzuoshang(int x, int y) {//注意左上坐标是最小
//System.out.println("x = " + x + " y = " + y );
int count = 0;
//System.out.print(chessA[x][y] + " ");
for(int i=x+1,j=y+1;i
count++;
//System.out.println("count = "+count);
}else{
break;
}
}
//向左上
for(int i=x,j=y;i>=0&&j>=0;j--,i--){
if(chessA[x][y] == chessA[i][j]){
count++;
//System.out.println("count2 = "+count);
}else{
break;
}
}
return count;
}
public int Spyoushang(int x, int y) {
//System.out.println("x = " + x + " y = " + y );
int count = 0;
//System.out.print(chessA[x][y] + " ");
for(int i=x+1,j=y-1;i=0;i++,j--){if(chessA[x][y] == chessA[i][j]){
count++;
//System.out.println("count = "+count);
}else{
break;
}
}
//向左下
for(int i=x,j=y;i>=0&&j
if(chessA[x][y] == chessA[i][j]){
count++;
//System.out.println("count2 = "+count);
}else{
break;
}
}
return count;
}
}
第三类(事件类):
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import com.chesswuzi1211.Config;
public class ChessListener extends MouseAdapter implements Config,ActionListener{
private Graphics g;
private ChessBoard j;
private int x, y, xx, yy;
private int count = 0;
// 保存棋子的数组
private int[][] chessArray;
private int[] setX = new int[ROWS * COLUMNS];
private int[] setY = new int[ROWS * COLUMNS];
public void setChessListener(Graphics g, int[][] chess,ChessBoard j) {
this.g = g;
this.chessArray = chess;
this.j = j;
}
public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
if ((x - X0) % SIZE > SIZE / 2) {
xx = (x - X0) / SIZE + 1;
} else {
xx = (x - X0) / SIZE;
}
if ((y - Y0) % SIZE > SIZE / 2) {
yy = (y - Y0) / SIZE + 1;
} else {
yy = (y - Y0) / SIZE;
}
if (chessArray[xx][yy] == 0) {
if (count % 2 == 0) {
chessArray[xx][yy] = 1;
} else {
g.setColor(Color.WHITE);
chessArray[xx][yy] = 2;
}
setX[count] = xx;
setY[count] = yy;
count++;
g.fillOval(xx * SIZE + X0 - CHESS_SIZE / 2, yy * SIZE + Y0 - CHESS_SIZE / 2, CHESS_SIZE, CHESS_SIZE);
Win win = new Win(chessArray);
win.isWin(xx,yy);
}
}
@Override
public void actionPerformed(ActionEvent e) {
if ("悔棋".equals(e.getActionCommand())) {
if (count>0){
count--;
chessArray[setX[count]][setY[count]]=0;
j.repaint();
}
}
if ("重新开始".equals(e.getActionCommand())) {
for (int j = 0; j < chessArray.length; j++) {
for (int i = 0; i < chessArray.length; i++) {
chessArray[i][j] = 0;
count = 0;
}
}
j.repaint();
}
}
}
第四个类(接口):
public interface Config {
public static final int X0 = 45; //左上点的x
public static final int Y0 = 80;//左上点的y
public static final int ROWS = 15;//行
public static final int COLUMNS = 15;//列
public static final int CHESS_SIZE = 30; //棋子大小
public static final int SIZE = 40;//线距
}