diff --git a/fibonacci/src/fibonacci/Main.java b/fibonacci/src/fibonacci/Main.java index 6ddb399..33339ca 100644 --- a/fibonacci/src/fibonacci/Main.java +++ b/fibonacci/src/fibonacci/Main.java @@ -36,7 +36,8 @@ class Examples { } // A generic list. -interface ILo {} +interface ILo { +} class Cons implements ILo { @@ -49,7 +50,8 @@ class Cons implements ILo { } } -class Mt implements ILo {} +class Mt implements ILo { +} interface ISequence { // Returns the current element in the sequence. @@ -78,19 +80,14 @@ class Fibonacci implements ISequence { public Integer get() { int ret; // What to return. /* - - idx pen pre ret - 0 0 1 0 - 1 0 1 1 - 2 1 1 2 - 3 1 2 3 - 4 2 3 5 - 5 3 5 8 - - */ + * + * idx pen pre ret 0 0 1 0 1 0 1 1 2 1 1 2 3 1 2 3 4 2 3 5 5 3 5 8 + * + */ // F(0) = 0; F(1) = 1 - if (this.idx <= 1) ret = this.idx; + if (this.idx <= 1) + ret = this.idx; else { // F(n) = F(n-1) + F(n-2) ret = this.pre + this.pen; diff --git a/mastermind/src/mastermind/Main.java b/mastermind/src/mastermind/Main.java index 6a6003d..d99bc15 100644 --- a/mastermind/src/mastermind/Main.java +++ b/mastermind/src/mastermind/Main.java @@ -1,164 +1,334 @@ package mastermind; -import tester.Tester; import java.awt.Color; import java.awt.Image; import java.util.Random; -import javalib.worldimages.*; import javalib.funworld.*; import javalib.worldcanvas.*; +import javalib.worldimages.*; +import tester.Tester; class Examples { - ILoInt noInt = new MtInt(), - intsOne = new ConsInt(1, new ConsInt(2, new ConsInt(3, noInt))); - Dot redDot = new Dot(Color.red), - greenDot = new Dot(Color.green), - blueDot = new Dot(Color.blue), - reenDot = new Dot(new Color(255, 255, 0)); - - ILoDot noDot = new MtDot(), - dotsOne = new ConsDot(redDot, new ConsDot(greenDot, new ConsDot(blueDot, noDot)), new Random(0)), - dotsTwo = new ConsDot(redDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot))), - dotsThree = new ConsDot(reenDot, new ConsDot(reenDot, new ConsDot(reenDot, noDot))), - exampleDotsOne = new ConsDot(redDot, new ConsDot(greenDot, new ConsDot(blueDot, new ConsDot(greenDot, new ConsDot(redDot, new ConsDot(greenDot, noDot)))))), - exampleDotsTwo = new ConsDot(redDot, new ConsDot(blueDot, new ConsDot(greenDot, new ConsDot(greenDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot)))))), - exampleDotsOneNoExact = new ConsDot(greenDot, new ConsDot(blueDot, new ConsDot(redDot, new ConsDot(greenDot, noDot)))), - exampleDotsTwoNoExact = new ConsDot(blueDot, new ConsDot(greenDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot)))); - + ILoInt noInt = new MtInt(); + ILoInt intsOne = new ConsInt(1, new ConsInt(2, new ConsInt(3, noInt))); + + Dot redDot = new Dot(Color.red); + Dot greenDot = new Dot(Color.green); + Dot blueDot = new Dot(Color.blue); + Dot reenDot = new Dot(new Color(255, 255, 0)); + + ILoDot noDot = new MtDot(); + ILoDot dotsOne = new ConsDot( + redDot, + new ConsDot(greenDot, new ConsDot(blueDot, noDot)), + new Random(0) + ); + ILoDot dotsTwo = new ConsDot( + redDot, + new ConsDot(blueDot, new ConsDot(blueDot, noDot)) + ); + ILoDot dotsThree = new ConsDot( + reenDot, + new ConsDot(reenDot, new ConsDot(reenDot, noDot)) + ); + ILoDot exampleDotsOne = new ConsDot( + redDot, + new ConsDot( + greenDot, + new ConsDot( + blueDot, + new ConsDot( + greenDot, + new ConsDot(redDot, new ConsDot(greenDot, noDot)) + ) + ) + ) + ); + ILoDot exampleDotsTwo = new ConsDot( + redDot, + new ConsDot( + blueDot, + new ConsDot( + greenDot, + new ConsDot( + greenDot, + new ConsDot(blueDot, new ConsDot(blueDot, noDot)) + ) + ) + ) + ); + ILoDot exampleDotsOneNoExact = new ConsDot( + greenDot, + new ConsDot(blueDot, new ConsDot(redDot, new ConsDot(greenDot, noDot))) + ); + ILoDot exampleDotsTwoNoExact = new ConsDot( + blueDot, + new ConsDot(greenDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot))) + ); + Feedback exampleFeedback = new Feedback(2, 2); - + Game exampleGame = new Game(); - + + boolean testDrawMethods(Tester t) { + // WorldImage incomplete = new IncompleteGuess(exampleDotsOne).draw(); + // WorldImage guesses = new ConsGuess(new Guess(dotsOne, new Feedback(1, 2)), + // new ConsGuess(new Guess(dotsTwo, new Feedback(2, 5)), new MtGuess())).draw(); + //Game game = new Game().addGuess(new Guess(dotsOne, exampleFeedback)); + + /* + WorldImage gameImg = game.draw(); + + int w = (int) gameImg.getWidth(); + int h = (int) gameImg.getHeight(); + + WorldCanvas c = new WorldCanvas(w, h); + WorldScene s = new WorldScene(w, h); + */ + + return exampleGame.launch(); + // c.drawScene(s.placeImageXY(gameImg, w/2, h/2)) + // c.drawScene(s.placeImageXY(incomplete, (int) (incomplete.getWidth()/2), 100)) + // c.drawScene(s.placeImageXY(exampleFeedback.draw(), 100, 100)) + // c.drawScene(s.placeImageXY(redDot.draw(), 100, 100)) + // c.drawScene(s.placeImageXY(dotsOne.draw(), 250, 250)) + // && c.show(); + // true; + } + boolean testILoDotLen(Tester t) { return t.checkExpect(noDot.len(), 0) && t.checkExpect(dotsOne.len(), 3); } - + boolean testILoDotGetnth(Tester t) { - return t.checkException(new IllegalArgumentException("Index out of bounds."), noDot, "get", 1) - && t.checkException(new IllegalArgumentException("Index out of bounds."), dotsOne, "get", 3) - && t.checkExpect(dotsOne.get(0), redDot) - && t.checkExpect(dotsOne.get(2), blueDot); + return ( + t.checkException( + new IllegalArgumentException("Index out of bounds."), + noDot, + "get", + 1 + ) && + t.checkException( + new IllegalArgumentException("Index out of bounds."), + dotsOne, + "get", + 3 + ) && + t.checkExpect(dotsOne.get(0), redDot) && + t.checkExpect(dotsOne.get(2), blueDot) + ); } - + boolean testILoDotGen(Tester t) { - return t.checkExpect(noDot.gen(219), noDot) - && t.checkExpect(dotsOne.gen(1), new ConsDot(redDot, noDot)) - && t.checkExpect(dotsOne.gen(3), new ConsDot(greenDot, new ConsDot(greenDot, new ConsDot(blueDot, noDot)))); + return ( + t.checkExpect(noDot.gen(219), noDot) && + t.checkExpect(dotsOne.gen(1), new ConsDot(redDot, noDot)) && + t.checkExpect( + dotsOne.gen(3), + new ConsDot( + greenDot, + new ConsDot(greenDot, new ConsDot(blueDot, noDot)) + ) + ) + ); } - + boolean testILoDotIn(Tester t) { - return t.checkExpect(dotsOne.in(blueDot), true) - && t.checkExpect(noDot.in(redDot), false) - && t.checkExpect(dotsThree.in(blueDot), false); + return ( + t.checkExpect(dotsOne.in(blueDot), true) && + t.checkExpect(noDot.in(redDot), false) && + t.checkExpect(dotsThree.in(blueDot), false) + ); } - + boolean testILoIntRemove(Tester t) { - return t.checkExpect(intsOne.remove(0), new ConsInt(2, new ConsInt(3, noInt))) - && t.checkExpect(intsOne.remove(2), new ConsInt(1, new ConsInt(2, noInt))) - && t.checkException(new IllegalArgumentException("Index out of bounds: cannot remove something from nothing."), intsOne, "remove", 3) - && t.checkException(new IllegalArgumentException("Index out of bounds: cannot remove something from nothing."), noInt, "remove", 0) - && t.checkException(new IllegalArgumentException("Indices must be positive."), intsOne, "remove", -2); + return ( + t.checkExpect( + intsOne.remove(0), + new ConsInt(2, new ConsInt(3, noInt)) + ) && + t.checkExpect( + intsOne.remove(2), + new ConsInt(1, new ConsInt(2, noInt)) + ) && + t.checkException( + new IllegalArgumentException( + "Index out of bounds: cannot remove something from nothing." + ), + intsOne, + "remove", + 3 + ) && + t.checkException( + new IllegalArgumentException( + "Index out of bounds: cannot remove something from nothing." + ), + noInt, + "remove", + 0 + ) && + t.checkException( + new IllegalArgumentException("Indices must be positive."), + intsOne, + "remove", + -2 + ) + ); } - + boolean testILoIntLen(Tester t) { return t.checkExpect(intsOne.len(), 3) && t.checkExpect(noInt.len(), 0); } - + boolean testILoIntSubOne(Tester t) { - return t.checkExpect(intsOne.subOne(), new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt)))); + return t.checkExpect( + intsOne.subOne(), + new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt))) + ); } - + boolean testILoDotExactIndices(Tester t) { - return t.checkException(new IllegalArgumentException("Empty list doesn't exactly match anything."), noDot, "exactIndices", noDot) - && t.checkExpect(dotsOne.exactIndices(dotsOne), new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt)))) - && t.checkExpect(dotsOne.exactIndices(dotsTwo), new ConsInt(0, new ConsInt(2, new MtInt()))); + return ( + t.checkException( + new IllegalArgumentException( + "Empty list doesn't exactly match anything." + ), + noDot, + "exactIndices", + noDot + ) && + t.checkExpect( + dotsOne.exactIndices(dotsOne), + new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt))) + ) && + t.checkExpect( + dotsOne.exactIndices(dotsTwo), + new ConsInt(0, new ConsInt(2, new MtInt())) + ) + ); } - + boolean testILoDotRemove(Tester t) { - return t.checkException(new IllegalArgumentException("Index out of bounds."), noDot, "remove", 0) - && t.checkExpect(dotsOne.remove(0), new ConsDot(greenDot, new ConsDot(blueDot, noDot))) - && t.checkExpect(dotsTwo.remove(1), new ConsDot(redDot, new ConsDot(blueDot, noDot))); + return ( + t.checkException( + new IllegalArgumentException("Index out of bounds."), + noDot, + "remove", + 0 + ) && + t.checkExpect( + dotsOne.remove(0), + new ConsDot(greenDot, new ConsDot(blueDot, noDot)) + ) && + t.checkExpect( + dotsTwo.remove(1), + new ConsDot(redDot, new ConsDot(blueDot, noDot)) + ) + ); } - + boolean testILoDotRemoveAll(Tester t) { - return t.checkExpect(dotsOne.removeAll(noInt), dotsOne) - && t.checkExpect(dotsOne.removeAll(new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt)))), noDot) - && t.checkExpect(noDot.removeAll(intsOne), noDot) - && t.checkExpect(dotsTwo.removeAll(new ConsInt(1, new ConsInt(2, noInt))), new ConsDot(redDot, noDot)); + return ( + t.checkExpect(dotsOne.removeAll(noInt), dotsOne) && + t.checkExpect( + dotsOne.removeAll( + new ConsInt(0, new ConsInt(1, new ConsInt(2, noInt))) + ), + noDot + ) && + t.checkExpect(noDot.removeAll(intsOne), noDot) && + t.checkExpect( + dotsTwo.removeAll(new ConsInt(1, new ConsInt(2, noInt))), + new ConsDot(redDot, noDot) + ) + ); } - + boolean testILoDotCountInexact(Tester t) { - return t.checkExpect(noDot.countInexact(noDot), 0) - && t.checkExpect(dotsOne.countInexact(dotsOne), 3) - && t.checkExpect(exampleDotsOneNoExact.countInexact(exampleDotsTwoNoExact), 2); + return ( + t.checkExpect(noDot.countInexact(noDot), 0) && + t.checkExpect(dotsOne.countInexact(dotsOne), 3) && + t.checkExpect( + exampleDotsOneNoExact.countInexact(exampleDotsTwoNoExact), + 2 + ) + ); } - + boolean testILoDotCompare(Tester t) { - return t.checkExpect(exampleDotsOne.compare(exampleDotsTwo), exampleFeedback) - && t.checkExpect(dotsOne.compare(dotsOne), new Feedback(3, 0)); - } - - boolean testDrawMethods(Tester t) { - // WorldImage incomplete = new IncompleteGuess(exampleDotsOne).draw(); - //WorldImage guesses = new ConsGuess(new Guess(dotsOne, new Feedback(1, 2)), new ConsGuess(new Guess(dotsTwo, new Feedback(2, 5)), new MtGuess())).draw(); - Game game = new Game().addGuess(new Guess(dotsOne, exampleFeedback)); - - WorldImage gameImg = game.draw(); - - int w = (int) gameImg.getWidth(); - int h = (int) gameImg.getHeight(); - - WorldCanvas c = new WorldCanvas(w, h); - WorldScene s = new WorldScene(w, h); - - return game.launch(); - //c.drawScene(s.placeImageXY(gameImg, w/2, h/2)) - //c.drawScene(s.placeImageXY(incomplete, (int) (incomplete.getWidth()/2), 100)) - //c.drawScene(s.placeImageXY(exampleFeedback.draw(), 100, 100)) - //c.drawScene(s.placeImageXY(redDot.draw(), 100, 100)) - //c.drawScene(s.placeImageXY(dotsOne.draw(), 250, 250)) - //&& c.show(); - //true; + return ( + t.checkExpect( + exampleDotsOne.compare(exampleDotsTwo), + exampleFeedback + ) && + t.checkExpect(dotsOne.compare(dotsOne), new Feedback(3, 0)) + ); } } class Util { + static int scale = 2; static int fontSz = 24 * scale; - static int gapW = 4 * scale; // The gap between objects. - + static int gapW = 4 * scale; // The gap between objects. + // Drawing methods. - static WorldImage gap = new RectangleImage(gapW, gapW, "outline", new Color(0, 0, 0, 0)); + static WorldImage gap = new RectangleImage( + gapW, + gapW, + "outline", + new Color(0, 0, 0, 0) + ); + static WorldImage pairGap(WorldImage img1, WorldImage img2) { return new BesideAlignImage(AlignModeY.MIDDLE, img1, gap, img2); } - + static WorldImage pairGapAbove(WorldImage img1, WorldImage img2) { return new AboveAlignImage(AlignModeX.CENTER, img1, gap, img2); } - + static WorldImage strPair(String str1, String str2) { - return pairGap(new TextImage(str1, fontSz, Color.black), new TextImage(str2, fontSz, Color.black)); + return pairGap( + new TextImage(str1, fontSz, Color.black), + new TextImage(str2, fontSz, Color.black) + ); } - + static int pairgapW = 2 * 16 * scale + gapW; } // A game state. class Game extends World { - static ILoDot DEFAULTDOTS = new ConsDot(new Dot(Color.RED), new ConsDot(new Dot(Color.GREEN), new ConsDot(new Dot(Color.BLUE), new MtDot()))); + + static ILoDot DEFAULTDOTS = new ConsDot( + new Dot(Color.RED), + new ConsDot( + new Dot(Color.GREEN), + new ConsDot(new Dot(Color.BLUE), new MtDot()) + ) + ); static GameConf DEFAULTCONF = new GameConf(true, 5, 5, DEFAULTDOTS); - - GameConf conf; // The game's configuration. - ILoDot solution; // The solution to the game. - int guessesLeft; // The number of guesses the player has left. - ILoGuess guesses; // The guesses the player has taken. - boolean done; // Is the game over? - boolean won; // Did they player win? - - Game(GameConf conf, ILoDot solution, int guessesLeft, ILoGuess guesses, boolean won, boolean done) { - if (this.won && !this.done) throw new IllegalArgumentException("Can't win before you've finished playing."); + + GameConf conf; // The game's configuration. + ILoDot solution; // The solution to the game. + int guessesLeft; // The number of guesses the player has left. + ILoGuess guesses; // The guesses the player has taken. + boolean done; // Is the game over? + boolean won; // Did they player win? + + Game( + GameConf conf, + ILoDot solution, + int guessesLeft, + ILoGuess guesses, + boolean won, + boolean done + ) { + if (this.won && !this.done) throw new IllegalArgumentException( + "Can't win before you've finished playing." + ); this.conf = conf; this.solution = solution; this.won = won; @@ -166,71 +336,130 @@ class Game extends World { this.guessesLeft = guessesLeft; this.guesses = guesses; } - + // Convenience constructor using default config and starting values. - Game() { this(DEFAULTCONF, DEFAULTCONF.options.gen(DEFAULTCONF.len), DEFAULTCONF.nguesses, new MtGuess(), false, false); } - + Game() { + this( + DEFAULTCONF, + DEFAULTCONF.options.gen(DEFAULTCONF.len), + DEFAULTCONF.nguesses, + new MtGuess(), + false, + false + ); + } + public WorldScene makeScene() { - WorldScene bg = this.getEmptyScene(); - WorldImage dot = new Dot(Color.RED).draw(); - return bg.placeImageXY(dot , (int)dot.getWidth(), (int)dot.getHeight()); + WorldImage img = this.draw(); + int w = (int) img.getWidth(), h = (int) img.getHeight(); + WorldScene bg = new WorldScene(w, h); + return bg.placeImageXY(img, (int) w / 2, (int) h / 2); } - + boolean launch() { - return this.bigBang(100, 100); + return this.bigBang(this.calcW(), this.calcH()); } - + + // Calculate the width of the window without drawing anything. + int calcW() { + return ( + (this.conf.len * Dot.r * 2) + // The width of all the dots. + ((this.conf.len + 1) * Util.gapW) + // The width of all the spaces between the dots. + Util.fontSz * 2 + // The width of the feedback numbers. + Util.gapW // The width of the gap between the feedback numbers. + ); + } + + // Calculate the height of the window without drawing anything. + int calcH() { + return ((this.conf.nguesses + 2) * Dot.r * 2); // Width of all the guess rows, plus the two rows above and below (for solution and options respectively.) + } + // Draw the current game state. WorldImage draw() { - return new AboveAlignImage(AlignModeX.LEFT, this.draw_sol(), this.draw_guesses(), this.draw_options()); + return new AboveAlignImage( + AlignModeX.LEFT, + this.draw_sol(), + this.draw_guesses(), + this.draw_options() + ); } - + // Draw the solution. WorldImage draw_sol() { if (this.done) return this.draw_sol_rev(); else return this.draw_sol_hid(); } - + // Draw the revealed answer. WorldImage draw_sol_rev() { return this.solution.draw(); } - + // Draw the hidden answer. WorldImage draw_sol_hid() { - return new RectangleImage(this.solution.getW(), 2*Dot.r, OutlineMode.SOLID, Color.BLACK); + return new RectangleImage( + this.solution.getW(), + 2 * Dot.r, + OutlineMode.SOLID, + Color.BLACK + ); } - + WorldImage draw_guesses() { return this.guesses.draw(); } - + WorldImage draw_options() { return this.conf.options.draw(); } - + // Convenience methods for testing -- not part of program. - Game win() { return new Game(this.conf, this.solution, this.guessesLeft, this.guesses, true, true); } - Game addGuess(Guess guess) { return new Game(this.conf, this.solution, this.guessesLeft, new ConsGuess(guess, this.guesses), this.won, this.done); } + Game win() { + return new Game( + this.conf, + this.solution, + this.guessesLeft, + this.guesses, + true, + true + ); + } + + Game addGuess(Guess guess) { + return new Game( + this.conf, + this.solution, + this.guessesLeft, + new ConsGuess(guess, this.guesses), + this.won, + this.done + ); + } } // A game configuration. class GameConf { - boolean dups; // Whether duplicates are allowed. - int len; // The length of the sequence to be guessed. - int nguesses; // Number of guesses the player is allowed. + + boolean dups; // Whether duplicates are allowed. + int len; // The length of the sequence to be guessed. + int nguesses; // Number of guesses the player is allowed. ILoDot options; // The dots of which the solution is comprised. - + GameConf(boolean dups, int len, int nguesses, ILoDot options) { - if (len <= 0) - throw new IllegalArgumentException("Length of the solution must be greater than 0."); - if (nguesses <= 0) - throw new IllegalArgumentException("Must provide the player some guesses."); + if (len <= 0) throw new IllegalArgumentException( + "Length of the solution must be greater than 0." + ); + if (nguesses <= 0) throw new IllegalArgumentException( + "Must provide the player some guesses." + ); int oplen = options.len(); - if (oplen <= 0) - throw new IllegalArgumentException("Must have dot options to guess with."); - if (!dups && len > oplen) - throw new IllegalArgumentException("Cant create solution of that length without duplicates."); + if (oplen <= 0) throw new IllegalArgumentException( + "Must have dot options to guess with." + ); + if (!dups && len > oplen) throw new IllegalArgumentException( + "Cant create solution of that length without duplicates." + ); this.dups = dups; this.len = len; @@ -245,120 +474,175 @@ interface ILoGuess { } class ConsGuess implements ILoGuess { + Guess guess; ILoGuess nxt; - + ConsGuess(Guess guess, ILoGuess nxt) { this.guess = guess; this.nxt = nxt; } - + public WorldImage draw() { return Util.pairGapAbove(guess.draw(), this.nxt.draw()); } } class MtGuess implements ILoGuess { + public WorldImage draw() { return new EmptyImage(); } } +// A guess. class Guess { - ILoDot guess; // The dots the user entered. - Feedback feedback; // The feedback returned. - + + ILoDot guess; // The dots the user entered. + Feedback feedback; // The feedback returned. + Guess(ILoDot guess, Feedback feedback) { - this.guess = guess; - this.feedback = feedback; + this.guess = guess; + this.feedback = feedback; } - + WorldImage draw() { return Util.pairGap(this.guess.draw(), this.feedback.draw()); } } +// A guess in the midst of being entered. class IncompleteGuess { + ILoDot guessSoFar; - + IncompleteGuess(ILoDot guessSoFar) { this.guessSoFar = guessSoFar; } - + WorldImage draw() { return guessSoFar.draw(); } } +// Feedback for a guess. class Feedback { - int exact, - inexact; - + + int exact, inexact; + Feedback(int exact, int inexact) { - this.exact = exact; - this.inexact = inexact; + this.exact = exact; + this.inexact = inexact; } - + Feedback add(Feedback other) { - int otherExact = other.exact, - otherInexact = other.inexact; - - return new Feedback(this.exact + otherExact, this.inexact + otherInexact); + int otherExact = other.exact, otherInexact = other.inexact; + + return new Feedback( + this.exact + otherExact, + this.inexact + otherInexact + ); } - + WorldImage draw() { - return Util.strPair(String.valueOf(this.exact), String.valueOf(this.exact)); + return Util.strPair( + String.valueOf(this.exact), + String.valueOf(this.exact) + ); } } +// A list of dots. interface ILoDot { - int len(); // Get length. - Dot get(int n); // Get nth element. - ILoDot remove(int n); // Remove nth element. - ILoDot removeAll(ILoInt indices); // Remove element at each index. - ILoDot gen(int n); // Generate randomized list. + int len(); // Get length. - boolean match(Color col); // Do the colors match? - boolean in(Dot dot); // Is the dot in here? + Dot get(int n); // Get nth element. + + ILoDot remove(int n); // Remove nth element. + + ILoDot removeAll(ILoInt indices); // Remove element at each index. + + ILoDot gen(int n); // Generate randomized list. + + boolean match(Color col); // Do the colors match? + + boolean in(Dot dot); // Is the dot in here? + + Feedback compare(ILoDot other); // Compare two lists & give feedback. + + ILoInt exactIndices(ILoDot other); // Get indices of exact matches. - Feedback compare(ILoDot other); // Compare two lists & give feedback. - ILoInt exactIndices(ILoDot other); // Get indices of exact matches. ILoInt exactIndicesHelper(ILoDot other, int i); - int countInexact(ILoDot other); // Get the number of inexact matches. Must be fed exact match-free lists to be accurate. + + int countInexact(ILoDot other); // Get the number of inexact matches. Must be fed exact match-free lists to be + // accurate. + int countInexactHelper(ILoDot other, ILoDot seen); - - WorldImage draw(); // Draw the dots. - int getW(); // Get the total width, in pixels, of the list. + + WorldImage draw(); // Draw the dots. + + int getW(); // Get the total width, in pixels, of the list. } class ConsDot implements ILoDot { + Random rand; Dot dot; ILoDot nxt; - + ConsDot(Dot dot, ILoDot nxt, Random rand) { this.rand = rand; this.dot = dot; this.nxt = nxt; } - ConsDot(Dot dot, ILoDot nxt) { this(dot, nxt, new Random()); } - - public ILoDot gen(int n) { - return n <= 0 ? new MtDot() : new ConsDot(this.get(this.rand.nextInt(this.len())), this.gen(n - 1)); + + ConsDot(Dot dot, ILoDot nxt) { + this(dot, nxt, new Random()); } + + public ILoDot gen(int n) { + return n <= 0 + ? new MtDot() + : new ConsDot( + this.get(this.rand.nextInt(this.len())), + this.gen(n - 1) + ); + } + public Dot get(int n) { if (n == 0) return this.dot; else return this.nxt.get(n - 1); } - public boolean in(Dot dot) { return dot.equals(this.dot) || this.nxt.in(dot); } - public int len() { return 1 + this.nxt.len(); } - public boolean match(Color col) { return col.equals(this.dot.c); } - - public WorldImage draw() { return new BesideAlignImage(AlignModeY.PINHOLE, this.dot.draw(), Util.gap, this.nxt.draw()); } - public int getW() { return this.len() * Dot.r * 2; } - + + public boolean in(Dot dot) { + return dot.equals(this.dot) || this.nxt.in(dot); + } + + public int len() { + return 1 + this.nxt.len(); + } + + public boolean match(Color col) { + return col.equals(this.dot.c); + } + + public WorldImage draw() { + return new BesideAlignImage( + AlignModeY.PINHOLE, + this.dot.draw(), + Util.gap, + this.nxt.draw() + ); + } + + public int getW() { + return this.len() * Dot.r * 2; + } + public Feedback compare(ILoDot other) { - if (this.len() != other.len()) throw new IllegalArgumentException("Cannot compare different lengthed lists."); + if (this.len() != other.len()) throw new IllegalArgumentException( + "Cannot compare different lengthed lists." + ); ILoInt exactIndices = this.exactIndices(other); @@ -371,36 +655,46 @@ class ConsDot implements ILoDot { return new Feedback(exact, inexact); } - public ILoInt exactIndices(ILoDot other) { return this.exactIndicesHelper(other, 0); } + public ILoInt exactIndices(ILoDot other) { + return this.exactIndicesHelper(other, 0); + } public ILoInt exactIndicesHelper(ILoDot other, int i) { // Stop after reaching the end of the list. if (i == this.len()) return new MtInt(); - - return this.get(i).equals(other.get(i)) ? - new ConsInt(i, this.exactIndicesHelper(other, i + 1)) - : this.exactIndicesHelper(other, i + 1); + + return this.get(i).equals(other.get(i)) + ? new ConsInt(i, this.exactIndicesHelper(other, i + 1)) + : this.exactIndicesHelper(other, i + 1); } - + public int countInexact(ILoDot other) { - return this.countInexactHelper(other, new MtDot()); + return this.countInexactHelper(other, new MtDot()); } - + public int countInexactHelper(ILoDot other, ILoDot seen) { if (seen.in(this.dot)) { - return this.nxt.countInexactHelper(other, new ConsDot(this.dot, seen)); + return this.nxt.countInexactHelper( + other, + new ConsDot(this.dot, seen) + ); } - - return (other.in(this.dot) ? 1 : 0) + this.nxt.countInexactHelper(other, new ConsDot(this.dot, seen)); + + return ( + (other.in(this.dot) ? 1 : 0) + + this.nxt.countInexactHelper(other, new ConsDot(this.dot, seen)) + ); } - + public ILoDot remove(int n) { - if (n < 0) throw new IllegalArgumentException("Indices must be positive."); - + if (n < 0) throw new IllegalArgumentException( + "Indices must be positive." + ); + if (n == 0) return this.nxt; else return new ConsDot(this.dot, this.nxt.remove(n - 1)); } - + public ILoDot removeAll(ILoInt indices) { if (indices.isEmpty()) return this; return this.remove(indices.first()).removeAll(indices.rest().subOne()); @@ -408,74 +702,171 @@ class ConsDot implements ILoDot { } class MtDot implements ILoDot { - public ILoDot gen(int n) { return new MtDot(); } - public Dot get(int n) { throw new IllegalArgumentException("Index out of bounds."); } - public int len() { return 0; } - public WorldImage draw() { return new EmptyImage(); } - public int getW() { return 0; } - public Feedback compare(ILoDot other) { return new Feedback(0, 0); } - public boolean match(Color col) { return false; } - public boolean in(Dot dot) { return false; } - public ILoInt exactIndices(ILoDot other) { - throw new IllegalArgumentException("Empty list doesn't exactly match anything."); + + public ILoDot gen(int n) { + return new MtDot(); + } + + public Dot get(int n) { + throw new IllegalArgumentException("Index out of bounds."); + } + + public int len() { + return 0; + } + + public WorldImage draw() { + return new EmptyImage(); + } + + public int getW() { + return 0; + } + + public Feedback compare(ILoDot other) { + return new Feedback(0, 0); + } + + public boolean match(Color col) { + return false; + } + + public boolean in(Dot dot) { + return false; + } + + public ILoInt exactIndices(ILoDot other) { + throw new IllegalArgumentException( + "Empty list doesn't exactly match anything." + ); + } + + public ILoInt exactIndicesHelper(ILoDot other, int i) { + return new MtInt(); + } + + public int countInexact(ILoDot other) { + return 0; + } + + public int countInexactHelper(ILoDot other, ILoDot seen) { + return 0; + } + + public ILoDot remove(int n) { + throw new IllegalArgumentException("Index out of bounds."); + } + + public ILoDot removeAll(ILoInt indices) { + return this; } - public ILoInt exactIndicesHelper(ILoDot other, int i) { return new MtInt(); } - public int countInexact(ILoDot other) { return 0; } - public int countInexactHelper(ILoDot other, ILoDot seen) { return 0; } - public ILoDot remove(int n) { throw new IllegalArgumentException("Index out of bounds."); } - public ILoDot removeAll(ILoInt indices) { return this; } } +// A dot. class Dot { + static int r = 16 * Util.scale; static OutlineMode outlineMode = OutlineMode.SOLID; - + Color c; - - Dot(Color c) { this.c = c; } - + + Dot(Color c) { + this.c = c; + } + // Draw the dot. - WorldImage draw() { return new CircleImage(r, outlineMode, this.c); } - + WorldImage draw() { + return new CircleImage(r, outlineMode, this.c); + } + // Get the width of the dot. - int getW() { return 2 * r; } + int getW() { + return 2 * r; + } } // A list of integers. interface ILoInt { - int len(); // Get the length of the list. - ILoInt remove(int n); // Remove the nth element of the list. - boolean isEmpty(); // Is it empty? - int first(); // Get the first value. - ILoInt rest(); // Get the rest value. - ILoInt subOne(); // Subtract 1 from every int. + int len(); // Get the length of the list. + + ILoInt remove(int n); // Remove the nth element of the list. + + boolean isEmpty(); // Is it empty? + + int first(); // Get the first value. + + ILoInt rest(); // Get the rest value. + + ILoInt subOne(); // Subtract 1 from every int. } class ConsInt implements ILoInt { + int val; ILoInt nxt; - + ConsInt(int val, ILoInt nxt) { this.val = val; this.nxt = nxt; } - - public int len() { return 1 + this.nxt.len(); } - public ILoInt remove(int n) { - if (n < 0) throw new IllegalArgumentException("Indices must be positive."); - return n == 0 ? this.nxt : new ConsInt(this.val, this.nxt.remove(n - 1)); + + public int len() { + return 1 + this.nxt.len(); + } + + public ILoInt remove(int n) { + if (n < 0) throw new IllegalArgumentException( + "Indices must be positive." + ); + return n == 0 + ? this.nxt + : new ConsInt(this.val, this.nxt.remove(n - 1)); + } + + public boolean isEmpty() { + return false; + } + + public int first() { + return this.val; + } + + public ILoInt rest() { + return this.nxt; + } + + public ILoInt subOne() { + return new ConsInt(this.val - 1, this.nxt.subOne()); } - public boolean isEmpty() { return false; } - public int first() { return this.val; } - public ILoInt rest() { return this.nxt; } - public ILoInt subOne() { return new ConsInt(this.val - 1, this.nxt.subOne()); } } class MtInt implements ILoInt { - public int len() { return 0; } - public ILoInt remove(int n) { throw new IllegalArgumentException("Index out of bounds: cannot remove something from nothing."); } - public boolean isEmpty() { return true; } - public int first() { throw new IllegalArgumentException("Cannot get first element in a list without any."); } - public ILoInt rest() { throw new IllegalArgumentException("Cannot get rest of empty list."); } - public ILoInt subOne() { return this; } -} \ No newline at end of file + + public int len() { + return 0; + } + + public ILoInt remove(int n) { + throw new IllegalArgumentException( + "Index out of bounds: cannot remove something from nothing." + ); + } + + public boolean isEmpty() { + return true; + } + + public int first() { + throw new IllegalArgumentException( + "Cannot get first element in a list without any." + ); + } + + public ILoInt rest() { + throw new IllegalArgumentException("Cannot get rest of empty list."); + } + + public ILoInt subOne() { + return this; + } +}