Listing C. Domain layer for SET game—OO design (triple dispatch).
- By Vince Huston
- August 16, 2001
Java Primer
The Game of SET & Software Design
Vince Huston
Listing C. Domain layer for SET gameOO design (triple dispatch).
// Domain layer for SET game - OO design (triple dispatch)
import java.util.Random;
abstract class Facet {
public abstract boolean isValid1( Facet second, Facet third );
public abstract boolean isValid2( Facet third, Zer first );
public abstract boolean isValid2( Facet third, One first );
public abstract boolean isValid2( Facet third, Two first );
public boolean isValid3( Zer first, Zer second ) { return false; }
public boolean isValid3( Zer first, One second ) { return false; }
public boolean isValid3( Zer first, Two second ) { return false; }
public boolean isValid3( One first, Zer second ) { return false; }
public boolean isValid3( One first, One second ) { return false; }
public boolean isValid3( One first, Two second ) { return false; }
public boolean isValid3( Two first, Zer second ) { return false; }
public boolean isValid3( Two first, One second ) { return false; }
public boolean isValid3( Two first, Two second ) { return false; }
}
class Zer extends Facet {
public String toString() { return "0"; }
public boolean isValid1( Facet second, Facet third ) {
return second.isValid2( third, this ); }
public boolean isValid2( Facet third, Zer first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, One first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, Two first ) {
return third.isValid3( first, this ); }
public boolean isValid3( Zer first, Zer second ) { return true; }
public boolean isValid3( One first, Two second ) { return true; }
public boolean isValid3( Two first, One second ) { return true; }
}
class One extends Facet {
public String toString() { return "1"; }
public boolean isValid1( Facet second, Facet third ) {
return second.isValid2( third, this ); }
public boolean isValid2( Facet third, Zer first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, One first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, Two first ) {
return third.isValid3( first, this ); }
public boolean isValid3( Zer first, Two second ) { return true; }
public boolean isValid3( One first, One second ) { return true; }
public boolean isValid3( Two first, Zer second ) { return true; }
}
class Two extends Facet {
public String toString() { return "2"; }
public boolean isValid1( Facet second, Facet third ) {
return second.isValid2( third, this ); }
public boolean isValid2( Facet third, Zer first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, One first ) {
return third.isValid3( first, this ); }
public boolean isValid2( Facet third, Two first ) {
return third.isValid3( first, this ); }
public boolean isValid3( Zer first, One second ) { return true; }
public boolean isValid3( One first, Zer second ) { return true; }
public boolean isValid3( Two first, Two second ) { return true; }
}
class Card {
private static Facet[] objects = { new Zer(), new One(), new Two() };
private static boolean[] used = new boolean[27];
private static Random rn = new Random();
private int number; ///// 0..26
private Facet[] facets = new Facet[3];
public Card() {
number = rn.nextInt(27);
while ( used[number] )
number = rn.nextInt(27);
used[number] = true;
facets[0] = objects[ number % 3 ];
facets[1] = objects[ number % 9 / 3 ];
facets[2] = objects[ number / 9 ];
}
public Facet getFacet( int i ) { return facets[i]; }
public int getNumber() { return number; }
public String toString() {
return "" + (number+1) + '-' + facets[0] + facets[1] + facets[2];
} }
class Set {
private Card[] cards = new Card[3];
public Set( Card one, Card two, Card thr ) {
cards[0] = one; cards[1] = two; cards[2] = thr;
}
public boolean isValid() {
for (int i=0; i < 3; i++)
if ( ! cards[0].getFacet(i).isValid1(
cards[1].getFacet(i), cards[2].getFacet(i) ))
return false;
return true;
} }