Java项目实训:五子棋v0.1
界面开发
- 界面开发:
- 界面类:
- 创建接口,存储期盼上的固定数据
- 棋盘面板:
- 创建一个类继承JPanel重写面板控制方法paint
- 绘制背景、网格线以及使用到的接口中的固定数据
- 按键面板:
- 添加按钮:
- 采用遍历字符串形式创建多个按钮
- 设置按钮尺寸等属性
- 添加按钮:
- 监听器类:
- 实现鼠标监听:
- 使用按下监听方法
- 获取鼠标按下的坐标
- 校准坐标
- 判断范围
- 实现按钮监听:
- 获取按钮上的字符串及按钮对象
- 实现鼠标监听:
- 界面类:
棋子数据化
- 存在的问题:
- 棋子绘制在棋盘会出现棋盘最小化再打开就消失
- 可以在同一个地方可以重复绘制
- 悔棋需要一个顺序数组 (坐标 先后顺序)
- 判断输赢/回放都需要棋子的数据
- 解决方法:
- 使用 二维数组 来存储棋子的数据 可以解决棋子最小化、重复绘制等问题
- 整数型二维数组,其中存储三个数值 0-无棋子 1-黑棋 2-白棋
- 在下棋的位置时,将对应的二维数组的值设置为1或2
- 在之前先判断这个位置上对应二维数组中是否为0,不为0则不允许下棋直接弹窗+return
- 在ChessPanel中,将chessArray传过来,遍历二维数组绘制棋子
- 可以使用 一维Chess数组 来存储棋子的数据 (r,c,chessFlag) 来解决悔棋操作
- 使用 二维数组 来存储棋子的数据 可以解决棋子最小化、重复绘制等问题
输赢判断
- 原理:
- 根据最后一颗棋子的六个方向进行判断
- 判断连续的五颗棋子
- 实现四个方法:判断四个方向上(从上到下、从左到右、从左上到右下、从右上到左下)是否有物资连棋
- 一个方法实现判断,返回布尔值,从而发送提示窗
代码
- 界面类:
package lyq0319;
import javax.swing.*;
import java.awt.*;
public class GoBangUI {
GoListener goListener=new GoListener();
public void initGoUI(){
JFrame jf=new JFrame();
jf.setSize(900,800);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setResizable(false);
jf.setLocationRelativeTo(null);
ChessPanel chessPanel = new ChessPanel();
chessPanel.addMouseListener(goListener);
chessPanel.setChessArray(goListener.getChessArray());
goListener.setChessPanel(chessPanel);
JPanel btnPanel = new JPanel();
btnPanel.setBackground(Color.GRAY);
btnPanel.setPreferredSize(new Dimension(110,0));
this.initBtnPanel(btnPanel);
jf.add(chessPanel,BorderLayout.CENTER);
jf.add(btnPanel,BorderLayout.WEST);
jf.setVisible(true);
goListener.setGraphics(chessPanel.getGraphics());
}
public void initBtnPanel(JPanel btnPanel){
String[] strs={"开始游戏","悔棋","退出游戏","历史记录"};
for(int i=0;i< strs.length;i++){
JButton btn=new JButton(strs[i]);
btn.setBackground(Color.WHITE);
btn.setPreferredSize(new Dimension(95,35));
btnPanel.add(btn);
btn.addActionListener(goListener);
}
}
public static void main(String[] args) {
new GoBangUI().initGoUI();
}
}
- 监听器类:
package lyq0319;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLOutput;
public class GoListener extends MouseAdapter implements ActionListener,Godate {
private Graphics g;
public void setGraphics(Graphics g){
this.g=g;
}
private int[][] chessArray = new int[ROWS][COLS];
private Chess[] chessList = new Chess[ROWS*COLS];
private int chessIndex = 0;
public int[][] getChessArray(){
return chessArray;
}
private ChessPanel chessPanel;
public void setChessPanel(ChessPanel chessPanel){
this.chessPanel = chessPanel;
}
int chessFlag =0;
@Override
public void actionPerformed(ActionEvent e){
String action = e.getActionCommand();
Object source = e.getSource();
JButton btn = (JButton) source;
if(action.equals("开始游戏")){
chessFlag=1;
btn.setText("结束游戏");
} else if (action.equals("结束游戏")) {
chessFlag=0;
btn.setText("开始游戏");
this.cleanChessArray();
chessPanel.paint(g);
}else if(action.equals("悔棋")){
this.rebackChess();
}
else if(action.equals("退出游戏")){
System.exit(0);
}
}
@Override
public void mousePressed(MouseEvent e) {
int x= e.getX();
int y=e.getY();
System.out.println("x:"+x+"y:"+y);
int r=(y-Y+SIZE/2)/SIZE;
int c=(x-X+SIZE/2)/SIZE;
System.out.println("r:"+r+"c:"+c);
if(chessFlag==0){
JOptionPane.showMessageDialog(null,"点击开始游戏 开始游戏!");
return;
}
if(x<=X-SIZE/2||y<=Y-SIZE/2||r<0||r>16||c<0||c>16){
JOptionPane.showMessageDialog(null,"此处不能下棋!");
return;
}
if(chessArray[r][c]!=0){
JOptionPane.showMessageDialog(null,"此处不能下棋啦!");
return;
}
chessArray[r][c] = chessFlag;
Chess chess = new Chess(r,c,chessFlag);
chessList[chessIndex]=chess;
chessIndex++;
if (chessFlag == 1) {
g.setColor(Color.BLACK);
chessFlag=2;
}else if(chessFlag == 2){
g.setColor(Color.WHITE);
chessFlag=1;
}
int cx=c*SIZE+X-SIZE/2;
int cy=r*SIZE+Y-SIZE/2;
g.fillOval(cx,cy,SIZE,SIZE);
printChessArray();
}
public void printChessArray(){
for(int i=0;i<chessArray.length;i++) {
for (int j = 0; j < chessArray[i].length; j++) {
System.out.print(chessArray[i][j] + " ");
}
System.out.println();
}
}
public void cleanChessArray(){
for(int i=0;i<chessArray.length;i++){
for(int j=0;j<chessArray[i].length;j++){
chessArray[i][j]=0;
}
}
}
public void rebackChess(){
if(chessIndex<=1){
JOptionPane.showMessageDialog(null,"不能再悔棋!");
return;
}
Chess chess = chessList[chessIndex-1];
chessArray[chess.r][chess.c] = 0;
chessFlag = chess.chessFlag;
chessList[chessIndex-1]=null;
chessIndex--;
chessPanel.paint(g);
}
}
- 重写控制面板的类
package lyq0319;
import javax.swing.*;
import java.awt.*;
public class ChessPanel extends JPanel implements Godate{
private int[][] chessArray;
public void setChessArray(int[][] chessArray){
this.chessArray=chessArray;
}
@Override
public void paint(Graphics g) {
g.setColor(new Color(200,150,30));
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(Color.BLACK);
for(int i=0;i<ROWS;i++){
g.drawLine(X,Y+i*SIZE,X+GRID_NUM*SIZE,Y+i*SIZE);
g.drawLine(X+i*SIZE,Y,X+i*SIZE,Y+GRID_NUM*SIZE);
}
for (int i=0;i<chessArray.length;i++){
for(int j=0;j<chessArray[i].length;j++){
int chessNum = chessArray[i][j];
if(chessNum!=0){
g.setColor(chessNum==1?Color.BLACK:Color.WHITE);
int cx =X+j*SIZE-SIZE/2;
int cy =Y+i*SIZE-SIZE/2;
g.fillOval(cx,cy,SIZE,SIZE);
}
}
}
}
}
- 棋子属性接口
package lyq0319;
public interface Godate {
int X=80;
int Y=80;
int SIZE=40;
int ROWS=16;
int COLS=16;
int GRID_NUM=15;
}
- 存储棋子数据的一维数组类
package lyq0319;
public class Chess {
int r,c,chessFlag;
public Chess(int r,int c,int chessFlag){
this.r=r;
this.c=c;
this.chessFlag=chessFlag;
}
}
- 输赢判断类
package lyq0319;
public class GoWin {
public static void main(String[] args) {
int[][] chessArray = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
};
isWin(chessArray,1,2);
}
public static boolean isWin(int[][] chessArray,int r,int c){
if(row(chessArray,r,c)>=5||
column(chessArray,r,c)>=5||
leftUpToRightDown(chessArray,r,c)>=5||
RightUpToLeftDown(chessArray,r,c)>=5){
return true;
}
return false;
}
//判断横向
public static int row(int[][] chessArray,int r,int c){
int count=1;
//当前所下棋子
int cnum=chessArray[r][c];
//向右
for(int i=c+1;i<chessArray.length;i++){
if(cnum==chessArray[r][i]){
count++;
}else {
break;
}
}
System.out.println("横向上向右查找到:count="+count);
//向左
for(int i=c-1;i>=0;i--){
if(cnum==chessArray[r][i]){
count++;
}else {
break;
}
}
System.out.println("横向上查找到:count="+count);
return count;
}
//判断纵向
public static int column(int[][] chessArray,int r,int c) {
int count=1;
//当前所下棋子
int cnum=chessArray[r][c];
//向右
for(int i=r+1;i<chessArray.length;i++){
if(cnum==chessArray[i][c]){
count++;
}else {
break;
}
}
System.out.println("纵向上向右查找到:count="+count);
//向左
for(int i=r-1;i>=0;i--){
if(cnum==chessArray[i][c]){
count++;
}else {
break;
}
}
System.out.println("纵向上查找到:count="+count);
return count;
}
public static int leftUpToRightDown(int[][] chessArray,int r,int c){
int count=1;
int cnum=chessArray[r][c];
//向左上角找 行列都变小 i-- j--
for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){
if(cnum==chessArray[i][j]){
count++;
}else{
break;
}
}
System.out.println("从左上:count"+count);
//向右下角找 行列式变大 i++ j++
for(int i=r+1,j=c+1;i<chessArray.length&&j< chessArray.length;i++,j++){
if(cnum==chessArray[i][j]){
count++;
}else{
break;
}
}
System.out.println("从左上到右下:count"+count);
return count;
}
public static int RightUpToLeftDown(int[][] chessArray,int r,int c){
int count=1;
int cnum=chessArray[r][c];
//向左下角找 行列都变小 i-- j--
for(int i=r-1,j=c+1;i>=0&&j<chessArray.length;i--,j++){
if(cnum==chessArray[i][j]){
count++;
}else{
break;
}
}
System.out.println("从左上:count"+count);
//向右上角找 行列式变大 i++ j++
for(int i=r+1,j=c-1;i<chessArray.length&&j>=0;i++,j--){
if(cnum==chessArray[i][j]){
count++;
}else{
break;
}
}
System.out.println("从左上到右下:count"+count);
return count;
}
}
运行结果