Friday, March 9, 2012

自制vimgolf競賽排行榜

緣起
因為朋友ypcatw的介紹開始玩vimgolf,現在一共有104個題目,解決了32個題目之後,晉升到第92名囉,也終於可以在Leaderboard看到自己的名字。不過這個排行榜有兩個特別的地方。
  1. 只有前一百名的排名
  2. 沒有真正的"竿數",也就是所有題目的排名總和。
排名規則
補充說明一下,vimgolf官方規定排名是用Global rank來計算,一個玩家的Global rank是他在所有比賽(題目)得到的rank總和。好比說fakecolor在"Get rid of html tags"這個比賽拿到第47名,rank就是47。如果沒有參與某場比賽,那rank就等同於參與該場比賽的最後一名玩家的rank。在計算排名時,Global rank越小的人名次越高。由此規則可知,每參與一場比賽都可以使你的Global rank下降。

自製排行榜
回到一開始的問題,官方沒有公布完整的排名,以及每個人的global rank。沒關係,身為programmer最棒的一件事就是可以自己動手做。為了知道自己和其他人的Global rank差距,我和Y決定自行計算所有人的Global rank,並製作成完整的排行榜。要怎麼自行計算Global rank呢? 要訣在於每場比賽的Leaderboard是公開的,就位於題目的右方。我們只須抓取每個比賽的Leaderboard,然後就能計算每個玩家的排名啦。
結果如下表格:

RankingIDGlobal Rank
1 clvv42 2147
2 gumnos 2491
3 wondible 2867
4 federicogalassi 2885
5 h_east 2929
6 yslinnctu 3014
7 Korvin79 3800
8 _Balkoth_ 3885
9 johnsyweb 4100
10 hujunfeng 4163
...
目前(2012 Feb)一共有約2000名玩家


製作方法
我們採用Google App Engine(GAE)做為平台,每天自動抓取所有比賽(Challenge)的Leaderboard,擷取出每場比賽的參賽者後,放入資料庫,並計算所有玩家的Global rank。使用GAE的好處是Google去別人家撈東西很勤快XD

尚未解決的問題
計算好玩家的成績後,我們利用web.py的template功能來產生網頁。目前為止都很順利,但是我們卻被頻寬的問題打敗。由於玩家約有2000名,所以每次產生網頁都需要從資料庫讀取2000資料。然而GAE是以量計價,免費帳號的資料庫存取量每天只夠我們讀取約60,000筆資料,也就是至多能產生30次網頁。為了減少流量,我們決定每天指更新一次資料庫,並利用GAE本身的記憶體快取(memcache)來減少需要讀取資料庫的情況。不過很可惜的是memcache常常會失敗。我們的第一個常識是把結果轉成RSS格式,並利用RSSPECT網站幫我們發佈,但是很可惜的是Google reader沒有辦法讀取發佈的文章,可能是因為內容太長了。
因此我們改採用另外一招:把動態產生的網頁轉成靜態網頁,放在其他伺服器上,做為權宜之計: http://www.csie.ntu.edu.tw/~b89107/vimgolf/ 。不過還是希望能夠在GAE內部就解決這個問題。