Mastermind.

This commit is contained in:
Jacob Signorovitch
2024-11-04 22:03:01 -05:00
parent c019f37677
commit 00ea869448

View File

@@ -22,7 +22,11 @@ class Examples {
dotsTwo = new ConsDot(redDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot))), dotsTwo = new ConsDot(redDot, new ConsDot(blueDot, new ConsDot(blueDot, noDot))),
dotsThree = new ConsDot(reenDot, new ConsDot(reenDot, new ConsDot(reenDot, 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)))))), 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)))))); 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))));
Feedback exampleFeedback = new Feedback(2, 2);
Game exampleGame = new Game(); Game exampleGame = new Game();
@@ -84,25 +88,35 @@ class Examples {
&& t.checkExpect(dotsTwo.removeAll(new ConsInt(1, new ConsInt(2, noInt))), new ConsDot(redDot, noDot)); && t.checkExpect(dotsTwo.removeAll(new ConsInt(1, new ConsInt(2, noInt))), new ConsDot(redDot, noDot));
} }
boolean testILoDotCountInexact(Tester t) { return true; } boolean testILoDotCountInexact(Tester t) {
return t.checkExpect(noDot.countInexact(noDot), 0)
&& t.checkExpect(dotsOne.countInexact(dotsOne), 3)
&& t.checkExpect(exampleDotsOneNoExact.countInexact(exampleDotsTwoNoExact), 2);
}
/*
boolean testILoDotCompare(Tester t) { boolean testILoDotCompare(Tester t) {
return t.checkExpect(exampleDotsOne.compare(exampleDotsTwo), new Feedback(2, 2)); return t.checkExpect(exampleDotsOne.compare(exampleDotsTwo), exampleFeedback)
}*/ && t.checkExpect(dotsOne.compare(dotsOne), new Feedback(3, 0));
}
boolean testDrawMethods(Tester t) { boolean testDrawMethods(Tester t) {
WorldCanvas c = new WorldCanvas(1000, 1000); WorldCanvas c = new WorldCanvas(1000, 1000);
WorldScene s = new WorldScene(1000, 1000); WorldScene s = new WorldScene(1000, 1000);
return return
// c.drawScene(s.placeImageXY(exampleGame.draw(), 0, 0)) c.drawScene(s.placeImageXY(exampleFeedback.draw(), 100, 100))
//c.drawScene(s.placeImageXY(redDot.draw(), 100, 100)) //c.drawScene(s.placeImageXY(redDot.draw(), 100, 100))
//c.drawScene(s.placeImageXY(dotsOne.draw(), 250, 250)) //c.drawScene(s.placeImageXY(dotsOne.draw(), 250, 250))
//&& c.show(); && c.show();
true; //true;
} }
} }
class Util {
static int scale = 2;
static int gapw = 4 * scale; // The gap between objects.
static WorldImage gap = new RectangleImage(gapw, gapw, "outline", new Color(0, 0, 0, 0));
}
// A game state. // A game state.
class Game { class Game {
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())));
@@ -151,7 +165,7 @@ class GameConf {
} }
} }
// A list of guesses; // A list of guesses.
interface ILoGuess {} interface ILoGuess {}
class ConsGuess implements ILoGuess { class ConsGuess implements ILoGuess {
@@ -167,8 +181,8 @@ class ConsGuess implements ILoGuess {
class MtGuess implements ILoGuess {} class MtGuess implements ILoGuess {}
class Guess { class Guess {
ILoDot guess; ILoDot guess; // The dots the user entered.
Feedback feedback; Feedback feedback; // The feedback returned.
Guess(ILoDot guess, Feedback feedback) { Guess(ILoDot guess, Feedback feedback) {
this.guess = guess; this.guess = guess;
@@ -191,6 +205,17 @@ class Feedback {
return new Feedback(this.exact + otherExact, this.inexact + otherInexact); return new Feedback(this.exact + otherExact, this.inexact + otherInexact);
} }
WorldImage draw() {
WorldImage exactDigit = new TextImage(String.valueOf(this.exact), 16 * Util.scale, FontStyle.BOLD, Color.BLACK);
WorldImage inexactDigit = new TextImage(String.valueOf(this.inexact), 16 * Util.scale, FontStyle.BOLD, Color.BLACK);
return new BesideAlignImage(AlignModeY.MIDDLE, exactDigit, Util.gap, inexactDigit);
}
int getW() {
return 2 * 16 * Util.scale + Util.gapw;
}
} }
interface ILoDot { interface ILoDot {
@@ -207,8 +232,10 @@ interface ILoDot {
ILoInt exactIndices(ILoDot other); // Get indices of exact matches. ILoInt exactIndices(ILoDot other); // Get indices of exact matches.
ILoInt exactIndicesHelper(ILoDot other, int i); 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. WorldImage draw(); // Draw the dots.
int getW(); // Get the total width, in pixels, of the list.
} }
class ConsDot implements ILoDot { class ConsDot implements ILoDot {
@@ -234,7 +261,8 @@ class ConsDot implements ILoDot {
public int len() { return 1 + this.nxt.len(); } public int len() { return 1 + this.nxt.len(); }
public boolean match(Color col) { return col.equals(this.dot.c); } public boolean match(Color col) { return col.equals(this.dot.c); }
public WorldImage draw() { return new BesideAlignImage(AlignModeY.PINHOLE, this.dot.draw(), this.nxt.draw()); } 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) { 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.");
@@ -256,12 +284,21 @@ class ConsDot implements ILoDot {
// Stop after reaching the end of the list. // Stop after reaching the end of the list.
if (i == this.len()) return new MtInt(); if (i == this.len()) return new MtInt();
return this.get(i).equals(other.get(i)) ? new ConsInt(i, this.exactIndicesHelper(other, i + 1)) return this.get(i).equals(other.get(i)) ?
: this.exactIndicesHelper(other, i + 1); new ConsInt(i, this.exactIndicesHelper(other, i + 1))
: this.exactIndicesHelper(other, i + 1);
} }
public int countInexact(ILoDot other) { public int countInexact(ILoDot other) {
return 0; 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 (other.in(this.dot) ? 1 : 0) + this.nxt.countInexactHelper(other, new ConsDot(this.dot, seen));
} }
public ILoDot remove(int n) { public ILoDot remove(int n) {
@@ -282,6 +319,7 @@ class MtDot implements ILoDot {
public Dot get(int n) { throw new IllegalArgumentException("Index out of bounds."); } public Dot get(int n) { throw new IllegalArgumentException("Index out of bounds."); }
public int len() { return 0; } public int len() { return 0; }
public WorldImage draw() { return new EmptyImage(); } public WorldImage draw() { return new EmptyImage(); }
public int getW() { return 0; }
public Feedback compare(ILoDot other) { return new Feedback(0, 0); } public Feedback compare(ILoDot other) { return new Feedback(0, 0); }
public boolean match(Color col) { return false; } public boolean match(Color col) { return false; }
public boolean in(Dot dot) { return false; } public boolean in(Dot dot) { return false; }
@@ -289,15 +327,14 @@ class MtDot implements ILoDot {
throw new IllegalArgumentException("Empty list doesn't exactly match anything."); throw new IllegalArgumentException("Empty list doesn't exactly match anything.");
} }
public ILoInt exactIndicesHelper(ILoDot other, int i) { return new MtInt(); } public ILoInt exactIndicesHelper(ILoDot other, int i) { return new MtInt(); }
public int countInexact(ILoDot other) { public int countInexact(ILoDot other) { return 0; }
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 remove(int n) { throw new IllegalArgumentException("Index out of bounds."); }
public ILoDot removeAll(ILoInt indices) { return this; } public ILoDot removeAll(ILoInt indices) { return this; }
} }
class Dot { class Dot {
static int r = 32; static int r = 16 * Util.scale;
static OutlineMode outlineMode = OutlineMode.SOLID; static OutlineMode outlineMode = OutlineMode.SOLID;
Color c; Color c;
@@ -306,6 +343,9 @@ class Dot {
// Draw the dot. // 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; }
} }
// A list of integers. // A list of integers.