package chess.view; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import javax.swing.JOptionPane; import javax.swing.JPanel; public class GraphicPanel extends JPanel{ private boolean isBlack=true;//当前下子是否是黑方 private char[][] allChess;//保存所有棋子的数组 private int boardX=-1;//最后一次有效落子在棋盘的x,y坐标 private int boardY=-1; public static final int ROW_NUM=16;//行数 public static final int COL_NUM=16;//列数 public static final int LEFT_BORDER=20;//左边界 public static final int RIGTH_BORDER=20;//右边界 public static final int UP_BORDER=20;//上边界 public static final int DOWN_BORDER=20;//下边界 public static final int ROW_GAP=40;//行间隙 public static final int COL_GAP=40;//列间隙 public static final int ChessRadio=15;//棋子半径 public GraphicPanel(){ allChess=new char[ROW_NUM][COL_NUM]; for(int i=0;i<allChess.length;i++){//给旗子数组实例化 for(int j=0;j<allChess[i].length;j++){ allChess[i][j]='*';//初始时都赋为‘*’ } } ChessBoard.label.setText((isBlack?"黑":"白")+"方请下子..."); addMouseListener(new MouseAdapter(){//给该面板添加鼠标事件监听 public void mouseClicked(MouseEvent e) { int button=e.getButton();//获得是按了那按钮 if(button!=MouseEvent.BUTTON1){//如果不是鼠标左键点击 return;//则不做任何处理 } int x=e.getX();//获得鼠标点击位置的x,y坐标 int y=e.getY(); //如果鼠标点击点没有发生在棋盘的有效位置 if(x<LEFT_BORDER/2 || x> LEFT_BORDER+(COL_NUM-1)*COL_GAP+RIGTH_BORDER/2 || y<UP_BORDER/2 || y>UP_BORDER+(ROW_NUM-1)*ROW_GAP+DOWN_BORDER/2){ ChessBoard.label.setText("无效位置!"); return;//则不做任何处理 } //将鼠标点击点的x,y坐标换算成棋盘上的x,y坐标。(x-20)/40 int boardX=Math.round((float)(x-LEFT_BORDER)/ROW_GAP);//除以行宽 int boardY=Math.round((float)(y-UP_BORDER)/COL_GAP);//除以列宽 //如果该位置上有棋子 if(allChess[boardY][boardX]!='*'){ ChessBoard.label.setText("该位置有棋子"); return;//则不做任何处理 } //将棋盘上该位置设置为指定棋子 allChess[boardY][boardX]=isBlack?'@':'O'; GraphicPanel.this.boardX=boardX;//保存最后一次有效落子的坐标 GraphicPanel.this.boardY=boardY; //重画棋盘 repaint(); if(wasWin()){ String mesg=(isBlack?"黑":"白")+"方获胜!"; ChessBoard.label.setText(mesg); JOptionPane.showMessageDialog(GraphicPanel.this,mesg); clear(); return; } //改变下棋方 isBlack=!isBlack; ChessBoard.label.setText((isBlack?"黑":"白")+"方请下子..."); } }); } public boolean wasWin(){ return wasWinAtV()||wasWinAtH()||wasWinAtLD()||wasWinAtRD(); } private boolean wasWinAtV(){ char ch=isBlack?'@':'O'; int i=boardX; while(i>=0 && allChess[boardY][i]==ch){//向左找到第一个不是ch的字符 i--; } int num=0; i++; while(i<allChess.length && allChess[boardY][i]==ch){ num++; i++; } return num>=5; } private boolean wasWinAtH(){ char ch=isBlack?'@':'O'; int i=boardY; while(i>=0 && allChess[i][boardX]==ch){//向左找到第一个不是ch的字符 i--; } int num=0; i++; while(i<allChess.length && allChess[i][boardX]==ch){ num++; i++; } return num>=5; } private boolean wasWinAtLD(){ char ch=isBlack?'@':'O'; int i=boardY; int j=boardX; while(i>=0 && j<allChess.length && allChess[i][j]==ch){//向左找到第一个不是ch的字符 i--; j++; } int num=0; i++; j--; while(i<allChess.length && j>=0 && allChess[i][j]==ch){ num++; i++; j--; } return num>=5; } private boolean wasWinAtRD(){ char ch=isBlack?'@':'O'; int i=boardY; int j=boardX; while(i>=0 && j>=0 && allChess[i][j]==ch){//向左找到第一个不是ch的字符 i--; j--; } int num=0; i++; j++; while(i<allChess.length && j<allChess.length && allChess[i][j]==ch){ num++; i++; j++; } return num>=5; } public void clear(){ boardX=-1; boardY=-1; for(int i=0;i<allChess.length;i++){ for(int j=0;j<allChess[i].length;j++){ allChess[i][j]='*';//初始时都赋为‘*’ } } isBlack=true; // 重画棋盘 repaint(); ChessBoard.label.setText((isBlack?"黑":"白")+"方请下子..."); } /** * 把当前棋盘状态保存到指定的文件中! * @param f */ public boolean saveToFile(File f){ //1,建立一个FileOutputStream FileOutputStream fos=null; try { fos=new FileOutputStream(f); for(int i=0;i<allChess.length;i++){ for(int j=0;j<allChess[i].length;j++){ if(i==boardY && j==boardX){ fos.write(isBlack?'W':'B'); }else{ fos.write(allChess[i][j]); } } } } catch (IOException e) { e.printStackTrace(); return false; }finally{ if(fos!=null)try{fos.close();}catch(IOException e){} } return true; } public boolean loadFromFile(File f){ FileInputStream fis=null; try { fis=new FileInputStream(f); for(int i=0;i<allChess.length;i++){ for(int j=0;j<allChess[i].length;j++){ char c=(char)fis.read(); if(c!='*' && c!='O' && c!='@' && c!='W' && c!='B'){ return false; } if(c=='B'){ allChess[i][j]='@'; boardX=j; boardY=i; isBlack=false; }else if(c=='W'){ allChess[i][j]='O'; boardX=j; boardY=i; isBlack=true; }else{ allChess[i][j]=c; } } } } catch (IOException e) { e.printStackTrace(); return false; }finally{ if(fis!=null)try{fis.close();}catch(IOException e){} } this.repaint(); return true; } @Override /** * 该方法为覆盖父类的方法,每次重画棋盘时系统会自动调用该方法。 */ public void paintComponent(Graphics g){ super.paintComponent(g); //定义画笔类型 Stroke stroke=new BasicStroke(2.0f); Graphics2D g2=(Graphics2D)g; g2.setStroke(stroke); //循环画出若干水平平行直线 for(int i=0;i<ROW_NUM;i++){ g2.drawLine(LEFT_BORDER,UP_BORDER+ROW_GAP*i, (COL_NUM-1)*COL_GAP+LEFT_BORDER,UP_BORDER+ROW_GAP*i); } //循环画出若干垂直平行直线 for(int i=0;i<COL_NUM;i++){ g2.drawLine(LEFT_BORDER+COL_GAP*i,UP_BORDER, LEFT_BORDER+COL_GAP*i,(ROW_NUM-1)*ROW_GAP+UP_BORDER); } //循环读取allChess数组,根据数组的内容画出每一个棋子。 for(int i=0;i<allChess.length;i++){ for(int j=0;j<allChess[i].length;j++){ if(allChess[i][j]=='*'){ continue; } Shape s=new Ellipse2D.Double(j*COL_GAP+LEFT_BORDER-ChessRadio, i*ROW_GAP+UP_BORDER-ChessRadio,ChessRadio*2,ChessRadio*2); g2.setColor(Color.BLACK); g2.draw(s); if(allChess[i][j]=='@'){ g2.setColor(Color.BLACK); }else{ g2.setColor(Color.WHITE); } g2.fill(s); } } if(boardX!=-1){//在最后一次有效落点位置画一个红‘X’,用以标识。 g2.setColor(Color.RED); g2.drawLine(boardX*ROW_GAP+LEFT_BORDER-5,boardY*COL_GAP+UP_BORDER-5,boardX*ROW_GAP+LEFT_BORDER+5,boardY*COL_GAP+UP_BORDER+5); g2.drawLine(boardX*ROW_GAP+LEFT_BORDER+5,boardY*COL_GAP+UP_BORDER-5,boardX*ROW_GAP+LEFT_BORDER-5,boardY*COL_GAP+UP_BORDER+5); } } }
最近下载更多
xsl250 LV1
6月20日
ewan007 LV30
3月3日
huangzy LV12
2023年4月6日
总有人间一两风 LV8
2022年12月12日
2483935277 LV3
2022年9月3日
Qzi qzi LV1
2022年6月24日
yebaobo LV4
2022年2月13日
zzy1170707748 LV1
2021年12月20日
models10086 LV1
2021年12月16日
chen_jw LV10
2021年12月14日
最近浏览更多
yansunling LV1
11月6日
wangming32 LV1
7月15日
xsl250 LV1
6月20日
sunxiaoyan LV1
6月19日
Dongshuo Han
6月16日
暂无贡献等级
啊撒旦撒
6月4日
暂无贡献等级
dexd1111 LV1
5月28日
860421 LV3
4月18日
ewan007 LV30
3月3日
luyouqi LV1
2月29日