Commit 78d6e5cd authored by sbalev's avatar sbalev

Common classes reside in lib

parent f081317f
class CodeToolkit {
final int N; // Code length
final int C; // Number of colors
final int M; // Numbre of possible codes
final int F; // Number of possible feedbacks
// Count vectors. Used locally in _feedback()
// but defined here to avoid reallocations
int[] d1, d2;
// Precomputed feedback matrix
int[][] feedbacks;
CodeToolkit(int codeLength, int colorCount) {
// Initialise constants
N = codeLength;
C = colorCount;
int m = 1;
for (int i = 0; i < N; i++) {
m *= C;
}
M = m;
F = (N + 1) * (N + 2) / 2;
// allocate arrays
d1 = new int[C];
d2 = new int[C];
feedbacks = new int[M][M];
// Precomputing feedbacks
for (int code1 = 0; code1 < M; code1++) {
for (int code2 = code1; code2 < M; code2++) {
feedbacks[code1][code2] = feedbacks[code2][code1] = _feedback(code1, code2);
}
}
}
int feedback(int code, int guess) {
return feedbacks[code][guess];
}
void decodeFeedback(int f, int[] bw) {
int s = 0;
int i = 0;
while (s + i <= f) {
s += i;
i++;
}
i--;
bw[0] = N - i;
bw[1] = f - s;
}
String codeToString(int code) {
String s = "";
for (int i = 0; i < N; i++) {
s = code % C + s;
code /= C;
}
return s;
}
void displayCode(int code, int x, int y, int pegSize, boolean eliminated) {
stroke(0);
rectMode(CORNER);
colorMode(HSB, C, 1, 1, 1);
for (int i = N - 1; i >= 0; i--) {
int c = code % C;
fill(color(c, 1, 1, eliminated ? 0.25 : 1));
rect(x + i * pegSize, y, pegSize, pegSize);
code /= C;
}
colorMode(RGB, 255, 255, 255, 255);
}
void displayCode(int code, int x, int y, int pegSize) {
displayCode(code, x, y, pegSize, false);
}
int _encodeFeedback(int black, int white) {
return (N - black) * (N - black + 1) / 2 + white;
}
int _feedback(int code1, int code2) {
for (int c = 0; c < C; c++) {
d1[c] = d2[c] = 0;
}
int black = 0;
for (int i = 0; i < N; i++) {
int c1 = code1 % C;
int c2 = code2 % C;
if (c1 == c2) {
black++;
} else {
d1[c1]++;
d2[c2]++;
}
code1 /= C;
code2 /= C;
}
int white = 0;
for (int c = 0; c < C; c++) {
white += min(d1[c], d2[c]);
}
return _encodeFeedback(black, white);
}
}
class CodeToolkit {
// Count vectors. Used locally in _feedback() but defined here for performance reasons
int[] d1 = new int[C];
int[] d2 = new int[C];
// Precomputed feedback matrix
int[][] feedbacks = new int[M][M];
CodeToolkit() {
// Precomputing feedbacks
for (int code1 = 0; code1 < M; code1++) {
for (int code2 = code1; code2 < M; code2++) {
feedbacks[code1][code2] = feedbacks[code2][code1] = _feedback(code1, code2);
}
}
}
int feedback(int code, int guess) {
return feedbacks[code][guess];
}
void decodeFeedback(int f, int[] bw) {
int s = 0;
int i = 0;
while (s + i <= f) {
s += i;
i++;
}
i--;
bw[0] = N - i;
bw[1] = f - s;
}
String codeToString(int code) {
String s = "";
for (int i = 0; i < N; i++) {
s = code % C + s;
code /= C;
}
return s;
}
void displayCode(int code, int x, int y, int pegSize, boolean eliminated) {
stroke(0);
rectMode(CORNER);
colorMode(HSB, C, 1, 1, 1);
for (int i = N - 1; i >= 0; i--) {
int c = code % C;
fill(color(c, 1, 1, eliminated ? 0.25 : 1));
rect(x + i * pegSize, y, pegSize, pegSize);
code /= C;
}
colorMode(RGB, 255, 255, 255, 255);
}
int _encodeFeedback(int black, int white) {
return (N - black) * (N - black + 1) / 2 + white;
}
int _feedback(int code1, int code2) {
for (int c = 0; c < C; c++) {
d1[c] = d2[c] = 0;
}
int black = 0;
for (int i = 0; i < N; i++) {
int c1 = code1 % C;
int c2 = code2 % C;
if (c1 == c2) {
black++;
} else {
d1[c1]++;
d2[c2]++;
}
code1 /= C;
code2 /= C;
}
int white = 0;
for (int c = 0; c < C; c++) {
white += min(d1[c], d2[c]);
}
return _encodeFeedback(black, white);
}
}
../../lib/CodeToolkit.pde
\ No newline at end of file
final int N = 4; // Code length
final int C = 6; // Number of colors
final int M = round(pow(C, N)); // Number of possible codes
final int F = (N + 1) * (N + 2) / 2; // Number of possible feedbacks
CodeToolkit tk = new CodeToolkit();
CodeToolkit tk = new CodeToolkit(4, 6);
final int PEG_SIZE = 40;
final int GAP = 10;
......@@ -15,8 +9,8 @@ int t;
void setup() {
size(310, 570);
background(191);
code = int(random(M));
tk.displayCode(code, GAP, GAP, PEG_SIZE, false);
code = int(random(tk.M));
tk.displayCode(code, GAP, GAP, PEG_SIZE);
line(GAP, 2 * GAP + PEG_SIZE, GAP + 4 * PEG_SIZE, 2 * GAP + PEG_SIZE);
println(tk.codeToString(code));
println("----");
......@@ -25,12 +19,12 @@ void setup() {
void draw() {
t++;
int guess = int(random(M));
int guess = int(random(tk.M));
int y = 2 * GAP + (GAP + PEG_SIZE) * t;
tk.displayCode(guess, GAP, y, PEG_SIZE, false);
tk.displayCode(guess, GAP, y, PEG_SIZE);
print(tk.codeToString(guess));
int f = tk.feedback(code, guess);
displayFeedback(f, 2 * GAP + N * PEG_SIZE, y + PEG_SIZE / 4);
displayFeedback(f, 2 * GAP + tk.N * PEG_SIZE, y + PEG_SIZE / 4);
if (f == 0 || t == 10) noLoop();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment