224 lines
4.8 KiB
Java
224 lines
4.8 KiB
Java
package chocobar.combi;
|
|
|
|
import java.lang.Long;
|
|
|
|
class ChocoBarLong extends ChocoBar {
|
|
/// Précalcul des puissances.
|
|
static private long[] powers;
|
|
|
|
/// Représente la ChocoBar
|
|
private long points;
|
|
|
|
/**
|
|
* Constructeur d'une barre de choco.
|
|
* Elle a x carres en largeur et y carres en hauteur, et est toute neuve.
|
|
**/
|
|
private ChocoBarLong()
|
|
{
|
|
points = 0;
|
|
}
|
|
|
|
/** Constructeur par copie.
|
|
*/
|
|
private ChocoBarLong(ChocoBarLong old)
|
|
{
|
|
points = old.points;
|
|
}
|
|
|
|
/** Constructeur par initialisation.
|
|
*/
|
|
private ChocoBarLong(long bi)
|
|
{
|
|
points = bi;
|
|
}
|
|
|
|
/** Constructeur par initialisation.
|
|
*/
|
|
private ChocoBarLong(int c[])
|
|
{
|
|
points = 0;
|
|
for (int i=0; (i<size); i++) {
|
|
points += powers[i] * c[size-i-1];
|
|
}
|
|
// XXX - DEBUG
|
|
// System.out.println(
|
|
// "ChocoBarLong(" + toLine(c) + ")"
|
|
// + " = " + toLine()
|
|
// + " = " + toNumber()
|
|
// );
|
|
// XXX - DEBUG
|
|
}
|
|
|
|
/**
|
|
* Affichage de la barre de choco en nombre.
|
|
**/
|
|
public String toNumber()
|
|
{
|
|
String s = (new Long(points)).toString();
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Affichage de la barre de choco en ligne.
|
|
**/
|
|
public String toLine()
|
|
{
|
|
String s = "";
|
|
for (int i=0; (i<size); i++) {
|
|
s += get(i) + " ";
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/**
|
|
* Affichage de la barre de choco en ligne.
|
|
**/
|
|
private static String toLine(int c[])
|
|
{
|
|
String s = "";
|
|
for (int i=0; (i<size); i++) {
|
|
s += c[i] + " ";
|
|
}
|
|
return s;
|
|
}
|
|
|
|
private int get(int x)
|
|
{
|
|
int i = (size - 1) - x;
|
|
long value = (points % powers[i+1]) / powers[i];
|
|
return (int) value;
|
|
}
|
|
|
|
/**
|
|
* 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((ChocoBarLong) comp); }
|
|
public boolean equals(ChocoBarLong comp)
|
|
{
|
|
return points == 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((ChocoBarLong) parent); }
|
|
public boolean isNextOf(ChocoBarLong parent)
|
|
{
|
|
// TODO - Il faudrait améliorer cet algo, en fonction des données que
|
|
// Long peut nous offrir
|
|
int eaten = -1;
|
|
for (int i=0; (i<size); i++) {
|
|
// Si le parent est plus mangé que le fils, c'est toujours non !
|
|
if (parent.get(i) > get(i)) {
|
|
return false;
|
|
}
|
|
|
|
if (eaten == -1) {
|
|
if (parent.get(i) != get(i)) {
|
|
// On a mangé ce carré, les carrés suivants doivent donc être
|
|
// identiquent à celui-ci ou à celui du père
|
|
eaten = get(i);
|
|
// On a traité ce carré, on passe au suivant
|
|
continue;
|
|
}
|
|
// Le carré est identique, suivant !
|
|
continue;
|
|
}
|
|
|
|
// On a mangé le carré précédent, ils doivent donc être
|
|
// identiques au point précédents, ou à celui que l'on vient de
|
|
// manger
|
|
if (parent.get(i) != get(i) && get(i) != eaten) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Si on arrive ici, c'est que tout c'est bien passé, a-t-on un carré
|
|
// mangé ?
|
|
return (eaten != -1);
|
|
}
|
|
|
|
/** 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
|
|
ChocoBarLong.size = x;
|
|
ChocoBarLong.height = y;
|
|
// Précalcul des puissances
|
|
long pows = 1;
|
|
ChocoBarLong.powers = new long[x+1];
|
|
for (int i=0; (i<=x); i++) {
|
|
ChocoBarLong.powers[i] = pows;
|
|
pows *= y + 1;
|
|
}
|
|
|
|
// 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
|
|
int[] points = new int[x];
|
|
|
|
boolean fin = false;
|
|
int cbIdx = 0;
|
|
while (!fin) {
|
|
// Affectation
|
|
chocoBars[cbIdx] = new ChocoBarLong(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; }
|
|
}
|