From f05d56e566e00bd1b6782a44a706c3a45ae769cf Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Tue, 19 Nov 2024 20:56:51 -0500 Subject: [PATCH] Updated Mastermind. --- mastermind/src/mastermind/Main.java | 136 ++++++++++++++++++++++------ 1 file changed, 109 insertions(+), 27 deletions(-) diff --git a/mastermind/src/mastermind/Main.java b/mastermind/src/mastermind/Main.java index d99bc15..d4c21c9 100644 --- a/mastermind/src/mastermind/Main.java +++ b/mastermind/src/mastermind/Main.java @@ -1,10 +1,8 @@ package mastermind; import java.awt.Color; -import java.awt.Image; import java.util.Random; import javalib.funworld.*; -import javalib.worldcanvas.*; import javalib.worldimages.*; import tester.Tester; @@ -343,7 +341,7 @@ class Game extends World { DEFAULTCONF, DEFAULTCONF.options.gen(DEFAULTCONF.len), DEFAULTCONF.nguesses, - new MtGuess(), + ConsPlaceholderGuess.mkN(DEFAULTCONF.nguesses), false, false ); @@ -360,6 +358,34 @@ class Game extends World { return this.bigBang(this.calcW(), this.calcH()); } + public Game onKeyEvent(String key) { + if ("123456789".contains(key)) { // User has entered a number. + int choice = Integer.valueOf(key); + return this.addDot(choice - 1); + //} else if (key.equals("backspace")) { + //return this.dropDot(); + } + return this; + } + + // Attempt to add the nth dot option to the incomplete guess. + Game addDot(int choice) { + return new Game( + this.conf, + this.solution, + this.guessesLeft, + this.guesses.addToIncomplete( + this.conf.options.get(choice), + this.conf.len + ), + this.won, + this.done + ); + } + + // Attempt to remove the last dot from the incomplete guess. + //Game dropDot() {} + // Calculate the width of the window without drawing anything. int calcW() { return ( @@ -372,7 +398,10 @@ class Game extends World { // 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.) + return ( + ((this.conf.nguesses + 2) * Dot.r * 2) + + ((this.conf.nguesses) * Util.gapW) + ); } // Draw the current game state. @@ -413,29 +442,6 @@ class Game extends World { 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 - ); - } } // A game configuration. @@ -471,6 +477,7 @@ class GameConf { // A list of guesses. interface ILoGuess { WorldImage draw(); + ILoGuess addToIncomplete(Dot dot, int limit); } class ConsGuess implements ILoGuess { @@ -486,6 +493,59 @@ class ConsGuess implements ILoGuess { public WorldImage draw() { return Util.pairGapAbove(guess.draw(), this.nxt.draw()); } + + public ILoGuess addToIncomplete(Dot dot, int limit) { + return this.nxt.addToIncomplete(dot, limit); + } +} + +class ConsIncompleteGuess implements ILoGuess { + + IncompleteGuess guessSoFar; + ILoGuess nxt; + + ConsIncompleteGuess(IncompleteGuess guessSoFar, ILoGuess nxt) { + this.guessSoFar = guessSoFar; + this.nxt = nxt; + } + + public WorldImage draw() { + return Util.pairGapAbove(guessSoFar.draw(), this.nxt.draw()); + } + + public ILoGuess addToIncomplete(Dot dot, int limit) { + return new ConsIncompleteGuess( + this.guessSoFar.tryAppend(dot, limit), + this.nxt + ); + } +} + +// Placeholder for guesses yet to be guessed. +class ConsPlaceholderGuess implements ILoGuess { + + ILoGuess nxt; + + ConsPlaceholderGuess(ILoGuess nxt) { + this.nxt = nxt; + } + + public WorldImage draw() { + return Util.pairGapAbove( + new RectangleImage(1, 2 * Dot.r, OutlineMode.SOLID, Color.BLACK), + this.nxt.draw() + ); + } + + // Fill a list with n placeholders. + static ILoGuess mkN(int n) { + if (n == 0) return new MtGuess(); + return new ConsPlaceholderGuess(mkN(n - 1)); + } + + public ILoGuess addToIncomplete(Dot dot, int limit) { + return this.nxt.addToIncomplete(dot, limit); + } } class MtGuess implements ILoGuess { @@ -493,6 +553,10 @@ class MtGuess implements ILoGuess { public WorldImage draw() { return new EmptyImage(); } + + public ILoGuess addToIncomplete(Dot dot, int limit) { + return this; + } } // A guess. @@ -523,6 +587,14 @@ class IncompleteGuess { WorldImage draw() { return guessSoFar.draw(); } + + // Append the dot, unless length exceeds limit. + IncompleteGuess tryAppend(Dot dot, int limit) { + if (this.guessSoFar.len() + 1 <= limit) return new IncompleteGuess( + this.guessSoFar.append(dot) + ); + else return this; + } } // Feedback for a guess. @@ -582,6 +654,8 @@ interface ILoDot { WorldImage draw(); // Draw the dots. int getW(); // Get the total width, in pixels, of the list. + + ILoDot append(Dot dot); } class ConsDot implements ILoDot { @@ -600,6 +674,10 @@ class ConsDot implements ILoDot { this(dot, nxt, new Random()); } + public ILoDot append(Dot dot) { + return new ConsDot(this.dot, this.nxt.append(dot), this.rand); + } + public ILoDot gen(int n) { return n <= 0 ? new MtDot() @@ -703,6 +781,10 @@ class ConsDot implements ILoDot { class MtDot implements ILoDot { + public ILoDot append(Dot dot) { + return new ConsDot(dot, this); + } + public ILoDot gen(int n) { return new MtDot(); }