summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/chc.h1
-rw-r--r--include/pttstruct.h3
-rw-r--r--mbbsd/Makefile1
-rw-r--r--mbbsd/chc.c33
-rw-r--r--mbbsd/talk.c5
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",