Skip to content
Snippets Groups Projects
Commit fb919841 authored by sbalev's avatar sbalev
Browse files

Code toolkit

parent 9aba659f
Branches
No related merge requests found
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);
}
}
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();
final int PEG_SIZE = 40;
final int GAP = 10;
int code;
int t;
void setup() {
size(310, 560);
background(191);
code = int(random(M));
tk.displayCode(code, GAP, GAP, PEG_SIZE, false);
t = 0;
}
void draw() {
t++;
int guess = int(random(M));
int y = GAP + (GAP + PEG_SIZE) * t;
tk.displayCode(guess, GAP, y, PEG_SIZE, false);
int f = tk.feedback(code, guess);
displayFeedback(f, 2 * GAP + N * PEG_SIZE, y + PEG_SIZE / 4);
if (f == 0 || t == 10) noLoop();
}
void displayFeedback(int f, int x, int y) {
int[] bw = new int[2];
tk.decodeFeedback(f, bw);
stroke(0);
for (int k = 0; k < bw[0] + bw[1]; k++) {
fill(k < bw[0] ? 0: 255);
rect(x, y, PEG_SIZE / 2, PEG_SIZE / 2);
x += PEG_SIZE / 2 + GAP;
}
}
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