2-APL UPC project.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 1110 lines 29 kB view raw
1 package blockworld; 2 3/* 4 3APL Blockworld program by Jelle Herold, copyright 2003. 5 Written for the Intelligent Systems group at Utrecht University. 6 This is LGPL software. 7 8 $Id: Env.java,v 1.7 2004/12/27 02:22:41 cvs-3apl Exp $ 9 */ 10 11// 2APL imports 12import apapl.Environment; 13import apapl.ExternalActionFailedException; 14import apapl.data.*; 15 16// Standard java imports 17import java.awt.Point; 18import java.util.Collection; 19import java.util.Iterator; 20import java.util.List; 21import java.util.Vector; 22import java.util.LinkedList; 23import javax.swing.SwingUtilities; 24import java.awt.Dimension; 25import java.util.ArrayList; 26import java.util.HashMap; 27 28import java.io.IOException; 29import java.io.InputStream; 30import java.io.ObjectInputStream; 31import java.io.ObjectOutputStream; 32import java.io.OutputStream; 33 34import blockworld.lib.ObsVectListener; 35import blockworld.lib.Signal; 36import blockworld.lib.ObsVect; 37 38public class Env extends Environment implements ObsVectListener 39{ 40 // To hold our reference to the window 41 final protected Window m_window; 42 43 // max distance of cells visible to each agent 44 protected int _senserange = 5; 45 46 // size of environment 47 protected Dimension m_size = new Dimension( 16, 16 ); 48 49 private HashMap<String,Agent> agentmap = new HashMap<String,Agent>(); 50 51 /* ---- ALL the stuff in the environment -----*/ 52 53 // list of agents (Agent) 54 protected ObsVect _agents = new ObsVect( this ); 55 // location of bomb traps 56 protected ObsVect _traps = new ObsVect(); 57 // list of coordinates (Point) containing stones 58 protected ObsVect _stones = new ObsVect(); 59 // list of coordinates (Point) containing bombs 60 protected ObsVect _bombs = new ObsVect(); 61 // id for identifiable objects 62 protected String _objType = "default"; 63 64 /* ------------------------------------------*/ 65 66 67 /* ---- SIGNALS -------------------------------*/ 68 // / emitted on collection of a bomb in the bomb trap 69 public transient Signal signalBombTrapped = new Signal( "env bomb trapped" ); 70 71 public transient Signal signalSenseRangeChanged = new Signal( 72 "env sense range changed" ); 73 74 // emitted if environment is resized 75 public transient Signal signalSizeChanged = new Signal( "env size changed" ); 76 77 // emitted if bomb traps location changed 78 public transient Signal signalTrapChanged = new Signal( 79 "env trap position changed" ); 80 81 /* ------------------------------------------*/ 82 83 84 // The default constructor 85 public Env() 86 { 87 super(); 88 // Create the window 89 m_window = new Window( this ); 90 } 91 92 /* Called from 2APL */ 93 94 // Enter the agent into the world 95 // Succesful returns true, else the ExternalActionFailedException exception is thrown 96 public Term enter( String sAgent, APLNum xt, APLNum yt, APLIdent colort) throws ExternalActionFailedException 97 { 98 int x = xt.toInt(); 99 int y = yt.toInt(); 100 String color = colort.toString(); 101 102 // Get the agent 103 Agent agent = getAgent(sAgent); 104 105 // Give a signal that we want to move 106 agent.signalMove.emit(); 107 108 writeToLog( "Agent entered: " +agent.getName()); 109 110 Point position = new Point(x,y); 111 String pos = "("+x+","+y+")"; 112 113 // Agent already entered 114 if( agent.isEntered() ) 115 { 116 writeToLog( "agent already entered" ); 117 throw new ExternalActionFailedException("Agent \""+agent.getName()+"\" has already entered."); 118 } 119 120 // Is this position within the world? 121 if (isOutOfBounds(position)) 122 { 123 throw new ExternalActionFailedException("Position "+pos+" out of bounds."); 124 } 125 // Is this position free? 126 if( !isFree( position ) ) 127 { 128 throw new ExternalActionFailedException("Position "+pos+" is not free."); 129 } 130 131 // Update the agent his position 132 agent._position = position; 133 134 // Which color does the agent want to be 135 int nColorID = getColorID(color); 136 agent._colorID = nColorID; 137 138 // Redraw so we can see the agent 139 validatewindow(); 140 m_window.repaint(); 141 142 // We came so far, this means success! 143 agent.signalMoveSucces.emit(); 144 145 return wrapBoolean(true); 146 } 147 148 // Move the agent north 149 public Term north(String sAgent) throws ExternalActionFailedException 150 { 151 // Get the correct agent 152 Agent agent = getAgent(sAgent); 153 154 // Get the agent his position 155 Point p = (Point) agent.getPosition().clone(); 156 p.y = p.y - 1; 157 158 // Set the position for the agent 159 boolean r = setAgentPosition( agent, p); 160 161 // can't move north 162 if (!r) throw new ExternalActionFailedException("Moving north failed."); 163 164 // Redraw the window 165 validatewindow(); 166 m_window.repaint(); 167 return wrapBoolean(r); 168 } 169 170 // Move the agent east 171 public Term east(String sAgent) throws ExternalActionFailedException 172 { 173 // Get the correct agent 174 Agent agent = getAgent(sAgent); 175 176 // Get the agent his position 177 Point p = (Point) agent.getPosition().clone(); 178 p.x = p.x + 1; 179 180 // Set the position for the agent 181 boolean r = setAgentPosition( agent, p); 182 183 // can't move north 184 if (!r) throw new ExternalActionFailedException("Moving north failed."); 185 186 // Redraw the window 187 validatewindow(); 188 m_window.repaint(); 189 return wrapBoolean(r); 190 } 191 192 // Move the agent south 193 public Term south(String sAgent) throws ExternalActionFailedException 194 { 195 // Get the correct agent 196 Agent agent = getAgent(sAgent); 197 198 // Get the agent his position 199 Point p = (Point) agent.getPosition().clone(); 200 p.y = p.y + 1; 201 202 // Set the position for the agent 203 boolean r = setAgentPosition( agent, p); 204 205 // can't move north 206 if (!r) throw new ExternalActionFailedException("Moving north failed."); 207 208 // Redraw the window 209 validatewindow(); 210 m_window.repaint(); 211 return wrapBoolean(r); 212 } 213 214 // Move the agent west 215 public Term west(String sAgent) throws ExternalActionFailedException 216 { 217 // Get the correct agent 218 Agent agent = getAgent(sAgent); 219 220 // Get the agent his position 221 Point p = (Point) agent.getPosition().clone(); 222 p.x = p.x - 1; 223 224 // Set the position for the agent 225 boolean r = setAgentPosition( agent, p); 226 227 // can't move north 228 if (!r) throw new ExternalActionFailedException("Moving north failed."); 229 230 // Redraw the window 231 validatewindow(); 232 m_window.repaint(); 233 return wrapBoolean(r); 234 } 235 236 // Pickup a bomb 237 public Term pickup( String sAgent ) throws ExternalActionFailedException 238 { 239 // Get the agent 240 Agent agent = getAgent(sAgent); 241 242 // Let everyone know we are going to pick up a bomb 243 agent.signalPickupBomb.emit(); 244 245 // see if we are not already carrying a bomb 246 if( agent.atCapacity() ) 247 { 248 writeToLog( "Pickup bomb failed" ); 249 throw new ExternalActionFailedException("Pickup bomb failed"); 250 } 251 252 // we are not already carying a bomb so get this one 253 TypeObject bomb = removeBomb( agent.getPosition() ); 254 if( bomb == null ) 255 { 256 writeToLog( "Pickup bomb failed" ); 257 throw new ExternalActionFailedException("Pickup bomb failed"); 258 } 259 260 // Yes 261 agent.signalPickupBombSucces.emit(); 262 263 // there was a bomb at that position, so set token 264 agent.pickBomb(bomb); 265 266 // show what happened 267 validatewindow(); 268 m_window.repaint(); 269 270 return wrapBoolean(true); 271 } 272 273 // Drop a bomb 274 public Term drop( String sAgent ) throws ExternalActionFailedException 275 { 276 // Get the agent 277 Agent agent = getAgent(sAgent); 278 // we are going to drop a bomb 279 agent.signalDropBomb.emit(); 280 281 TypeObject bomb = agent.senseBomb(); 282 // see if we are actually carrying a bomb 283 if( bomb == null) 284 { 285 writeToLog( "Drop bomb failed" ); 286 throw new ExternalActionFailedException("Drop bomb failed"); 287 } 288 289 Point pos = agent.getPosition(); 290 // see if we can drop that bomb here 291 292 if( !addBomb(pos) && (isTrap( pos ) == null 293 || agent.senseBomb( isTrap( pos ).getType() ) == null) ) 294 { 295 writeToLog( "Drop bomb failed" ); 296 throw new ExternalActionFailedException("Drop bomb failed"); 297 } 298 299 if(isTrap( pos ) != null 300 && agent.senseBomb( isTrap( pos ).getType() ) != null) 301 { 302 signalBombTrapped.emit(); 303 } 304 305 // unset token 306 agent.dropBomb(); 307 308 agent.signalDropBombSucces.emit(); 309 310 // Show it 311 validatewindow(); 312 m_window.repaint(); 313 314 // return success 315 return wrapBoolean(true); 316 } 317 318 // What is the agent his Sense Range 319 public Term getSenseRange(String agent) 320 { 321 // the below function is also used by EnvView 322 int r = getSenseRange(); 323 return new APLList(new APLNum(r)); 324 } 325 326 // Sense all agents. This does not include self. 327 public synchronized Term senseAllAgent(String sAgent) throws ExternalActionFailedException 328 { 329 //Collection c = senseAllAgents(getAgent(agent).getPosition()); 330 Point position = getAgent(sAgent).getPosition(); 331 // iterate over all agents 332 Vector all = new Vector(); 333 334 Iterator j = _agents.iterator(); 335 while( j.hasNext() ) { 336 Agent agent = (Agent) j.next(); 337 Point p = agent.getPosition(); 338 339 // Changed SA: when there are no other agents, this return null, which 340 // causes Java to throw an exception and never return the empty list. 341 if (p == null) 342 continue; 343 344 // skip self 345 if( p.equals( position ) ) 346 continue; 347 348 all.add( agent ); 349 } 350 351 LinkedList<Term> listpar = new LinkedList<Term>(); 352 for(Object i : all) { 353 final Agent a = (Agent) i; 354 APLListVar tmp = new APLList(new APLIdent(a.getName()),new APLNum(a.getPosition().x),new APLNum(a.getPosition().y)); 355 listpar.add(tmp); 356 } 357 return new APLList(listpar); 358 } 359 360 // Sense the given agent his position 361 public synchronized Term sensePosition(String sAgent) throws ExternalActionFailedException 362 { 363 Point p = getAgent(sAgent).getPosition(); 364 return new APLList(new APLNum(p.x),new APLNum(p.y)); 365 } 366 367 // is there a trap in the senserange of the agent? 368 public synchronized Term senseTraps(String agent) throws ExternalActionFailedException 369 { 370 // Get the agent his position 371 Point position = getAgent(agent).getPosition(); 372 373 // iterate over all traps and decide according to distance if it is in 374 // vision range 375 Vector visible = new Vector(); 376 377 Iterator i = _traps.iterator(); 378 while( i.hasNext() ) { 379 TypeObject t = (TypeObject) i.next(); 380 if( position.distance( t.getPosition() ) <= _senserange ) 381 visible.add( t ); 382 } 383 384 return convertCollectionToTerm(visible); 385 } 386 387 // Get all the traps in the env 388 public synchronized Term senseAllTraps(String agent) 389 { 390 // iterate over all traps 391 Vector all = new Vector(); 392 393 Iterator i = _traps.iterator(); 394 while( i.hasNext() ) 395 { 396 all.add( (TypeObject) i.next() ); 397 } 398 399 return convertCollectionToTerm(all); 400 } 401 402 // Sends a bom in the senserange of the agent 403 public synchronized Term senseBombs(String agent) throws ExternalActionFailedException 404 { 405 // Get the agent his position 406 Point position = getAgent(agent).getPosition(); 407 408 // iterate over all bombs and decide according to distance if it is in 409 // vision range 410 Vector visible = new Vector(); 411 412 Iterator i = _bombs.iterator(); 413 while( i.hasNext() ) 414 { 415 TypeObject b = (TypeObject) i.next(); 416 if( position.distance( b.getPosition() ) <= _senserange ) 417 visible.add( b ); 418 } 419 420 return convertCollectionToTerm(visible); 421 } 422 423 // Find all the bombs in the environment 424 public synchronized Term senseAllBombs (String agent) 425 { 426 // iterate over all bombs 427 Vector all = new Vector(); 428 429 Iterator i = _bombs.iterator(); 430 while( i.hasNext() ) 431 { 432 all.add( (TypeObject) i.next() ); 433 } 434 435 return convertCollectionToTerm(all); 436 } 437 438 // Sense the stones in the agent senserange 439 public synchronized Term senseStones(String agent) throws ExternalActionFailedException 440 { 441 // Get the agent his position 442 Point position = getAgent(agent).getPosition(); 443 444 // iterate over all stones and decide according to distance if it is in 445 // vision range 446 Vector visible = new Vector(); 447 448 Iterator i = _stones.iterator(); 449 while( i.hasNext() ) 450 { 451 TypeObject t = (TypeObject) i.next(); 452 if( position.distance( t.getPosition() ) <= _senserange ) 453 visible.add( t ); 454 } 455 456 return convertCollectionToTerm(visible); 457 } 458 459 // Sense all stones 460 public synchronized Term senseAllStones (String agent) 461 { 462 // iterate over all traps 463 Vector all = new Vector(); 464 465 Iterator i = _stones.iterator(); 466 while( i.hasNext() ) 467 { 468 all.add( (TypeObject) i.next() ); 469 } 470 471 return convertCollectionToTerm(all); 472 } 473 474 // Sense visible area for agents. This does not include self. 475 public synchronized Term senseAgent(String sAgent) throws ExternalActionFailedException 476 { 477 //Collection c = senseAgents(getAgent(agent).getPosition()); 478 Point position = getAgent(sAgent).getPosition(); 479 480 // iterate over all agents and decide according to distance if it is in 481 // vision range 482 Vector visible = new Vector(); 483 484 Iterator j = _agents.iterator(); 485 486 while( j.hasNext() ) 487 { 488 Agent agent = (Agent) j.next(); 489 490 Point p = agent.getPosition(); 491 492 // Changed SA: when there are no other agents, this return null, which 493 // causes Java to throw an exception and never return the empty list. 494 if (p == null) 495 continue; 496 497 // skip self 498 if( p.equals( position ) ) 499 continue; 500 501 // agent within visible range 502 if( position.distance( p ) <= _senserange ) 503 visible.add( agent ); 504 } 505 506 LinkedList<Term> listpar = new LinkedList<Term>(); 507 for(Object i : visible) { 508 final Agent a = (Agent) i; 509 APLListVar tmp = new APLList(new APLIdent(a.getName()),new APLNum(a.getPosition().x),new APLNum(a.getPosition().y)); 510 listpar.add(tmp); 511 } 512 return new APLList(listpar); 513 } 514 515 516 517 /* Standard functions --------------------------------------*/ 518 519 private void notifyAgents(APLFunction event, String... receivers) { 520 throwEvent(event, receivers); 521 } 522 523 private void notifyEvent(String parm1, Point ptPosition) 524 { 525 APLNum nX = new APLNum((double)(ptPosition.getX())); 526 APLNum nY = new APLNum((double)(ptPosition.getY())); 527 528 // Send an external event to all agents within the senserange. 529 ArrayList<String> targetAgents = new ArrayList<String>(); 530 for (Agent a : agentmap.values()) 531 { 532 // Changed SA: I got no idea why there is always 1 agent which does not exists, 533 // but this fixes the exceptions 534 if ((a.getPosition() != null) && (ptPosition.distance(a.getPosition()) <= getSenseRange())) 535 targetAgents.add(a.getName()); 536 } 537 538 writeToLog("EVENT: "+parm1+"("+nX+","+nY+")"+" to "+targetAgents); 539 540 if (!targetAgents.isEmpty()) 541 { 542 notifyAgents(new APLFunction(parm1,nX,nY),targetAgents.toArray(new String[0])); 543 } 544 } 545 546 // Add an agent to the environment 547 public synchronized void addAgent(String sAgent) { 548 String sAgentMain = getMainModule(sAgent); 549 // Agent not yet in the environment 550 if (agentmap.keySet().contains(sAgentMain)) { 551 agentmap.put(sAgent,agentmap.get(sAgentMain)); 552 writeToLog("linking " + sAgent + ""); 553 } else{ 554 final Agent agent = new Agent(sAgentMain); 555 _agents.add(agent); 556 agentmap.put(sAgent, agent); 557 writeToLog("agent " + agent + " added"); 558 } 559 } 560 561 // Remove the agent from the environment 562 public synchronized void removeAgent(String sAgent) 563 { 564 try 565 { 566 //String sAgentMain = getMainModule(sAgent); 567 568 Agent a = getAgent(sAgent); 569 agentmap.remove( sAgent ); 570 571 // there can be several agent 572 if (!agentmap.containsValue(a)) { 573 _agents.remove(a); 574 a.reset(); 575 } 576 577 writeToLog("Agent removed: " + sAgent); 578 579 synchronized( this ) 580 { 581 notifyAll(); 582 } 583 } 584 catch (ExternalActionFailedException e) {} 585 } 586 587 /* END Standard functions --------------------------------------*/ 588 589 590 591 592 /* Helper functions --------------------------------------*/ 593 594 // Get the size of the blockworld 595 public synchronized Term getWorldSize(String agent) 596 { 597 int w = getWidth(); 598 int h = getHeight(); 599 return new APLList(new APLNum(w),new APLNum(h)); 600 } 601 602 // Get the agent from its name 603 private synchronized Agent getAgent(String name) throws ExternalActionFailedException 604 { 605 Agent a = null; 606 //a = agentmap.get(getMainModule(name)); 607 a = agentmap.get(name); 608 if (a==null) throw new ExternalActionFailedException("No such agent: "+name); 609 else return a; 610 611 } 612 613 private static String getMainModule(String sAgent) 614 { 615 int dotPos; 616 if ((dotPos = sAgent.indexOf('.')) == -1) 617 return sAgent; 618 else 619 return sAgent.substring(0, dotPos); 620 } 621 622 // Get the environment width 623 public synchronized int getWidth() { return m_size.width; } 624 625 // Get the environment height 626 public synchronized int getHeight() { return m_size.height; } 627 628 // Return the agents 629 public synchronized Collection getBlockWorldAgents() 630 { 631 return new Vector(_agents); 632 } 633 634 // convert a collection to a term 635 private static Term convertCollectionToTerm(Collection c) 636 { 637 LinkedList<Term> listpar = new LinkedList<Term>(); 638 for(Object i : c) { 639 final TypeObject o = (TypeObject) i; 640 APLListVar tmp = new APLList(new APLIdent(o.getType()),new APLNum(o.getPosition().x),new APLNum(o.getPosition().y)); 641 listpar.add(tmp); 642 } 643 return new APLList(listpar); 644 } 645 646 // Get senserange 647 public int getSenseRange() 648 { 649 return _senserange; 650 } 651 652 // Redrawing the window is a nightmare, this does some redraw stuff 653 private void validatewindow() 654 { 655 Runnable repaint = new Runnable() 656 { 657 public void run() 658 { 659 //try {Thread.sleep(500);} catch(Exception e) {} 660 m_window.doLayout(); 661 662 /*if (!m_window.isVisible()) 663 { 664 m_window.setVisible( true ); 665 }*/ 666 } 667 }; 668 SwingUtilities.invokeLater(repaint); 669 } 670 671 // Move the agent 672 private synchronized boolean setAgentPosition( Agent agent, Point position) 673 { 674 agent.signalMove.emit(); 675 676 if( isOutOfBounds( position ) ) 677 return false; 678 679 // suspend thread if some other agent is blocking our entrance 680 681 // Is the position free? 682 if( !isFree( position ) ) 683 return false; 684 685 agent.signalMoveSucces.emit(); 686 687 // there may be other threads blocked because this agent was in the way, 688 // notify 689 // them of the changed state of environment 690 synchronized( this ) 691 { 692 notifyAll(); 693 } 694 695 // set the agent position 696 agent._position = position; 697 return true; 698 } 699 700 // check if point is within environment boundaries 701 // return false is p is within bounds 702 protected boolean isOutOfBounds( Point p ) 703 { 704 if( (p.x >= m_size.getWidth()) || (p.x < 0) || (p.y >= m_size.getHeight()) || (p.y < 0) ) 705 { 706 return true; 707 } 708 709 return false; 710 } 711 712 // Is the position free? 713 public synchronized boolean isFree( final Point position ) 714 { 715 return (isStone( position )) == null && (isAgent( position ) == null); 716 } 717 718 // Check for agent at coordinate. \return Null if there is no agent at the 719 // specified coordinate. Otherwise return a reference to the agent there. 720 public synchronized Agent isAgent( final Point p ) 721 { 722 synchronized (_agents) { 723 Iterator i = _agents.iterator(); 724 while( i.hasNext() ) { 725 final Agent agent = (Agent) i.next(); 726 if( p.equals( agent.getPosition() ) ) 727 return agent; 728 } 729 return null; 730 } 731 } 732 733 // Is there a stone at this point 734 public synchronized TypeObject isStone( Point p ) 735 { 736 synchronized (_agents) { 737 Iterator i = _stones.iterator(); 738 while( i.hasNext() ) { 739 TypeObject stones = (TypeObject) i.next(); 740 if( p.equals( stones.getPosition() ) ) 741 return stones; 742 } 743 return null; 744 } 745 } 746 747 // see if there is a trap at the specified coordinate 748 public synchronized TypeObject isTrap( Point p ) { 749 synchronized (_traps) { 750 Iterator i = _traps.iterator(); 751 while( i.hasNext() ) { 752 TypeObject trap = (TypeObject) i.next(); 753 if( p.equals( trap.getPosition() ) ) 754 return trap; 755 } 756 return null; 757 } 758 } 759 760 public synchronized TypeObject isBomb( Point p ) 761 { 762 synchronized (_bombs) { 763 Iterator i = _bombs.iterator(); 764 while( i.hasNext() ) { 765 TypeObject bomb = (TypeObject)i.next(); 766 if(p.equals(bomb.getPosition())) 767 return bomb; 768 } 769 return null; 770 } 771 } 772 773 // Remove bomb at position TODO Jaap; why is this different then remove stone??? 774 public synchronized TypeObject removeBomb( Point position ) 775 { 776 // find bomb in bombs list 777 synchronized(this) { 778 Iterator i = _bombs.iterator(); 779 while (i.hasNext()) 780 { 781 TypeObject bomb = (TypeObject) i.next(); 782 if (position.equals(bomb.getPosition())) 783 { 784 i.remove(); 785 return bomb; 786 } 787 } 788 } 789 790 notifyEvent("bombRemovedAt", position); 791 return null; 792 793 } 794 795 // remove stone at position 796 public synchronized boolean removeStone( Point position ) 797 { 798 synchronized(_stones) { 799 // find stone in stones list 800 Iterator i = _stones.iterator(); 801 while (i.hasNext()) 802 //if( position.equals( i.next() ) ) { 803 // Changed SA: 804 if (position.equals(((TypeObject)i.next()).getPosition())) 805 { 806 i.remove(); 807 808 // there may be other threads blocked because this agent was in 809 // the way, notify 810 // them of the changed state of environment 811 synchronized( this ) 812 { 813 notifyAll(); 814 } 815 816 return true; 817 } 818 } 819 notifyEvent("wallRemovedAt", position); 820 return false; 821 } 822 823 // remove trap at position 824 public synchronized boolean removeTrap( Point position ) 825 { 826 synchronized(_traps) { 827 // find trap in traps list 828 Iterator i = _traps.iterator(); 829 while (i.hasNext()) { 830 if (position.equals(((TypeObject)i.next()).getPosition())) 831 { 832 i.remove(); 833 834 835 // Sohan: I believe this notification is unnecessary, commented it out: 836 //synchronized( this ) { 837 // notifyAll(); 838 //} 839 840 return true; 841 } 842 } 843 } 844 845 notifyEvent("trapRemovedAt", position); 846 return false; 847 } 848 849 // Add a stone at the given position 850 public synchronized boolean addStone( Point position ) throws IndexOutOfBoundsException 851 { 852 // valid coordinate 853 if( isOutOfBounds( position ) ) 854 throw new IndexOutOfBoundsException( "setStone out of range: " 855 + position + ", " + m_size ); 856 857 // is position clear of other stuff 858 // Changed SA: 859 if( isBomb( position ) != null || isStone( position ) != null || isTrap( position ) != null ) 860 return false; 861 862 synchronized (_stones) { 863 _stones.add( new TypeObject(_objType,position) ); 864 } 865 notifyEvent("wallAt", position); 866 867 return true; 868 } 869 870 // Add a bomb to the environment 871 public synchronized boolean addBomb( Point position ) throws IndexOutOfBoundsException 872 { 873 if( isOutOfBounds( position ) ) 874 throw new IndexOutOfBoundsException( "addBomb outOfBounds: " 875 + position + ", " + m_size ); 876 877 // is position clear of other stuff 878 if( isBomb( position ) != null || isStone( position ) != null || isTrap( position ) != null ) 879 return false; 880 881 // all clear, accept bomb 882 synchronized (_bombs) { 883 _bombs.add( new TypeObject(_objType,position) ); 884 } 885 notifyEvent("bombAt", position); 886 887 return true; 888 } 889 890 // Add a trap at the given position 891 public synchronized boolean addTrap( Point position ) throws IndexOutOfBoundsException { 892 // valid coordinate 893 if( isOutOfBounds( position ) ) 894 throw new IndexOutOfBoundsException( "setTrap out of range: " 895 + position + ", " + m_size ); 896 897 // is position clear of other stuff 898 // Changed SA: 899 if( isBomb( position ) != null || isStone( position ) != null || isTrap( position ) != null ) 900 return false; 901 synchronized(_traps) { 902 _traps.add( new TypeObject(_objType,position) ); 903 } 904 notifyEvent("trapAt", position); 905 906 return true; 907 } 908 909 // Print a message to the console 910 static public void writeToLog(String message) { 911 //System.out.println("blockworld: " + message); 912 } 913 914 // helper function to wrap a boolean value inside a ListPar. 915 static public APLListVar wrapBoolean( boolean b ) 916 { 917 return new APLList(new APLIdent(b ? "true" : "false")); 918 } 919 920 // Which color does the agent want to be! 921 private int getColorID(String sColor) 922 { 923 if (sColor.equals("army") ) 924 { 925 return 0; 926 } 927 else if (sColor.equals("blue") ) 928 { 929 return 1; 930 } 931 else if (sColor.equals("gray") ) 932 { 933 return 2; 934 } 935 else if (sColor.equals("green") ) 936 { 937 return 3; 938 } 939 else if (sColor.equals("orange") ) 940 { 941 return 4; 942 } 943 else if (sColor.equals("pink") ) 944 { 945 return 5; 946 } 947 else if (sColor.equals("purple") ) 948 { 949 return 6; 950 } 951 else if (sColor.equals("red") ) 952 { 953 return 7; 954 } 955 else if (sColor.equals("teal") ) 956 { 957 return 8; 958 } 959 else if (sColor.equals("yellow") ) 960 { 961 return 9; 962 } 963 964 // Red is the default 965 return 7; 966 } 967 968 // Set the senserange 969 public void setSenseRange( int senserange ) 970 { 971 _senserange = senserange; 972 signalSenseRangeChanged.emit(); 973 } 974 975 // helper function, calls setSize(Dimension) 976 public void setSize( int width, int height ) 977 { 978 setSize( new Dimension( width, height ) ); 979 } 980 981 // resize world 982 public void setSize( Dimension size ) 983 { 984 m_size = size; 985 signalSizeChanged.emit(); 986 987 Iterator i = _bombs.iterator(); 988 while( i.hasNext() ) { 989 if( isOutOfBounds( ((TypeObject) i.next()).getPosition() ) ) 990 i.remove(); 991 } 992 i = _stones.iterator(); 993 while( i.hasNext() ) { 994 if( isOutOfBounds( (Point) i.next() ) ) 995 i.remove(); 996 } 997 i = _traps.iterator(); 998 while( i.hasNext() ) { 999 if( isOutOfBounds( ((TypeObject) i.next()).getPosition() ) ) 1000 i.remove(); 1001 } 1002 } 1003 1004 // what kind of object is it, bomb, stone, wall ? 1005 public String getObjType() 1006 { 1007 return _objType; 1008 } 1009 1010 // what kind of object is it, bomb, stone, wall ? 1011 public void setObjType(String objType) 1012 { 1013 _objType = objType; 1014 } 1015 1016 // Remove everything 1017 public void clear() 1018 { 1019 _stones.removeAllElements(); 1020 _bombs.removeAllElements(); 1021 _traps.removeAllElements(); 1022 } 1023 1024 // Save the environment 1025 public void save( OutputStream destination ) throws IOException 1026 { 1027 ObjectOutputStream stream = new ObjectOutputStream( destination ); 1028 stream.writeObject( m_size ); 1029 1030 stream.writeInt( _senserange ); 1031 1032 stream.writeObject( (Vector) _stones ); 1033 stream.writeObject( (Vector) _bombs ); 1034 stream.writeObject( (Vector) _traps ); 1035 stream.flush(); 1036 } 1037 1038 // Load the environment 1039 public void load( InputStream source ) throws IOException, ClassNotFoundException 1040 { 1041 ObjectInputStream stream = new ObjectInputStream( source ); 1042 Dimension size = (Dimension) stream.readObject(); 1043 1044 int senserange = stream.readInt(); 1045 1046 Vector stones = (Vector) stream.readObject(); 1047 Vector bombs = (Vector) stream.readObject(); 1048 Vector traps = (Vector) stream.readObject(); 1049 1050 // delay assignments until complete load is succesfull 1051 m_size = size; 1052 _senserange = senserange; 1053 1054 signalSizeChanged.emit(); 1055 signalTrapChanged.emit(); 1056 signalSenseRangeChanged.emit(); 1057 1058 clear(); 1059 1060 _stones.addAll( stones ); 1061 _bombs.addAll( bombs ); 1062 _traps.addAll( traps ); 1063 } 1064 1065 /* END Helper functions --------------------------------------*/ 1066 1067 /* Listeners ------------------------------------------------*/ 1068 1069 // / This listener is notified upon changes regarding the Agent list. 1070 // / Please note that this only involves registering new agents or 1071 // / removing existing agents. To track agent position changes, add 1072 // / a listener to that specific agent. 1073 // / \sa Agent 1074 public void addAgentListener( ObsVectListener o ) 1075 { 1076 _agents.addListener( o ); 1077 } 1078 1079 // / This listener is notified upon changes regarding the Stones list. 1080 public void addStonesListener( ObsVectListener o ) 1081 { 1082 _stones.addListener( o ); 1083 } 1084 1085 // / This listener is notified upon changes regarding the Bombs list. 1086 public void addBombsListener( ObsVectListener o ) 1087 { 1088 _bombs.addListener( o ); 1089 } 1090 1091 // / This listener is notified upon changes regarding the Traps list. 1092 public void addTrapsListener( ObsVectListener o ) 1093 { 1094 _traps.addListener( o ); 1095 } 1096 1097 /* END Liseteners ------------------------------------------*/ 1098 1099 1100 /* Overrides for ObsVector ---------------------------------*/ 1101 1102 public void onAdd( int index, Object o ) {} 1103 1104 public void onRemove( int index, Object o ) 1105 { 1106 ((Agent) o).deleteObservers(); 1107 } 1108 1109 /* END Overrides for ObsVector ---------------------------------*/ 1110}