Added trees.

This commit is contained in:
Jacob Signorovitch
2024-11-05 16:31:17 -05:00
parent 41aef7d6b1
commit bb35bd5aab

269
trees/src/trees/Main.java Normal file
View File

@@ -0,0 +1,269 @@
package trees;
import java.awt.Color;
import tester.Tester;
class Examples {
IBlob red = new Solid("red", new Color(255, 0, 0));
IBlob green = new Solid("green", new Color(0, 255, 0));
IBlob blue = new Solid("blue", new Color(0, 0, 255));
IBlob brown = new Solid("brown", new Color(96, 61, 14));
IBlob brightBrown = new Combo("brown", new Brighten(brown));
IBlob darkBrown = new Combo("brown", new Darken(brown));
IBlob neon = new Solid("neon", new Color(255, 255, 255));
IBlob darkNeon = new Combo("neon", new Darken(neon));
IBlob brightNeon = new Combo("neon", new Brighten(neon));
IBlob neonBrown = new Combo("neon brown", new Blend(neon, brown));
IBlob darkNeonDarkBrown = new Combo("neon brown", new Blend(darkBrown, darkNeon));
IBlob brightNeonBrightBrown = new Combo("neon brown", new Blend(brightBrown, brightNeon));
IBlob purple = new Combo("purple", new Blend(red, blue));
IBlob darkPurple = new Combo("dark purple", new Darken(purple));
IBlob khaki = new Combo("khaki", new Blend(red, green));
IBlob yellow = new Combo("yellow", new Brighten(khaki));
IBlob mauve = new Combo("mauve", new Blend(purple, khaki));
IBlob pink = new Combo("pink", new Brighten(mauve));
IBlob coral = new Combo("coral", new Blend(pink, khaki));
boolean testIMixtureApply(Tester t) {
return t.checkExpect(new Darken(red).apply(), Color.red.darker()) &&
t.checkExpect(new Brighten(green).apply(), Color.green.brighter()) &&
t.checkExpect(new Blend(red, green).apply(), new Color(127, 127, 0));
}
boolean testIBlobGetFinalColor(Tester t) {
return t.checkExpect(red.getFinalColor(), Color.red) &&
t.checkExpect(purple.getFinalColor(), new Color(127, 0, 127));
}
boolean testIMixtureCountPaints(Tester t) {
return t.checkExpect(new Blend(neon, brown).countPaints(), 2) &&
t.checkExpect(new Darken(brown).countPaints(), 2);
}
boolean testIBlobCountPaints(Tester t) {
return t.checkExpect(red.countPaints(), 1) &&
t.checkExpect(purple.countPaints(), 2) &&
t.checkExpect(mauve.countPaints(), 4);
}
boolean testIMixtureFormulaDepth(Tester t) {
return t.checkExpect(new Blend(neon, purple).formulaDepth(), 2) &&
t.checkExpect(new Darken(neon).formulaDepth(), 1);
}
boolean testIBlobFormulaDepth(Tester t) {
return t.checkExpect(red.formulaDepth(), 0) &&
t.checkExpect(purple.formulaDepth(), 1) &&
t.checkExpect(darkPurple.formulaDepth(), 2) &&
t.checkExpect(coral.formulaDepth(), 4);
}
boolean testIMixtureInvert(Tester t) {
return t.checkExpect(new Blend(neon, brown).invert(), new Blend(neon, brown)) &&
t.checkExpect(new Darken(brown).invert(), new Brighten(brown)) &&
t.checkExpect(new Darken(new Combo("bright brown", new
Brighten(brown))).invert(), new Brighten(new
Combo("bright brown", new Darken(brown))));
}
boolean testIBlobInvert(Tester t) {
return t.checkExpect(red.invert(), red) &&
t.checkExpect(brightBrown.invert(), darkBrown) &&
t.checkExpect(brightNeonBrightBrown.invert(), darkNeonDarkBrown);
}
boolean testIBlobMixingFormula(Tester t) {
return t.checkExpect(red.mixingFormula(0), "red") &&
t.checkExpect(red.mixingFormula(1000), "red") &&
t.checkExpect(pink.mixingFormula(0), "pink") &&
t.checkExpect(pink.mixingFormula(1), "(brighten mauve)") &&
t.checkExpect(pink.mixingFormula(2), "(brighten (blend purple khaki))") &&
t.checkExpect(pink.mixingFormula(3), "(brighten (blend (blend red blue) (blend red green)))") &&
t.checkExpect(pink.mixingFormula(300), "(brighten (blend (blend red blue) (blend red green)))");
}
}
interface IBlob {
// Calculate the final color.
Color getFinalColor();
// Count how many solids were used.
int countPaints();
// Find the maximum number of blends used in a tree path.
int formulaDepth();
// Swap all darkens and brightens.
IBlob invert();
// Returns a string describing the steps to create the color, to a certain depth.
String mixingFormula(int depth);
}
class Solid implements IBlob {
String name;
Color color;
Solid(String name, Color color) {
this.name = name;
this.color = color;
}
public Color getFinalColor() { return this.color; }
public int countPaints() { return 1; }
public int formulaDepth() { return 0; }
public IBlob invert() { return this; }
public String mixingFormula(int _depth) { return this.name; }
}
class Combo implements IBlob {
String name;
IMixture mixture;
Combo(String name, IMixture mixture) {
this.name = name;
this.mixture = mixture;
}
public Color getFinalColor() {
return this.mixture.apply();
}
public int countPaints() {
return this.mixture.countPaints();
}
public int formulaDepth() {
return this.mixture.formulaDepth();
}
public IBlob invert() {
return new Combo(this.name, this.mixture.invert());
}
public String mixingFormula(int depth) {
return depth <= 0 ? this.name : this.mixture.mixingFormula(depth);
}
}
interface IMixture {
// Apply a mixture.
Color apply();
// Count how many solid IBlobs were used.
int countPaints();
// Count the deepest the mixtures are nested.
int formulaDepth();
// Swap all darkens and brightens.
IMixture invert();
String mixingFormula(int depth);
}
class Darken implements IMixture {
IBlob color;
Darken(IBlob color) {
this.color = color;
}
public Color apply() {
return this.color.getFinalColor().darker();
}
public int countPaints() {
// Adds black paint.
return this.color.countPaints() + 1;
}
public int formulaDepth() {
return 1 + this.color.formulaDepth();
}
public IMixture invert() {
return new Brighten(this.color.invert());
}
public String mixingFormula(int depth) {
return "(darken ".concat(this.color.mixingFormula(depth - 1)).concat(")");
}
}
class Brighten implements IMixture {
IBlob color;
Brighten(IBlob color) {
this.color = color;
}
public Color apply() {
return this.color.getFinalColor().brighter();
}
public int countPaints() {
// Adds white paint.
return this.color.countPaints() + 1;
}
public int formulaDepth() {
return 1 + this.color.formulaDepth();
}
public IMixture invert() {
return new Darken(this.color.invert());
}
public String mixingFormula(int depth) {
return "(brighten ".concat(this.color.mixingFormula(depth - 1)).concat(")");
}
}
class Blend implements IMixture {
IBlob colorOne;
IBlob colorTwo;
Blend(IBlob colorOne, IBlob colorTwo) {
this.colorOne = colorOne;
this.colorTwo = colorTwo;
}
public Color apply() {
Color finalColorOne = this.colorOne.getFinalColor();
Color finalColorTwo = this.colorTwo.getFinalColor();
int redOne = finalColorOne.getRed();
int redTwo = finalColorTwo.getRed();
int greenOne = finalColorOne.getGreen();
int greenTwo = finalColorTwo.getGreen();
int blueOne = finalColorOne.getBlue();
int blueTwo = finalColorTwo.getBlue();
return new Color(redOne/2 + redTwo/2, greenOne/2 + greenTwo/2, blueOne/2 + blueTwo/2);
}
public int countPaints() {
return this.colorOne.countPaints() + this.colorTwo.countPaints();
}
public int formulaDepth() {
return 1 + Math.max(this.colorOne.formulaDepth(), this.colorTwo.formulaDepth());
}
public IMixture invert() {
return new Blend(this.colorOne.invert(), this.colorTwo.invert());
}
public String mixingFormula(int depth) {
return "(blend ".concat(this.colorOne.mixingFormula(depth - 1))
.concat(" ")
.concat(this.colorTwo.mixingFormula(depth - 1))
.concat(")");
}
}