Mastermind
Számkitaláló játék
mastermind.c
Ugrás a fájl dokumentációjához.
1 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <time.h>
7 
9 enum {
10  NUM_COLORS = 10,
11  NUM_PEGS = 4,
12  N0 = 10000
13 };
14 
16 typedef struct {
17  int black;
18  int white;
19 } Response;
20 
25  printf("(%d,%d)", r.black, r.white);
26 }
27 
34  return r1.black == r2.black && r1.white == r2.white;
35 }
36 
41 void digits(int a, int d[]) {
42  int i;
43  for (i = 0; i < NUM_PEGS; ++i) {
44  d[i] = a % NUM_COLORS;
45  a /= NUM_COLORS;
46  }
47 }
48 
54 Response common_digits(int guess, int secret) {
55  Response res = {0, 0};
56  int i, j, dg[NUM_PEGS], ds[NUM_PEGS];
57 
58  digits(guess, dg); /* tipp jegyeinek számítása */
59  digits(secret, ds); /* titok jegyeimek számítása */
60 
61  /* fekete tüskék gyűjtése */
62  for (i = 0; i < NUM_PEGS; ++i)
63  if (dg[i] == ds[i]) {
64  res.black++;
65  dg[i] = -1;
66  ds[i] = -2;
67  }
68 
69  /* fehér tüskék gyűjtése */
70  for (i = 0; i < NUM_PEGS; ++i)
71  for (j = 0; j < NUM_PEGS; ++j)
72  if (dg[i] == ds[j]) {
73  res.white++;
74  ds[j] = -2;
75  break;
76  }
77 
78  return res;
79 }
80 
88 int filter(int S[], int N, int guess, Response response)
89 {
90  int n = 0, i;
91  for (i = 0; i < N; ++i)
92  if (isSameResponse(common_digits(S[i], guess), response))
93  S[n++] = S[i];
94  return n;
95 }
96 
104 int weight(int S[], int N, int guess, Response response)
105 {
106  int w = 0, i;
107  for (i = 0; i < N; ++i)
108  if (isSameResponse(response, common_digits(S[i], guess)))
109  w++;
110  return w;
111 }
112 
119 int worstWeightOfGuess(int S[], int N, int guess) {
120  Response r;
121  int Weight = 0;
122  for (r.black = 0; r.black <= NUM_PEGS; ++r.black)
123  for (r.white = 0; r.white < NUM_PEGS; ++r.white) {
124  int w;
125  if (r.black+r.white > NUM_PEGS)
126  continue;
127  w = weight(S, N, guess, r);
128  if (w > Weight)
129  Weight = w;
130  }
131  return Weight;
132 }
133 
139 int findBestGuess(int S[], int N) {
140  int ming = 0, g;
141  int W = worstWeightOfGuess(S, N, S[ming]);
142  for (g = 1; g < N; ++g) {
143  int w = worstWeightOfGuess(S, N, S[g]);
144  if (w < W) {
145  W = w;
146  ming = g;
147  }
148  }
149  return S[ming];
150 }
151 
153 int main(void) {
154  int S[N0], N, secret, i, k;
155 
156  srand(time(NULL));
157  secret = rand() % N0;
158  printf(" %04d\n", secret);
159  printf(" ------------\n");
160  k = 0;
161 
162  N = N0;
163  for (i = 0; i < N0; ++i)
164  S[i] = i;
165 
166  do {
167  time_t t0 = time(NULL);
168  int guess = findBestGuess(S, N);
169  double dt = difftime(time(NULL), t0);
170  Response response = common_digits(guess, secret);
171  N = filter(S, N, guess, response);
172 
173  k++;
174 
175  printf("%3d: %04d | ", k, guess);
176  printResponse(response);
177  printf(" %4d %5.2f\n", N, dt);
178  } while (N > 1);
179 
180  printf("%d", S[0]);
181 
182  return 0;
183 }
184 
digits
void digits(int a, int d[])
egész szám jegyeinek előállítása
Definition: mastermind.c:41
weight
int weight(int S[], int N, int guess, Response response)
tipp súlya egy adott válasz esetén
Definition: mastermind.c:104
N0
@ N0
összes lehetséges választás.
Definition: mastermind.c:12
common_digits
Response common_digits(int guess, int secret)
tipp és titkos szám közös jegyeinek meghatározása
Definition: mastermind.c:54
Response::white
int white
a fehér tüskék száma
Definition: mastermind.c:18
NUM_PEGS
@ NUM_PEGS
számjegyek száma
Definition: mastermind.c:11
isSameResponse
int isSameResponse(Response r1, Response r2)
két válasz megegyezik-e
Definition: mastermind.c:33
filter
int filter(int S[], int N, int guess, Response response)
Lehetséges megoldások halmazának szűrése tipp és válasz alapján.
Definition: mastermind.c:88
Response::black
int black
a fekete tüskék száma
Definition: mastermind.c:17
main
int main(void)
a főprogram
Definition: mastermind.c:153
findBestGuess
int findBestGuess(int S[], int N)
legjobb tipp kikeresése az S halmazból
Definition: mastermind.c:139
NUM_COLORS
@ NUM_COLORS
színek száma
Definition: mastermind.c:10
worstWeightOfGuess
int worstWeightOfGuess(int S[], int N, int guess)
tipp maximális súlya minden lehetséges válasz esetére
Definition: mastermind.c:119
Response
egy választ tároló típus
Definition: mastermind.c:16
printResponse
void printResponse(Response r)
egy válasz kiírása a képernyőre
Definition: mastermind.c:24