Updated Mastermind.

This commit is contained in:
Jacob Signorovitch
2024-11-19 20:56:51 -05:00
parent 0f8c20aa73
commit f05d56e566

View File

@@ -1,10 +1,8 @@
package mastermind; package mastermind;
import java.awt.Color; import java.awt.Color;
import java.awt.Image;
import java.util.Random; import java.util.Random;
import javalib.funworld.*; import javalib.funworld.*;
import javalib.worldcanvas.*;
import javalib.worldimages.*; import javalib.worldimages.*;
import tester.Tester; import tester.Tester;
@@ -343,7 +341,7 @@ class Game extends World {
DEFAULTCONF, DEFAULTCONF,
DEFAULTCONF.options.gen(DEFAULTCONF.len), DEFAULTCONF.options.gen(DEFAULTCONF.len),
DEFAULTCONF.nguesses, DEFAULTCONF.nguesses,
new MtGuess(), ConsPlaceholderGuess.mkN(DEFAULTCONF.nguesses),
false, false,
false false
); );
@@ -360,6 +358,34 @@ class Game extends World {
return this.bigBang(this.calcW(), this.calcH()); 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. // Calculate the width of the window without drawing anything.
int calcW() { int calcW() {
return ( return (
@@ -372,7 +398,10 @@ class Game extends World {
// Calculate the height of the window without drawing anything. // Calculate the height of the window without drawing anything.
int calcH() { 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. // Draw the current game state.
@@ -413,29 +442,6 @@ class Game extends World {
WorldImage draw_options() { WorldImage draw_options() {
return this.conf.options.draw(); 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. // A game configuration.
@@ -471,6 +477,7 @@ class GameConf {
// A list of guesses. // A list of guesses.
interface ILoGuess { interface ILoGuess {
WorldImage draw(); WorldImage draw();
ILoGuess addToIncomplete(Dot dot, int limit);
} }
class ConsGuess implements ILoGuess { class ConsGuess implements ILoGuess {
@@ -486,6 +493,59 @@ class ConsGuess implements ILoGuess {
public WorldImage draw() { public WorldImage draw() {
return Util.pairGapAbove(guess.draw(), this.nxt.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 { class MtGuess implements ILoGuess {
@@ -493,6 +553,10 @@ class MtGuess implements ILoGuess {
public WorldImage draw() { public WorldImage draw() {
return new EmptyImage(); return new EmptyImage();
} }
public ILoGuess addToIncomplete(Dot dot, int limit) {
return this;
}
} }
// A guess. // A guess.
@@ -523,6 +587,14 @@ class IncompleteGuess {
WorldImage draw() { WorldImage draw() {
return guessSoFar.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. // Feedback for a guess.
@@ -582,6 +654,8 @@ interface ILoDot {
WorldImage draw(); // Draw the dots. WorldImage draw(); // Draw the dots.
int getW(); // Get the total width, in pixels, of the list. int getW(); // Get the total width, in pixels, of the list.
ILoDot append(Dot dot);
} }
class ConsDot implements ILoDot { class ConsDot implements ILoDot {
@@ -600,6 +674,10 @@ class ConsDot implements ILoDot {
this(dot, nxt, new Random()); 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) { public ILoDot gen(int n) {
return n <= 0 return n <= 0
? new MtDot() ? new MtDot()
@@ -703,6 +781,10 @@ class ConsDot implements ILoDot {
class MtDot implements ILoDot { class MtDot implements ILoDot {
public ILoDot append(Dot dot) {
return new ConsDot(dot, this);
}
public ILoDot gen(int n) { public ILoDot gen(int n) {
return new MtDot(); return new MtDot();
} }