267 lines
6.1 KiB
Java
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;
|
|
}
|
|
}
|
|
|