예제 #1
1
  /**
   * Method to read in a vector layer
   *
   * @param layer
   * @param filename
   * @param layerDescription
   * @param attributes - optional: include only the given attributes
   */
  synchronized void readInVectorLayer(
      GeomVectorField layer, String filename, String layerDescription, Bag attributes) {
    try {
      System.out.print("Reading in " + layerDescription + "from " + filename + "...");
      File file = new File(filename);
      if (attributes == null || attributes.size() == 0) ShapeFileImporter.read(file.toURL(), layer);
      else ShapeFileImporter.read(file.toURL(), layer, attributes);
      System.out.println("done");

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
예제 #2
0
  private School findAppropriateSchool(int age, Point location) {
    GeomVectorField zones;
    if (age < 11) {
      zones = elementarySchoolZones;
    } else if (age < 15) {
      zones = middleSchoolZones;
    } else {
      zones = highSchoolZones;
    }

    Bag catchment = zones.getContainingObjects(location);

    if (catchment.numObjs != 1) {
      System.out.format(
          "Error: school search (age: %d, location: %s) found %d catchments.\n",
          age, location, catchment.numObjs);
      for (int i = 0; i < catchment.numObjs; i++) {
        System.out.format(
            "    Catchment %d: %s\n",
            i, ((MasonGeometry) catchment.get(i)).getAttribute("SCHID_3"));
      }
      return null;
    }

    MasonGeometry mg = (MasonGeometry) catchment.get(0);
    Integer num = mg.getIntegerAttribute("SCHOOL_NUM");

    return schoolMap.get(num);
  }
 private void assignStudent(Student s) {
   for (int y = 0; y < dorms.size(); y++) {
     if (s.hasRoom()) {
       break;
     }
     Dorm d = (Dorm) dorms.get(y);
     if (d.isFull()) {
       continue;
     }
     if (d.isFemaleOnly() && s.getGender() == Student.Gender.MALE) {
       continue;
     }
     int i = 0;
     while (i < d.getNumRooms()) {
       if (s.hasRoom()) {
         break;
       }
       try {
         d.getRoomByIndex(i).addResident(s);
       } catch (IllegalArgumentException e) {
       }
       i++;
     }
   }
 }
예제 #4
0
  private void addAgents() {
    // Agent a = null;

    for (int i = 0; i < NUM_AGENTS; i++) {
      // pick a random political region to plop the agent in
      Bag allRegions = county.getGeometries();

      if (allRegions.isEmpty()) {
        // Something went wrong.  We *should* have regions.
        throw new RuntimeException("No regions found.");
      }
      MasonGeometry region = ((MasonGeometry) allRegions.objs[random.nextInt(allRegions.numObjs)]);

      // give each agent a random direction to initially move in
      Agent a = new Agent(random.nextInt(8));

      // set each agent in the center of corresponding region
      a.setLocation(region.getGeometry().getCentroid());

      // place the agents in the GeomVectorField
      agents.addGeometry(new MasonGeometry(a.getGeometry()));

      // add the new agent the schedule
      schedule.scheduleRepeating(a);
    }
  }
예제 #5
0
  /**
   * populate network with lines from a GeomVectorField
   *
   * @param field containing line segments
   *     <p>Assumes that 'field' contains co-planar linear objects
   */
  public void createFromGeomField(GeomVectorField field) {
    Bag geometries = field.getGeometries();

    for (int i = 0; i < geometries.numObjs; i++) {
      if (((MasonGeometry) geometries.get(i)).geometry instanceof LineString) {
        addLineString((MasonGeometry) geometries.get(i));
      }
    }

    // Abandoned work on rectifying non-planar data. MAC 8/24/10.
    //        field.clear();
    //
    //        Collection<LineString> lines = lineMerger.getMergedLineStrings();
    //
    //        PrecisionModel pm = new PrecisionModel(PrecisionModel.FLOATING);
    //
    //        GeometryNoder noder = new GeometryNoder(pm);
    //
    //        Collection<LineString> more_lines = noder.node(lines);
    //
    //        // Now add nodes and edges to graph
    //
    //        for (LineString line : more_lines)
    //        {
    //            addLineString(line);
    //            field.addGeometry(new MasonGeometry(line));
    // }

  }
  /** Used to find the global attributes that another inspector has set so I can share it. */
  ChartGenerator chartToUse(final String sName, Frame parent, final GUIState simulation) {
    Bag charts = new Bag();
    if (simulation.guiObjects != null)
      for (int i = 0; i < simulation.guiObjects.numObjs; i++)
        if (simulation.guiObjects.objs[i] instanceof ChartGenerator
            && validChartGenerator((ChartGenerator) (simulation.guiObjects.objs[i])))
          charts.add(simulation.guiObjects.objs[i]);
    if (charts.numObjs == 0) return createNewChart(simulation);

    // init the dialog panel
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());

    String[] chartNames = new String[charts.numObjs + 1];

    chartNames[0] = "[Create a New Chart]";
    for (int i = 0; i < charts.numObjs; i++)
      chartNames[i + 1] = ((ChartGenerator) (charts.objs[i])).getTitle();

    // add widgets
    JPanel panel2 = new JPanel();
    panel2.setLayout(new BorderLayout());
    panel2.setBorder(new javax.swing.border.TitledBorder("Plot on Chart..."));
    JComboBox encoding = new JComboBox(chartNames);
    panel2.add(encoding, BorderLayout.CENTER);
    p.add(panel2, BorderLayout.SOUTH);

    // ask
    if (JOptionPane.showConfirmDialog(
            parent, p, "Create a New Chart...", JOptionPane.OK_CANCEL_OPTION)
        != JOptionPane.OK_OPTION) return null;

    if (encoding.getSelectedIndex() == 0) return createNewChart(simulation);
    else return (ChartGenerator) (charts.objs[encoding.getSelectedIndex() - 1]);
  }
예제 #7
0
 public double[] getAgitationDistribution() {
   Bag students = buddies.getAllNodes();
   double[] distro = new double[students.numObjs];
   int len = students.size();
   for (int i = 0; i < len; i++) distro[i] = ((Student) (students.get(i))).getAgitation();
   return distro;
 }
예제 #8
0
  public void vision(SimState state, SparseGrid2D grid) {
    // System.out.println("Direction: " + direction);
    // Visual Processor

    Int2D cord = grid.getObjectLocation(this);
    assert (vP != null && cord != null);
    assert (direction != 0);
    // System.out.println(this + "was at location: " + cord);
    if (cord != null) {
      seen = vP.sight(cord.x, cord.y, state, direction);
      Bag locations = new Bag();

      // Testing Print Statements
      for (int s = 0; s < seen.size(); s++) {
        Object j = seen.get(s);
        // System.out.print(s + "saw " + seen.get(s));
        Int2D obLoc = grid.getObjectLocation(j);
        locations.add(obLoc);
        // System.out.println(" at location:" + obLoc);
        // if(j.equals(Prey.class))
        // System.out.println("****" + seen.get(s));
      } // end of for loop

      this.behaviorProb(locations, seen);

      // Move every timestep
      super.move(grid, state);
    }
  } // end of vision
예제 #9
0
 public Caller(int teamNr, IntGrid2D baseMapGrid) {
   this.teamNr = teamNr;
   this.baseMapGrid = baseMapGrid;
   communicationRadius = 100;
   zeroPos = new Int2D(0, 0);
   callerNr = callers.size() + 1;
   callers.add(this);
 }
예제 #10
0
 public Furniture getFurniture(int x, int y) {
   if (x < grid.getWidth() && y < grid.getHeight()) {
     Bag b = grid.getObjectsAtLocation(x, y);
     if (b != null && b.size() > 0) {
       Cell cell = (Cell) b.get(0);
       if (cell.getValue() instanceof Furniture) {
         return (Furniture) cell.getValue();
       }
     }
   }
   return null;
 }
예제 #11
0
 private void chooseTarget() {
   if (target == null) {
     int num = callers.size();
     int tc = targets.size();
     int tspan = tc / num;
     target = (Int2D) targets.get(tspan * (callerNr - 1));
   } else {
     // check if target was already found
     if (baseMapGrid.get(target.x, target.y) != 0) {
       target = null;
       chooseTarget();
     }
   }
 }
예제 #12
0
 protected void createGrids() {
   emptySpaces.clear();
   neighbors = new IntGrid2D(gridWidth, gridHeight, 0);
   int[][] g = neighbors.field;
   for (int x = 0; x < gridWidth; x++)
     for (int y = 0; y < gridHeight; y++) {
       double d = random.nextDouble();
       if (d < redProbability) g[x][y] = RED;
       else if (d < redProbability + blueProbability) g[x][y] = BLUE;
       else if (d < redProbability + blueProbability + emptyProbability) {
         g[x][y] = EMPTY;
         emptySpaces.add(new Int2D(x, y));
       } else g[x][y] = UNAVAILABLE;
     }
 }
예제 #13
0
 private void updateBaseMap(SparseGrid2D localMap, Int2D localPos, Int2D actualPos) {
   int diffx = 0; // actualPos.x - localPos.x;
   int diffy = 0; // actualPos.y - localPos.y;
   // System.out.printf("BaseGridSize: %d,%d.\n",baseMapGrid.getWidth(),baseMapGrid.getHeight());
   // System.out.printf("Actual: %d,%d, Local: %d,%d; Diff:
   // %d,%d\n",actualPos.x,actualPos.y,localPos.x,localPos.y,diffx,diffy);
   Bag all = localMap.getAllObjects();
   for (int i = 0; i < all.size(); ++i) {
     Int2D localLoc = localMap.getObjectLocation(all.get(i));
     Int2D actualLoc = new Int2D(localLoc.x + diffx, localLoc.y + diffy);
     // System.out.printf("Bag: local: %d,%d and actual %d,%d.\n",localLoc.x,localLoc.y,
     // actualLoc.x,actualLoc.y);
     baseMapGrid.set(actualLoc.x, actualLoc.y, (Integer) ((Value) all.get(i)).get());
   }
 }
예제 #14
0
  @Override
  public void step(SimState state) {
    // System.out.println("Caller scheduled");
    updateInternalState(state);
    updatePosition();

    if (callerSteps % callers.size() == 0) {
      updateTargets(this.baseMapGrid, scale, zeroPos);
    }
    chooseTarget();
    if (target == null) {
      swarm();
    } else {
      // move to target
      boolean top = false;
      boolean left = false;
      if (target.x < pos.x) {
        left = true;
      }
      if (target.y < pos.y) {
        top = true;
      }
      // TODO
    }
    if (snr.schedule.getSteps() % 20 == 0) sendMessage(new Ping(this, (AbstractAgent) team.get(0)));
    callerSteps++;
  }
예제 #15
0
  private void countCatchments(GeomVectorField catchments) {
    Bag geoms = catchments.getGeometries();
    for (int i = 0; i < geoms.numObjs; i++) {
      MasonGeometry mg = (MasonGeometry) geoms.get(i);

      Integer num = mg.getIntegerAttribute("SCHOOL_NUM");

      if (num != null) {
        School s = schoolMap.get(num);
        if (s != null) {
          s.catchmentCount++;
        } else {
          System.out.format("School %s not found.\n", num);
        }
      }
    }
  }
예제 #16
0
  private void createSchoolsFromData(GeomVectorField schoolField) {

    Bag geoms = schoolField.getGeometries();
    for (int i = 0; i < geoms.numObjs; i++) {
      MasonGeometry mg = (MasonGeometry) geoms.get(i);

      Integer num = mg.getIntegerAttribute("SCHOOL_NUM");
      String name = mg.getStringAttribute("SCHOOL_NAM");
      String type = mg.getStringAttribute("SCHOOL_TYP");

      if (num != null) {
        School s = new School(this, name, type);
        schoolMap.put(num, s);
        schools.add(s);
      }
    }
  }
예제 #17
0
  public void start() {
    super.start();

    // clear the yard
    yard.clear();

    // clear the buddies
    buddies.clear();

    // add some students to the yard
    for (int i = 0; i < numStudents; i++) {
      Student student = new Student();
      yard.setObjectLocation(
          student,
          new Double2D(
              yard.getWidth() * 0.5 + random.nextDouble() - 0.5,
              yard.getHeight() * 0.5 + random.nextDouble() - 0.5));

      buddies.addNode(student);
      schedule.scheduleRepeating(student);
    }

    // define like/dislike relationships
    Bag students = buddies.getAllNodes();
    for (int i = 0; i < students.size(); i++) {
      Object student = students.get(i);

      // who does he like?
      Object studentB = null;
      do {
        studentB = students.get(random.nextInt(students.numObjs));
      } while (student == studentB);
      double buddiness = random.nextDouble();
      buddies.addEdge(student, studentB, new Double(buddiness));

      // who does he dislike?
      do {
        studentB = students.get(random.nextInt(students.numObjs));
      } while (student == studentB);
      buddiness = random.nextDouble();
      buddies.addEdge(student, studentB, new Double(-buddiness));
    }
  }
예제 #18
0
  private void setActive(EpsteinGrid epState) {
    boolean alreadyActive = false;

    if (this.active) alreadyActive = true;

    int activeV = 0;
    int copsV = 0;

    // Loop through all the agents within vision and count the number of active civilians and cops
    for (int i = 0; i < neighborsX.size(); i++) {
      int x = neighborsX.get(i);
      int y = neighborsY.get(i);
      Bag agents = epState.grid.getObjectsAtLocation(x, y);

      if (agents != null) {
        Agent agent;
        for (int j = 0; j < agents.size(); j++) {
          agent = (Agent) agents.get(j);

          if (agent instanceof Civilian && agent.active) {
            activeV++;
          } else if (agent instanceof Cop) {
            copsV++;
          }
        }
      }
    }

    /*Calculations for going active*/
    arrestProbability = 1 - Math.exp(-2.3 * ((copsV / (activeV + 1))));
    grievance = perceivedHardship * (1 - govtLegitimacy);
    this.active = (grievance - (riskAversion * arrestProbability)) > epState.threshold;

    if (!alreadyActive && this.active) {
      epState.activeCount++;
      epState.quietCount--;
    } else if (alreadyActive && !this.active) {
      epState.activeCount--;
      epState.quietCount++;
    }
  }
  /**
   * For each <xPos,yPos,zPos> location, puts all such objects into the result bag. Returns the
   * result bag. If the provided result bag is null, one will be created and returned.
   */
  public Bag getObjectsAtLocations(
      final IntBag xPos, final IntBag yPos, final IntBag zPos, Bag result) {
    if (result == null) result = new Bag();
    else result.clear();

    final int len = xPos.numObjs;
    final int[] xs = xPos.objs;
    final int[] ys = yPos.objs;
    final int[] zs = zPos.objs;
    for (int i = 0; i < len; i++) {
      // a little efficiency: add if we're 1, addAll if we're > 1,
      // do nothing if we're 0
      Bag temp = getObjectsAtLocation(xs[i], ys[i], zs[i]);
      if (temp != null) {
        int n = temp.numObjs;
        if (n == 1) result.add(temp.objs[0]);
        else if (n > 1) result.addAll(temp);
      }
    }
    return result;
  }
  private UpperclassHousingSelection() {

    dorms = new Bag();

    // actually mixed-year but for simplicity I'm keeping it
    // upperclassman only for now
    Dorm Arrington = new Dorm("Arrington", false, false, 74);

    Dorm Ball = new Dorm("Ball", true, false, 53);
    Dorm Custis = new Dorm("Custis", false, false, 21);
    Dorm EagleLanding = new Dorm("Eagle Landing", false, false, 312);
    Dorm Framar = new Dorm("Framar", false, false, 11);
    Dorm Madison = new Dorm("Madison", false, false, 21);
    Dorm Marshall = new Dorm("Marshall", false, false, 74);
    Dorm Mason = new Dorm("Mason", false, false, 93);
    Dorm Westmoreland = new Dorm("Westmoreland", false, false, 56);

    // Willard houses students in single rooms which is not accounted for yet
    Dorm Willard = new Dorm("Willard", false, false, 91);

    // 100 of the rooms in the aparments are singles which is not
    // accounted for yet
    Dorm Apartments = new Dorm("Apartments", false, false, 381);

    // for extraneous students who commute or live off campus
    Dorm Offcampus = new Dorm("Offcampus", false, false, 3500);

    dorms.add(Ball);
    dorms.add(Arrington);
    dorms.add(Custis);
    dorms.add(Framar);
    dorms.add(Madison);
    dorms.add(Mason);
    dorms.add(Westmoreland);
    dorms.add(Willard);
    dorms.add(Apartments);
    dorms.add(EagleLanding);
    dorms.add(Offcampus);
  }
예제 #21
0
  public void setupAgents(GeomVectorField populationLayer) {
    Bag nodeBag = majorRoadNodesLayer.getGeometries();

    int numNodes = nodeBag.size();
    for (Object o : populationLayer.getGeometries()) {
      MasonGeometry g = (MasonGeometry) o;
      Coordinate c = g.geometry.getCoordinate();
      for (int i = 0; i < 50; i++) {
        //				GeoNode gn = (GeoNode) nodeBag.get(random.nextInt(numNodes));
        //				Coordinate myHome = (Coordinate) gn.geometry.getCoordinate().clone();
        //				double distance = Math.abs(random.nextGaussian()) * 1500;
        //				double degrees = random.nextDouble() * 2 * Math.PI;
        //				double xOffset = distance * Math.cos(degrees) + c.x;
        double xOffset = random.nextGaussian() * 100 + c.x;
        //				double yOffset = distance * Math.sin(degrees) + c.y;
        double yOffset = random.nextGaussian() * 100 + c.y;
        Coordinate myHome = new Coordinate(xOffset, yOffset);
        Geometry point = fa.createPoint(myHome);
        if (!landArea.contains(point)) continue;
        HumanTeleporter hum = new HumanTeleporter("id_" + random.nextLong(), myHome, myHome, this);
        humans.add(hum);
      }
    }
  }
예제 #22
0
 private static void updateTargets(IntGrid2D baseMapGrid, int scale, Int2D zeroPos) {
   if (targets == null) {
     targets = new Bag();
   } else {
     targets.clear();
   }
   java.util.HashMap<Integer, java.util.HashSet<Integer>> starget =
       new java.util.HashMap<Integer, java.util.HashSet<Integer>>();
   for (int i = 0; i < baseMapGrid.getWidth(); ++i) {
     for (int j = 0; j < baseMapGrid.getHeight(); ++j) {
       int val = baseMapGrid.get(i, j);
       if (val == 0) {
         Int2D locPos = posToLocalMapPos(new Int2D(i, j), scale, zeroPos);
         if (!starget.containsKey(locPos.x)) {
           starget.put(locPos.x, new java.util.HashSet<Integer>());
         }
         boolean ok = starget.get(locPos.x).add(locPos.y);
         if (ok) {
           targets.add(locPos);
         }
       }
     }
   }
 }
예제 #23
0
  @Override
  public void receiveMessage(Message m) {
    if (m instanceof MapUpdate) {
      // int del = -1;
      for (int i = 0; i < teamPosition.size(); ++i) {
        Bag b = (Bag) teamPosition.get(i);
        if (((MapUpdate) m).sender.equals(((MapUpdate) b.get(0)).sender)) {
          // del = i;
          System.out.printf(
              "Newer map received from sender. Already collected %d positions.\n",
              ((Bag) teamPosition.get(i)).size() - 1);
          teamPosition.remove(i);
          break;
        }
      }
      // if (del != -1) {
      // }

      MapUpdate mu = (MapUpdate) m;
      // for position some more steps are needed -> wait for pings from sender while "traveling
      // around"
      Bag b = new Bag();
      b.add(mu);
      b.add(new Int2D(super.pos.x, super.pos.y));
      teamPosition.add(b);
    } else if (m instanceof Ping) {
      Ping p = (Ping) m;
      // Look for all teams that want to update the map
      for (int i = 0; i < teamPosition.size(); ++i) {
        Bag b = (Bag) teamPosition.get(i);
        if (p.sender.equals(((MapUpdate) b.get(0)).sender)) {
          boolean newPos = true;
          for (int j = 1; j < b.size(); ++j) {
            Int2D pos = (Int2D) b.get(j);
            if (pos.x == super.pos.x && pos.y == super.pos.y) {
              newPos = false;
            }
          }
          if (newPos) {
            if (b.size() < 1 + neededPositions - 1) {
              b.add(new Int2D(super.pos.x, super.pos.y));
              // System.out.printf("New position collected.\n");
            } else {
              // all needed positions collected
              MapUpdate msg = (MapUpdate) b.get(0);
              System.out.printf("Collected all needed positions!\n");
              MapUpdate answer = new MapUpdate(this, msg.sender, msg.number, null, null, true);
              sendMessage(answer);
              // System.out.printf("Sender position:
              // %d,%d.\n",msg.sender.getPos().x,msg.sender.getPos().y);
              updateBaseMap(
                  msg.map,
                  msg.agentpos,
                  posToLocalMapPos(msg.sender.getPos(), msg.sender.getLocalMapScale()));
            }
          }
        }
      }
    }
  }
예제 #24
0
 public void addTeamMember(AbstractAgent a) {
   team.add(a);
 }
예제 #25
0
 public void removeTeamMember(AbstractAgent a) {
   team.remove(a);
 }
  /**
   * Assign the set of students (presumably non-incoming-freshmen, but this is not checked) passed
   * to their dorm rooms, in a way that does not take race into account. (compare {@link
   * #assignByRace}.) As a precursor (side effect) to this, any students already existing in
   * upperclass dorms will be removed.
   */
  public void assign(Bag students) {

    emptyDorms();

    // Purge all freshmen. (We're not assigning those.)
    Bag upperclassmen = null;
    try {
      upperclassmen = (Bag) students.clone();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(1);
    }
    for (int x = upperclassmen.size() - 1; x >= 0; x--) {
      Student s = (Student) upperclassmen.get(x);
      if (s.getGrade() < 2) {
        upperclassmen.remove(s);
      }
    }

    for (int x = 0; x < upperclassmen.size(); x++) {
      Student s = (Student) upperclassmen.get(x);
      if (s.getGrade() < 2) {
        // We're only assigning upperclassmen here.
        continue;
      }
      s.leaveRoom();
      for (int y = 0; y < dorms.size(); y++) {
        if (s.hasRoom()) {
          break;
        }
        Dorm d = (Dorm) dorms.get(y);
        if (d.isFull()) {
          continue;
        }
        if (d.isFemaleOnly() && s.getGender() == Student.Gender.MALE) {
          continue;
        }
        int i = 0;
        while (i < d.getNumRooms()) {
          if (s.hasRoom()) {
            break;
          }
          try {
            d.getRoomByIndex(i).addResident(s);
          } catch (IllegalArgumentException e) { // System.out.println(e);
          }
          i++;
        }
      }
    }

    // Error testing to see if there are upperclassmen who don't have a
    //  room/dorms that aren't full
    // int q=0;
    for (int x = 0; x < upperclassmen.size(); x++) {
      Student s = (Student) upperclassmen.get(x);
      if (!s.hasRoom()) {
        System.out.println(s + " has no upperclass dorm room!");
      }
    }
  }
 private void emptyDorms() {
   for (int y = 0; y < dorms.size(); y++) {
     Dorm d = (Dorm) dorms.get(y);
     d.emptyAllRooms();
   }
 }
  /**
   * Assign the set of students (presumably non-incoming-freshmen, but this is not checked) students
   * passed to their dorm rooms, in a way that <i>does</i> take race into account. (compare {@link
   * #assign}.) Minorities will have a higher probability of rooming with other minorities than they
   * would otherwise have had. As a precursor (side effect) to this, any students already existing
   * in upperclass dorms will be removed.
   */
  public void assignByRace(Bag upperclassmen) {
    emptyDorms();
    boolean foundRoomie;
    for (int x = 0; x < upperclassmen.size(); x++) {
      foundRoomie = false;
      Student s = (Student) upperclassmen.get(x);
      // need to leave current room so that they can get a new room
      s.leaveRoom();
      if (s.getRace() == Student.Race.MINORITY) {
        double rollDice = Sim.instance().random.nextDouble();
        if (rollDice < Sim.PROB_DUAL_MINORITY) {
          for (int m = 0; m < upperclassmen.size(); m++) {
            Student r = (Student) upperclassmen.get(m);
            // if the potential roommate is the same gender, is a
            //  minority, and has no room
            if (r.getId() == s.getId()) {
              continue;
            }
            if (r.getRace() == Student.Race.MINORITY
                && r.getGender() == s.getGender()
                && !(r.hasRoom())
                && !(s.hasRoom())) {
              // find a room that is completely empty
              foundRoomie = true;
              for (int y = 0; y < dorms.size(); y++) {
                Dorm d = (Dorm) dorms.get(y);
                if (d.isFull()) {
                  continue;
                }
                if (d.isFemaleOnly() && s.getGender() == Student.Gender.MALE) {
                  continue;
                }
                int i = 0;
                while (i < d.getNumRooms()) {
                  if (s.hasRoom() && r.hasRoom()) {
                    break;
                  }
                  try {
                    if (d.getRoomByIndex(i).isEmpty()) {
                      try {
                        d.getRoomByIndex(i).addResidents(s, r);
                      } catch (IllegalArgumentException e) {
                        System.out.println(e);
                      }
                    }
                  } catch (IllegalArgumentException e) {
                  }
                  i++;
                }
              }
              if (!s.hasRoom()) {
                // no empty room has been found to put these
                // students in; just assign them normally
                assignStudent(s);
              }
              if (!r.hasRoom()) {
                assignStudent(r);
              }
            }
          }
          if (foundRoomie == false) {
            // no same-minority, same-sex, roomless roommate found
            assignStudent(s);
          }
        } else {
          // dice roll not under PROB_DUAL_MINORITY
          assignStudent(s);
        }

      } else {
        // not a minority, assign normally
        assignStudent(s);
      }
    }
  }
  protected void hitOrDraw(Graphics2D graphics, DrawInfo2D info, Bag putInHere) {
    final Grid2D field = (Grid2D) (this.field);
    if (field == null) return;

    // first question: determine the range in which we need to draw.
    final int maxX = field.getWidth();
    final int maxY = field.getHeight();
    if (maxX == 0 || maxY == 0) return;

    final double divideByX =
        ((maxX % 2 == 0) ? (3.0 * maxX / 2.0 + 0.5) : (3.0 * maxX / 2.0 + 2.0));
    final double divideByY = (1.0 + 2.0 * maxY);

    final double xScale = info.draw.width / divideByX;
    final double yScale = info.draw.height / divideByY;
    int startx = (int) (((info.clip.x - info.draw.x) / xScale - 0.5) / 1.5) - 2;
    int starty = (int) ((info.clip.y - info.draw.y) / (yScale * 2.0)) - 2;
    int endx = /*startx +*/
        (int) (((info.clip.x - info.draw.x + info.clip.width) / xScale - 0.5) / 1.5)
            + 4; // with rounding, width be as much as 1 off
    int endy = /*starty +*/
        (int) ((info.clip.y - info.draw.y + info.clip.height) / (yScale * 2.0))
            + 4; // with rounding, height be as much as 1 off

    //
    //
    // CAUTION!
    //
    // At some point we should triple check the math for rounding such
    // that the margins are drawn properly
    //
    //

    // next we determine if this is a DoubleGrid2D or an IntGrid2D

    //        final Rectangle clip = (graphics==null ? null : graphics.getClipBounds());

    final boolean isDoubleGrid2D = (field instanceof DoubleGrid2D);
    final double[][] doubleField = (isDoubleGrid2D ? ((DoubleGrid2D) field).field : null);
    final int[][] intField = (isDoubleGrid2D ? null : ((IntGrid2D) field).field);

    double xyC_x, xyC_y, xyC_ulx, xyC_uly, xyC_upx, xyC_upy, xyC_urx, xyC_ury, x0, y0, tx, ty;

    if (startx < 0) startx = 0;
    if (starty < 0) starty = 0;
    if (endx > maxX) endx = maxX;
    if (endy > maxY) endy = maxY;

    for (int y = starty; y < endy; y++)
      for (int x = startx; x < endx; x++) {
        // getxyC( x, y, xScale, yScale, info.draw.x, info.draw.y, xyC );
        // getxyC( field.ulx(x,y), field.uly(x,y), xScale, yScale, info.draw.x, info.draw.y, xyC_ul
        // );
        // getxyC( field.upx(x,y), field.upy(x,y), xScale, yScale, info.draw.x, info.draw.y, xyC_up
        // );
        // getxyC( field.urx(x,y), field.ury(x,y), xScale, yScale, info.draw.x, info.draw.y, xyC_ur
        // );

        x0 = x;
        y0 = y;
        tx = info.draw.x;
        ty = info.draw.y;
        xyC_x = tx + xScale * (1.5 * x0 + 1);
        xyC_y = ty + yScale * (1.0 + 2.0 * y0 + (x0 < 0 ? (-x0) % 2 : x0 % 2));

        x0 = field.ulx(x, y);
        y0 = field.uly(x, y);
        tx = info.draw.x;
        ty = info.draw.y;
        xyC_ulx = tx + xScale * (1.5 * x0 + 1);
        xyC_uly = ty + yScale * (1.0 + 2.0 * y0 + (x0 < 0 ? (-x0) % 2 : x0 % 2));

        x0 = field.upx(x, y);
        y0 = field.upy(x, y);
        tx = info.draw.x;
        ty = info.draw.y;
        xyC_upx = tx + xScale * (1.5 * x0 + 1);
        xyC_upy = ty + yScale * (1.0 + 2.0 * y0 + (x0 < 0 ? (-x0) % 2 : x0 % 2));

        x0 = field.urx(x, y);
        y0 = field.ury(x, y);
        tx = info.draw.x;
        ty = info.draw.y;
        xyC_urx = tx + xScale * (1.5 * x0 + 1);
        xyC_ury = ty + yScale * (1.0 + 2.0 * y0 + (x0 < 0 ? (-x0) % 2 : x0 % 2));

        xPoints[0] = (int) (xyC_urx - 0.5 * xScale);
        yPoints[0] = (int) (xyC_ury + yScale);
        xPoints[1] = (int) (xyC_upx + 0.5 * xScale);
        yPoints[1] = (int) (xyC_upy + yScale);
        xPoints[2] = (int) (xyC_upx - 0.5 * xScale);
        yPoints[2] = (int) (xyC_upy + yScale);
        xPoints[3] = (int) (xyC_ulx + 0.5 * xScale);
        yPoints[3] = (int) (xyC_uly + yScale);
        xPoints[4] = (int) (xyC_x - 0.5 * xScale);
        yPoints[4] = (int) (xyC_y + yScale);
        xPoints[5] = (int) (xyC_x + 0.5 * xScale);
        yPoints[5] = (int) (xyC_y + yScale);

        if (graphics == null) {
          generalPath.reset();
          generalPath.moveTo(xPoints[0], yPoints[0]);
          for (int i = 1; i < 6; i++) generalPath.lineTo(xPoints[i], yPoints[i]);
          generalPath.closePath();
          Area area = new Area(generalPath);
          if (area.intersects(info.clip.x, info.clip.y, info.clip.width, info.clip.height)) {
            valueToPass.val = isDoubleGrid2D ? doubleField[x][y] : intField[x][y];
            putInHere.add(getWrapper(valueToPass.val, x, y));
          }
        } else {
          Color c = map.getColor(isDoubleGrid2D ? doubleField[x][y] : intField[x][y]);
          if (c.getAlpha() == 0) continue;
          graphics.setColor(c);

          // MacOS X 10.3 Panther has a bug which resets the clip, YUCK
          //                    graphics.setClip(clip);
          graphics.fillPolygon(xPoints, yPoints, 6);
        }
      }
  }