From bb35bd5aabd97c037aef686709db2f62d3eca3c8 Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Tue, 5 Nov 2024 16:31:17 -0500 Subject: [PATCH] Added trees. --- trees/src/trees/Main.java | 269 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 269 insertions(+) create mode 100644 trees/src/trees/Main.java diff --git a/trees/src/trees/Main.java b/trees/src/trees/Main.java new file mode 100644 index 0000000..911b994 --- /dev/null +++ b/trees/src/trees/Main.java @@ -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(")"); + } +} \ No newline at end of file