實驗報告(結對專案)

琴韻畔晨曦發表於2015-05-16

•   題目簡介

1.棋盤是10乘以10的方框。

2.棋盤處於滑鼠監聽狀態,當滑鼠在棋盤上有點選操作的時候,程式會獲得滑鼠點選的座標然後換算成對應的棋盤的位置,在判斷此處是否有棋子,假如沒有,那麼在此處畫出對應顏色的實心棋子,假如已經有棋子了,則提示玩家此處已經有棋子請重新下棋。

3.無論黑白雙方哪一方有五個棋子沿著橫豎斜連在一起是,系統自動判斷輸贏,並顯示黑方或者白方勝利。

本程式共有3個類,下載後將三個類複製到三個記事本里然後重名記事本(為了閱讀方便分三個檔案,其中main()方法在StartChessJFrame類中。

 

•   程式碼地址

徐敏https://github.com/xumin1994/cooperation

韓爽https://github.com/hanshuangshuang/HEZUO

import java.awt.Color;

public class Point {

         private int x;

         //棋盤中X的索引

         private int y;

         //棋盤中Y的索引

         private Color color;//顏色

         public static final int DIAMETER = 30;

         //直徑

         public Point(int x,int y,Color color){

                   this.x=x;

                   this.y=y;

                   this.color =color;

         }

         //拿到棋盤中的Y索引

         public int getX(){

                    return x;

         }

        

         public int getY(){

                    return y;

         }

        

         //得到顏色

         public Color getColor(){

                   return color;

         }

}

 

 

import javax.swing.*;

import java.awt.*;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.awt.event.MouseEvent;

/*

 五子棋-棋盤類

 */

public class ChessBoard extends JPanel implements MouseListener {

         public static final int MARGIN = 30;

         //邊距

         protected static final int GRID_SPAN = 35;

         //網格間距

         public static final int ROWS = 10;

         //棋盤行數

         public static final int COLS = 10;

        

         //棋盤列數

         Point[] chessList = new Point[(ROWS+1)*(COLS+1)];

         //初始化每個陣列元素為null

         boolean isBlack = true;

         //預設開始是黑棋先下

         boolean gameOver = false;

         //遊戲是否結束

         int chessCount;

         //當前棋盤棋子的個數

         int xIndex,yIndex;

         //當前剛下的棋子的索引

         public ChessBoard(){

                   super.setBackground(Color.ORANGE);

                   //setBackground(Color.ORANGE);//設定背景顏色為橘黃色

                   addMouseListener(this);//新增監聽器

                   addMouseMotionListener(new MouseMotionListener(){//匿名內部類

                            public void mouseDragged(MouseEvent e){  

                            }

                            public void mouseMoved(MouseEvent e){

                                     int x1 = (e.getX()- MARGIN +GRID_SPAN/2)/GRID_SPAN;

                                     //將滑鼠單擊的座標位置轉換成網格索引

                                     int y1 = (e.getY()- MARGIN +GRID_SPAN/2)/GRID_SPAN;

                                     //遊戲已經結束,落在棋盤外,x、y位置已經有棋子存在,不能下

                                     if(x1<0||x1>ROWS||y1<0||y1>COLS||gameOver||findChess(x1,y1))

                                               setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

                                               //設定成預設形狀

                                     else

                                               setCursor(new Cursor(Cursor.HAND_CURSOR));

                                     //設定成手型

                            }

                   });

         }

        

 

 

         //繪製

         public void paintComponent(Graphics g){

                   super.paintComponent(g);

                   //畫棋類

                   for(int i=0;i<=ROWS;i++){//畫橫線

                            g.drawLine(MARGIN,MARGIN+i*GRID_SPAN,MARGIN+COLS*GRID_SPAN,MARGIN+i*GRID_SPAN);        

                   }

                   for(int i=0;i<=COLS;i++){//畫直線

                            g.drawLine(MARGIN+i*GRID_SPAN,MARGIN,MARGIN+i*GRID_SPAN,MARGIN+ROWS*GRID_SPAN);

                   }

                   //畫棋子

                   for(int i=0;i<chessCount;i++) {

                            int xPos = chessList[i].getX()*GRID_SPAN+MARGIN;

                            //網路交叉點的x座標

                            int yPos = chessList[i].getY()*GRID_SPAN+MARGIN;

                            //網路交叉點的y座標

                            g.setColor(chessList[i].getColor());//設定顏色

                            g.fillOval(xPos-Point.DIAMETER/2, yPos-Point.DIAMETER/2, Point.DIAMETER, Point.DIAMETER);

                            //標記最後一個棋子的紅矩形框

                            if(i == chessCount -1){

                                     //最後一個棋子

                                     g.setColor(Color.red);

                                     g.drawRect(xPos - Point.DIAMETER/2,yPos-Point.DIAMETER/2,Point.DIAMETER,Point.DIAMETER);

                            }

                   }

                  

                  

                   }

        

         //滑鼠按鍵在組建上按下時呼叫

         public void mousePressed(MouseEvent e){

                   //遊戲已經結束,不能下

                   if(gameOver)

                            return;

         String colorName = isBlack ?"黑棋":"白棋";

         xIndex = (e.getX() - MARGIN + GRID_SPAN/2)/GRID_SPAN;

         //將滑鼠單擊的座標位置轉換成網格索引

         yIndex = (e.getY() - MARGIN + GRID_SPAN/2)/GRID_SPAN;

         //落在棋盤外,不能下

         if(xIndex <0 || xIndex > ROWS || yIndex < 0 || yIndex > COLS)

                   return;

         //x、y位置都已經有棋子存在,不能下

         if(findChess(xIndex , yIndex))

                   return;

        

         Point ch = new Point(xIndex,yIndex,isBlack ? Color.black:Color.white);

         chessList[chessCount++] = ch;

         repaint();//通知系統重新繪製

         if(isWin()){

                   //給出勝利資訊,不能再繼續下棋

                   String msg = String.format("恭喜,%s贏了!", colorName);

                   JOptionPane.showMessageDialog(this, msg);

                   gameOver = true;

         }

                   isBlack = !isBlack;   

         }

         //覆蓋MouseListener的方法

         public void mouseClicked(MouseEvent e){

         }//滑鼠按鍵在元件上單擊(按下並釋放)時呼叫

         public void mouseEntered(MouseEvent e){

         }//滑鼠進入到元件上時呼叫

         public void mouseExited(MouseEvent e){

         }//滑鼠離開元件時呼叫

         public void mouseReleased(MouseEvent e){

         }//滑鼠離開元件時呼叫

         //在棋子陣列中查詢是否有索引為x、y的棋子存在

         private boolean findChess(int x, int y){

                   for(Point c : chessList){

                            if(c !=null && c.getX() == x && c.getY() == y)

                                     return true;     

                   }

                                     return false;

         }

        

                   //判定哪方贏

         private boolean isWin(){

                   int continueCount =1;

                   //連續棋子的個數

                   //橫向向西尋找

                   for(int x = xIndex-1; x>=0;x--){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,yIndex,c) !=null){

                                     continueCount++;   

                            }else

                                     break;

                   }

                   //橫向向東尋找

                   for(int x  =xIndex+1;x<=ROWS;x++){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,yIndex,c) !=null){

                                      continueCount++;

                            }else

                                     break;

                   }

                   //判定記錄數大於等於五,即表示此方取勝

                   if(continueCount>=5){

                            return true;

                   }else

                            continueCount =1;

                   //繼續另一種情況的搜尋:縱向

                   //縱向向上尋找

                            for(int y = yIndex - 1; y >= 0; y--){

                                     Color c =isBlack ? Color.black : Color.white;

                                     if(getChess(xIndex,y,c) !=null){

                                               continueCount++;

                                     }else

                                               break;

                            }

                   //縱向向下尋找

                   for(int y = yIndex + 1; y<=ROWS; y++){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(xIndex,y,c)!=null){

                                     continueCount++;

                            }else

                                     break;

                   }

        

                   if(continueCount>=5){

                            return true;

                   }else

                            continueCount =1;

                  

                   //繼續另一種情況的搜尋:斜向

                   //東北尋找

                   for(int x = xIndex + 1,y=yIndex-1; y>=0 && x<=COLS; x++,y--){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,y,c)!=null){

                                     continueCount++;

                            }else

                                     break;

                            }

                  

                   //西南尋找

                   for(int x = xIndex - 1,y=yIndex+1; y<=ROWS && x>=0; x--,y++){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,y,c)!=null){

                                     continueCount++;

                            }else

                                     break;

                   }

                   if(continueCount >=5){

                            return true;

                   }else

                            continueCount = 1;

                   //繼續另一種情況的搜尋:斜向

                   //西北尋找

                   for(int x = xIndex - 1,y = yIndex-1; y>=0 && x>=0; x--,y--){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,y,c)!=null){

                                     continueCount++;

                            }else

                                     break;

                  

         }

         //西南尋找

                   for(int x = xIndex + 1,y=yIndex+1; y<=ROWS && x<=COLS; x++,y++){

                            Color c = isBlack ? Color.black : Color.white;

                            if(getChess(x,y,c)!=null){

                                     continueCount++;

                            }else

                                     break;

                   }

                   if(continueCount >=5){

                            return true;

                   }else

                            continueCount = 1;

                   return false;

         }

         private Point getChess(int xIndex, int yIndex, Color color){

                   for(Point c: chessList){

                            if(c !=null && c.getX() == xIndex && c.getY() == yIndex && c.getColor() == color)

                                     return c;

                   }

                   return null;

         }

         public void restartGame(){

                   //清除棋子

                   for(int i=0; i< chessList.length; i++)

                            chessList[i]=null;

                   //恢復遊戲相關的變數值

                   isBlack = true;

                   gameOver = false;//遊戲是否結束

                   chessCount = 0;//當前棋盤的棋子個數

                   //System.out.println(this.toString());

                   //repaint();

                           

         }

         //悔棋

         public void goback(){

                   if (chessCount == 0)

                            return;

                  

                   chessList[chessCount-1]=null;

                   chessCount--;

                   if(chessCount >0){

                            xIndex = chessList[chessCount -1].getX();

                            yIndex = chessList[chessCount -1].getY();

                   }

                   isBlack = !isBlack;

                   //repaint();

         }

         //Dimension:矩形

         public Dimension getPreferredSize(){

                   return new Dimension (MARGIN*2 + GRID_SPAN*COLS,MARGIN*2 + GRID_SPAN*ROWS);

        

 

         }

}       

        

        

 

 

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JMenu;

import javax.swing.JMenuBar;

import javax.swing.JMenuItem;

import javax.swing.JPanel;

public class StartChessJFrame  extends JFrame {

         private ChessBoard chessBoard;

         //對戰皮膚

         private JPanel toolbar;

         //工具條皮膚

         private JButton startButton;

         private JButton backButton;

         private JButton exitButton;

         //“重新開始”按鈕,“悔棋”按鈕,“退出”按鈕

         private JMenuBar menuBar;

         //選單欄

         private JMenu sysMenu;

         //系統選單

         private JMenuItem startMenuItem;

         private JMenuItem exitMenuIatem;

         private JMenuItem backMenuItem;

         //“重新開始”,“退出”和“悔棋”選單項

         public StartChessJFrame(){

                   setTitle("單機版五子棋");

                   //設定標題

                   chessBoard =new ChessBoard();

                   //初始化皮膚物件

                   //建立和新增選單

                   menuBar = new JMenuBar();

                   //初始化選單欄

                   sysMenu = new JMenu("系統");

                   //初始化選單

                   startMenuItem = new JMenuItem("重新開始");

                   exitMenuIatem = new JMenuItem("退出");

                   backMenuItem = new JMenuItem("悔棋");

                   //初始化選單項

                   sysMenu.add(startMenuItem);

                   //將三個選單項新增到選單上

                   sysMenu.add(backMenuItem);

                   sysMenu.add(exitMenuIatem);

                   MyItemListener lis = new MyItemListener();

                   //初始化按鈕事件監聽器內部類

                   this.startMenuItem.addActionListener(lis);

                   //將三個選單項註冊到事件監聽器上

                   backMenuItem.addActionListener(lis);

                   exitMenuIatem.addActionListener(lis);

                   menuBar.add(sysMenu);

                   //將“系統”選單新增到選單欄上

                   setJMenuBar(menuBar);

                   //將menuBar設定為選單欄

                   toolbar =new JPanel();

                   //工具皮膚例項化

                   startButton = new JButton("重新開始");

                   //三個按鈕初始化

                   backButton = new JButton("悔棋");

                   exitButton = new JButton("退出");

                   toolbar.setLayout(new FlowLayout(FlowLayout.LEFT));

                   //將工具皮膚按鈕用FlowLayout佈局

                   toolbar.add(startButton);

                   //將三個按鈕新增到工具皮膚上

                   toolbar.add(backButton);

                   toolbar.add(exitButton);

                   startButton.addActionListener(lis);

                   //將三個按鈕註冊監聽事件

                  backButton.addActionListener(lis);

                   exitButton.addActionListener(lis);

                   add(toolbar,BorderLayout.SOUTH);

                   //將工具皮膚佈局到介面“南”方也就是下面

                   add(chessBoard);//將皮膚物件新增到窗體上

                   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                   //設定介面關閉事件

                   //setSize(600,650);

                   pack();

                   //自適應大小

 

         }

 

         //事件監聽器內部類

         private class MyItemListener implements ActionListener{

                   public void actionPerformed(ActionEvent e){

                            Object obj = e.getSource();

                            //取得事件源

                            if(obj == StartChessJFrame.this.startMenuItem || obj ==startButton){

                                     //重新開始

                                     //JFiveFrame.this //內部類引用外部類

                                     System.out.println("重新開始...");

                                     chessBoard.restartGame();

                                     repaint();

                            }else if (obj == exitMenuIatem || obj == exitButton){

                                     System.exit(0);

                                     //結束應用程式

                            }else if (obj == backMenuItem || obj == backButton){

                                     //悔棋

                                     System.out.println("悔棋...");

                                chessBoard.goback();

                                repaint();

                            }

                   }

         }

          public static void main(String[] args){

                    StartChessJFrame f = new StartChessJFrame();

                    //建立主框架

                    f.setVisible(true);

                    //顯示主框架

          }

 

   

         }

 

 

•    結對分工情況

韓爽負責JUnit4的測試部分,徐敏負責程式碼編寫。

•    結對實踐過程

(1)對局雙方各執一色棋子。

(2)空棋盤開局。

(3)黑先、白後,交替下子,每次只能下一子。

(4)棋子下在棋盤的空白點上,棋子下定後,不得向其它點移動,不得從棋盤上拿掉或拿起另落別處。

(5)黑方的第一枚棋子可下在棋盤任意交叉點上。

(6)輪流下子是雙方的權利,但允許任何一方放棄下子權(即:PASS權)。

 

•   測試情況

 

•   問題及心得

通過這次綜合實驗,我們將Java程式設計語言所要掌握的基本知識加以貫穿,把分散的知識點提高到對java程式設計的整體認識,全面體驗java物件導向程式設計的特點,提高綜合應用能力。由對語言的基本理解向程式設計層面上轉變。

 

相關文章