Skip to content

Instantly share code, notes, and snippets.

@kobalab
Created January 31, 2018 23:39
Show Gist options
  • Save kobalab/e52d8d7a44cbd3b0088416496e1b16d3 to your computer and use it in GitHub Desktop.
Save kobalab/e52d8d7a44cbd3b0088416496e1b16d3 to your computer and use it in GitHub Desktop.
牌譜から和了点計算を呼出すスクリプト
"use strict";
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const assert = require('assert');
const Majiang = require('../src/js/majiang');
function conv_hupai(hupai) {
const conv_list = [
['立直', '立直' ],
['両立直', 'ダブル立直' ],
['一発', '一発' ],
['海底摸月', '海底摸月' ],
['河底撈魚', '河底撈魚' ],
['嶺上開花', '嶺上開花' ],
['槍槓', '槍槓' ],
['門前清自摸和', '門前清自摸和' ],
['場風 東', '場風 東' ],
['場風 南', '場風 南' ],
['場風 西', '場風 西' ],
['場風 北', '場風 北' ],
['自風 東', '自風 東' ],
['自風 南', '自風 南' ],
['自風 西', '自風 西' ],
['自風 北', '自風 北' ],
['役牌 白', '翻牌 白' ],
['役牌 發', '翻牌 發' ],
['役牌 中', '翻牌 中' ],
['平和', '平和' ],
['断幺九', '断幺九' ],
['一盃口', '一盃口' ],
['三色同順', '三色同順' ],
['一気通貫', '一気通貫' ],
['混全帯幺九', '混全帯幺九' ],
['七対子', '七対子' ],
['対々和', '対々和' ],
['三暗刻', '三暗刻' ],
['三槓子', '三槓子' ],
['三色同刻', '三色同刻' ],
['混老頭', '混老頭' ],
['小三元', '小三元' ],
['混一色', '混一色' ],
['純全帯幺九', '純全帯幺九' ],
['二盃口', '二盃口' ],
['清一色', '清一色' ],
['天和', '天和' ],
['地和', '地和' ],
['国士無双', '国士無双' ],
['国士無双13面', '国士無双十三面'],
['四暗刻', '四暗刻' ],
['四暗刻単騎', '四暗刻単騎' ],
['大三元', '大三元' ],
['小四喜', '小四喜' ],
['大四喜', '大四喜' ],
['字一色', '字一色' ],
['緑一色', '緑一色' ],
['清老頭', '清老頭' ],
['四槓子', '四槓子' ],
['九蓮宝燈', '九蓮宝燈' ],
['純正九蓮宝燈', '純正九蓮宝燈' ],
['ドラ', 'ドラ' ],
['赤ドラ', '赤ドラ' ],
['裏ドラ', '裏ドラ' ]
];
let new_hupai = [];
for (let conv of conv_list) {
let h = hupai.find(h => h.name == conv[0] && h.fanshu);
if (h) {
h.name = conv[1];
new_hupai.push(h);
}
}
return new_hupai;
}
function conv_damanguan(hule) {
for (let hupai of hule.hupai) {
if (hupai.name == '国士無双13面' || hupai.name == '四暗刻単騎'
|| hupai.name == '大四喜' || hupai.name == '純正九蓮宝燈')
{
hupai.fanshu = '**';
hule.damanguan++;
for (let l = 0; l < 4; l++) {
if (l == hule.l) {
hule.fenpei[l] += 8000 * (hule.l == 0 ? 6 : 4);
hule.defen += 8000 * (hule.l == 0 ? 6 : 4);
}
else if (l == hule.baojia)
hule.fenpei[l] -= 8000 * (hule.l == 0 ? 6 : 4);
else if (hule.baojia == null)
hule.fenpei[l] -= 8000 * (hule.l == 0 || l == 0 ? 2 : 1);
}
}
if (hupai.name == '大三元') {
let bao_mianzi = Majiang.Shoupai.fromString(hule.shoupai)._fulou
.filter(m =>
m.match(/^z([567])\1\1(?:[\+\=\-]|\1)(?!\!)/));
let baojia = (bao_mianzi[2] && bao_mianzi[2].match(/[\+\=\-]/));
if (baojia) hupai.baojia = baojia[0];
return;
}
}
return 1;
}
function conv_hule(log) {
let zhuangfeng = 0;
let menfeng = 1;
let changbang = 0;
let lizhibang = 0;
let baopai = [];
let fubaopai = [];
let paishu = 136 - 13 * 4 -14;
let diyizimo = true;
let say_lizhi = false;
let lizhi = [0,0,0,0];
let yifa = [false,false,false,false];
let shoupai;
let rongpai;
let hule_option;
let hule = {};
for (let data of log) {
if (say_lizhi && ! data.hule) {
lizhibang++;
say_lizhi = false;
}
if (data.qipai) {
zhuangfeng = data.qipai.zhuangfeng;
changbang = data.qipai.changbang;
lizhibang = data.qipai.lizhibang;
baopai = [ data.qipai.baopai ];
}
else if (data.zimo) {
paishu--;
hule_option = null;
}
else if (data.gangzimo) {
paishu--;
hule_option = 'lingshang';
diyizimo = false;
yifa = [false,false,false,false];
}
else if (data.dapai) {
hule_option = null;
yifa[data.dapai.l] = false;
if (data.dapai.p.substr(-1) == '*') {
say_lizhi = true;
lizhi[data.dapai.l] = diyizimo ? 2 : 1;
yifa[data.dapai.l] = true;
}
if (data.dapai.l == 3) diyizimo = false;
}
else if (data.fulou) {
diyizimo = false;
yifa = [false,false,false,false];
}
else if (data.gang) {
hule_option = 'qianggang';
}
else if (data.kaigang) {
baopai.push(data.kaigang.baopai);
}
else if (data.hule) {
shoupai = data.hule.shoupai;
menfeng = data.hule.l;
fubaopai = data.hule.fubaopai || [];
if (data.hule.baojia != null) {
rongpai = Majiang.Shoupai.fromString(shoupai)._zimo
+ ['_','+','=','-'][(4 + data.hule.baojia - menfeng) % 4];
}
if (! conv_damanguan(data.hule)) return;
hule = {
hupai: conv_hupai(data.hule.hupai),
fu: data.hule.fu || null,
fanshu: data.hule.fanshu || null,
damanguan: data.hule.damanguan || null,
defen: data.hule.defen,
fenpei: data.hule.fenpei
}
break;
}
else if (data.pingju) return;
}
return {
in: {
shoupai: shoupai,
rongpai: rongpai,
param: {
zhuangfeng: zhuangfeng,
menfeng: menfeng,
hupai: {
lizhi: lizhi[menfeng] || undefined,
yifa: yifa[menfeng] || undefined,
qianggang: hule_option == 'qianggang' || undefined,
lingshang: hule_option == 'lingshang' || undefined,
haidi: (paishu > 0 || hule_option == 'lingshang')
? undefined
: ! rongpai ? 1
: 2,
tianhu: (diyizimo && ! rongpai)
? (menfeng == 0 ? 1 : 2)
: undefined
},
baopai: baopai,
fubaopai: fubaopai,
jicun: { changbang: changbang, lizhibang, lizhibang }
},
},
out: hule
};
}
function test_file(filename) {
let paipu = JSON.parse(
zlib.gunzipSync(fs.readFileSync(filename)).toString());
for (let log of paipu.log) {
let r = conv_hule(log);
if (! r) continue;
let hule = Majiang.Util.hule(
Majiang.Shoupai.fromString(r.in.shoupai),
r.in.rongpai, r.in.param);
assert.deepEqual(hule, r.out);
// data.push(r);
// if (data.length >= 10000) return;
}
}
function shuffle(array) {
let new_array = [];
while (array.length) {
new_array.push(array.splice(Math.random() * array.length, 1)[0])
}
return new_array;
}
function test_dir(dirname) {
let files = fs.readdirSync(dirname)
.filter(n => n.match(/\.json\.gz$/)).sort();
/*
let files = shuffle(fs.readdirSync(dirname)
.filter(n => n.match(/\.json\.gz$/)));
*/
for (let filename of files) {
if (process.argv[3] && filename <= process.argv[3]) continue;
console.log(filename);
test_file(path.join(dirname, filename));
// if (data.length >= 10000) return;
}
}
let data = [];
let target = (process.argv[2] || './');
if (target.match(/\.gz$/)) test_file(target);
else test_dir(target);
//fs.writeSync(1, JSON.stringify(data));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment