實驗三結對專案

LINKVK發表於2015-05-17
一、題目簡介
1、計算機能對棋局進行分析、判斷。根據棋局狀態來確定機器方的下棋行為。
2、計算機能根據棋局狀態實時的判斷對弈雙方的勝負。
3、控制雙方交替下棋。
4、友好的介面呈現。 
 
二、結對分工及過程
 結對 劉永政(學號後四位:1139) 張斌(學號後四位:1136)

 組員各自的優缺點:

      1.劉永政: 程式碼的編寫和程式碼規範。

     2.張斌:程式的分析和程式的測試及測試程式碼的編寫

三、結對程式設計優缺點:

    優點:

    1.結對程式設計時間緊密,在一定程度上可以督促雙方學習,提高效率

   2.Coder在coding過程中會遇到一些細小的問題,而reviewer可以及時指出錯誤,並給予解決方案進行討論。

   3.遇到問題時,兩個人一起討論,並補充對方沒有想到的地方,是完善程式最好的方式。

   缺點:

   在程式設計過程中,很長時間是coder在coding的過程中想思路,大概這也是每個程式設計師的特點,而這個時候reviewer就會長時間遇到空檔期。

四、程式碼地址

https://github.com/LINKVK/test/tree/master

原始碼:

import javax.swing.*;
   
  import java.awt.*;
  import java.awt.event.*;
  import java.net.URL;
  @SuppressWarnings("serial")
  public class ChessMap extends JFrame {
  private ImageIcon map; //棋盤背景點陣圖
  private ImageIcon blackchess; //黑子點陣圖
  private ImageIcon whitechess; //白子點陣圖
  private ChessPanel cp; //棋盤
  private JPanel east;
  private JPanel west;
  private static final int FINAL_WIDTH = 450;
  private static final int FINAL_HEIGHT = 500;
  //以下為下拉選單
  private JMenuBar menubar;
  private JMenu[] menu={new JMenu("開始"),new JMenu("設定"),new JMenu("幫助")};
  private JMenuItem[] menuitem1={new JMenuItem("重新開始"),new JMenuItem("悔棋"),new JMenuItem("退出")};
  private JMenuItem[] menuitem2={new JMenuItem("禁手選擇"),new JMenuItem("人機對戰"),new JMenuItem("雙人對戰")};
  private JMenuItem[] menuitem3={new JMenuItem("規則"),new JMenuItem("關於")};
  private boolean haveai=true; //人與人下還是人與電腦下,true與電腦下
  Mouseclicked mouseclicked=new Mouseclicked();
  MouseMoved mousemoved=new MouseMoved();
  Menuitemclicked menuclicked=new Menuitemclicked();
   
  //建構函式
  public ChessMap(){
  //改變系統預設字型
  Font font = new Font("Dialog", Font.PLAIN, 12);
  java.util.Enumeration keys = UIManager.getDefaults().keys();
  while (keys.hasMoreElements()) {
  Object key = keys.nextElement();
  Object value = UIManager.get(key);
  if (value instanceof javax.swing.plaf.FontUIResource) {
  UIManager.put(key, font);
  }
  }
  setTitle("五子棋 ");
  setSize(FINAL_WIDTH,FINAL_HEIGHT);
  setResizable(false);
  init();
  setLocation(Toolkit.getDefaultToolkit().getScreenSize().width / 2
  - FINAL_WIDTH / 2, Toolkit.getDefaultToolkit()
  .getScreenSize().height
  / 2 - FINAL_HEIGHT / 2);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  cp.reset();
  setVisible(true);
  }
   
  //初始化與預設值
  public void init()
  {
   
  map=new ImageIcon(getClass().getResource("bg.jpg"));
  blackchess=new ImageIcon(getClass().getResource("blackchess.gif"));
  whitechess=new ImageIcon(getClass().getResource("whitechess.gif"));
  cp=new ChessPanel(map,blackchess,whitechess);
  menubar=new JMenuBar();
  menuitem1[0].setActionCommand("Restart");
  menuitem1[1].setActionCommand("Rollback");
  menuitem1[2].setActionCommand("Exit");
  menuitem2[0].setActionCommand("Forbid");
  menuitem2[1].setActionCommand("Robot");
  menuitem2[2].setActionCommand("Human");
  menuitem3[0].setActionCommand("Rule");
  menuitem3[1].setActionCommand("About");
  for(int i=0;i<3;i++)
  menu[0].add(menuitem1[i]);
  for(int i=0;i<3;i++)
  menu[1].add(menuitem2[i]);
  for(int i=0;i<2;i++)
  menu[2].add(menuitem3[i]);
  for(int i=0;i<3;i++)
  menubar.add(menu[i]);
  Container p = getContentPane();
  setJMenuBar(menubar);
  east = new JPanel();
  west = new JPanel();
  p.add(east, "East");
  p.add(west, "West");
  p.add(cp, "Center");
  cp.addMouseListener(mouseclicked);
  cp.addMouseMotionListener(mousemoved);
  menuitem1[0].addActionListener(menuclicked);
  menuitem1[1].addActionListener(menuclicked);
  menuitem1[2].addActionListener(menuclicked);
  menuitem2[0].addActionListener(menuclicked);
  menuitem2[1].addActionListener(menuclicked);
  menuitem2[2].addActionListener(menuclicked);
  menuitem3[0].addActionListener(menuclicked);
  menuitem3[1].addActionListener(menuclicked);
   
  }
  class Mouseclicked extends MouseAdapter //判斷滑鼠左擊並通知棋盤和電腦
  {
  public void mouseClicked(MouseEvent e)
  {
  if(cp.win==false){
  if(haveai){ //和電腦博弈
  Point p1=new Point();
  p1=cp.getPoint(e.getX(),e.getY());
  int x=p1.x;
  int y=p1.y;
  // 如果該位置已經放置棋子
  System.out.println("x="+x+",y="+y);
  if (cp.isChessOn[x][y] != 2)
  return;
  // 玩家為黑棋,考慮禁手
  if( cp.able_flag && cp.bw == 0) {
  int type = cp.getType(x,y,cp.bw);
  String str = null;
  switch(type){
  case 20:
  str = "黑長連禁手!請選擇其它位置下棋!";
  break;
  case 21:
  str = "黑四四禁手!請選擇其它位置下棋!";
  break;
  case 22:
  str = "黑三三禁手!請選擇其它位置下棋!";
  break;
  default : break;
  }
  if(str != null) {
  JOptionPane.showMessageDialog(null,str);
  return;
  }
  }
  boolean flag=cp.haveWin(x, y, cp.bw);
  cp.update( x, y );
  cp.putVoice(); //落子聲音
  // 第一步棋,需初始化設定邊界值
  if( cp.chess_num == 1){
  if(x-1>=0)
  cp.x_min = x-1;
  if(x-1<=15)
  cp.x_max = x+1;
  if(y-1>=0)
  cp.y_min = y-1;
  if(y-1<=15)
  cp.y_max = y+1;
  }
  else
  cp.resetMaxMin(x,y);
  if (flag) {
  cp.wined(1 - cp.bw);
  return;
  }
  cp.putOne(cp.bw);
  }else{ //和人博弈
  Point p1=new Point();
  p1=cp.getPoint(e.getX(),e.getY());
  int x=p1.x;
  int y=p1.y;
  // 如果該位置已經放置棋子
  System.out.println("x="+x+",y="+y);
  if (cp.isChessOn[x][y] != 2)
  return;
  // 玩家為黑棋,考慮禁手
  if( cp.able_flag && cp.bw == 0) {
  int type = cp.getType(x,y,cp.bw);
  String str = null;
  switch(type){
  case 20:
  str = "黑長連禁手!請選擇其它位置下棋!";
  break;
  case 21:
  str = "黑四四禁手!請選擇其它位置下棋!";
  break;
  case 22:
  str = "黑三三禁手!請選擇其它位置下棋!";
  break;
  default : break;
  }
  if(str != null) {
  JOptionPane.showMessageDialog(null,str);
  return;
  }
  }
  boolean flag=cp.haveWin(x, y, cp.bw);
  cp.update( x, y );
  cp.putVoice(); //落子聲音
  cp.repaint();
  // 第一步棋,需初始化設定邊界值
  if( cp.chess_num == 1){
  if(x-1>=0)
  cp.x_min = x-1;
  if(x-1<=15)
  cp.x_max = x+1;
  if(y-1>=0)
  cp.y_min = y-1;
  if(y-1<=15)
  cp.y_max = y+1;
  }
  else
  cp.resetMaxMin(x,y);
  if (flag) {
  cp.wined(1 - cp.bw);
  return;
  }
  }
  }
  }
  }
  class MouseMoved implements MouseMotionListener //除錯用,獲得滑鼠位置
  {
  public void mouseMoved(MouseEvent e)
  {
  cp.showMousePos(e.getPoint());
  }
  public void mouseDragged(MouseEvent e)
  {}
  }
  class Menuitemclicked implements ActionListener //選單訊息處理
  {
  public void actionPerformed(ActionEvent e)
  {
  JMenuItem target = (JMenuItem)e.getSource();
  String actionCommand = target.getActionCommand();
  if(actionCommand.equals("Restart")){ //重開一局
  cp.reset();
  if(cp.sbw==cp.WHITE_ONE)
  cp.update(7, 7);
  //player=cp.BLACK_ONE;
  }
  if(actionCommand.equals("Rollback")){ //悔棋
  if(cp.win) {
  JOptionPane.showMessageDialog(null,"棋局已經結束,不能悔棋!請重新開始新的棋局!");
  return;
  }
  // 當前輪到玩家下棋,取消兩步 否則,取消一步
  if(cp.chess_num >= 2 && cp.bw == cp.sbw){
  cp.isChessOn[cp.pre[cp.chess_num-1][0]][cp.pre[cp.chess_num-1][1]] = 2;
  cp.isChessOn[cp.pre[cp.chess_num-2][0]][cp.pre[cp.chess_num-2][1]] = 2;
  cp.chess_num -= 2;
  cp.repaint();
  }
  else if(cp.chess_num >= 1 && cp.bw == 1-cp.sbw){
  cp.isChessOn[cp.pre[cp.chess_num-1][0]][cp.pre[cp.chess_num-1][1]] = 2;
  cp.chess_num --;
  cp.repaint();
  }
  }
  else if(actionCommand.equals("Exit")){ //退出
  System.exit(1);
  }
  else if(actionCommand.equals("Forbid")){ //禁手選擇
  Object[] options = { "無禁手", "有禁手" };
  int sel = JOptionPane.showOptionDialog(
  null, "你的選擇:", "禁手選擇",
  JOptionPane.DEFAULT_OPTION,
  JOptionPane.QUESTION_MESSAGE, null,
  options, options[0]);
  if(sel==1){
  cp.able_flag=true;
  System.out.println("有禁手");
  }else{
  cp.able_flag=false;
  System.out.println("無禁手");
  }
  }
  else if(actionCommand.equals("Robot")){ //人機博弈
  haveai=true;
  Object[] options = { "人類先手", "機器先手" };
  int sel = JOptionPane.showOptionDialog(
  null, "你的選擇:", "先手選擇",
  JOptionPane.DEFAULT_OPTION,
  JOptionPane.QUESTION_MESSAGE, null,
  options, options[0]);
  if(sel==1){ //機器先手
  cp.sbw=cp.WHITE_ONE;
  cp.update(7, 7);
  System.out.println("機器先手");
   
  }else{ //人先手
  //player=cp.BLACK_ONE;
  cp.sbw=cp.BLACK_ONE;
  System.out.println("人先手");
  }
  }
  else if(actionCommand.equals("Human")){ //人人博弈
  haveai=false;
  cp.setHumanhuman(true);
  }else if(actionCommand.equals("Rule")){ //規則
  JOptionPane.showConfirmDialog(null,
  "1、無禁手:" +"\n"+
  " 黑白雙方依次落子,任一方先在棋盤上形成連續的五個(含五個以上)棋子的一方為勝。" +"\n"+
  "2、有禁手:(走禁手就輸,禁手不能落子)" +"\n"+
  " 鑑於無禁手規則黑棋必勝,人們不斷採用一些方法限制黑棋先行的優勢,以平衡黑白雙方的形式。" +"\n"+
  " 於是針對黑棋的各種禁手逐漸形成。" +"\n"+
  " 禁手主要分為以下幾類:" +"\n"+
  " (1)黑長連禁手:連成六個以上連續相同的棋子。" +"\n"+
  " (2)黑三三禁手:兩個以上的活三。" + "\n"+
  " (3)黑四四禁手:兩個以上的四。" + "\n"+
  " 禁手是針對黑棋而言的,白棋沒有任何禁手。" ,"規則",JOptionPane.CLOSED_OPTION,JOptionPane.INFORMATION_MESSAGE);
  }
  else if(actionCommand.equals("About")){ //版權與幫助
  JOptionPane.showConfirmDialog(null,"團隊成員:\n" +
  "張斌\n" +
  "劉永政","關於",JOptionPane.CLOSED_OPTION,JOptionPane.INFORMATION_MESSAGE);
  }
  }
   
  }
  public static void main(String[] args) {
  new ChessMap();
  }
  }

執行截圖

五、測試情況

六、心得

 這是我的第一次結對程式設計,總體感覺是很坑爹且痛苦。感覺上我還是不太適應結對程式設計這種模式,我們前期閱讀程式碼時是分開進行的,我總感覺我和一個人一起閱讀程式碼時會看不下去(然而儘管是一個人閱讀的,我的閱讀過程還是很痛苦)。而且兩個人進度難免不一樣,不過好在並不是太耽誤,而且結隊的優點也是不可忽視的,結對程式設計是提高程式碼走查效率和質量的非常有效的手段。

 

相關文章