Added mastermind.
This commit is contained in:
12
mastermind/.classpath
Normal file
12
mastermind/.classpath
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="module" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="lib" path="/home/jacob/Documents/javalib.jar"/>
|
||||||
|
<classpathentry kind="lib" path="/home/jacob/Documents/tester.jar"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
17
mastermind/.project
Normal file
17
mastermind/.project
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>mastermind</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
2
mastermind/.settings/org.eclipse.core.resources.prefs
Normal file
2
mastermind/.settings/org.eclipse.core.resources.prefs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding/<project>=UTF-8
|
11
mastermind/.settings/org.eclipse.jdt.core.prefs
Normal file
11
mastermind/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=21
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||||
|
org.eclipse.jdt.core.compiler.release=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.source=21
|
348
mastermind/src/mastermind/One.java
Normal file
348
mastermind/src/mastermind/One.java
Normal file
@@ -0,0 +1,348 @@
|
|||||||
|
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.*;
|
||||||
|
|
||||||
|
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))))));
|
||||||
|
|
||||||
|
Game exampleGame = new Game();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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))));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean testILoDotIn(Tester t) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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))));
|
||||||
|
}
|
||||||
|
|
||||||
|
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())));
|
||||||
|
}
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean testILoDotCountInexact(Tester t) { return true; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
boolean testILoDotCompare(Tester t) {
|
||||||
|
return t.checkExpect(exampleDotsOne.compare(exampleDotsTwo), new Feedback(2, 2));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
boolean testDrawMethods(Tester t) {
|
||||||
|
WorldCanvas c = new WorldCanvas(1000, 1000);
|
||||||
|
WorldScene s = new WorldScene(1000, 1000);
|
||||||
|
return
|
||||||
|
// c.drawScene(s.placeImageXY(exampleGame.draw(), 0, 0))
|
||||||
|
//c.drawScene(s.placeImageXY(redDot.draw(), 100, 100))
|
||||||
|
//c.drawScene(s.placeImageXY(dotsOne.draw(), 250, 250))
|
||||||
|
//&& c.show();
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A game state.
|
||||||
|
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 GameConf DEFAULTCONF = new GameConf(true, 5, 5, DEFAULTDOTS);
|
||||||
|
|
||||||
|
GameConf conf;
|
||||||
|
int guessesLeft;
|
||||||
|
ILoGuess guesses;
|
||||||
|
|
||||||
|
Game(GameConf conf, int guessesLeft, ILoGuess guesses) {
|
||||||
|
this.conf = conf;
|
||||||
|
this.guessesLeft = guessesLeft;
|
||||||
|
this.guesses = guesses;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience constructor using default config.
|
||||||
|
Game() { this(DEFAULTCONF, DEFAULTCONF.nguesses, new MtGuess()); }
|
||||||
|
|
||||||
|
WorldImage draw() {
|
||||||
|
return new EmptyImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
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.");
|
||||||
|
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.");
|
||||||
|
|
||||||
|
this.dups = dups;
|
||||||
|
this.len = len;
|
||||||
|
this.nguesses = nguesses;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A list of guesses;
|
||||||
|
interface ILoGuess {}
|
||||||
|
|
||||||
|
class ConsGuess implements ILoGuess {
|
||||||
|
Guess guess;
|
||||||
|
ILoGuess nxt;
|
||||||
|
|
||||||
|
ConsGuess(Guess guess, ILoGuess nxt) {
|
||||||
|
this.guess = guess;
|
||||||
|
this.nxt = nxt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MtGuess implements ILoGuess {}
|
||||||
|
|
||||||
|
class Guess {
|
||||||
|
ILoDot guess;
|
||||||
|
Feedback feedback;
|
||||||
|
|
||||||
|
Guess(ILoDot guess, Feedback feedback) {
|
||||||
|
this.guess = guess;
|
||||||
|
this.feedback = feedback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Feedback {
|
||||||
|
int exact,
|
||||||
|
inexact;
|
||||||
|
|
||||||
|
Feedback(int exact, int 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
|
||||||
|
WorldImage draw(); // Draw the dots.
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
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(), this.nxt.draw()); }
|
||||||
|
|
||||||
|
public Feedback compare(ILoDot other) {
|
||||||
|
if (this.len() != other.len()) throw new IllegalArgumentException("Cannot compare different lengthed lists.");
|
||||||
|
|
||||||
|
ILoInt exactIndices = this.exactIndices(other);
|
||||||
|
|
||||||
|
ILoDot thisWithoutExact = this.removeAll(exactIndices);
|
||||||
|
ILoDot otherWithoutExact = other.removeAll(exactIndices);
|
||||||
|
|
||||||
|
int exact = exactIndices.len();
|
||||||
|
int inexact = thisWithoutExact.countInexact(otherWithoutExact);
|
||||||
|
|
||||||
|
return new Feedback(exact, inexact);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countInexact(ILoDot other) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILoDot remove(int n) {
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 ILoDot remove(int n) { throw new IllegalArgumentException("Index out of bounds."); }
|
||||||
|
public ILoDot removeAll(ILoInt indices) { return this; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Dot {
|
||||||
|
static int r = 32;
|
||||||
|
static OutlineMode outlineMode = OutlineMode.SOLID;
|
||||||
|
|
||||||
|
Color c;
|
||||||
|
|
||||||
|
Dot(Color c) { this.c = c; }
|
||||||
|
|
||||||
|
// Draw the dot.
|
||||||
|
WorldImage draw() { return new CircleImage(r, outlineMode, this.c); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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; }
|
||||||
|
}
|
Reference in New Issue
Block a user