m1.chocobarlite/src/chocobar/bpl/ChocoBar.java
2009-05-01 08:07:06 +00:00

267 lines
6.1 KiB
Java

package chocobar.bpl;
// JDK imports
import java.util.*;
import graph.Vertice;
import exception.*;
class ChocoBar implements Vertice, Cloneable {
private int width;
private int height;
public BreakPointList brkPtLst;
/**
* Constructeur d'une barre de choco ayant x carres en largeur
* et y carres en hauteur, toute neuve.
**/
public ChocoBar(int x,int y){
this.width=x;
this.height=y;
this.brkPtLst=new BreakPointList();
}
public ChocoBar(int x, int y, BreakPointList oldBP){
this(x,y);
this.brkPtLst=new BreakPointList(oldBP);
}
/**
* Return the hash int of the current configuration
*/
public int getHash(){
int hash=0;
int hoffset=0;
IntPoint pt=null;
int ptcounter=0;
for (int x=0;x<this.width;x++){
if (this.brkPtLst.size()>0){
pt=(IntPoint)this.brkPtLst.elementAt(ptcounter);
if (x==pt.getX()){
if (ptcounter<this.brkPtLst.size()-1){
ptcounter++;
}
hoffset=this.height-pt.getY();
}
}
System.out.print(hoffset+" ");
hash=hash*this.height+hoffset;
}
System.out.println(" = "+hash);
return hash;
}
/**
* Constructeur d'une ChocoBar à partir d'une ancienne barre
**/
public ChocoBar(ChocoBar old){
this(0,0);
try{
if (old==null){
throw new Exception();
} else {
this.width=old.width;
this.height=old.height;
this.brkPtLst=new BreakPointList(old.brkPtLst);
}
} catch (Exception e){
e.printStackTrace();
System.exit(-3);
}
}
/**
* Fonction qui affiche sur STDOUT cette barre de choco
**/
public void display(){
boolean[][] chocobar= new boolean[width][height];
System.out.print(" ");
for (int w=0;w<this.width;w++){ // affichage de l'indice x
if (w<100){ System.out.print(" "); }
if (w<10){ System.out.print(" "); }
System.out.print(w);
}
System.out.println("");
for (int h=0;h<this.height;h++){ // affichage de l'indice y
if (h<100){ System.out.print(" "); }
if (h<10){ System.out.print(" "); }
System.out.print(h+". ");
for (int w=0;w<this.width;w++){
if (this.brkPtLst.isBroken(new IntPoint(w, h))){
System.out.print(" _ ");
} else {
System.out.print(" X ");
}
}
System.out.println("");
}
}
/**
* Add a new breakpoint at position newBP
**/
public void addBreakPoint(IntPoint newBP)
throws OutOfRangeBreakPointException, AlreadyBrokenPointException
{
this.addBreakPoint(newBP.getX(),newBP.getY());
}
/**
* Add a new breakpoint at position (x,y)
**/
public void addBreakPoint(int x, int y)
throws OutOfRangeBreakPointException, AlreadyBrokenPointException
{
if ((x<0) || (x>=this.width)
|| (y<0) || (y>=this.height)){
throw (new OutOfRangeBreakPointException());
}
IntPoint current=new IntPoint(x,y);
if (this.brkPtLst.isBroken(current)){
throw (new AlreadyBrokenPointException());
}
this.brkPtLst.add(current);
}
/**
* Fonction qui verifie si la barre passee en argument
* contient la meme config que cet objet
**/
public boolean equals(ChocoBar comp){
boolean eq=true;
if ((this.width != comp.width)||(this.height != comp.height)){
eq=false;
} else {
eq=this.brkPtLst.equals(comp.brkPtLst);
}
return eq;
}
/**
* Fonction qui verifie si cet objet est une config
* suivante de la config passee en parametre
* cplx: O(|brkPtLst|)
**/
public boolean isNextOf(ChocoBar parent){
Iterator pointToEat=this.brkPtLst.iterator();
ChocoBar parentCopy=null;
BreakPointList parentBPCopy=null;
IntPoint currentEatPoint;
while(pointToEat.hasNext()){
currentEatPoint=(IntPoint)pointToEat.next();
// we make a copy of parent
parentBPCopy=new BreakPointList(parent.brkPtLst);
// we eat the copy with each break current chocobar
parentBPCopy.add(currentEatPoint);
// one of the resulting chocobars should be the same.
if (this.brkPtLst.equals(parentBPCopy)){ return true; }
}
return false;
}
/**
* Fonction qui renvoie true si cette barre de choco
* est la derniere config possible
**/
public boolean isFinalConfig(){
if (this.brkPtLst.size() != 1){
return false;
} else {
if (this.brkPtLst.contains(new IntPoint(0, 0)))
return true;
else
return false;
}
}
/**
* Fonction qui calcule les points de frontiere
* des carrees non mangés
**/
public Vector getBreakLine(){
Vector frontline=new Vector();
if ((brkPtLst==null) || (brkPtLst.size()<1)){
// on a une barre toute neuve, seul carre
// a manger est (width-1, height-1)
frontline.add(new IntPoint(this.width-1, this.height-1));
} else {
IntPoint firstPt;
IntPoint secondPt;
// draw vertical line before first point
firstPt=(IntPoint)this.brkPtLst.elementAt(0);
if (firstPt.getX()<0){
// do nothing, the point is on the left border
} else {
for (int y=this.height-1;y>=firstPt.getY();y--){
frontline.add(
new IntPoint(firstPt.getX()-1,y)
);
}
}
// loop with two points
for (int i=0;i<this.brkPtLst.size()-1;i++){
firstPt=(IntPoint)this.brkPtLst.elementAt(i);
secondPt=(IntPoint)this.brkPtLst.elementAt(i+1);
// horizontal line between...
for (int x=firstPt.getX()-1;
x<secondPt.getX()-1;
x++){
frontline.add(
new IntPoint(x,firstPt.getY()-1)
);
}
// then the vertical one
for (int y=firstPt.getY()-1;
y>=secondPt.getY();
y--){
frontline.add(
new IntPoint(secondPt.getX()-1,y)
);
}
}
// draw horizontal line after last point
secondPt=(IntPoint)this.brkPtLst.elementAt(this.brkPtLst.size()-1);
if (secondPt.getY()<1){
// do nothing, the point is on the top border
} else {
int hshift=-1;
if ((secondPt.getX()+hshift)<0){ hshift=0; }
for (int x=secondPt.getX()+hshift;x<this.width;x++){
frontline.add(
new IntPoint(x,secondPt.getY()-1)
);
}
}
}
return frontline;
}
public int getColor(){
//TODO: fill;
return 0;
}
public void setColor(int c){
//TODO:fill
}
public String getLabel(){
//TODO:fill
return new String("");
}
public void setLabel(String s){
//TODO:fill
}
public BreakPointList getBreakPointList(){
return this.brkPtLst;
}
}