亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

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
 



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧亚精品中文字幕| 久久久久女教师免费一区| 久久久精品免费| 国产精品国语对白| 欧美高清videos高潮hd| 国模精品视频一区二区三区| 亚洲国产精品久久久久秋霞不卡| 欧美综合第一页| 日本精品视频在线观看| 中文字幕国产精品| 国产成人精品在线视频| 久操成人在线视频| 91国内精品久久| 久久午夜a级毛片| 超在线视频97| 5566日本婷婷色中文字幕97| 国产丝袜视频一区| 久久成人av网站| 欧美体内谢she精2性欧美| 日韩欧美在线观看视频| 色噜噜久久综合伊人一本| 懂色av中文一区二区三区天美| 91在线视频免费| 狠狠色狠狠色综合日日小说| 欧美精品免费在线观看| 91av视频在线免费观看| 美女久久久久久久| 日韩av大片免费看| 欧美中文在线视频| 欧美激情第一页xxx| 26uuu另类亚洲欧美日本老年| 欧美片一区二区三区| 久久久国产一区二区| 亚洲tv在线观看| 日韩欧美中文字幕在线播放| 亚洲精品视频在线观看视频| 国产色视频一区| 中文字幕免费精品一区| 欧美激情va永久在线播放| 欧美日韩国产一区中文午夜| 国产精品高精视频免费| 亚洲第一偷拍网| 2019国产精品自在线拍国产不卡| 久久精品人人做人人爽| xxav国产精品美女主播| 久久久久久久久久av| 亚洲一级免费视频| 日韩欧美国产黄色| 欧美激情视频播放| 欧美中文字幕第一页| 国产成人+综合亚洲+天堂| 欧美精品一区在线播放| 波霸ol色综合久久| 国产免费一区二区三区香蕉精| 久久777国产线看观看精品| 亚洲女人被黑人巨大进入al| 国产日韩欧美中文在线播放| 欧美大片免费看| 成人久久一区二区三区| 欧美激情视频一区二区| 亚洲视频欧美视频| 亚洲成人精品视频| 亚洲视频网站在线观看| 亚洲欧洲在线免费| 日韩美女激情视频| 色无极影院亚洲| 国产99久久久欧美黑人| 一本一本久久a久久精品综合小说| 日韩欧美极品在线观看| 日韩一区视频在线| 日韩久久免费电影| 国产精品久久久久久久久久久不卡| 日产精品久久久一区二区福利| 激情成人在线视频| 亚洲一区二区三区四区在线播放| 久久精品国产综合| 欧美激情一区二区三级高清视频| 欧美激情视频网址| 综合136福利视频在线| 欧美性在线视频| 亚洲视频精品在线| 亚洲综合一区二区不卡| 欧美日韩国产成人在线观看| 91精品久久久久久综合乱菊| 成人免费大片黄在线播放| 精品国产福利视频| 国产精品高潮呻吟久久av黑人| 北条麻妃一区二区三区中文字幕| 国内揄拍国内精品少妇国语| 久久91精品国产91久久跳| 91po在线观看91精品国产性色| 国产网站欧美日韩免费精品在线观看| 国产午夜精品美女视频明星a级| 成人福利视频在线观看| 97久久国产精品| 欧美老女人bb| 欧美成人精品在线播放| 国产精品国产亚洲伊人久久| 久久久久久久影院| 日韩国产高清污视频在线观看| 成人在线视频福利| 91视频免费网站| 色琪琪综合男人的天堂aⅴ视频| 国产成人一区二区| 国产精品久久久久福利| 久久免费精品日本久久中文字幕| 久久99久国产精品黄毛片入口| 亚洲欧洲国产一区| 国产日本欧美一区二区三区| 亚洲欧美另类人妖| 欧洲美女7788成人免费视频| 91精品国产综合久久久久久蜜臀| 久久全球大尺度高清视频| 国产美女久久精品| www.日韩视频| 久久电影一区二区| 欧美日韩国产精品一区二区三区四区| 日本精品中文字幕| 日本一区二区在线免费播放| 国产精品自在线| 国产精品自产拍在线观看中文| 欧美一级高清免费| 国产精品成av人在线视午夜片| 亚洲成人性视频| 亚洲成人在线网| 欧美风情在线观看| 日韩中文视频免费在线观看| 91精品国产高清| 日韩欧美在线视频免费观看| 中文字幕亚洲一区二区三区五十路| 久久综合免费视频| 亚洲人精品午夜在线观看| 亚洲美腿欧美激情另类| 91精品国产综合久久久久久蜜臀| www.日韩免费| 精品国产精品三级精品av网址| 精品女厕一区二区三区| 精品久久中文字幕久久av| 欧美激情视频在线观看| 国产精品入口免费视频一| 欧美在线视频在线播放完整版免费观看| 亚洲一区二区精品| 欧美日韩在线免费观看| 亚洲国产精品va在线看黑人动漫| 国产成人精品久久二区二区| 亚洲深夜福利视频| 色综合天天综合网国产成人网| 在线电影av不卡网址| 国产亚洲美女久久| 国产日韩视频在线观看| 在线视频欧美日韩| 成人av.网址在线网站| 亚洲r级在线观看| 欧美日韩亚洲一区二区三区| 在线日韩日本国产亚洲| 国产精品福利网| 91a在线视频| 亚洲国产女人aaa毛片在线| 茄子视频成人在线| 亚洲国产高清高潮精品美女| 欧美老女人xx| 久久久久久国产精品久久| 日本成熟性欧美| 欧美日产国产成人免费图片|