change ActionSpace interface temporarily to quickly fit antWorld test and improve gui of walking ant
This commit is contained in:
		
							parent
							
								
									2fb218a129
								
							
						
					
					
						commit
						8a533dda94
					
				|  | @ -1,9 +1,9 @@ | |||
| package core; | ||||
| 
 | ||||
| import java.util.Set; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public interface ActionSpace<A extends Enum> { | ||||
|     Set<Action> getAllActions(); | ||||
|     int getNumberOfAction(); | ||||
|     void addAction(DiscreteAction<A> a); | ||||
|     void addActions(A[] as); | ||||
| } | ||||
|  |  | |||
|  | @ -1,13 +1,13 @@ | |||
| package core; | ||||
| 
 | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class DiscreteActionSpace<A extends Enum> implements ActionSpace<A>{ | ||||
|     private Set<Action> actions; | ||||
|     private List<DiscreteAction<A>> actions; | ||||
| 
 | ||||
|     public DiscreteActionSpace(){ | ||||
|         actions = new HashSet<>(); | ||||
|         actions = new ArrayList<>(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -15,14 +15,19 @@ public class DiscreteActionSpace<A extends Enum> implements ActionSpace<A>{ | |||
|         actions.add(action); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void addActions(A[] as) { | ||||
|         for(A a : as){ | ||||
|             actions.add(new DiscreteAction<>(a)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int getNumberOfAction(){ | ||||
|         return actions.size(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Set<Action> getAllActions(){ | ||||
|     public List<DiscreteAction<A>> getAllDiscreteActions(){ | ||||
|         return actions; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -58,9 +58,9 @@ public class StateActionHashTable<A extends Enum> implements StateActionTable { | |||
| 
 | ||||
|     private Map<Action, Double> createDefaultActionValues(){ | ||||
|         final Map<Action, Double> defaultActionValues = new HashMap<>(); | ||||
|         for(Action action: actionSpace.getAllActions()){ | ||||
|             defaultActionValues.put(action, DEFAULT_VALUE); | ||||
|         } | ||||
|        // for(Action action: actionSpace.getAllActions()){ | ||||
|        //     defaultActionValues.put(action, DEFAULT_VALUE); | ||||
|         //} | ||||
|         return defaultActionValues; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -11,7 +11,10 @@ import java.awt.*; | |||
| @Getter | ||||
| @Setter | ||||
| public class Ant { | ||||
|     // only set this via .setLocation of Point-class! | ||||
|     @Setter(AccessLevel.NONE) | ||||
|     private Point pos; | ||||
|     private int points; | ||||
|     private boolean spawned; | ||||
|     @Getter(AccessLevel.NONE) | ||||
|     private boolean hasFood; | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ package evironment.antGame; | |||
| import core.*; | ||||
| import evironment.antGame.gui.MainFrame; | ||||
| 
 | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| 
 | ||||
| public class AntWorld { | ||||
|  | @ -37,6 +38,7 @@ public class AntWorld { | |||
|     public AntWorld(int width, int height, double foodDensity){ | ||||
|         grid = new Grid(width, height, foodDensity); | ||||
|         antAgent = new AntAgent(width, height); | ||||
|         myAnt = new Ant(new Point(-1,-1), 0, false, false); | ||||
|         gui = new MainFrame(this, antAgent); | ||||
|         tick = 0; | ||||
|         maxEpisodeTicks = 1000; | ||||
|  | @ -60,10 +62,11 @@ public class AntWorld { | |||
| 
 | ||||
|         if(!myAnt.isSpawned()){ | ||||
|             myAnt.setSpawned(true); | ||||
|             myAnt.setPos(grid.getStartPoint()); | ||||
|             myAnt.getPos().setLocation(grid.getStartPoint()); | ||||
|             observation = new AntObservation(grid.getCell(myAnt.getPos()), myAnt.getPos(), myAnt.hasFood()); | ||||
|             newState = antAgent.feedObservation(observation); | ||||
|             reward = 0.0; | ||||
|             ++tick; | ||||
|             return new StepResult(newState, reward, false, "Just spawned on the map"); | ||||
|         } | ||||
| 
 | ||||
|  | @ -120,6 +123,7 @@ public class AntWorld { | |||
|                         reward = Reward.FOOD_DROP_DOWN_FAIL_NOT_START; | ||||
|                     }else{ | ||||
|                         reward = Reward.FOOD_DROP_DOWN_SUCCESS; | ||||
|                         myAnt.setPoints(myAnt.getPoints() + 1); | ||||
|                         checkCompletion = true; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -141,7 +145,7 @@ public class AntWorld { | |||
| 
 | ||||
|         // valid movement | ||||
|         if(!stayOnCell){ | ||||
|             myAnt.setPos(potentialNextPos); | ||||
|             myAnt.getPos().setLocation(potentialNextPos); | ||||
|             if(antAgent.getCell(myAnt.getPos()).getType() == CellType.UNKNOWN){ | ||||
|                 // the ant will move to a cell that was previously unknown | ||||
|                 reward = Reward.UNKNOWN_FIELD_EXPLORED; | ||||
|  | @ -177,7 +181,10 @@ public class AntWorld { | |||
|     public void reset() { | ||||
|         RNG.reseed(); | ||||
|         grid.initRandomWorld(); | ||||
|         myAnt = new Ant(new Point(-1,-1), false, false); | ||||
|         myAnt.getPos().setLocation(-1,-1); | ||||
|         myAnt.setPoints(0); | ||||
|         myAnt.setHasFood(false); | ||||
|         myAnt.setSpawned(false); | ||||
|     } | ||||
| 
 | ||||
|     public void setMaxEpisodeLength(int maxTicks){ | ||||
|  | @ -191,19 +198,25 @@ public class AntWorld { | |||
|         return grid.getGrid(); | ||||
|     } | ||||
| 
 | ||||
|     public int getTick(){ | ||||
|         return tick; | ||||
|     } | ||||
| 
 | ||||
|     public Ant getAnt(){ | ||||
|         return myAnt; | ||||
|     } | ||||
|     public static void main(String[] args) { | ||||
|         RNG.setSeed(1993); | ||||
|         AntWorld a = new AntWorld(10, 10, 0.1); | ||||
|         System.out.println("ayay"); | ||||
|         a.getGui().repaint(); | ||||
|         for(int i = 0; i< 10; ++i){ | ||||
|             a.step(new DiscreteAction<>(AntAction.MOVE_RIGHT)); | ||||
|             a.getGui().repaint(); | ||||
|         DiscreteActionSpace<AntAction> actionSpace = new DiscreteActionSpace<>(); | ||||
|         actionSpace.addActions(AntAction.values()); | ||||
| 
 | ||||
|         for(int i = 0; i< 1000; ++i){ | ||||
|             DiscreteAction<AntAction> selectedAction = actionSpace.getAllDiscreteActions().get(RNG.getRandom().nextInt(actionSpace.getNumberOfAction())); | ||||
|             StepResult step = a.step(selectedAction); | ||||
|             SwingUtilities.invokeLater(()-> a.getGui().update(selectedAction.getValue(), step)); | ||||
|             try { | ||||
|                 Thread.sleep(1000); | ||||
|                 Thread.sleep(100); | ||||
|             } catch (InterruptedException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ public enum CellType { | |||
|     START, | ||||
|     FREE, | ||||
|     OBSTACLE, | ||||
|     FOOD, | ||||
|     UNKNOWN, | ||||
|     POSSIBLE_FOOD, | ||||
|     KNOWN_FOOD, | ||||
| } | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ public class Grid { | |||
|         for(int x = 0; x < width; ++x){ | ||||
|             for(int y = 0; y < height; ++y){ | ||||
|                 if( RNG.getRandom().nextDouble() < foodDensity){ | ||||
|                     grid[x][y] = new Cell(new Point(x,y), CellType.FOOD, 1); | ||||
|                     grid[x][y] = new Cell(new Point(x,y), CellType.FREE, 1); | ||||
|                 }else{ | ||||
|                     grid[x][y] = new Cell(new Point(x,y), CellType.FREE); | ||||
|                 } | ||||
|  |  | |||
|  | @ -13,7 +13,6 @@ public class CellColor { | |||
|         map.put(CellType.FREE, Color.GREEN); | ||||
|         map.put(CellType.START, Color.BLUE); | ||||
|         map.put(CellType.UNKNOWN, Color.GRAY); | ||||
|         map.put(CellType.FOOD, Color.YELLOW); | ||||
|         map.put(CellType.OBSTACLE, Color.RED); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| package evironment.antGame.gui; | ||||
| 
 | ||||
| import evironment.antGame.Ant; | ||||
| import evironment.antGame.Cell; | ||||
| 
 | ||||
| import javax.swing.*; | ||||
|  | @ -9,12 +10,12 @@ public class CellsScrollPane extends JScrollPane { | |||
|     private int cellSize; | ||||
|     private final int paneWidth = 500; | ||||
|     private final int paneHeight = 500; | ||||
| 
 | ||||
|     public CellsScrollPane(Cell[][] cells, int size){ | ||||
|     private Font font; | ||||
|     public CellsScrollPane(Cell[][] cells, Ant ant, int size){ | ||||
|         super(); | ||||
|         cellSize = size; | ||||
|         setPreferredSize(new Dimension(paneWidth, paneHeight)); | ||||
|         cellSize = (paneWidth- cells.length) /cells.length; | ||||
|         font = new Font("plain", Font.BOLD, cellSize); | ||||
|         JPanel worldPanel = new JPanel(){ | ||||
|             { | ||||
|                 setPreferredSize(new Dimension(cells.length * cellSize, cells[0].length * cellSize)); | ||||
|  | @ -26,6 +27,7 @@ public class CellsScrollPane extends JScrollPane { | |||
|                     }else { | ||||
|                         cellSize += 1; | ||||
|                     } | ||||
|                     font = new Font("plain", Font.BOLD, cellSize); | ||||
|                     setPreferredSize(new Dimension(cells.length * cellSize, cells[0].length * cellSize)); | ||||
|                     revalidate(); | ||||
|                     repaint(); | ||||
|  | @ -40,9 +42,19 @@ public class CellsScrollPane extends JScrollPane { | |||
|                         g.setColor(Color.BLACK); | ||||
|                         g.drawRect(i*cellSize, j*cellSize, cellSize, cellSize); | ||||
|                         g.setColor(CellColor.map.get(cells[i][j].getType())); | ||||
|                         if(cells[i][j].getFood() > 0){ | ||||
|                             g.setColor(Color.YELLOW); | ||||
|                         } | ||||
|                         g.fillRect(i*cellSize+1, j*cellSize+1, cellSize -1, cellSize-1); | ||||
|                     } | ||||
|                 } | ||||
|                 if(ant.hasFood()){ | ||||
|                     g.setColor(Color.RED); | ||||
|                 }else { | ||||
|                     g.setColor(Color.BLACK); | ||||
|                 } | ||||
|                 g.setFont(font); | ||||
|                 g.drawString("A", ant.getPos().x * cellSize, (ant.getPos().y + 1) * cellSize); | ||||
|             } | ||||
|         }; | ||||
|         getViewport().add(worldPanel); | ||||
|  |  | |||
|  | @ -1,9 +1,28 @@ | |||
| package evironment.antGame.gui; | ||||
| 
 | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| 
 | ||||
| public class HistoryPanel extends JPanel { | ||||
|     private final int panelWidth =  1000; | ||||
|     private final int panelHeight = 300; | ||||
|     private JTextArea textArea; | ||||
| 
 | ||||
|     public HistoryPanel(){ | ||||
|         setPreferredSize(new Dimension(panelWidth, panelHeight)); | ||||
|         textArea = new JTextArea(); | ||||
|         textArea.setLineWrap(true); | ||||
|         textArea.setWrapStyleWord(true); | ||||
|         textArea.setEditable(false); | ||||
|         JScrollPane scrollBar = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); | ||||
|         scrollBar.setPreferredSize(new Dimension(panelWidth, panelHeight)); | ||||
|         add(scrollBar); | ||||
|         setVisible(true); | ||||
|     } | ||||
| 
 | ||||
|     public void addText(String toAppend){ | ||||
|         textArea.append(toAppend); | ||||
|         textArea.append("\n\n"); | ||||
|         revalidate(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| package evironment.antGame.gui; | ||||
| 
 | ||||
| import core.StepResult; | ||||
| import evironment.antGame.AntAction; | ||||
| import evironment.antGame.AntAgent; | ||||
| import evironment.antGame.AntWorld; | ||||
| 
 | ||||
|  | @ -7,12 +9,16 @@ import javax.swing.*; | |||
| import java.awt.*; | ||||
| 
 | ||||
| public class MainFrame extends JFrame { | ||||
|     private AntWorld antWorld; | ||||
|     private HistoryPanel historyPanel; | ||||
| 
 | ||||
|     public MainFrame(AntWorld antWorld, AntAgent antAgent){ | ||||
|         this.antWorld = antWorld; | ||||
|         setLayout(new BorderLayout()); | ||||
|         setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | ||||
|         CellsScrollPane worldPane = new CellsScrollPane(antWorld.getCellArray(), 10); | ||||
|         CellsScrollPane antBrainPane = new CellsScrollPane(antAgent.getKnownWorld(), 10); | ||||
|         CellsScrollPane worldPane = new CellsScrollPane(antWorld.getCellArray(), antWorld.getAnt(), 10); | ||||
|         CellsScrollPane antBrainPane = new CellsScrollPane(antAgent.getKnownWorld(), antWorld.getAnt(), 10); | ||||
|         historyPanel = new HistoryPanel(); | ||||
| 
 | ||||
|         JComponent mapComponent = new JPanel(); | ||||
|         FlowLayout flowLayout = new FlowLayout(); | ||||
|  | @ -22,7 +28,15 @@ public class MainFrame extends JFrame { | |||
|         mapComponent.add(antBrainPane); | ||||
| 
 | ||||
|         add(BorderLayout.CENTER, mapComponent); | ||||
|         add(BorderLayout.SOUTH, historyPanel); | ||||
|         pack(); | ||||
|         setVisible(true); | ||||
|     } | ||||
| 
 | ||||
|     public void update(AntAction lastAction, StepResult stepResult){ | ||||
|         historyPanel.addText(String.format("Tick %d: \t Selected action: %s \t Reward: %f \t Info: %s \n totalPoints: %d \t hasFood: %b \t ", | ||||
|                 antWorld.getTick(), lastAction.toString(), stepResult.getReward(), stepResult.getInfo(), antWorld.getAnt().getPoints(), antWorld.getAnt().hasFood())); | ||||
| 
 | ||||
|         repaint(); | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue