界面开发部分:
1:创建窗体
继承JFrame 调用JFrame 设置标题 尺寸 关闭 可视化 布局等功能
设置布局为null 布局 ,按钮都需要指定位置
public void showUI(){
//调用继承方法
setTitle("五子棋");
setSize(850,750);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(null);
//创建按钮对象
JButton btnStart = new JButton("开始游戏");
JButton btnRb = new JButton("悔棋");
btnStart.setBounds(650,100,100,50);
btnRb.setBounds(650,150,100,50);
setVisible(true);
2:绘制棋盘 重写JFrame 的paint方法
绘制背景矩形 绘制网格
@Override
public void paint(Graphics g) {
super.paint(g);
gol.paintChessPad(g);
//设置颜色 绘制底板
Color bgColor = new Color(120, 190, 80);
g.setColor(bgColor);
g.fillRect(X - SIZE / 2, Y - SIZE / 2, SIZE * ROWS + SIZE, SIZE * COLS + SIZE);
//设置颜色,绘制网格
g.setColor(Color.BLACK);
for (int i = 0; i <= ROWS; i++) {
g.drawLine(X, Y + i * SIZE, X + COLS * SIZE, Y + i * SIZE);
g.drawLine(X + i * SIZE, Y, X + i * SIZE, Y + ROWS * SIZE);
}
监听器部分:
1: 按钮监听 ActionListener
2: 鼠标监听器: MouseListener
public class Golistener implements ActionListener, MouseListener {
Graphics g;
//棋盘数据设定
int X=50,Y=75,SIZE=40,ROWS=15,COLS=15;
//设置标识
int chessFlag=0;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮被点击了" );
//获取按钮文本
String btnText = e.getActionCommand();
//获取按钮对象
JButton btn = (JButton) e.getSource();
if(btnText.equals("开始游戏")){
chessFlag=1;
btn.setText("结束游戏");
}else if(btnText.equals("结束游戏")){
chessFlag=0;
chessArr = new int[ROWS+1][COLS+1];
listIndex=0;
chessList = new Chess[(ROWS+1)*(COLS+1)];
paintChessPad(g);
btn.setText("开始游戏");
}else if(btnText.equals("悔棋")){
if(listIndex<=1){
JOptionPane.showMessageDialog(null,"无棋可悔");
return;
}
Chess chess = chessList[listIndex-1];
chessArr[chess.r][chess.c]=0;
chessList[listIndex-1] = null;
listIndex--;
chessFlag = chess.chessFlag;
paintChessPad(g);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if(chessFlag==0){
JOptionPane.showMessageDialog(null,"游戏未开始,请先点击开始游戏");
return;
}
//获取鼠标按下坐标
int x = e.getX();
int y = e.getY();
//将坐标转换为行列值
int r = (y-Y+SIZE/2)/SIZE;
int c = (x-X+SIZE/2)/SIZE;
//判断是否在棋盘内下棋
if(x<X-SIZE/2||y<Y-SIZE/2||c>COLS||r>ROWS){
JOptionPane.showMessageDialog(null,"请在棋盘内下棋");
return;
}
//判断是否重复下棋
if(chessArr[r][c]!=0){
JOptionPane.showMessageDialog(null,"此处已有棋子,请重新下棋");
return;
}
存储棋子部分:
1: 二维数组存储棋子
//存储棋子的数组
Chess[] chessList = new Chess[(ROWS+1) * (COLS+1)];
int listIndex=0;
//将棋子存入棋盘数组中
chessArr[r][c] = chessFlag;
//将数据转为一个棋子对象
Chess chess = new Chess();
chess.r=r;
chess.c=c;
chess.chessFlag=chessFlag;
//存入棋子对象数组中
chessList[listIndex]=chess;
listIndex++;
//将行列值转化为标准坐标
int chessX = c*SIZE+X-SIZE/2;
int chessY = r*SIZE+Y-SIZE/2;
if(chessFlag==1){
for(int i=0;i <SIZE;i++){
Color color = new Color(i*5,i*5,i*5);
g.setColor(color);
g.fillOval(chessX+i/2,chessY+i/2,SIZE-i,SIZE-i);
}
chessFlag = 2;
}else if(chessFlag==2){
for(int i=0;i <SIZE;i++){
Color color = new Color(i+200,i+200,i+200);
g.setColor(color);
g.fillOval(chessX+i/2,chessY+i/2,SIZE-i,SIZE-i);
}
chessFlag = 1;
}
2: 实现重绘棋子 在重绘的方法中 paint方法中
//使用监听器对象 调用二维数组 绘制棋子
int[][] chessArr = gol.chessArr;
for(int i = 0;i<chessArr.length;i++){
for (int j=0;j<chessArr[i].length;j++){
int chessNum = chessArr[i][j];
if (chessNum!=0){
//将行列值转化为标准坐标
int chessX = j*SIZE+X-SIZE/2;
int chessY = i*SIZE+Y-SIZE/2;
if(chessNum==1){
for(int k=0;k <SIZE;k++){
Color color = new Color(k*5,k*5,k*5);
g.setColor(color);
g.fillOval(chessX+k/2,chessY+k/2,SIZE-k,SIZE-k);
}
}else if(chessNum==2){
for(int k=0;k <SIZE;k++){
Color color = new Color(k+200,k+200,k+200);
g.setColor(color);
g.fillOval(chessX+k/2,chessY+k/2,SIZE-k,SIZE-k);
}
3: 判断输赢
public class GoIsWin {
public static boolean isWin(int r,int c,int[][] chessArr){
if(row(r,c,chessArr)>=5||
col(r,c,chessArr)>=5||
left(r,c,chessArr)>=5||
right(r,c,chessArr)>=5){
return true;
}
return false;
}
private static int right(int r, int c, int[][] chessArr) {
int count = 0;
int c1 = chessArr[r][c];
for(int i =r-1,j=c+1;i>=0&&j<chessArr[0].length;i--,j++){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
for (int i =r+1,j=c-1;i<chessArr.length&&j>=0;i++,j--){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int left(int r, int c, int[][] chessArr) {
int count = 0;
int c1 = chessArr[r][c];
for(int i =r+1,j=c+1;i<chessArr.length&&j<chessArr[0].length;i++,j++){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
for (int i =r-1,j=c-1;i<chessArr[0].length&&j<chessArr[0].length;i--,j--){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int col(int r, int c, int[][] chessArr) {
int count=0;
int c1 = chessArr[r][c];
for(int i =r+1;i<chessArr.length;i++){
if(c1 == chessArr[i][c]){
count++;
}else{
break;
}
}
for (int i=r-1;i>=0;i--){
if(c1 == chessArr[i][c]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int row(int r, int c, int[][] chessArr) {
int count=0;
int c1 = chessArr[r][c];
for(int i =c+1;i<chessArr[0].length;i++){
if(c1 == chessArr[r][i]){
count++;
}else{
break;
}
}
for (int i=c-1;i>=0;i--){
if(c1 == chessArr[r][i]){
count++;
}else{
break;
}
}
count++;
return count;
}
}
悔棋:
知道每一颗棋子的顺序
创建一个棋子类,将棋子的坐标以及棋子标识设置为属性
public class Chess {
int r;
int c;
int chessFlag;
}
每次下棋时 创建一个棋子对象 存入一个棋子对象一维数组中
Chess[] chessList = new Chess[(ROWS+1) * (COLS+1)];
int listIndex=0;
//存入棋子对象数组中
chessList[listIndex]=chess;
listIndex++;
点击悔棋按钮时,将棋子对象数组中的最后一个棋子对象取出
获取其行列值 删除二维数组中的数据 再删除一维数组中的棋子对象 重置标识
自动刷新
else if(btnText.equals("悔棋")){
if(listIndex<=1){
JOptionPane.showMessageDialog(null,"无棋可悔");
return;
}
Chess chess = chessList[listIndex-1];
chessArr[chess.r][chess.c]=0;
chessList[listIndex-1] = null;
listIndex--;
chessFlag = chess.chessFlag;
paintChessPad(g);
}
完整代码如下:
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 ActionListener, MouseListener {
Graphics g;
//棋盘数据设定
int X=50,Y=75,SIZE=40,ROWS=15,COLS=15;
//设置标识
int chessFlag=0;
//创建存储棋子的二维数组
int[][] chessArr = new int[ROWS+1][COLS+1];
//存储棋子的数组
Chess[] chessList = new Chess[(ROWS+1) * (COLS+1)];
int listIndex=0;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮被点击了" );
//获取按钮文本
String btnText = e.getActionCommand();
//获取按钮对象
JButton btn = (JButton) e.getSource();
if(btnText.equals("开始游戏")){
chessFlag=1;
btn.setText("结束游戏");
}else if(btnText.equals("结束游戏")){
chessFlag=0;
chessArr = new int[ROWS+1][COLS+1];
listIndex=0;
chessList = new Chess[(ROWS+1)*(COLS+1)];
paintChessPad(g);
btn.setText("开始游戏");
}else if(btnText.equals("悔棋")){
if(listIndex<=1){
JOptionPane.showMessageDialog(null,"无棋可悔");
return;
}
Chess chess = chessList[listIndex-1];
chessArr[chess.r][chess.c]=0;
chessList[listIndex-1] = null;
listIndex--;
chessFlag = chess.chessFlag;
paintChessPad(g);
}
}
@Override
public void mouseClicked(MouseEvent e) {
if(chessFlag==0){
JOptionPane.showMessageDialog(null,"游戏未开始,请先点击开始游戏");
return;
}
//获取鼠标按下坐标
int x = e.getX();
int y = e.getY();
//将坐标转换为行列值
int r = (y-Y+SIZE/2)/SIZE;
int c = (x-X+SIZE/2)/SIZE;
//判断是否在棋盘内下棋
if(x<X-SIZE/2||y<Y-SIZE/2||c>COLS||r>ROWS){
JOptionPane.showMessageDialog(null,"请在棋盘内下棋");
return;
}
//判断是否重复下棋
if(chessArr[r][c]!=0){
JOptionPane.showMessageDialog(null,"此处已有棋子,请重新下棋");
return;
}
//将棋子存入棋盘数组中
chessArr[r][c] = chessFlag;
//将数据转为一个棋子对象
Chess chess = new Chess();
chess.r=r;
chess.c=c;
chess.chessFlag=chessFlag;
//存入棋子对象数组中
chessList[listIndex]=chess;
listIndex++;
//将行列值转化为标准坐标
int chessX = c*SIZE+X-SIZE/2;
int chessY = r*SIZE+Y-SIZE/2;
if(chessFlag==1){
for(int i=0;i <SIZE;i++){
Color color = new Color(i*5,i*5,i*5);
g.setColor(color);
g.fillOval(chessX+i/2,chessY+i/2,SIZE-i,SIZE-i);
}
chessFlag = 2;
}else if(chessFlag==2){
for(int i=0;i <SIZE;i++){
Color color = new Color(i+200,i+200,i+200);
g.setColor(color);
g.fillOval(chessX+i/2,chessY+i/2,SIZE-i,SIZE-i);
}
chessFlag = 1;
}
//判断输赢
boolean winFlag = GoIsWin.isWin(r,c,chessArr);
if(winFlag){
if(chessFlag ==1){
JOptionPane.showMessageDialog(null,"白棋胜");
} else if(chessFlag ==2) {
JOptionPane.showMessageDialog(null, "黑棋胜");
}
chessFlag = 0;
}
}
public void paintChessPad(Graphics g){
//设置颜色 绘制底板
Color bgColor = new Color(120, 190, 80);
g.setColor(bgColor);
g.fillRect(X - SIZE / 2, Y - SIZE / 2, SIZE * ROWS + SIZE, SIZE * COLS + SIZE);
//设置颜色,绘制网格
g.setColor(Color.BLACK);
for (int i = 0; i <= ROWS; i++) {
g.drawLine(X, Y + i * SIZE, X + COLS * SIZE, Y + i * SIZE);
g.drawLine(X + i * SIZE, Y, X + i * SIZE, Y + ROWS * SIZE);
}
for(int i = 0;i<chessArr.length;i++){
for (int j=0;j<chessArr[i].length;j++){
int chessNum = chessArr[i][j];
if (chessNum!=0){
//将行列值转化为标准坐标
int chessX = j*SIZE+X-SIZE/2;
int chessY = i*SIZE+Y-SIZE/2;
if(chessNum==1){
for(int k=0;k <SIZE;k++){
Color color = new Color(k*5,k*5,k*5);
g.setColor(color);
g.fillOval(chessX+k/2,chessY+k/2,SIZE-k,SIZE-k);
}
}else if(chessNum==2){
for(int k=0;k <SIZE;k++){
Color color = new Color(k+200,k+200,k+200);
g.setColor(color);
g.fillOval(chessX+k/2,chessY+k/2,SIZE-k,SIZE-k);
}
}
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusListener;
public class GoBangUI extends JFrame{
//设置棋盘数据
int X=50,Y=75,SIZE=40,ROWS=15,COLS=15;
//创建监听器对象
Golistener gol = new Golistener();
public void showUI(){
//调用继承方法
setTitle("五子棋");
setSize(850,750);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(null);
//创建按钮对象
JButton btnStart = new JButton("开始游戏");
JButton btnRb = new JButton("悔棋");
btnStart.setBounds(650,100,100,50);
btnRb.setBounds(650,150,100,50);
setVisible(true);
add (btnStart);
add (btnRb);
setVisible(true);
//按钮,窗体添加监听
btnRb.addActionListener(gol);
btnStart.addActionListener(gol);
addMouseListener(gol);
//获取画笔 传给监听器对象 用于绘制棋子
getGraphics();
Graphics gr =getGraphics();
gol.g=gr;
}
@Override
public void paint(Graphics g) {
super.paint(g);
gol.paintChessPad(g);
//设置颜色 绘制底板
Color bgColor = new Color(120, 190, 80);
g.setColor(bgColor);
g.fillRect(X - SIZE / 2, Y - SIZE / 2, SIZE * ROWS + SIZE, SIZE * COLS + SIZE);
//设置颜色,绘制网格
g.setColor(Color.BLACK);
for (int i = 0; i <= ROWS; i++) {
g.drawLine(X, Y + i * SIZE, X + COLS * SIZE, Y + i * SIZE);
g.drawLine(X + i * SIZE, Y, X + i * SIZE, Y + ROWS * SIZE);
}
public class GoIsWin {
public static boolean isWin(int r,int c,int[][] chessArr){
if(row(r,c,chessArr)>=5||
col(r,c,chessArr)>=5||
left(r,c,chessArr)>=5||
right(r,c,chessArr)>=5){
return true;
}
return false;
}
private static int right(int r, int c, int[][] chessArr) {
int count = 0;
int c1 = chessArr[r][c];
for(int i =r-1,j=c+1;i>=0&&j<chessArr[0].length;i--,j++){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
for (int i =r+1,j=c-1;i<chessArr.length&&j>=0;i++,j--){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int left(int r, int c, int[][] chessArr) {
int count = 0;
int c1 = chessArr[r][c];
for(int i =r+1,j=c+1;i<chessArr.length&&j<chessArr[0].length;i++,j++){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
for (int i =r-1,j=c-1;i<chessArr[0].length&&j<chessArr[0].length;i--,j--){
if(c1 == chessArr[i][j]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int col(int r, int c, int[][] chessArr) {
int count=0;
int c1 = chessArr[r][c];
for(int i =r+1;i<chessArr.length;i++){
if(c1 == chessArr[i][c]){
count++;
}else{
break;
}
}
for (int i=r-1;i>=0;i--){
if(c1 == chessArr[i][c]){
count++;
}else{
break;
}
}
count++;
return count;
}
private static int row(int r, int c, int[][] chessArr) {
int count=0;
int c1 = chessArr[r][c];
for(int i =c+1;i<chessArr[0].length;i++){
if(c1 == chessArr[r][i]){
count++;
}else{
break;
}
}
for (int i=c-1;i>=0;i--){
if(c1 == chessArr[r][i]){
count++;
}else{
break;
}
}
count++;
return count;
}
}
public class Chess {
int r;
int c;
int chessFlag;
}