summaryrefslogtreecommitdiffstats
path: root/mbbsd/othello.c
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd/othello.c')
-rw-r--r--mbbsd/othello.c427
1 files changed, 230 insertions, 197 deletions
diff --git a/mbbsd/othello.c b/mbbsd/othello.c
index 4a146f77..76cd2f8c 100644
--- a/mbbsd/othello.c
+++ b/mbbsd/othello.c
@@ -1,4 +1,4 @@
-/* $Id: othello.c,v 1.3 2002/06/04 13:08:34 in2 Exp $ */
+/* $Id: othello.c,v 1.4 2002/07/05 17:10:27 in2 Exp $ */
#include "bbs.h"
#define LOGFILE "etc/othello.log"
@@ -20,67 +20,71 @@
#define INVERT(COLOR) (((COLOR))==WHITE?BLACK:WHITE)
-static char nowx = 3, nowy = 3;
-static char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS};
-static char DIRX[] = {-1,-1,-1, 0, 1, 1, 1, 0};
-static char DIRY[] = {-1, 0, 1, 1, 1, 0,-1,-1};
-static char number[2];
-
-static char pass = 0;
-static char if_hint = 0;
-static int think, which_table;
-
-static char nowboard[10][10]=
-{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
-static 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 char nowx = 3, nowy = 3;
+static char *CHESS_TYPE[] = {NONE_CHESS, HINT_CHESS, BLACK_CHESS, WHITE_CHESS};
+static char DIRX[] = {-1, -1, -1, 0, 1, 1, 1, 0};
+static char DIRY[] = {-1, 0, 1, 1, 1, 0, -1, -1};
+static char number[2];
+
+static char pass = 0;
+static char if_hint = 0;
+static int think, which_table;
+
+static char nowboard[10][10] =
+{{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, -1},
+{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
+static 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 char table[NR_TABLE + 1][10][10];
-static void print_chess(int x, int y, char chess) {
+static char table[NR_TABLE + 1][10][10];
+static void
+print_chess(int x, int y, char chess)
+{
move(STARTX - 1 + x * 2, STARTY - 2 + y * 4);
- if(chess != HINT || if_hint == 1)
+ if (chess != HINT || if_hint == 1)
prints(CHESS_TYPE[(int)chess]);
else
prints(CHESS_TYPE[NONE]);
refresh();
}
-static void printboard() {
- int i;
-
+static void
+printboard()
+{
+ int i;
+
move(STARTX, STARTY);
prints("┌─┬─┬─┬─┬─┬─┬─┬─┐");
- for(i = 0; i < 7; i++) {
+ for (i = 0; i < 7; i++) {
move(STARTX + 1 + i * 2, STARTY);
- prints ("│ │ │ │ │ │ │ │ │");
+ prints("│ │ │ │ │ │ │ │ │");
move(STARTX + 2 + i * 2, STARTY);
- prints ("├─┼─┼─┼─┼─┼─┼─┼─┤");
+ prints("├─┼─┼─┼─┼─┼─┼─┼─┤");
}
move(STARTX + 1 + i * 2, STARTY);
prints("│ │ │ │ │ │ │ │ │");
@@ -91,7 +95,7 @@ static void printboard() {
print_chess(4, 5, BLACK);
print_chess(5, 4, BLACK);
move(3, 56);
- prints("(黑)%s",cuser.userid);
+ prints("(黑)%s", cuser.userid);
move(3, 72);
prints(": 02");
move(4, 56);
@@ -102,7 +106,7 @@ static void printboard() {
prints("[q] 退出");
move(8, 56);
prints("[h] 開啟/關閉 提示");
- move(9,56);
+ move(9, 56);
prints("[Enter][Space] 下棋");
move(10, 56);
prints("上:↑, i");
@@ -114,39 +118,43 @@ static void printboard() {
prints("右:→, l");
}
-static int get_key(char nowx, char nowy) {
- int ch;
-
+static int
+get_key(char nowx, char nowy)
+{
+ int ch;
+
move(STARTX - 1 + nowx * 2, STARTY - 1 + nowy * 4);
ch = igetkey();
move(STARTX - 1 + nowx * 2, STARTY - 2 + nowy * 4);
- if(nowboard[(int)nowx][(int)nowy] != HINT || if_hint==1)
+ if (nowboard[(int)nowx][(int)nowy] != HINT || if_hint == 1)
outs(CHESS_TYPE[(int)nowboard[(int)nowx][(int)nowy]]);
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;
-
+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)
+ if (tmpchess == -1)
return false;
- if(tmpchess != INVERT(color))
+ if (tmpchess != INVERT(color))
return false;
-
+
tmpx += DIRX[dir];
tmpy += DIRY[dir];
tmpchess = chessboard[tmpx][tmpy];
- while(tmpchess != -1) {
- if(tmpchess < BLACK)
+ while (tmpchess != -1) {
+ if (tmpchess < BLACK)
return false;
- if(tmpchess == color) {
- while(i != tmpx || j != tmpy) {
+ if (tmpchess == color) {
+ while (i != tmpx || j != tmpy) {
chessboard[i][j] = color;
i += DIRX[dir];
j += DIRY[dir];
@@ -160,32 +168,36 @@ static int eatline(int i, int j, char color, int dir, char chessboard[][10]) {
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++) {
+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)
+ if (temp < BLACK)
continue;
- if(temp != color)
- while(chessboard[checkx += DIRX[i]][checky += DIRY[i]] > HINT)
- if(chessboard[checkx][checky] == color)
+ 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(char color) {
- int i, j, temp = 0;
-
- for(i = 1; i <= 8; i++)
- for(j = 1; j <= 8; j++) {
- if(nowboard[i][j] == HINT)
+static int
+get_hint(char color)
+{
+ int i, j, temp = 0;
+
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++) {
+ if (nowboard[i][j] == HINT)
nowboard[i][j] = NONE;
- if(if_can_put(i, j, color, nowboard)) {
+ if (if_can_put(i, j, color, nowboard)) {
nowboard[i][j] = HINT;
temp++;
}
@@ -194,89 +206,96 @@ static int get_hint(char color) {
return temp;
}
-static void eat(int x, int y, int color, char chessboard[][10]) {
- int k;
-
- for(k = 0; k < 8; k++)
+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(int quit) {
- FILE *fp,*fp1;
- char *opponent[] = {"","CD-65","","嬰兒","小孩","","大人","專家"};
-
+static void
+end_of_game(int quit)
+{
+ FILE *fp, *fp1;
+ char *opponent[] = {"", "CD-65", "", "嬰兒", "小孩", "", "大人", "專家"};
+
move(STARTX - 1, 30);
- prints (" ");
+ prints(" ");
move(22, 35);
fp = fopen(LOGFILE, "a");
- if(!quit) {
+ if (!quit) {
fp1 = fopen(SECRET, "a");
- if(fp1) {
+ if (fp1) {
fprintf(fp1, "%d,%d,%s,%02d,%02d\n", think, which_table,
- cuser.userid, number[0], number[1]);
+ cuser.userid, number[0], number[1]);
fclose(fp1);
}
}
-
- if(quit) {
- if(number[0] == 2 && number[1] == 2) {
- if(fp)
+ if (quit) {
+ if (number[0] == 2 && number[1] == 2) {
+ if (fp)
fclose(fp);
return;
}
fprintf(fp, "在%s級中, %s臨陣脫逃\n", opponent[think], cuser.userid);
- if(fp)
- fclose(fp);
+ if (fp)
+ fclose(fp);
return;
- }
- if(number[0] > number[1]) {
+ }
+ if (number[0] > number[1]) {
prints("你贏了電腦%02d子", number[0] - number[1]);
- if(think == 6 && number[0] - number[1] >= 50)
+ if (think == 6 && number[0] - number[1] >= 50)
demoney(200);
- if(think == 7 && number[0] - number[1] >= 40)
+ if (think == 7 && number[0] - number[1] >= 40)
demoney(200);
- if(fp)
+ if (fp)
fprintf(fp, "在%s級中, %s以 %02d:%02d 贏了電腦%02d子\n",
opponent[think], cuser.userid, number[0], number[1],
number[0] - number[1]);
- } else if(number[1] > number[0]) {
+ } else if (number[1] > number[0]) {
prints("電腦贏了你%02d子", number[1] - number[0]);
- if(fp) {
+ if (fp) {
fprintf(fp, "在%s級中, ", opponent[think]);
- if(number[1] - number[0] > 20)
+ if (number[1] - number[0] > 20)
fprintf(fp, "電腦以 %02d:%02d 慘電%s %02d子\n", number[1],
number[0], cuser.userid, number[1] - number[0]);
else
fprintf(fp, "電腦以 %02d:%02d 贏了%s %02d子\n", number[1],
number[0], cuser.userid, number[1] - number[0]);
- }
+ }
} else {
prints("你和電腦打成平手!!");
- if(fp)
+ if (fp)
fprintf(fp, "在%s級中, %s和電腦以 %02d:%02d 打成了平手\n",
opponent[think], cuser.userid, number[1], number[0]);
}
- if(fp)
+ if (fp)
fclose(fp);
- move(1,1);
+ move(1, 1);
igetkey();
}
-static void othello_redraw() {
- int i, j;
-
- for(i = 1; i <= 8; i++)
- for(j = 1; j <= 8; j++)
+static void
+othello_redraw()
+{
+ int i, j;
+
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++)
print_chess(i, j, nowboard[i][j]);
}
-static int player(char color) {
- int ch;
-
- if(get_hint(color)) {
- while(true) {
- ch = get_key(nowx,nowy);
- switch(ch) {
+static int
+player(char color)
+{
+ int ch;
+
+ if (get_hint(color)) {
+ while (true) {
+ ch = get_key(nowx, nowy);
+ switch (ch) {
case 'J':
case 'j':
case KEY_LEFT:
@@ -296,10 +315,10 @@ static int player(char color) {
case 'k':
case KEY_DOWN:
nowx++;
- break;
+ break;
case ' ':
case '\r':
- if(nowboard[(int)nowx][(int)nowy] != HINT)
+ if (nowboard[(int)nowx][(int)nowy] != HINT)
break;
pass = 0;
nowboard[(int)nowx][(int)nowy] = color;
@@ -311,26 +330,26 @@ static int player(char color) {
return false;
case 'H':
case 'h':
- if_hint = if_hint^1;
+ if_hint = if_hint ^ 1;
othello_redraw();
break;
}
- if(nowx == 9)
- nowx=1;
- if(nowx == 0)
- nowx=8;
- if(nowy == 9)
- nowy=1;
- if(nowy == 0)
- nowy=8;
+ if (nowx == 9)
+ nowx = 1;
+ if (nowx == 0)
+ nowx = 8;
+ if (nowy == 9)
+ nowy = 1;
+ if (nowy == 0)
+ nowy = 8;
}
} else {
pass++;
- if(pass == 1) {
+ if (pass == 1) {
move(23, 34);
prints("你必需放棄這一步!!");
igetch();
- move(28,23);
+ move(28, 23);
prints(" ");
} else {
end_of_game(0);
@@ -340,35 +359,39 @@ static int player(char color) {
return 0;
}
-static void init() {
- int i, j, i1, j1;
-
+static void
+init()
+{
+ int i, j, i1, j1;
+
nowx = 4;
nowy = 4;
number[0] = number[1] = 2;
- for(i = 1; i <= 8; i++)
- for(j = 1;j <= 8; j++) {
+ 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);
table[0][i][j] = init_table[0][i1][j1];
table[1][i][j] = init_table[1][i1][j1];
}
- for(i = 1; i <= 8; i++)
- for(j = 1; j <= 8; j++)
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++)
nowboard[i][j] = NONE;
nowboard[4][4] = nowboard[5][5] = WHITE;
nowboard[4][5] = nowboard[5][4] = BLACK;
}
-static void report() {
- int i, j;
-
+static void
+report()
+{
+ int i, j;
+
number[0] = number[1] = 0;
- for(i = 1; i <= 8; i++)
- for(j = 1; j <= 8; j++)
- if(nowboard[i][j] == BLACK)
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++)
+ if (nowboard[i][j] == BLACK)
number[0]++;
- else if(nowboard[i][j] == WHITE)
+ else if (nowboard[i][j] == WHITE)
number[1]++;
move(3, 60);
prints("%s", cuser.userid);
@@ -378,12 +401,14 @@ static void report() {
prints("電腦 : %02d", number[1]);
}
-static int EVL(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)
+static int
+EVL(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 += table[table_number][a][b];
else
points -= table[table_number][a][b];
@@ -391,57 +416,61 @@ static int EVL(char chessboard[][10], int color, int table_number) {
return ((color == BLACK) ? points : -points);
}
-static int alphabeta(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)
+static int
+alphabeta(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(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)) {
+ 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(alpha, beta, level + 1, tempboard, thinkstep,
((color - 2) ^ 1) + 2, table);
- if(((level & 1) && k > alpha))
+ if (((level & 1) && k > alpha))
alpha = k;
- else if(!(level & 1) && k < beta)
+ else if (!(level & 1) && k < beta)
beta = k;
- if(alpha >= beta)
+ if (alpha >= beta)
break;
}
}
}
- if(flag)
+ if (flag)
return EVL(chessboard, color, table);
return ((level & 1) ? alpha : beta);
}
-static int Computer(int thinkstep, int table) {
- int i, j, maxi = 0, maxj = 0, level = 1;
- char chessboard[10][10];
- int alpha = -10000, k;
- if((number[0] + number[1]) > 44)
+static int
+Computer(int thinkstep, int table)
+{
+ int i, j, maxi = 0, maxj = 0, level = 1;
+ char chessboard[10][10];
+ int alpha = -10000, k;
+ if ((number[0] + 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,nowboard)) {
+ for (i = 1; i <= 8; i++)
+ for (j = 1; j <= 8; j++) {
+ if (if_can_put(i, j, WHITE, nowboard)) {
memcpy(chessboard, nowboard, sizeof(char) * 100);
eat(i, j, WHITE, chessboard);
k = alphabeta(alpha, 10000, level + 1, chessboard, thinkstep,
BLACK, table);
- if(k > alpha) {
+ if (k > alpha) {
alpha = k;
maxi = i;
maxj = j;
}
}
}
- if(alpha != -10000) {
+ if (alpha != -10000) {
eat(maxi, maxj, WHITE, nowboard);
pass = 0;
nowx = maxi;
@@ -450,7 +479,7 @@ static int Computer(int thinkstep, int table) {
move(23, 30);
prints("電腦放棄這一步棋!!");
pass++;
- if(pass == 2) {
+ if (pass == 2) {
move(23, 24);
prints(" ");
end_of_game(0);
@@ -458,26 +487,28 @@ static int Computer(int thinkstep, int table) {
}
igetch();
move(23, 24);
- prints(" ");
+ prints(" ");
}
return true;
}
-static int choose() {
- char thinkstep[2];
-
+static int
+choose()
+{
+ char thinkstep[2];
+
move(2, 0);
prints("請選擇難度:");
move(5, 0);
- prints("(1) CD-65\n"); /* 想 1 步 */
- prints("(2) 嬰兒\n"); /* 想 3 步 */
- prints("(3) 小孩\n"); /* 想 4 步 */
+ prints("(1) CD-65\n"); /* 想 1 步 */
+ prints("(2) 嬰兒\n"); /* 想 3 步 */
+ prints("(3) 小孩\n"); /* 想 4 步 */
do {
getdata(4, 0, "請選擇一個對象和您對打:(1~5)",
thinkstep, sizeof(thinkstep), LCECHO);
- } while(thinkstep[0] < '1' || thinkstep[0] > '3');
+ } while (thinkstep[0] < '1' || thinkstep[0] > '3');
clear();
- switch(thinkstep[0]) {
+ switch (thinkstep[0]) {
case '2':
thinkstep[0] = '3';
break;
@@ -493,33 +524,35 @@ static int choose() {
#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-int othello_main() {
+int
+othello_main()
+{
lockreturn0(OTHELLO, LOCK_MULTI);
clear();
init();
think = choose();
- showtitle("黑白棋", BBSName);
+ showtitle("黑白棋", BBSName);
printboard();
which_table = rand() % NR_TABLE;
- while(true) {
+ while (true) {
move(STARTX - 1, 30);
prints("輪到你下了...");
- if(!player(BLACK))
+ if (!player(BLACK))
break;
report();
othello_redraw();
- if(number[0] + number[1] == 64) {
+ if (number[0] + number[1] == 64) {
end_of_game(0);
break;
}
move(STARTX - 1, 30);
prints("電腦思考中...");
refresh();
- if(!Computer(think, which_table))
+ if (!Computer(think, which_table))
break;
report();
othello_redraw();
- if(number[0] + number[1] == 64) {
+ if (number[0] + number[1] == 64) {
end_of_game(0);
break;
}