org.pealfactory.ring
Class Row

java.lang.Object
  |
  +--org.pealfactory.ring.Row
All Implemented Interfaces:
java.lang.Cloneable, Constants
Direct Known Subclasses:
ImmutableRow

public class Row
extends java.lang.Object
implements Constants, java.lang.Cloneable

Represents a single row of bells, at any stage between kMINNBELLS and kMAXNBELLS (inclusive). The current number of bells in the row is kept, as well as the row itself as a character array. Methods are provided to permute rows (including applying place notation changes), and to analyse them, for example to discover whether the tenors are together, or whether the row is found in the plain course of Plain Bob at the appropriate stage.

Rows can be constructed from Strings of bell characters. Normally these will look like the kROUNDS constant ("12345678"), but we can use anything - e.g. "1--------" to draw just the treble path. Rows constructed from kROUNDS can be converted to a byte array representation using numbers 1...nbells - see toBytes().

Since Rows are mutable, we allow cloning for clients who want to preserve a copy of a particular row. See also ImmutableRow.

Efficiency is a prime concern of this class, so methods are provided which avoid slow String operations and deal directly with Row and byte array objects. Performance advice for each method is given in the method javadoc.


Field Summary
protected  int fNBells
          The 'size' (number of bells) of the row
protected  char[] fRow
          Internal representation of the row
 
Fields inherited from interface org.pealfactory.ring.Constants
kCALL_BOB, kCALL_EXTREME, kCALL_PLAIN, kCALL_SINGLE, kCALL_USER, kCHAR_CROSS, kCHAR_LH, kMAXNBELLS, kMINNBELLS, kROUNDS
 
Constructor Summary
Row(int nbells)
          Construct a row containing rounds on nbells.
Row(Row r)
          Make a Row from another Row (just like clone really).
Row(java.lang.String s)
          Construct a row from the String s, setting the number of bells from the string length.
 
Method Summary
 void applyPermutation(byte[] permutation)
          Permutes this row by the given change.
 void applyPermutation(Row permutation)
          Permutes this row by the given Row transformation.
 void applyPN(byte[] pn)
          Permute the row by a single change of place notation.
 int bellAt(int place)
          Place is 1..nbells.
 void calcPermutation(Row r, byte[] perm)
          Given a Row r, calculates the permutation (as a byte[]) which would permute us to that row.
 java.lang.Object clone()
           
 boolean equals(java.lang.Object o)
          As well as comparing Row with Row, we can compare with a String - in this case, it doesn't matter if the String is longer than us, as the extra characters are dropped.
 int findBell(char bell)
          Given a bell character from kROUNDS, returns the index at which the bell occurs in the row, 1..nbells.
 int getNBells()
          Returns the current number of bells defined for this row.
 int hashCode()
          The hashcode is based on that of the underlying row string, however the calculation is performed directly, to avoid the slow toString() conversion.
 boolean isPBrow()
          Returns true if the current row occurs in a plain course of Plain Bob at this stage.
private  boolean isPBrow(boolean direction)
          Returns true if the current row occurs in a plain course of Plain Bob at backstroke (when direction=true) or handstroke (direction=false).
 boolean isTenorsHome()
          Returns true if the tenors (bells 7..n) are home
 boolean isTenorsTogether()
          Returns true if the tenors (bells 7..n) are in a PB leadhead position
 int nextCourseBell(int i, boolean evensUp)
          Finds the next bell in Plain Bob coursing order from i (where i = 1..nbells).
 int nextCourseBellNoTreble(int i, boolean evensUp)
          Just like nextCourseBell() above, but always skips the treble (i.e.
protected  void setNBells(int n)
          The number of bells in the row can be reduced but not increased.
 void setRow(Row r)
          This is an efficient way to assign the contents of another Row to ourselves.
 void setRow(java.lang.String s)
          Resets the row to the contents of the given String.
 void swap(int i, int j)
          Swap bells at i and j in this row, numbering from 1 as usual.
 void test(PN pn)
           
 byte[] toBytes()
          Returns the row as a byte[] with bells represented by bytes 1..nbells, not bell characters.
 java.lang.String toString()
          Return the row as a String whose length is the current number of bells.
 
Methods inherited from class java.lang.Object
, finalize, getClass, notify, notifyAll, registerNatives, wait, wait, wait
 

Field Detail

fRow

protected char[] fRow
Internal representation of the row

fNBells

protected int fNBells
The 'size' (number of bells) of the row
Constructor Detail

Row

public Row(int nbells)
Construct a row containing rounds on nbells.

Row

public Row(Row r)
Make a Row from another Row (just like clone really). This is much faster than new Row(r.toString()) because slow string conversion is avoided.

Row

public Row(java.lang.String s)
Construct a row from the String s, setting the number of bells from the string length.
Method Detail

setRow

public void setRow(java.lang.String s)
Resets the row to the contents of the given String. Note that String processing is relatively inefficient, and it better to use setRow(r) if you already have a Row r.

setRow

public void setRow(Row r)
This is an efficient way to assign the contents of another Row to ourselves. It uses a direct array copy, so is much faster than the equivalent setRow(r.toString()).

setNBells

protected void setNBells(int n)
The number of bells in the row can be reduced but not increased. To create a row with more bells, construct a new object.

toString

public java.lang.String toString()
Return the row as a String whose length is the current number of bells. Creating Strings is fairly slow, so do not use this in performance-critical code.
Overrides:
toString in class java.lang.Object

toBytes

public final byte[] toBytes()
Returns the row as a byte[] with bells represented by bytes 1..nbells, not bell characters. Useful for creating permutations from rows. Final for speed.

equals

public boolean equals(java.lang.Object o)
As well as comparing Row with Row, we can compare with a String - in this case, it doesn't matter if the String is longer than us, as the extra characters are dropped. This helps easy comparison with kROUNDS.

Optimisation: slow toString() conversions avoided.

Overrides:
equals in class java.lang.Object

hashCode

public int hashCode()
The hashcode is based on that of the underlying row string, however the calculation is performed directly, to avoid the slow toString() conversion.
Overrides:
hashCode in class java.lang.Object

getNBells

public final int getNBells()
Returns the current number of bells defined for this row. Final for speed.

clone

public java.lang.Object clone()
Overrides:
clone in class java.lang.Object

findBell

public int findBell(char bell)
Given a bell character from kROUNDS, returns the index at which the bell occurs in the row, 1..nbells. Returns 0 if not found.

bellAt

public final int bellAt(int place)
Place is 1..nbells. Returns bell number 1..nbells at that position in row, or 0 if not found. Final for speed.

swap

public void swap(int i,
                 int j)
Swap bells at i and j in this row, numbering from 1 as usual.

test

public void test(PN pn)

applyPermutation

public void applyPermutation(Row permutation)
Permutes this row by the given Row transformation. The Row should be a valid change formed from kROUNDS characters and of the right length. Then, if e.g. permutation = reverse rounds, the effect is to reverse this row.

applyPermutation

public void applyPermutation(byte[] permutation)
Permutes this row by the given change. Bells in the byte array are represented by numbers 1..nbells.

calcPermutation

public final void calcPermutation(Row r,
                                  byte[] perm)
Given a Row r, calculates the permutation (as a byte[]) which would permute us to that row. This is the reverse of applyPermutation(). Note the permutation array must be pre-allocated and passed to this method as a parameter.

Final for speed.


applyPN

public void applyPN(byte[] pn)
Permute the row by a single change of place notation. The place notation is represented as a byte array, and should be in the format provided by PN.getChange(int).

isTenorsHome

public boolean isTenorsHome()
Returns true if the tenors (bells 7..n) are home

isTenorsTogether

public boolean isTenorsTogether()
Returns true if the tenors (bells 7..n) are in a PB leadhead position

nextCourseBell

public int nextCourseBell(int i,
                          boolean evensUp)
Finds the next bell in Plain Bob coursing order from i (where i = 1..nbells). If evensUp set, we move even bells up two and odd bells down two, and vice versa. For evensUp, the effect is to incrementally generate (on 8 bells) the numbers 2 4 6 8 7 5 3 1 2 4 6 8...

nextCourseBellNoTreble

public int nextCourseBellNoTreble(int i,
                                  boolean evensUp)
Just like nextCourseBell() above, but always skips the treble (i.e. never returns 1).

isPBrow

public boolean isPBrow()
Returns true if the current row occurs in a plain course of Plain Bob at this stage. We use the isPBrow(boolean) method to check for either backstroke (direction=true) or handstroke (direction=false) PB rows.

isPBrow

private boolean isPBrow(boolean direction)
Returns true if the current row occurs in a plain course of Plain Bob at backstroke (when direction=true) or handstroke (direction=false). This is accomplished by stepping through places 1,2,4,6... down to 5,3,1, skipping any place that contains the treble. For each step, we make sure that the bell found is the expected course (or after) bell of the one before.