diff options
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/Makefile | 2 | ||||
-rw-r--r-- | mbbsd/guess.c | 242 | ||||
-rw-r--r-- | mbbsd/menu.c | 10 | ||||
-rw-r--r-- | mbbsd/othello.c | 568 |
4 files changed, 5 insertions, 817 deletions
diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 723e0d39..4f199b42 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -16,7 +16,7 @@ UTILOBJS = stuff.o kaede.o convert.o name.o syspost.o PAGEROBJS= more.o pmore.o PLUGOBJS = lovepaper.o calendar.o topsong.o gamble.o vice.o angel.o CHESSOBJS= chc.o chc_tab.o chess.o go.o gomo.o dark.o reversi.o -GAMEOBJS = card.o guess.o chicken.o othello.o +GAMEOBJS = card.o chicken.o OBJS:= admin.o assess.o edit.o menu.o xyz.o var.o visio.o \ vote.o voteboard.o \ $(COREOBJS) $(ACCOBJS) $(NETOBJS) $(TALKOBJS) $(UTILOBJS) \ diff --git a/mbbsd/guess.c b/mbbsd/guess.c deleted file mode 100644 index dea421b5..00000000 --- a/mbbsd/guess.c +++ /dev/null @@ -1,242 +0,0 @@ -/* $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/n>[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; -} diff --git a/mbbsd/menu.c b/mbbsd/menu.c index aad3493a..15841fcf 100644 --- a/mbbsd/menu.c +++ b/mbbsd/menu.c @@ -801,12 +801,10 @@ static int chessroom() { static const commands_t plist[] = { {ticket_main, PERM_LOGINOK, "11Gamble 【 " BBSMNAME2 "賭場 】"}, - {guess_main, PERM_LOGINOK, "22Guess number【 猜數字 】"}, - {othello_main, PERM_LOGINOK, "33Othello 【 黑白棋 】"}, - {vice_main, PERM_LOGINOK, "44Vice 【 發票對獎 】"}, - {g_card_jack, PERM_LOGINOK, "55Jack 【 黑傑克 】"}, - {g_ten_helf, PERM_LOGINOK, "66Tenhalf 【 十點半 】"}, - {card_99, PERM_LOGINOK, "77Nine 【 九十九 】"}, + {vice_main, PERM_LOGINOK, "22Vice 【 發票對獎 】"}, + {g_card_jack, PERM_LOGINOK, "33Jack 【 黑傑克 】"}, + {g_ten_helf, PERM_LOGINOK, "44Tenhalf 【 十點半 】"}, + {card_99, PERM_LOGINOK, "55Nine 【 九十九 】"}, {NULL, 0, NULL} }; diff --git a/mbbsd/othello.c b/mbbsd/othello.c deleted file mode 100644 index 27e385dc..00000000 --- a/mbbsd/othello.c +++ /dev/null @@ -1,568 +0,0 @@ -/* $Id$ */ -#include "bbs.h" - -#define LOGFILE "etc/othello.log" -#define NR_TABLE 2 - -#define true 1 -#define false 0 -#define STARTX 3 -#define STARTY 20 -#define NONE_CHESS " " -#define WHITE_CHESS "●" -#define BLACK_CHESS "○" -#define HINT_CHESS "#" -#define NONE 0 -#define HINT 1 -#define BLACK 2 -#define WHITE 3 - -#define INVERT(COLOR) (((COLOR))==WHITE?BLACK:WHITE) - -struct OthelloData { - char nowx, nowy; - char number[2]; - - char pass; - char if_hint; - int think, which_table; - - char nowboard[10][10]; - char evaltable[NR_TABLE + 1][10][10]; -}; - -static const char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS}; -static const char DIRX[] = {-1, -1, -1, 0, 1, 1, 1, 0}; -static const char DIRY[] = {-1, 0, 1, 1, 1, 0, -1, -1}; -static const char init_table[NR_TABLE + 1][5][5] = { - {{0, 0, 0, 0, 0}, - {0, 30, -3, 2, 2}, - {0, -3, -3, -1, -1}, - {0, 2, -1, 1, 1}, - {0, 2, -1, 1, 0}}, - - {{0, 0, 0, 0, 0}, - {0, 70, 5, 20, 30}, - {0, 5, -5, 3, 3}, - {0, 20, 3, 5, 5}, - {0, 30, 3, 5, 5}}, - - {{0, 0, 0, 0, 0}, - {0, 5, 2, 2, 2}, - {0, 2, 1, 1, 1}, - {0, 2, 1, 1, 1}, - {0, 2, 1, 1, 1}} -}; - -static void -print_chess(struct OthelloData *od, int x, int y, char chess) -{ - move(STARTX - 1 + x * 2, STARTY - 2 + y * 4); - if (chess != HINT || od->if_hint == 1) - outs(CHESS_TYPE[(int)chess]); - else - outs(CHESS_TYPE[NONE]); - refresh(); -} - -static void -printboard(struct OthelloData *od) -{ - int i; - - move(STARTX, STARTY); - outs("┌─┬─┬─┬─┬─┬─┬─┬─┐"); - for (i = 0; i < 7; i++) { - move(STARTX + 1 + i * 2, STARTY); - outs("│ │ │ │ │ │ │ │ │"); - move(STARTX + 2 + i * 2, STARTY); - outs("├─┼─┼─┼─┼─┼─┼─┼─┤"); - } - move(STARTX + 1 + i * 2, STARTY); - outs("│ │ │ │ │ │ │ │ │"); - move(STARTX + 2 + i * 2, STARTY); - outs("└─┴─┴─┴─┴─┴─┴─┴─┘"); - print_chess(od, 4, 4, WHITE); - print_chess(od, 5, 5, WHITE); - print_chess(od, 4, 5, BLACK); - print_chess(od, 5, 4, BLACK); - move(3, 56); - prints("(黑)%s", cuser.userid); - move(3, 72); - outs(": 02"); - move(4, 56); - outs("(白)電腦 : 02"); - move(6, 56); - outs("# 可以下之處"); - move(7, 56); - outs("[q] 退出"); - move(8, 56); - outs("[h] 開啟/關閉 提示"); - move(9, 56); - outs("[Enter][Space] 下棋"); - move(10, 56); - outs("上:↑, i"); - move(11, 56); - outs("下:↓, k"); - move(12, 56); - outs("左:←, j"); - move(13, 56); - outs("右:→, l"); -} - -static int -get_key(struct OthelloData *od, int x, int y) -{ - int ch; - - move(STARTX - 1 + x * 2, STARTY - 1 + y * 4); - ch = igetch(); - move(STARTX - 1 + x * 2, STARTY - 2 + y * 4); - if (od->nowboard[x][y] != HINT || od->if_hint == 1) - outs(CHESS_TYPE[(int)od->nowboard[x][y]]); - else - outs(CHESS_TYPE[NONE]); - return ch; -} - -static int -eatline(int i, int j, char color, int dir, char chessboard[][10]) -{ - int tmpx, tmpy; - char tmpchess; - - tmpx = i + DIRX[dir]; - tmpy = j + DIRY[dir]; - tmpchess = chessboard[tmpx][tmpy]; - if (tmpchess == -1) - return false; - if (tmpchess != INVERT(color)) - return false; - - tmpx += DIRX[dir]; - tmpy += DIRY[dir]; - tmpchess = chessboard[tmpx][tmpy]; - while (tmpchess != -1) { - if (tmpchess < BLACK) - return false; - if (tmpchess == color) { - while (i != tmpx || j != tmpy) { - chessboard[i][j] = color; - i += DIRX[dir]; - j += DIRY[dir]; - } - return true; - } - tmpx += DIRX[dir]; - tmpy += DIRY[dir]; - tmpchess = chessboard[tmpx][tmpy]; - } - return false; -} - -static int -if_can_put(int x, int y, char color, char chessboard[][10]) -{ - int i, temp, checkx, checky; - - if (chessboard[x][y] < BLACK) - for (i = 0; i < 8; i++) { - checkx = x + DIRX[i]; - checky = y + DIRY[i]; - temp = chessboard[checkx][checky]; - if (temp < BLACK) - continue; - if (temp != color) - while (chessboard[checkx += DIRX[i]][checky += DIRY[i]] > HINT) - if (chessboard[checkx][checky] == color) - return true; - } - return false; -} - -static int -get_hint(struct OthelloData *od, char color) -{ - int i, j, temp = 0; - - for (i = 1; i <= 8; i++) - for (j = 1; j <= 8; j++) { - if (od->nowboard[i][j] == HINT) - od->nowboard[i][j] = NONE; - if (if_can_put(i, j, color, od->nowboard)) { - od->nowboard[i][j] = HINT; - temp++; - } - print_chess(od, i, j, od->nowboard[i][j]); - } - return temp; -} - -static void -eat(int x, int y, int color, char chessboard[][10]) -{ - int k; - - for (k = 0; k < 8; k++) - eatline(x, y, color, k, chessboard); -} - -static void -end_of_game(struct OthelloData *od, int quit) -{ - FILE *fp; - char *opponent[] = {"", "CD-65", "", "嬰兒", "小孩", "", "大人", "專家"}; - - move(STARTX - 1, 30); - outs(" "); - move(22, 35); - fp = fopen(LOGFILE, "a"); - if (quit) { - if (od->number[0] == 2 && od->number[1] == 2) { - if (fp) - fclose(fp); - return; - } - fprintf(fp, "在%s級中, %s臨陣脫逃\n", opponent[od->think], cuser.userid); - if (fp) - fclose(fp); - return; - } - if (od->number[0] > od->number[1]) { - prints("你贏了電腦%02d子", od->number[0] - od->number[1]); - if (od->think == 6 && od->number[0] - od->number[1] >= 50) - demoney(200); - if (od->think == 7 && od->number[0] - od->number[1] >= 40) - demoney(200); - if (fp) - fprintf(fp, "在%s級中, %s以 %02d:%02d 贏了電腦%02d子\n", - opponent[od->think], cuser.userid, od->number[0], od->number[1], - od->number[0] - od->number[1]); - } else if (od->number[1] > od->number[0]) { - prints("電腦贏了你%02d子", od->number[1] - od->number[0]); - if (fp) { - fprintf(fp, "在%s級中, ", opponent[od->think]); - if (od->number[1] - od->number[0] > 20) - fprintf(fp, "電腦以 %02d:%02d 慘電%s %02d子\n", od->number[1], - od->number[0], cuser.userid, od->number[1] - od->number[0]); - else - fprintf(fp, "電腦以 %02d:%02d 贏了%s %02d子\n", od->number[1], - od->number[0], cuser.userid, od->number[1] - od->number[0]); - } - } else { - outs("你和電腦打成平手!!"); - if (fp) - fprintf(fp, "在%s級中, %s和電腦以 %02d:%02d 打成了平手\n", - opponent[od->think], cuser.userid, od->number[1], od->number[0]); - } - if (fp) - fclose(fp); - move(1, 1); - igetch(); -} - -static void -othello_redraw(struct OthelloData *od) -{ - int i, j; - - for (i = 1; i <= 8; i++) - for (j = 1; j <= 8; j++) - print_chess(od, i, j, od->nowboard[i][j]); -} - -static int -player(struct OthelloData *od, char color) -{ - int ch; - - if (get_hint(od, color)) { - while (true) { - ch = get_key(od, od->nowx, od->nowy); - switch (ch) { - case 'J': - case 'j': - case KEY_LEFT: - od->nowy--; - break; - case 'L': - case 'l': - case KEY_RIGHT: - od->nowy++; - break; - case 'I': - case 'i': - case KEY_UP: - od->nowx--; - break; - case 'K': - case 'k': - case KEY_DOWN: - od->nowx++; - break; - case ' ': - case KEY_ENTER: - if (od->nowboard[(int)od->nowx][(int)od->nowy] != HINT) - break; - od->pass = 0; - od->nowboard[(int)od->nowx][(int)od->nowy] = color; - eat(od->nowx, od->nowy, color, od->nowboard); - print_chess(od, od->nowx, od->nowy, color); - return true; - case 'q': - end_of_game(od, 1); - return false; - case 'H': - case 'h': - od->if_hint = od->if_hint ^ 1; - othello_redraw(od); - break; - } - if (od->nowx == 9) - od->nowx = 1; - if (od->nowx == 0) - od->nowx = 8; - if (od->nowy == 9) - od->nowy = 1; - if (od->nowy == 0) - od->nowy = 8; - } - } else { - od->pass++; - if (od->pass == 1) { - move(23, 34); - outs("你必需放棄這一步!!"); - igetch(); - move(28, 23); - outs(" "); - } else { - end_of_game(od,0); - return false; - } - } - return 0; -} - -static void -init(struct OthelloData *od) -{ - int i, j, i1, j1; - - memset(od, 0, sizeof(struct OthelloData)); - od->nowx = 4; - od->nowy = 4; - od->number[0] = od->number[1] = 2; - for (i = 1; i <= 8; i++) - for (j = 1; j <= 8; j++) { - i1 = 4.5 - abs(4.5 - i); - j1 = 4.5 - abs(4.5 - j); - od->evaltable[0][i][j] = init_table[0][i1][j1]; - od->evaltable[1][i][j] = init_table[1][i1][j1]; - } - memset(od->nowboard, NONE, sizeof(od->nowboard)); - for(i=0;i<10;i++) - od->nowboard[i][0]=od->nowboard[0][i]=od->nowboard[i][9]=od->nowboard[9][i]=-1; - od->nowboard[4][4] = od->nowboard[5][5] = WHITE; - od->nowboard[4][5] = od->nowboard[5][4] = BLACK; -} - -static void -report(struct OthelloData *od) -{ - int i, j; - - od->number[0] = od->number[1] = 0; - for (i = 1; i <= 8; i++) - for (j = 1; j <= 8; j++) - if (od->nowboard[i][j] == BLACK) - od->number[0]++; - else if (od->nowboard[i][j] == WHITE) - od->number[1]++; - move(3, 60); - outs(cuser.userid); - move(3, 72); - prints(": %02d", od->number[0]); - move(4, 60); - prints("電腦 : %02d", od->number[1]); -} - -static int -EVL(struct OthelloData *od, char chessboard[][10], int color, int table_number) -{ - int points = 0, a, b; - for (a = 1; a <= 8; a++) - for (b = 1; b <= 8; b++) - if (chessboard[a][b] > HINT) { - if (chessboard[a][b] == BLACK) - points += od->evaltable[table_number][a][b]; - else - points -= od->evaltable[table_number][a][b]; - } - return ((color == BLACK) ? points : -points); -} - -static int -alphabeta(struct OthelloData *od, int alpha, int beta, int level, char chessboard[][10], - int thinkstep, int color, int table) -{ - int i, j, k, flag = 1; - char tempboard[10][10]; - if (level == thinkstep + 1) - return EVL(od, chessboard, (level & 1 ? color : ((color - 2) ^ 1) + 2), - table); - for (i = 1; i <= 8; i++) { - for (j = 1; j <= 8; j++) { - if (if_can_put(i, j, color, chessboard)) { - flag = 0; - memcpy(tempboard, chessboard, sizeof(char) * 100); - eat(i, j, color, tempboard); - - k = alphabeta(od, alpha, beta, level + 1, tempboard, thinkstep, - ((color - 2) ^ 1) + 2, table); - if (((level & 1) && k > alpha)) - alpha = k; - else if (!(level & 1) && k < beta) - beta = k; - if (alpha >= beta) - break; - } - } - } - if (flag) - return EVL(od, chessboard, color, table); - return ((level & 1) ? alpha : beta); -} - -static int -Computer(struct OthelloData *od, int thinkstep, int table) -{ - int i, j, maxi = 0, maxj = 0, level = 1; - char chessboard[10][10]; - int alpha = -10000, k; - if ((od->number[0] + od->number[1]) > 44) - table = NR_TABLE; - for (i = 1; i <= 8; i++) - for (j = 1; j <= 8; j++) { - if (if_can_put(i, j, WHITE, od->nowboard)) { - memcpy(chessboard, od->nowboard, sizeof(char) * 100); - eat(i, j, WHITE, chessboard); - k = alphabeta(od, alpha, 10000, level + 1, chessboard, thinkstep, - BLACK, table); - if (k > alpha) { - alpha = k; - maxi = i; - maxj = j; - } - } - } - if (alpha != -10000) { - eat(maxi, maxj, WHITE, od->nowboard); - od->pass = 0; - od->nowx = maxi; - od->nowy = maxj; - } else { - move(23, 30); - outs("電腦放棄這一步棋!!"); - od->pass++; - if (od->pass == 2) { - move(23, 24); - outs(" "); - end_of_game(od, 0); - return false; - } - igetch(); - move(23, 24); - outs(" "); - } - return true; -} - -static int -choose(void) -{ - char thinkstep[2]; - - move(2, 0); - outs("請選擇難度:"); - move(5, 0); - outs("[0] 離開\n"); - outs("(1) CD-65\n");/* 想 1 步 */ - outs("(2) 嬰兒\n"); /* 想 3 步 */ - outs("(3) 小孩\n"); /* 想 4 步 */ - do { - if (getdata(4, 0, "請選擇一個對象和您對打:(1~3)", - thinkstep, sizeof(thinkstep), LCECHO) == 0 || - thinkstep[0] == '0') - return 0; - - } while (thinkstep[0] < '1' || thinkstep[0] > '3'); - clear(); - switch (thinkstep[0]) { - case '2': - thinkstep[0] = '3'; - break; - case '3': - thinkstep[0] = '4'; - break; - default: - thinkstep[0] = '1'; - break; - } - return atoi(thinkstep); -} - -#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0 - -int -othello_main(void) -{ - struct OthelloData *od; - - lockreturn0(OTHELLO, LOCK_MULTI); - - od=(struct OthelloData*)malloc(sizeof(struct OthelloData)); - if(od==NULL) { - unlockutmpmode(); - return 0; - } - - clear(); - init(od); - od->think = choose(); - if (!od->think) - { - unlockutmpmode(); - free(od); - return 0; - } - showtitle("單人黑白棋", BBSName); - printboard(od); - od->which_table = random() % NR_TABLE; - while (true) { - move(STARTX - 1, 30); - outs("輪到你下了..."); - if (!player(od, BLACK)) - break; - report(od); - othello_redraw(od); - if (od->number[0] + od->number[1] == 64) { - end_of_game(od, 0); - break; - } - move(STARTX - 1, 30); - outs("電腦思考中..."); - refresh(); - if (!Computer(od, od->think, od->which_table)) - break; - report(od); - othello_redraw(od); - if (od->number[0] + od->number[1] == 64) { - end_of_game(od, 0); - break; - } - } - more(LOGFILE, YEA); - unlockutmpmode(); - free(od); - return 1; -} |