diff options
-rw-r--r-- | include/chc.h | 1 | ||||
-rw-r--r-- | include/pttstruct.h | 3 | ||||
-rw-r--r-- | mbbsd/Makefile | 1 | ||||
-rw-r--r-- | mbbsd/chc.c | 33 | ||||
-rw-r--r-- | mbbsd/talk.c | 5 |
5 files changed, 42 insertions, 1 deletions
diff --git a/include/chc.h b/include/chc.h index 416f1193..052565cf 100644 --- a/include/chc.h +++ b/include/chc.h @@ -37,6 +37,7 @@ typedef struct chcusr_t{ int win; int lose; int tie; + unsigned short rating; } chcusr_t; #define CHC_ACT_BOARD 0x1 /* set if transfered board to this sock */ diff --git a/include/pttstruct.h b/include/pttstruct.h index 2fb8dd87..edffe721 100644 --- a/include/pttstruct.h +++ b/include/pttstruct.h @@ -99,7 +99,8 @@ typedef struct userec_t { unsigned char goodsale; /* 競標 好的評價 */ unsigned char badsale; /* 競標 壞的評價 */ char myangel[IDLEN+1]; /* 我的小天使 */ - char pad[54]; + unsigned short chess_elo_rating; /* 象棋等級分 */ + char pad[52]; } userec_t; /* these are flags in userec_t.uflag */ #define PAGER_FLAG 0x4 /* true if pager was OFF last session */ diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 124ae821..e2177d43 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -20,6 +20,7 @@ OBJS= admin.o announce.o args.o assess.o bbs.o board.o cache.o cal.o card.o\ CFLAGS+= -DMERGEBBS OBJS+= merge.o .endif +LDFLAGS+= -lm .SUFFIXES: .c .o .c.o: ../include/var.h diff --git a/mbbsd/chc.c b/mbbsd/chc.c index 7d36ce9d..06623a5f 100644 --- a/mbbsd/chc.c +++ b/mbbsd/chc.c @@ -1,4 +1,5 @@ /* $Id$ */ +#include <math.h> #include "bbs.h" #define CENTER(a, b) (((a) + (b)) >> 1) @@ -563,6 +564,7 @@ chcusr_put(userec_t *userec, chcusr_t *user) userec->chc_win = user->win; userec->chc_lose = user->lose; userec->chc_tie = user->tie; + userec->chess_elo_rating = user->rating; } static void @@ -572,6 +574,9 @@ chcusr_get(userec_t *userec, chcusr_t *user) user->win = userec->chc_win; user->lose = userec->chc_lose; user->tie = userec->chc_tie; + user->rating = userec->chess_elo_rating; + if(user->rating == 0) + user->rating = 1500; /* ELO initial value */ } static int @@ -754,6 +759,30 @@ myplay(int s, chcusr_t *user1, chcusr_t *user2, board_t board, board_t tmpbrd) return endgame; } +/* + * ELO rating system + * see http://www.wordiq.com/definition/ELO_rating_system + */ +static void +count_chess_elo_rating(chcusr_t *user1, chcusr_t *user2, double myres) +{ + double k; + double exp_res; + if(user1->rating < 1800) + k = 30; + else if(user1->rating < 2000) + k = 25; + else if(user1->rating < 2200) + k = 20; + else if(user1->rating < 2400) + k = 15; + else + k = 10; + + exp_res = 1.0/(1.0 + pow(10.0, (user2->rating-user1->rating)/400.0)); + user1->rating += (int)floor(k*(myres-exp_res)+0.5); +} + static void mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t play_func[2]) { @@ -776,16 +805,20 @@ mainloop(int s, chcusr_t *user1, chcusr_t *user2, board_t board, play_func_t pla } if (chc_mode & CHC_VERSUS) { + /* XXX 不正常斷線目前不會更改 ELO rating */ if (endgame == 1) { strlcpy(chc_warnmsg, "對方認輸了!", sizeof(chc_warnmsg)); + count_chess_elo_rating(user1, user2, 1.0); user1->win++; currutmp->chc_win++; } else if (endgame == 2) { strlcpy(chc_warnmsg, "你認輸了!", sizeof(chc_warnmsg)); + count_chess_elo_rating(user1, user2, 0.0); user1->lose++; currutmp->chc_lose++; } else { strlcpy(chc_warnmsg, "和棋", sizeof(chc_warnmsg)); + count_chess_elo_rating(user1, user2, 0.5); user1->tie++; currutmp->chc_tie++; } diff --git a/mbbsd/talk.c b/mbbsd/talk.c index 66613e99..a85e3d75 100644 --- a/mbbsd/talk.c +++ b/mbbsd/talk.c @@ -1634,9 +1634,14 @@ descript(int show_mode, userinfo_t * uentp, time_t diff) uentp->five_lose, uentp->five_tie); return description; case 3: +#ifdef DEBUG + snprintf(description, sizeof(description), + "%d", uentp->chess_elo_rating); +#else snprintf(description, sizeof(description), "%3d/%3d/%3d", uentp->chc_win, uentp->chc_lose, uentp->chc_tie); +#endif return description; default: syslog(LOG_WARNING, "damn!!! what's wrong?? show_mode = %d", |