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