/* $Id$ */ #include "bbs.h" #define LOGPASS BBSHOME "/etc/winguess.log" static int check_data(const char *str) { int i, j; if (strlen(str) != 4) return -1; for (i = 0; i < 4; i++) if (str[i] < '0' || str[i] > '9') return -1; for (i = 0; i < 4; i++) for (j = i + 1; j < 4; j++) if (str[i] == str[j]) return -1; return 1; } static char * get_data(char data[5], int count) { while (1) { getdata(6, 0, "輸入四位數字(不重複): ", data, 5, LCECHO); if (check_data(data) == 1) break; } return data; } static int guess_play(const char *data, const char *answer, int count) { int A_num = 0, B_num = 0; int i, j; for (i = 0; i < 4; i++) { if (data[i] == answer[i]) A_num++; for (j = 0; j < 4; j++) if (i == j) continue; else if (data[i] == answer[j]) { B_num++; break; } } if (A_num == 4) return 1; move(count + 8, 55); prints("%s => " ANSI_COLOR(1;32) "%dA %dB" ANSI_RESET, data, A_num, B_num); return 0; } static int result(int correct, int number) { char a = 0, b = 0, i, j; char n1[5], n2[5]; snprintf(n1, sizeof(n1), "%04d", correct); snprintf(n2, sizeof(n2), "%04d", number); for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) if (n1[(int)i] == n2[(int)j]) b++; for (i = 0; i < 4; i++) if (n1[(int)i] == n2[(int)i]) { b--; a++; } return 10 * a + b; } static int legal(int number) { char i, j; char temp[5]; snprintf(temp, sizeof(temp), "%04d", number); for (i = 0; i < 4; i++) for (j = i + 1; j < 4; j++) if (temp[(int)i] == temp[(int)j]) return 0; return 1; } static void initcomputer(char flag[]) { int i; for (i = 0; i < 10000; i++) if (legal(i)) flag[i] = 1; else flag[i] = 0; } static int computer(int correct, int total, char flag[], int n[]) { int guess; static int j; int k, i; char data[5]; if (total == 1) { do { guess = random() % 10000; } while (!legal(guess)); } else guess = n[random() % j]; k = result(correct, guess); if (k == 40) { move(total + 8, 25); snprintf(data, sizeof(data), "%04d", guess); prints("%s => 猜中了!!", data); return 1; } else { move(total + 8, 25); snprintf(data, sizeof(data), "%04d", guess); prints("%s => " ANSI_COLOR(1;32) "%dA %dB" ANSI_RESET, data, k / 10, k % 10); } j = 0; for (i = 0; i < 10000; i++) if (flag[i]) { if (result(i, guess) != k) flag[i] = 0; else n[j++] = i; } return 0; } static void Diff_Random(char *answer) { register int i = 0, j, k; while (i < 4) { k = random() % 10 + '0'; for (j = 0; j < i; j++) if (k == answer[j]) break; if (j == i) { answer[j] = k; i++; } } answer[4] = 0; } int guess_main(void) { char data[5]; char computerwin = 0, youwin = 0; int count = 0, c_count = 0; char ifcomputer[2]; char answer[5]; char yournum[5]; const int max_guess = 10; // these variables are not very huge, no need to use malloc // to prevent heap allocation. char flag[10000]; int n[1500]; setutmpmode(GUESSNUM); clear(); showtitle("猜數字", BBSName); Diff_Random(answer); move(2, 0); clrtoeol(); getdata(4, 0, "您要和電腦比賽嗎? [y]:", ifcomputer, sizeof(ifcomputer), LCECHO); *ifcomputer = (*ifcomputer == 'n') ? 0 : 1; if (ifcomputer[0]) { do { getdata(5, 0, "請輸入您要讓電腦猜的數字: ", yournum, sizeof(yournum), LCECHO); } while (!legal(atoi(yournum))); move(8, 25); outs("電腦猜"); initcomputer(flag); } move(8, 55); outs("你猜"); while (((!computerwin || !youwin) && count < max_guess && (ifcomputer[0])) || (!ifcomputer[0] && count < max_guess && !youwin)) { if (!computerwin && ifcomputer[0]) { ++c_count; if (computer(atoi(yournum), c_count, flag, n)) computerwin = 1; } move(20, 55); prints("第 %d/%d 次機會 ", count + 1, max_guess); if (!youwin) { ++count; if (guess_play(get_data(data, count), answer, count)) youwin = 1; } } move(17, 33); if (ifcomputer[0]) { if (count > c_count) { outs(" 你輸給電腦了"); } else if (count < c_count) { outs("真厲害, 讓你猜到囉"); } else { prints("真厲害, 和電腦打成平手了"); } pressanykey(); return 1; } if (youwin) { if (count < 5) { outs("真厲害!"); } else if (count > 5) { outs("唉, 太多次才猜出來了"); } else { outs("五次猜出來, 還可以~"); move(18, 35); clrtoeol(); } pressanykey(); return 1; } move(17, 32); prints("嘿嘿 標準答案是 %s ", answer); move(18, 32); outs("下次再來吧"); pressanykey(); return 1; }