麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

Java源代碼案例--騎士巡游問題

2019-11-18 14:30:32
字體:
來源:轉載
供稿:網友

  本文展示了一個KT(Knight’s Tour)小程序, 用來演示一個限制版的騎士巡游問題。 騎士并不是從任何一個方格開始, 而是從角落上的四個方格之一開始。這個applet的界面如圖1所示:

Java源代碼案例--騎士巡游問題(圖一)



  圖1: KT的界面由一個棋盤, 一個選擇開始方格的組合框和一個開始游歷的按鈕組成

  在啟動巡游之前, 先從組合框中選擇騎士開始的角落。 程序響應會讓騎士顯示在正確的角落上(默認情況下騎士在最左上角)。 然后單擊"Take the Tour"(開始巡游)按鈕來開始整個巡游過程。 按鈕和組合框在巡游過程中都將被禁止。巡游過程是怎么樣的呢? 圖2展現了一系列的線段(軌跡), 每一個線段都是隨著騎士在棋盤的行動從上一個方格的中心到當前方格的中心。
                


Java源代碼案例--騎士巡游問題(圖二)



  圖2: 巡游從左上角開始

  現在你已經看到了這個小程序的界面和巡游過程, 讓我們開始學習它的源代碼吧。

  清單1.  KT.java


// KT.java

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.util.ArrayList;

public class KT extends Applet
{
   // 線程延遲以毫秒為單位

   public final static int DELAY = 500;

   // 開始騎士巡游線程

   PRivate Thread thd;

   // 初始化小程序

   public void init ()
   {
      // 創建一個標簽對象來標明小程序的標題

      Label lblTitle = new Label ("Knight's Tour", Label.CENTER);
      lblTitle.setFont (new Font ("Arial", Font.BOLD, 18));

      // 把標簽對象加到小程序的面板容器

      add (lblTitle);

      // 創建一個ChessBoard對象,它具有顯示一個棋盤、移動騎士到
// 任何方格并留下騎士巡游軌跡的能力.

      final ChessBoard cb = new ChessBoard (this);

      //把ChessBoard對象加入到小程序的面板容器

      add (cb);

      // 創建一個Panel對象來保存Label,Choice和按鈕對象.

      Panel pnl = new Panel ();

      //創建一個標簽來標明Choice對象并把它添加到Panel中

      pnl.add (new Label ("Choose starting position:"));

      //創建一個Choice對象,用來選擇騎士的開始位置(棋盤的四個角落)
//并把它添加到Panel中.

      final Choice c = new Choice ();
      c.add ("Upperleft corner");
      c.add ("Upperright corner");

      //創建Choice的item listener,這個監聽器按選擇結果來重設騎士的開始位置.

      c.addItemListener (new ItemListener ()
                         {
                             public void itemStateChanged (ItemEvent e)
                             {
                                Choice c = (Choice) e.getSource ();

                                if (c.getSelectedIndex () == 0)
                                    cb.moveKnight (1);
                                else
                                    cb.moveKnight (8);

                                cb.reset ();
                             }
                         });
      pnl.add (c);

      //把Panel加入到小程序的面板容器

      add (pnl);

      //創建一個按鈕對象用來開始騎士巡游.

      final Button BTn = new Button ("Take the Tour");

      //創建按鈕的Action listener(動作監聽器),用來確定騎士巡游的位置.
//按照規則將騎士從一個位置移動到另一個位置.

      ActionListener al;

      al = new ActionListener ()
           {
               public void actionPerformed (ActionEvent e)
               {
                  Runnable r;
                  r = new Runnable ()
                      {
                          int [] boardPositions1 =
                          {
                              1, 18, 33, 50, 60, 54, 64, 47,
                             32, 15,  5, 11, 17, 34, 49, 59,
                             53, 63, 48, 31, 16,  6, 12,  2,
                             19, 25, 42, 57, 51, 61, 55, 40,
                             23,  8, 14,  4, 10, 27, 44, 38,
                             21, 36, 46, 29, 35, 41, 58, 52,
                             62, 56, 39, 24,  7, 13,  3,  9,
                             26, 43, 37, 22, 28, 45, 30, 20
                          };

                          int [] boardPositions2 =
                          {
                              8, 23, 40, 55, 61, 51, 57, 42,
                             25, 10,  4, 14, 24, 39, 56, 62,
                             52, 58, 41, 26,  9,  3, 13,  7,
                             22, 32, 47, 64, 54, 60, 50, 33,
                             18,  1, 11,  5, 15, 30, 45, 35,
                             20, 37, 43, 28, 38, 48, 63, 53,
                             59, 49, 34, 17,  2, 12,  6, 16,
                             31, 46, 36, 19, 29, 44, 27, 21
                          };

                          public void run ()
                          {
                             cb.reset ();

                             // thd用來檢查用戶離開小程序網頁
                 // 以便停止小程序的運行.

                             for (int i = 0; i < boardPositions1.length &&
                                  thd != null; i++)
                             {
                                  if (c.getSelectedIndex () == 0)
                                      cb.moveKnight (boardPositions1 [i]);
                                  else
                                      cb.moveKnight (boardPositions2 [i]);

                                  try
                                  {
                                      Thread.sleep (DELAY);
                                  }
                                  catch (InterruptedException e2)
                                  {
                                  }
                             }

                             c.setEnabled (true);
                             btn.setEnabled (true);
                          }
                      };

                  c.setEnabled (false);
                  btn.setEnabled (false);

                  thd = new Thread (r);
                  thd.start ();
               }
           };
      btn.addActionListener (al);

      //添加按鈕到小程序面板容器

      add (btn);
   }

   //停止小程序

   public void stop ()
   {
      //用戶離開網頁時必須停止”騎士巡游”線程

      thd = null;
   }
}

final class ChessBoard extends Canvas
{
   //非白色方格的顏色

   private final static Color SQUARECOLOR = new Color (195, 214, 242);

   //棋盤方格的尺寸

   private final static int SQUAREDIM = 40;

   //棋盤方格的尺寸(包括黑邊框)

   private final static int BOARDDIM = 8 * SQUAREDIM + 2;

   //棋盤左上角的左坐標(X坐標)

   private int boardx;

   //棋盤左上角的頂坐標(Y坐標)

   private int boardy;

   //棋盤長度

   private int width;

   // 棋盤寬度

   private int height;

   // 圖像緩沖

   private Image imBuffer;

   // Graphics context associated with image buffer.

   private Graphics imG;

   // 騎士圖像

   private Image imKnight;

   // 騎士圖像的長度

   private int knightWidth;

   // 騎士圖像的寬度

   private int knightHeight;

   //騎士軌跡的坐標

   private ArrayList trail;

   // Left coordinate of knight rectangle origin (upper-left corner).

   private int ox;

   // Top coordinate of knight rectangle origin (upper-left corner).

   private int oy;

   // 創建ChessBoard的Applet--調用它的getImage()和getDocumentBase()方法,
// 并且我們將使用它作為drawImage()方法的image observer

   Applet a;

   // 構造棋盤

   ChessBoard (Applet a)
   {
      // 確定部件的大小

      width = BOARDDIM+1;
      height = BOARDDIM+1;

      // 初始化棋盤, 使它處于中心

      boardx = (width - BOARDDIM) / 2 + 1;
      boardy = (height - BOARDDIM) / 2 + 1;

      //使用MediaTracker來確保騎士圖像在我們獲取它的長和寬之前被完全導入

      MediaTracker mt = new MediaTracker (this);

      // 導入騎士圖像

      imKnight = a.getImage (a.getDocumentBase (), "knight.gif");
      mt.addImage (imKnight, 0);

      try
      {
         mt.waitForID (0);
      }
      catch (InterruptedException e) {}

      //獲得騎士的長度和寬度, 幫助騎士定位于方格中心

      knightWidth = imKnight.getWidth (a);
      knightHeight = imKnight.getHeight (a);

      //初始化騎士圖像, 使騎士定位于左上角方格的中心

      ox = boardx + (SQUAREDIM - knightWidth) / 2 + 1;
      oy = boardy + (SQUAREDIM - knightHeight) / 2 + 1;

      //創建一個數據結構, 用來保存騎士巡游時的軌跡

      trail = new ArrayList ();

      //保存applet引用以便后面調用drawImage()時使用.

      this.a = a;
   }

   // This method is called when the ChessBoard component's peer is created.
   // The code in this method cannot be called in the ChessBoard constrUCtor
   // because the createImage() method returns null at that point. It doesn't
   // return a meaningful value until the ChessBoard component has been added
   // to its container. The addNotify() method is not called until the first
   // time ChessBoard is added to a container.

   public void addNotify ()
   {
      // Given this object's Canvas "layer" a chance to create a Canvas peer.

      super.addNotify ();

      //創建圖像緩沖

      imBuffer = createImage (width, height);

      //得到圖像緩沖的內容。

      imG = imBuffer.getGraphics ();
   }

   //當小程序的布局治理器布置它的組件時,會調用這個方法。
//假如可能,組件會顯示為首選大小。

   public Dimension getPreferredSize ()
   {
      return new Dimension (width, height);
   }

   //移動騎士到指定的棋盤位置。假如位置小于1或大于64則拋出一個異常

   public void moveKnight (int boardPosition)
   {
      if (boardPosition < 1 boardPosition > 64)
          throw new IllegalArgumentException ("invalid board position: " +
                                              boardPosition);

      int rebasedBoardPosition = boardPosition-1;

      int col = rebasedBoardPosition % 8;
      int row = rebasedBoardPosition / 8;

      ox = boardx + col * SQUAREDIM + (SQUAREDIM - knightWidth) / 2 + 1;
      oy = boardy + row * SQUAREDIM + (SQUAREDIM - knightHeight) / 2 + 1;

      trail.add (new Point (ox + knightWidth / 2, oy + knightHeight / 2));

      repaint ();
   }

   //畫出所有部件――先棋盤然后是騎士

   public void paint (Graphics g)
   {
      //畫出棋盤

      paintChessBoard (imG, boardx, boardy);

      //畫出騎士

      paintKnight (imG, ox, oy);

      //畫出騎士的軌跡

      paintTrail (imG);

      //畫出圖像緩沖的內容

      g.drawImage (imBuffer, 0, 0, this);
   }

   //畫出棋盤――(x, y)是左上角坐標

   void paintChessBoard (Graphics g, int x, int y)
   {
      // 畫出棋盤的邊框

      g.setColor (Color.black);
      g.drawRect (x, y, 8 * SQUAREDIM + 1, 8 * SQUAREDIM + 1);

      //畫出棋盤

      for (int row = 0; row < 8; row++)
      {
           g.setColor (((row & 1) != 0) ? SQUARECOLOR : Color.white);

           for (int col = 0; col < 8; col++)
           {
                g.fillRect (x + 1 + col * SQUAREDIM, y + 1 + row * SQUAREDIM,
                            SQUAREDIM, SQUAREDIM);

                g.setColor ((g.getColor () == SQUARECOLOR) ? Color.white :
                            SQUARECOLOR);
           }
      }
   }

   //畫出騎士――(x, y)是圖片左上角坐標

   void paintKnight (Graphics g, int x, int y)
   {
      g.drawImage (imKnight, x, y, a);
   }

   //畫出騎士的軌跡

   void paintTrail (Graphics g)
   {
      g.setColor (Color.black);

      int len = trail.size ();

      if (len == 0)
          return;

      Point pt = (Point) trail.get (0);
      int ox = pt.x;
      int oy = pt.y;

      for (int i = 1; i < len; i++)
      {
           pt = (Point) trail.get (i);
           g.drawLine (ox, oy, pt.x, pt.y);
           ox = pt.x;
           oy = pt.y;
      }
   }

   //清空ArrayList來重設棋盤

   public void reset ()
   {
      trail.clear ();
   }

   // The AWT invokes the update() method in response to the repaint() method
   // call that is made as a knight is moved. The default implementation of
   // this method, which is inherited from the Container class, clears the
   // applet's drawing area to the background color prior to calling paint().
   // This clearing followed by drawing causes flicker. KT overrides
   // update() to prevent the background from being cleared, which eliminates
   // the flicker.

   public void update (Graphics g)
   {
      paint (g);
   }
}


  清單1展示了基于抽象窗口工具集(AWT)的KT小程序。當然我并沒有半點反對Swing的意思――我只是希望讓KT集中于AWT。小程序的public void init()方法負責創建程序界面,包含一個ChessBoard類的實例用來描述一個棋盤。

  ChessBoard繼續自java.awt.Canvas,從定制的AWT組件中實例化ChessBoard。構造器負責決定各個部件的大小,導入騎士圖片,安置左上角為騎士的初始位置和創建一個數據結構來保存騎士巡游的軌跡。程序覆蓋了public Dimension getPreferredSize()方法,用來返回組件的大小,通知布局治理器ChessBoard希望在布局操作時維持這些尺寸為首選的大小。

  我同樣也覆蓋了public void addNotify()方法,以便createImage()方法被調用時不返回null值。當Canvas(或許我應該說ChessBoard)創建完成時這個方法才返回null。在addNotify() 中調用super.addNotify()后,null不會被返回。

  public void moveKnight(int boardPosition)方法移動騎士到boardPosition指定的位置上。這個參數必須在1-64的范圍內,否則將拋出異常。除了將騎士的圖像畫在指定位置的中心外,這個方法還將圖像的位置保存在前面創建的數據結構中(參看構造器)。public void reset()方法清除數據結構中的內容。假如沒有這個方法,連續的巡游將會同時顯示以前和新的巡游軌跡。此外,數據結構應該控制大小的增長,避免浪費內存和最終導致內存不足的錯誤。剩下的方法負責畫出棋盤,畫出騎士的圖像和軌跡。同樣,update()方法被覆蓋來防止閃爍。

  編譯清單1以后,你應該想運行這個小程序。但是,在你能運行它之前,你必須通過Html來向小程序查看器(appletviewer)描述我們編寫的小程序。清單2提供了所需的HTML

  清單2. KT.html
 



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美一级做一级爱a做片性 久久久资源网 | 国产人成免费爽爽爽视频 | 久久久久久久久淑女av国产精品 | 中文字幕综合在线观看 | 中文字幕一区在线观看视频 | 永久av在线免费观看 | 视频一区二区国产 | javhdfreejaⅴhd| 国产精品久久久免费 | 成人不卡免费视频 | 欧美一级毛片大片免费播放 | 日韩精品中文字幕一区二区三区 | 精品一区二区电影 | 久久久久免费电影 | 青青国产在线视频 | 国产日韩三区 | 欧美一级片免费在线观看 | 国产一级在线免费观看 | 视频h在线| 亚洲一区成人在线 | 欧美日韩国产中文字幕 | 婷婷久久青草热一区二区 | 久久99国产视频 | 国产精品爱久久久久久久 | 亚洲成人久久精品 | 毛片免费看电影 | 粉嫩av一区二区三区四区在线观看 | 国产午夜免费不卡精品理论片 | 深夜福利视频绿巨人视频在线观看 | 午夜生活理论片 | 97色在线观看免费视频 | 国产成人免费高清激情视频 | 黄色网址在线免费播放 | 日韩精品中文字幕在线播放 | 神马久久精品综合 | 成人毛片免费播放 | 日日噜噜夜夜爽 | 久久黄色影院 | 久久精品一二三区 | 久久精品网址 | 韩国十九禁高潮床戏在线观看 |