• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Merlin

            Life was like a box of chocolates. You never know what you're gonna get.

               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              34 隨筆 :: 0 文章 :: 40 評論 :: 0 Trackbacks
            有可能在閃躲炮彈和執行精確攻擊的演練中學會繼承、多態性、事件處理以及內部類這些內容嗎?Robocode 這個游戲即將為全世界的 Java 開發者實現這個愿望,它把游戲風潮變成了教學工具,人們對它的上癮程度令人吃驚。請跟隨 Sing Li 一起拆解 Robocode,同時著手建造屬于自己的、定制的、小而精悍的戰斗機器。

            Robocode 是一個很容易使用的機器人戰斗仿真器,可以在所有支持 Java 2 的平臺上運行。您創建一個機器人,把它放到戰場上,然后讓它同其他開發者們創建的機器人對手拼死戰斗到底。Robocode 里有一些預先做好的機器人對手讓你入門,但一旦您不再需要它們,就可以把您自己創建的機器人加入到正在世界范圍內形成的某個聯盟里去和世界最強手對陣。

            每個 Robocode 參加者都要利用 Java 語言元素創建他或她的機器人,這樣就使從初學者到高級黑客的廣大開發者都可以參與這一娛樂活動。初級的 Java 的開發者們可以學習一些基礎知識:調用 API 代碼、閱讀 Javadoc、繼承、內部類、事件處理等等。高級開發者們可以在構建“最優品種”的軟件機器人全球競賽中提高他們的編程技巧。在本文中,我們將介紹 Robocode,并指導您從構建您平生第一個 Robocode 機器人開始征服世界。我們還將看一下迷人的“后臺”機制,正是它使得 Robocode 起作用。

            下載并安裝 Robocode

            Robocode 是 Mathew Nelson 的智慧之作,他是 IBM Internet 部門 Advanced Technology 的軟件工程師。請首先訪問 IBM alphaWorks Robocode 頁面。在這個頁面上,您可以找到 Robocode 系統最新的可執行文件。這個分發包是一個自包含的安裝文件,在下載該分發包之后,您就可以使用下面的命令行在您的系統上安裝這個軟件包(當然,我們假定您的機器上已經預安裝了 Java VM(JDK 1.3.x)):

            java -jar robocode-setup.jar

            ?在安裝過程中,Robocode 將問您是否要使用這個外部的 Java VM 來編譯機器人。您也可以選擇使用作為 Robocode 分發包一部分而提供的 Jikes 編譯器。

            安裝完成后,您可以通過 shell 腳本(robocode.sh)、批處理文件(robocode.bat)或桌面上的圖標來啟動 Robocode 系統。此時,戰場將會出現。在此,您可以通過菜單調用 Robot Editor 和 compiler。





            回頁首


            Robocode 系統組件

            當您激活 Robocode 時,將看到兩個相關的 GUI 窗口,這兩個窗口構成了 Robocode 的 IDE:

            • 戰場
            • Robot Editor

            圖 1 展示了處于工作狀態的戰場和 Robot Editor。


            圖 1. Robocode IDE
            Robocode IDE

            戰場是機器人之間進行戰斗直至分出勝負的場地。主要的仿真引擎被置于其中,并且允許您在這里創建戰斗、保存戰斗以及打開新建的或現有的戰斗。通過界面區域內的控件,您可以暫停或繼續戰斗、終止戰斗、消滅任何機器人個體或獲取任何機器人的統計數據。此外,您可以在此屏幕上激活 Robot Editor。

            Robot Editor 是一個定制的文本編輯器,它可以用于編輯生成機器人的 Java 源文件。在它的菜單里集成了 Java 編譯器(用于編譯機器人代碼)以及定制的 Robot 打包器。由 Robot Editor 創建并成功編譯的所有機器人都會處于戰場上一個部署就緒的位置。

            Robocode 里的每個機器人都由一個或多個 Java 類構成。這些類可以被壓縮成一個 JAR 包。為此,Robocode 的最新版本提供了一個可以在戰場 GUI 窗口中激活的“Robot Packager”。





            回頁首


            對 Robocode 機器人的詳細分析

            在寫這篇文章時,Robocode 機器人是一個圖形化的坦克。圖 2 是一個典型的 Robocode 機器人的圖解。


            圖 2. 對 Robocode 機器人的詳細分析
            Robocode 機器人

            請注意,機器人有一門可以旋轉的炮,炮上面的雷達也是可以旋轉的。機器人坦克車(Vehicle)、炮(Gun)以及雷達(Radar)都可以單獨旋轉,也就是說,在任何時刻,機器人坦克車、炮以及雷達都可以轉向不同的方向。缺省情況下,這些方向是一致的,都指向坦克車運動的方向。





            回頁首


            Robot 命令

            Robocode 機器人的命令集都收錄在 Robocode API Javadoc 中。您將會發現這些命令都是 robocode.Robot 類的公共方法。在這一部分,我們將分類討論每個可用的命令。

            移動機器人、炮和雷達

            讓我們從移動機器人及其裝備的基本命令開始:

            • turnRight(double degree)turnLeft(double degree) 使機器人轉過一個指定的角度。
            • ahead(double distance)back(double distance) 使機器人移動指定的像素點距離;這兩個方法在機器人碰到墻或另外一個機器人時即告完成。
            • turnGunRight(double degree)turnGunLeft(double degree) 使炮可以獨立于坦克車的方向轉動。
            • turnRadarRight(double degree)turnRadarLeft(double degree) 使炮上面的雷達轉動,轉動的方向也獨立于炮的方向(以及坦克車的方向)。

            這些命令都是在執行完畢后才把控制權交還給程序。此外,轉動坦克車的時候,除非通過調用下列方法分別指明炮(和雷達)的方向,否則炮(和雷達)的指向也將移動。

            • setAdjustGunForRobotTurn(boolean flag) :如果 flag 被設置成 true,那么坦克車轉動時,炮保持原來的方向。
            • setAdjustRadarForRobotTurn(boolean flag) :如果 flag 被設置成 true,那么坦克車(和炮)轉動時,雷達會保持原來的方向。
            • setAdjustRadarForGunTurn(boolean flag) :如果 flag 被設置成 true,那么炮轉動時,雷達會保持原來的方向。而且,它執行的動作如同調用了 setAdjustRadarForRobotTurn(true)

            獲取關于機器人的信息

            有許多方法可以得到關于機器人的信息。下面簡單列舉了常用的方法調用:

            • getX()getY() 可以捕捉到機器人當前的坐標。
            • getHeading()getGunHeading()getRadarHeading() 可以得出坦克車、炮或雷達當前的方向,該方向是以角度表示的。
            • getBattleFieldWidth()getBattleFieldHeight() 可以得到當前這一回合的戰場尺寸。

            射擊命令

            一旦您掌握了移動機器人以及相關的武器裝備的方法,您就該考慮射擊和控制損害的任務了。每個機器人在開始時都有一個缺省的“能量級別”,當它的能量級別減小到零的時候,我們就認為這個機器人已經被消滅了。射擊的時候,機器人最多可以用掉三個能量單位。提供給炮彈的能量越多,對目標機器人所造成的損害也就越大。 fire(double power)fireBullet(double power) 用來發射指定能量(火力)的炮彈。調用的 fireBullet() 版本返回 robocode.Bullet 對象的一個引用,該引用可以用于高級機器人。

            事件

            每當機器人在移動或轉動時,雷達一直處于激活狀態,如果雷達檢測到有機器人在它的范圍內,就會觸發一個事件。作為機器人創建者,您有權選擇處理可能在戰斗中發生的各類事件。基本的 Robot 類中包括了所有這些事件的缺省處理程序。但是,您可以覆蓋其中任何一個“什么也不做的”缺省處理程序,然后實現您自己的定制行為。下面是一些較為常用的事件:

            • ScannedRobotEvent 。通過覆蓋 onScannedRobot() 方法來處理 ScannedRobotEvent ;當雷達檢測到機器人時,就調用該方法。
            • HitByBulletEvent 。通過覆蓋 onHitByBullet() 方法來處理 HitByBulletEvent ;當機器人被炮彈擊中時,就調用該方法。
            • HitRobotEvent 。通過覆蓋 onHitRobot() 方法來處理 HitRobotEvent ;當您的機器人擊中另外一個機器人時,就調用該方法。
            • HitWallEvent 。通過覆蓋 onHitWall() 方法來處理 HitWallEvent ;當您的機器人撞到墻時,就調用該方法。

            我們只需要知道這些就可以創建一些相當復雜的機器人了。您可以通過戰場的幫助菜單或 Robot Editor 的幫助菜單訪問 Javadoc 中其余的 Robocode API。

            現在,我們該把學到的知識付諸實踐了。





            回頁首


            創建機器人

            要創建一個新的機器人,請啟動 Robot Editor 并選擇 File-> New-> Robot。系統將會提示您輸入機器人的名稱,這個名稱將成為 Java 類名。請您在提示符處輸入 DWStraight。接下來,系統還會提示您輸入一個獨一無二的包前綴,它將用作存放機器人(還可能有相關的 Java 文件)的包的名稱。請在該提示符處輸入 dw

            Robot Editor 就會顯示您要控制這個機器人需要編寫的 Java 代碼。清單 1 是您將會看到的代碼的一個示例:


            清單 1. Robocode 生成的 Robot 代碼
            												
            														package dw;
            import robocode.*;
            
            /**
             * DWStraight - a robot by (developerWorks)
             */
            public class DWStraight extends Robot
            {
                ...  // <<Area 1>>
                /**
                 * run: DWStraight's default behavior
                 */
                public void run() {
                    ... // <<Area 2>>
                    while(true) {
                    ... // <<Area 3>>
                    }
                }
                  ... // <<Area 4>>
                public void onScannedRobot(ScannedRobotEvent e) {
                    fire(1);
                }
            }
            
            												
            										

            突出顯示的區域就是我們添加控制機器人的代碼的地方:

            Area 1
            我們可以在這片空白里聲明類作用域變量并設置這些變量的值。這些變量可以在機器人的 run() 方法內以及其他一些您可能創建的助手方法內使用。

            Area 2
            戰斗管理器調用 run() 方法激活機器人。典型情況下,run() 方法包括兩個區域(即在清單 1 中指出的 Area 2 和 Area 3),您可以在這兩塊空白里添加代碼。您在 Area 2 中加入的代碼每個機器人實例只運行一次。這部分代碼通常用于使機器人先處于一種預設狀態后再開始執行重復行為。

            Area 3
            這是典型的 run() 方法實現的第二部分。在此,我們將在無限 while 循環內對機器人可能執行的重復行為進行編程。

            Area 4
            您可以在這一區域內添加機器人在 run() 邏輯內使用的助手方法。您也可以在此添加您想要覆蓋的任何事件處理程序。例如,清單 1 里的代碼處理 ScannedRobot 事件,每當雷達檢測到機器人的時候,只是直接向其發射炮彈。

            我們對第一個機器人(DWStraight)的代碼的更新如清單 2 中紅色標記所示。


            清單 2. DWStraight 機器人代碼的增加部分
            												
            														package dw;
            import robocode.*;
            
            public class DWStraight extends Robot
            {
                public void run() {
                    turnLeft(getHeading());
                    while(true) {
                        ahead(1000);
                        turnRight(90);
            
                    }
                }
                     public void onScannedRobot(ScannedRobotEvent e) {
                    fire(1);
                }
                public void onHitByBullet(HitByBulletEvent e) {
                    turnLeft(180);
                }
                  
            }
            
            												
            										

            下面我們逐區地描述這個第一個機器人將做些什么:

            Area 1我們沒有在這個機器人的程序中指定任何類作用域變量。

            Area 2
            為了使機器人處于已知的狀態,我們通過 turnLeft(getHeading()) 使它轉到 0 度的方向。

            Area 3
            在這個重復性的部分,我們使用語句 ahead(1000) 讓機器人盡其所能向前移動到最遠的地方。當機器人撞到墻或其他機器人時,就會停下來。接著,我們通過 turnRight(90) 使它向右轉。在重復執行這一行為時,機器人基本上是在沿著墻按順時針方向移動。

            Area 4
            在此,除處理自動生成的 ScannedRobot 事件并向被發現的機器人直接射擊之外,我們還會檢測 HitByBullet 事件,并且讓機器人在被擊中的時候轉過 180 度(沿順時針方向或逆時針方向)。





            回頁首


            編譯以及測試機器人

            在 Robot Editor 菜單上選擇 Compiler-> Compile編譯您的機器人代碼。現在我們可以嘗試第一回合的戰斗了。切換回戰場并選擇菜單上的 Battle-> New,將會出現一個類似于圖 3 中所示的對話框。


            圖 3. New Battle 對話框
            New Battle 對話框

            請先將我們的機器人 dw.DWStraight 添加到戰斗中,然后再添加一個對手機器人,比如 sample.SittingDuck。單擊 Finish,戰斗就開始了。不可否認,同 SittingDuck 戰斗并不怎么有趣,但是您可以目睹這個叫做 DWStraight 的機器人在缺省情況下的行為。試試 sample 文件夾里的其他機器人,看看 DWStraight 同這些機器人的戰斗情況如何。

            當您準備開始研究另外一個機器人的代碼時,請先看看隨 參考資料 中的代碼分發包一起提供的 dw.DWRotater 這個機器人的代碼。在缺省情況下,這個機器人將會:

            • 移動到戰場中心
            • 一直轉動它的炮,直到檢測到機器人
            • 每次嘗試以不同的角度在離被檢測到的機器人前方不遠的地方射擊
            • 每當它被另外一個機器人擊中時,它都會迅速的來回移動

            這段代碼簡單易懂,所以我們在這里就不做分析了,但是我鼓勵您試驗一下。Robocode 中的 sample 包還提供了許多其他機器人的代碼。

            附加的機器人支持類

            隨著您設計機器人的水平的提高,機器人的代碼主體將充分增長。對這些代碼的一種模塊化處理方法是把代碼分解成獨立的 Java 類,然后通過打包器把這些 Java 類打包成一個單獨的包(JAR 文件),并將它包括在您的機器人分發包內。Robocode 將自動在它的 robots 目錄下的包里找到 robot 類。

            其他 Robot 子類

            任何人都可以創建 Robot 子類并添加用于構建機器人的新功能。Robocode 提供了一個叫做 AdvancedRobotRobot 子類,它允許異步 API 調用。雖然對 AdvancedRobot 類的描述超出了本文的范圍,但我鼓勵您在掌握了基本的 Robot 類的操作后,試驗一下這個高級類。

            設計 Robocode 的目的

            我碰見了 Robocode 的創建者 Mathew Nelson,向他請教創建 Robocode 最初的設計目的。Mat 所說的是:“編寫 Robocode 的一部分目的是為了向世界證明:象‘Java 比較慢’以及‘Java 不可以用來寫游戲’之類的論斷不再正確。我認為我證明了這一點。”





            回頁首


            戰斗仿真器的體系結構

            通過“在后臺”對 Robocode 進行分析,我們發現復雜的仿真引擎既具高性能(為了以現實的速度生成戰斗)又具靈活性(使創建復雜的機器人邏輯不存在障礙)。特別感謝 Robocode 的創建者 Mathew Nelson 無私的提供了仿真引擎體系結構的內部信息。

            利用 Java 平臺進行設計

            圖 4 中所示的仿真引擎利用的是大多數現代的 Java VM 都提供的非搶占式線程技術,并結合使用了 JDK GUI 和 2D 圖形庫提供的生成功能。


            圖 4. Robocode 仿真引擎體系結構
            仿真引擎

            請注意,所仿真的每個機器人都在它自己的 Java 線程上,它可以在任何可適用的地方利用 VM 本地線程映射機制。戰斗管理器線程是系統的控制器:它安排仿真并驅動圖形化的生成子系統。圖形化的生成子系統本身是基于 Java 2D 和 AWT 的。

            松散的線程耦合

            為了減少共享資源可能帶來的問題(以及有可能隨之出現的死鎖或阻塞仿真引擎),戰斗管理器線程和機器人線程之間的耦合應當非常松散。為了實現這種松散耦合,每個機器人線程都將有屬于自己的事件隊列。獲取及處理這些事件都是在每個機器人自己的線程內進行。這種基于線程的隊列有效地消除了戰斗管理器線程和機器人線程之間(或機器人線程本身之間)可能存在的任何爭用。

            Robocode 內部結構

            您可以把 Robocode 仿真器引擎看作是一個仿真器程序,該程序在運行時會使用一些插件(定制機器人);這些插件可以利用已有的 API( robocode.Robot 類的方法)。實際上,每個機器人都是一個獨立的 Java 線程,同時 run() 方法內包含了每個線程上將要執行的邏輯。

            在任何時候,機器人線程都可以調用由它的父類 robocoode.Robot 類所提供的 API。典型情況下,這將通過調用 Object.wait() 阻塞機器人線程。

            戰斗管理器線程

            戰斗管理器線程管理機器人、炮彈及它們在戰場上的生成。仿真“時鐘”是根據戰場上生成的幀的數目來標記的。用戶可以調整真實的幀的速度。

            在一個典型的回合中,戰斗管理器線程喚醒每個機器人線程,然后等待機器人完成它的一輪戰斗(即,再次調用一個阻塞 API)。等待的間隔時間通常是幾十毫秒,即使是最復雜的機器人,使用現今典型的系統速度進行策略安排和計算,也只要 1 到 2 毫秒的時間。

            以下是戰斗管理器線程執行的邏輯的偽代碼:


            清單 3. 戰斗管理器的邏輯的偽代碼
            												
            														while (round is not over) do
               call the rendering subsystem to draw robots, bullets, explosions
               for  each robot do
                   wake up the robot
                   wait for it to make a blocking call, up to a max time interval
               end for
               clear all robot event queue
               move bullets, and generate event into robots' event queue if applicable
               move robots, and generate event into robots' event queue if applicable
               do battle housekeeping and generate event into robots' event queue
                     if applicable
               delay for frame rate if necessary
            end do
            
            												
            										

            請注意,在 for 循環內部,戰斗管理器線程的等待時間不會超過最大的時間間隔。如果機器人線程沒有及時調用阻塞 API(典型情況下是由于一些應用程序邏輯錯誤或無限循環),那么,它將繼續進行戰斗。生成一個 SkippedTurnEvent 并將其加入機器人事件隊列中,用來通知高級機器人。

            可替換的生成子系統

            AWT 和 Java 2D 線程就是當前實現中的生成子系統,它從戰斗管理器中獲取命令并生成戰場。它同系統的其余部分是完全分離的。我們可以預見到,在這個生成子系統將來的修訂版中,它可以被替換掉(比如,用 3-D 生成器)。在當前的實現中,只要 Robocode 應用程序被最小化,生成就禁用了,這可以以更快的速度進行仿真。





            回頁首


            Robocode 的未來

            通過 alphaWorks Robocode 站點上的一個討論組(請參閱 參考資料 ),Mathew Nelson 可以同 Robocode 用戶社區保持緊密的反饋聯系。許多反饋都并入了真實的代碼中。Mathew 已計劃即將要進行的一些改進有:

            • 通過不同的物體和障礙來定制戰場地圖
            • 基于團隊的戰斗
            • 對聯賽或聯盟的集成支持
            • 用戶可選擇坦克車體/炮/雷達/武器的樣式




            回頁首


            擋不住的 Robocode 風潮

            對于一個從 2001 年 7 月 12 日出現在公眾面前的項目,Robocode 的出名簡直讓人吃驚。盡管最新的可用版本還不到 1.0(在寫這篇文章時是版本 0.98.2),但它已經是全世界的大學校園以及公司的 PC 機上頗受歡迎的娛樂活動了。Robocode 聯盟(或 roboleagues)正如雨后春筍般出現,在這些聯盟里,人們通過因特網讓自己定制的作品相互較量。大學教授們一直在挖掘 Robocode 的教育特性,并且已經把它納入了大學里的計算機科學課程。在因特網上,Robocode 用戶組、討論列表、FAQ、教程和 Webring 隨處可見。

            顯然,Robocode 已經填補了大眾化的寓教于樂領域的空白 ― 它為學生們和熬夜的工程師們提供簡便、有趣、非脅迫卻富競爭力的方式,釋放他們的創造力,而且有可能實現他們征服世界的夢想。

            posted on 2006-07-19 20:55 Merlin 閱讀(420) 評論(0)  編輯 收藏 引用 所屬分類: java基礎篇
            久久亚洲中文字幕精品有坂深雪| 人妻少妇久久中文字幕| 精品久久人妻av中文字幕| 99久久这里只精品国产免费| 国产精品99久久久久久www| 国产成人久久激情91| 久久国产亚洲高清观看| 亚洲精品乱码久久久久久按摩 | 精品综合久久久久久88小说 | 99精品久久精品| 日日噜噜夜夜狠狠久久丁香五月| 日日躁夜夜躁狠狠久久AV| 亚洲精品无码久久久影院相关影片| 国产精品成人久久久| 亚洲精品tv久久久久久久久| 一本色道久久99一综合| 久久天天躁狠狠躁夜夜96流白浆| 国产成人久久AV免费| 99久久精品免费看国产免费| 久久AⅤ人妻少妇嫩草影院| 一本久久免费视频| 久久99精品久久久久久久不卡| 久久国产精品久久国产精品| 91精品日韩人妻无码久久不卡| 久久天天躁狠狠躁夜夜2020| 亚洲国产精品无码久久一线| 99久久精品费精品国产一区二区| 久久国产成人精品国产成人亚洲| 欧美亚洲国产精品久久高清| 亚洲国产一成人久久精品| 51久久夜色精品国产| 久久99精品国产麻豆宅宅| www.久久热.com| 伊人久久无码精品中文字幕| 99精品久久精品| 免费久久人人爽人人爽av| 91秦先生久久久久久久| 亚洲第一极品精品无码久久| 久久精品二区| 久久r热这里有精品视频| 久久成人国产精品免费软件|