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

164 lines
3.6 KiB
Java

package chocobar.combi;
import java.math.BigInteger;
class ChocoBarBigInt extends ChocoBar {
static private BigInteger[] powers;
private BigInteger points;
/**
* Constructeur d'une barre de choco.
* Elle a x carres en largeur et y carres en hauteur, et est toute neuve.
**/
private ChocoBarBigInt()
{
points = new BigInteger("0");
}
/** Constructeur par copie.
*/
private ChocoBarBigInt(ChocoBarBigInt old)
{
points = old.points;
}
/** Constructeur par initialisation.
*/
private ChocoBarBigInt(BigInteger bi)
{
points = bi;
}
/** Constructeur par initialisation.
*/
private ChocoBarBigInt(char c[])
{
points = new BigInteger("0");
for (int i=0; (i<size); i++) {
points.add(powers[i].multiply(new BigInteger("" + (int)c[i])));
}
}
/**
* Affichage de la barre de choco en ligne.
**/
public String toLine()
{
String s = "";
BigInteger bi = points;
for (int i=0; (i<size); i++) {
s += get(i) + " ";
}
return s;
}
private int get(int x)
{
BigInteger rest = points.pow(x);
BigInteger value = (rest.mod(ChocoBarBigInt.powers[x+1])).divide(powers[x]);
return value.intValue();
}
/**
* Vérifie si le carre (x, y) est déjà mangé.
**/
protected boolean isBroken(int cX, int cY)
{
return ((height - cY) <= get(cX));
}
/**
* Comparaison de barres.
* La conversion entre type de ChocoBar n'est pas implémentée
**/
public boolean equals(ChocoBar comp) { return equals((ChocoBarBigInt) comp); }
public boolean equals(ChocoBarBigInt comp)
{
return points.equals(comp.points);
}
/** Recherche si l'on peut être un fils de la ChocoBar.
* La conversion entre type de ChocoBar n'est pas implémentée
*/
public boolean isNextOf(ChocoBar parent) { return isNextOf((ChocoBarBigInt) parent); }
public boolean isNextOf(ChocoBarBigInt parent)
{
return false;
}
/** Usine pour construire une liste de ChocoBar.
* Cette usine contruit une liste exhaustive et ordonnée de ChocoBar.
*/
public static ChocoBar[] genChocoBars(int x, int y)
{
// On mets à jour les variables statiques de taille
ChocoBarBigInt.size = x;
ChocoBarBigInt.height = y;
// Précalcul des puissances
ChocoBarBigInt.powers = new BigInteger[x+1];
BigInteger bi = new BigInteger("1");
for (int i=0; (i<=x); i++) {
ChocoBarBigInt.powers[i] = bi;
bi = bi.multiply(new BigInteger("" + y));
}
// Calcul du nombre de chocobars différentes existantes
int nbChocobars = nbChocoBars(x, y);
// Hop, on réserve le tableau de résultat...
ChocoBar[] chocoBars = new ChocoBar[nbChocobars];
// Il est temps de remplir le tableau !
// Création du tableau pour stocker les valeurs
char[] points = new char[x];
boolean fin = false;
int cbIdx = 0;
while (!fin) {
// Affectation
chocoBars[cbIdx] = new ChocoBarBigInt(points);
cbIdx++;
// Calcul du suivant :
// On incrémente ...
int idx = x-1;
points[idx] ++;
// ... et on gère la retenue
boolean overflow = (points[idx] > y);
while (points[idx] > y) {
if (idx == 0) {
fin = true;
break;
}
points[idx-1] ++;
idx--;
}
// On répercute la modif vers la droite s'il y a eu overflow
if (overflow) {
for (int i=idx; (i<x); i++) {
points[i] = points[idx];
}
}
}
return chocoBars;
}
public static ChocoBar[] genChocoBars(Integer x, Integer y)
{
return genChocoBars(x.intValue(), y.intValue());
}
// Implémentation de Vertice
public void setLabel(String l) { }
public String getLabel() { return "null"; }
public void setColor(int c) { }
public int getColor() { return 0; }
}