gvgai框架搭建及controller编写
gvgai框架搭建及controller編寫
- gvgai框架搭建
- controller編寫
gvgai框架搭建
gvgai官網:http://www.gvgai.net/
框架下載:http://www.gvgai.net/software.php
該框架的運行需要安裝JDK和Intellij idea(我用的是這個)。
controller編寫
以框架中的pacoman為例:
pacoman是一個雙人游戲,游戲中,需要有兩個agent控制兩個吃豆人,要在躲避四個幽靈的前提下盡可能多的吃到金幣,同時吃 豆人也可以獲得一些獎勵的道具,獲得分數的同時能夠得到特殊的增益效果。
這個游戲的程序入口位于src\tracks\multiplayer\testMultiplayer.java。在這里你可以選擇用于雙人游戲的控制器。如果你自己想玩可以將其中的一個控制器改為humanController。
編寫控制器需要注意:
每一個控制器都是由一個繼承自core\player\AbstractMultiPlayer.java的java類類構成(由此應該容易推知其它的控制器類從哪里繼承),且這個類必須命名為Agent.java且必須實現兩個方法:
public Agent(StateObservation stateObs, ElapsedCpuTimer elapsedTimer, playerID)
public Types.ACTIONS act(StateObservation stateObs, ElapsedCpuTimer elapsedTimer)
兩個方法都需要兩個參數 StateObservation stateObs 和 ElapsedCpuTimer elapsedTimer,其中:
StateObservation stateObs: 定義了 agent 當前所處的狀態信息,一般通過上層程序傳遞下來,你 可以通過在可運行的控制器上加斷點來查看其所包含的內容;另外,源文件位于 src\core\game\StateObservationMulti.java ,你可以去查看其自帶的一些方法(使用Intellij idea的go to 命令簡單直接)。
ElapsedCpuTimer elapsedTimer: 是一個類,它允許查詢代理返回一個動作的剩余CPU時間。
通過如下代碼實現控制器:
package tracks.multiPlayer.hw;import core.game.StateObservation;
import core.game.StateObservationMulti;
import core.player.AbstractMultiPlayer;
import ontology.Types;
import tools.ElapsedCpuTimer;
import tools.Vector2d;import java.util.ArrayList;
import java.util.Random;public class Agent extends AbstractMultiPlayer {int id;int oppID;Random rnd;int no_player;public Agent(StateObservationMulti stateObs, ElapsedCpuTimer elapsedTimer, int playerID) {id = playerID;no_player = stateObs.getNoPlayers();oppID = (playerID + 1) % stateObs.getNoPlayers();rnd = new Random();}@Overridepublic Types.ACTIONS act(StateObservationMulti stateObs, ElapsedCpuTimer elapsedTimer) {Types.ACTIONS bestAction = getBestAction(stateObs,id);//System.out.printf("當前最好的動作是:%s\n",bestAction);return bestAction;}//獲取玩家當前較優動作private Types.ACTIONS getBestAction(StateObservationMulti stateObs, int id) {Graph g=new Graph();g=g.search(stateObs,id);if(g==null)return keepMovingAction(stateObs,id);return g.getScdEntry().action;}// 獲得一個使吃豆人保持移動的動作private Types.ACTIONS keepMovingAction(StateObservationMulti stateObs,int id){ArrayList<Types.ACTIONS> movingActions=new ArrayList<>();ArrayList<Types.ACTIONS> actions=stateObs.getAvailableActions(id);int oppID=(id+1)%stateObs.getNoPlayers();int no_player=stateObs.getNoPlayers();Vector2d avatar=stateObs.getAvatarPosition(id);for(Types.ACTIONS action:stateObs.getAvailableActions(id)){//不考慮ACTION_NILif(action==Types.ACTIONS.ACTION_NIL)continue;Types.ACTIONS []acts=new Types.ACTIONS[no_player];acts[id]=action;acts[oppID]=Types.ACTIONS.ACTION_NIL;StateObservationMulti stCopy=stateObs.copy();stCopy.advance(acts);//如果該動作會導致玩家死亡,也不考慮boolean gameOver=stCopy.isGameOver();Types.WINNER win=stCopy.getMultiGameWinner()[id];if(gameOver||win==Types.WINNER.PLAYER_LOSES)continue;//如果該動作無法改變玩家位置,不考慮Vector2d new_avatar=stCopy.getAvatarPosition(id);if(new_avatar!=avatar)movingActions.add(action);}//最終返回所有改變玩家位置的動作中的一個,或返回隨機if(movingActions.size()==0)return actions.get(new Random().nextInt(actions.size()));elsereturn movingActions.get(new Random().nextInt(movingActions.size()));}
}
附帶的圖搜索算法:
package tracks.multiPlayer.hw;import core.game.StateObservationMulti;
import ontology.Types;
import tools.Vector2d;import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Random;public class Graph {public Types.ACTIONS action=null;public Types.ACTIONS no_action=null;public StateObservationMulti stateObs=null;public Graph parent=null;//返回帶有最優前進路徑之動作的節點public Graph getScdEntry(){if(this.parent!=null&&this.parent.action!=null)return this.parent.getScdEntry();elsereturn this;}//通過act返回相應的數字public int classifyAct(Types.ACTIONS act){switch (act){case ACTION_UP: return 1;case ACTION_DOWN: return 2;case ACTION_LEFT: return 3;case ACTION_RIGHT: return 4;}return 0;}//通過數字i的值返回對應的動作public Types.ACTIONS getAct(int i){switch (i){case 1:return Types.ACTIONS.ACTION_UP;case 2:return Types.ACTIONS.ACTION_DOWN;case 3:return Types.ACTIONS.ACTION_LEFT;case 4:return Types.ACTIONS.ACTION_RIGHT;}return Types.ACTIONS.ACTION_NIL;}//對Graph對象進行拷貝,返回一個與拷貝對象一致的Graphprivate Graph copy(){int i;Graph g=new Graph();i=classifyAct(this.action);g.action=getAct(i);i=classifyAct(this.no_action);g.no_action=getAct(i);g.stateObs=this.stateObs.copy();return g;}public Graph search(StateObservationMulti stateObs,int id){//初始化變量this.stateObs=stateObs;this.action=null;this.no_action=null;this.parent=null;int step=0,maxStep=50;int oppID = (id + 1) % stateObs.getNoPlayers();int no_player = stateObs.getNoPlayers();double score = stateObs.getGameScore(id);//初始化“隊列”,并將帶有當前狀態的節點入列int front=-1,rear=-1;Graph entry1=null,entry2=null;Graph[]entries=new Graph[999];rear=(rear+1)%999;entries[rear]=this;//開始搜索路徑,當搜索深度到達極限而仍未得到結果的情況下,返回nullwhile(front!=rear&&step<maxStep){step++;front=(front+1)%999;entry1=entries[front];//對于節點entry1的每個可行的動作通過copy()和advance()方法判斷是否能夠for(Types.ACTIONS action:entry1.stateObs.getAvailableActions(id)){//如果動作為保持不動或者是轉換位前一個轉臺的動作,則放棄(為防止搜索陷入死循環)if(action==Types.ACTIONS.ACTION_NIL||action==entry1.no_action)continue;Types.ACTIONS []acts=new Types.ACTIONS[no_player];acts[id]=action;acts[oppID]=Types.ACTIONS.ACTION_NIL;StateObservationMulti stCopy=entry1.stateObs.copy();Vector2d avatar=stCopy.getAvatarPosition(id);stCopy.advance(acts);//如果此動作過后導致了玩家的死亡,則放棄boolean gameOver=stCopy.isGameOver();Types.WINNER win=stCopy.getMultiGameWinner()[id];if(gameOver||win==Types.WINNER.PLAYER_LOSES)continue;//如果此動作后玩家仍呆在先前的位置,則放棄Vector2d new_avatar=stCopy.getAvatarPosition(id);if(new_avatar==avatar)continue;//通過篩選的節點可以入列entry2=new Graph();entry2.parent=entry1;entry2.stateObs=stCopy;entry2.action=action;switch (action){case ACTION_UP:entry2.no_action= Types.ACTIONS.ACTION_DOWN;break;case ACTION_DOWN:entry2.no_action= Types.ACTIONS.ACTION_UP;break;case ACTION_LEFT:entry2.no_action=Types.ACTIONS.ACTION_RIGHT;break;case ACTION_RIGHT:entry2.no_action= Types.ACTIONS.ACTION_LEFT;break;}rear=(rear+1)%999;entries[rear]=entry2;if(entry2.stateObs.getGameScore(id)>score){return entry2;}}}return null;}
}
控制器效果展示(我是那個“走路帶風”的):
總結
以上是生活随笔為你收集整理的gvgai框架搭建及controller编写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言读取bmp图像并做简单显示
- 下一篇: C语言实现bmp图像几何变换(移动,旋转