/** * Where to insert <CODE>n</CODE>, based only on degree, in the current tower. In <CODE> * addField()</CODE> we further test to see if the floors above, and/or at, and/or below are * sub-/superfields. * * @param n The NumberField whose insertion index we are intersted in * @return The index where <CODE>n</CODE> should be inserted into <CODE>floors</CODE> * @see #floors */ private int findInsertionIndex(NumberField n) { int i = 0; for (i = 0; i < floors.size(); i++) { Floor f = (Floor) floors.get(i); if (f.getDegree() <= n.getDegree()) break; } return i; }
/** * Determine the subfields of <CODE>n</CODE> and store the results there as well. * * @param n The NumberField whose subfields we are after */ private void determineSubfields(NumberField n) { // Progress Bar GiANT.gui.appendConsoleText( "\nDetermining sub- and superfield relations for new field" + ELL, false); GiANT.gui.showProgressBar(true); // DEBUG // System.err.println("subfields start for " + n.getName()); int i = 0; final float size = (float) allFields.size(); final int max = GiANT.gui.getProgressMax(); Iterator it = allFields.iterator(); while (it.hasNext()) { // Progress Bar float index = (float) i++; int progress = (int) (max * (index / size)); // DEBUG // System.err.println("\tprogress=" + progress); GiANT.gui.setProgress(progress); NumberField test = (NumberField) it.next(); if (n.hasSubfield(test) || test.hasSubfield(n)) { // do nothing } else if (GiANT.gui.kash.isSubfield(test, n)) { n.addSubfield(test); // also adds all subfields of test to subfields of this if (test.getDegree() == n.getDegree()) { test.addSubfield(n); } } else if (GiANT.gui.kash.isSubfield(n, test)) { test.addSubfield(n); // also adds all subfields of n to subfields of this } } // Progress Bar GiANT.gui.showProgressBar(false); GiANT.gui.appendConsoleText("done.\n", false); // System.err.println("subfields end for " + n.getName()); }
/** * Creates a new <CODE>Floor</CODE> with the given inhabitant * * @param n A <CODE>NumberField</CODE> that should live on the new <CODE>Floor</CODE> */ private Floor(NumberField n) { super(); // DEBUG use /* addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { floorMouseEntered(evt); } });*/ setLayout(new BoxLayout(this, javax.swing.BoxLayout.X_AXIS)); setFocusable(false); setOpaque(false); degree = n.getDegree(); add(n); }
/** * Add <CODE>newguy</CODE> to the list of all fields in this city * * @param newguy the NumberField to add * @see #allFields */ protected void addField(NumberField newguy) { boolean fatal = false; if (population >= MAX_POPULATION) { GiANT.gui.appendConsoleText( "\nUnable to add numberfield; maximum population of " + MAX_POPULATION + " reached.", true); fatal = true; } else if (allFields.contains(newguy)) { GiANT.gui.appendConsoleText( "\nUnable to add numberfield. It duplicates one already displayed.", true); fatal = true; } if (fatal) return; // we will need to know all subfields of this cat... determineSubfields(newguy); // System.err.println("entering addField()"); // TODO do not allow duplicate (isomorphic) numberfields to be added boolean homeless = true; // we have yet to find a place for newguy boolean redraw = false; // update maxDegree final int newDeg = newguy.getDegree(); if (newDeg > maxDegree) { maxDegree = newDeg; redraw = true; } // search all towers, left to right towers: for (int i = 0; i < towers.size(); i++) { Tower t = (Tower) towers.get(i); // boolean flags for existence of [proper] superfields / subfields boolean hasSuper = false; boolean hasSub = false; final int insert = t.findInsertionIndex(newguy); boolean hasEqual = false; Tower.Floor f = null; if (insert == t.getHeight()) { // nothing to check; we are outside of the current tower array } else { f = t.getFloor(insert); if (f.getDegree() == newDeg) hasEqual = true; } Tower.Floor above = null; Tower.Floor below = null; if (insert == 0) { // we are at the top of the tower hasSuper = true; // super is C int fetch = 0; if (hasEqual) fetch = 1; if (fetch >= t.getHeight()) { hasSub = true; // there are no towers below, sub is Q } else { below = t.getFloor(fetch); if (below.allSubfieldsOf(newguy)) hasSub = true; } } else if (insert == t.getHeight()) { // we are at the very bottom of the tower hasSub = true; // sub is Q itself above = t.getFloor(t.getHeight() - 1); if (above.allSuperFieldsOf(newguy)) hasSuper = true; } else { // we are somewhere WITHIN the tower if (hasEqual) { above = t.getFloor(insert - 1); if (insert == t.getHeight() - 1) hasSub = true; // sub is Q else below = t.getFloor(insert + 1); } else { above = t.getFloor(insert - 1); below = t.getFloor(insert); } if (above.allSuperFieldsOf(newguy)) hasSuper = true; if (hasSub) { // do nothing } else { // test for the same if (below.allSubfieldsOf(newguy)) hasSub = true; } } if (hasSub && hasSuper) { if (hasEqual) // kkl if (!f.allSubfieldsOf( newguy)) // could also use allSuperfieldsOf(), we need to make sure all fields this // floor are isomorphic to newguy... continue towers; // homeless = false; t.add(insert, hasEqual, newguy); break towers; } } if (homeless) { // then build a new tower for newguy Tower newT = newTower(); newT.add(0, false, newguy); } population++; // one more citizen! allFields.add(newguy); // add him to the set of all fields // if(redraw) //OPTIM redraw(); GiANT.gui.repaint(); // System.err.println("exiting addField()"); }