// require: mjcommon.js
/** 向聴数などを計算した結果を文字列表現にして返す…
* 複雑な文字列で返されるので使い道がない…
* 関数内部でmjcommon.jsの{@link paiName34}を使用している
* @param {number[]} pai 牌ID(0-135)のリスト(手牌相当)
* @param {number} len
* @returns {string}
*/
function calc(pai, len) {
var j;
var pais = new Array(34);
for (j = 0; j < 34; ++j) {
pais[j] = 0;
}
for (j = 0; j < len; ++j) {
p = pai[j] >> 2;
++pais[p];
}
function mentzName(pai, type) {
switch (type) {
case 101:
return paiName34(pai);
case 201:
return paiName34(pai) + paiName34(pai);
case 202:
return paiName34(pai) + paiName34(pai + 1);
case 203:
return paiName34(pai) + paiName34(pai + 2);
case 301:
return paiName34(pai) + paiName34(pai) + paiName34(pai);
case 302:
return paiName34(pai) + paiName34(pai + 1) + paiName34(pai + 2);
}
return "Er";
}
function TInfo() {
var self = this;
this.mentz = 0;
this.toitz = 0;
this.tartz = 0;
this.tanki = 0;
this.error = 0;
this.getShanten = function () {
if (self.error > 0) {
return -1;
}
var m = (self.mentz * 3) + ((self.toitz + self.tartz) * 2) + self.tanki;
var mc = (m - (m % 3)) / 3;
var t = self.tartz + (self.toitz > 1 ? self.toitz - 1 : 0);
m -= self.mentz * 3;
if ((m % 3) == 0) {
if (self.toitz > 0) {
++t;
}
} else {
if (self.toitz > 0) {
m -= 2;
} else {
m -= 1;
}
}
if (self.mentz < mc) {
if (t > (mc - self.mentz)) {
m -= (mc - self.mentz) * 2;
} else {
m -= t * 2 + ((mc - self.mentz) - t);
}
}
return m;
};
}
function MyList (p,t) {
var self = this;
this.pai = p;
this.type = t;
this.list = null;
this.name = mentzName(p, t);
this.next = null;
this.clone = function () { return new MyList(self.pai, self.type); };
this.conString = function () {
if (self.next == null) {
return "[" + self.name + "]";
} else {
return "[" + self.name + "]" + self.next.conString();
}
};
this.conClone = function () {
var c = new MyList(self.pai, self.type);
if (self.next != null) {
c.next = self.next.conClone();
}
return c;
};
this.append = function (a) {
if (self.next == null) {
self.next = a;
} else {
self.next.append(a);
}
return self;
};
this.getTInfo = function () {
var info;
if (self.next == null) {
info = new TInfo();
} else {
info = self.next.getTInfo();
}
if (self.type > 300) {
++info.mentz;
} else if (self.type == 201) {
++info.toitz;
} else if (self.type > 200) {
++info.tartz;
} else if (self.type > 100) {
++info.tanki;
} else {
++info.error;
}
return info;
};
}
function check3(pais, n, o) {
var j, i = 0, p, ml;
var list = new Array();
for (j = o; j < 9; ++j) {
p = j + n;
if (pais[p] == 0) {
continue;
}
if (pais[p] > 1) {
list = new Array();
list[0] = ml = new MyList(p, -1);
ml.list = new Array();
return list;
}
//--pais[p];
list[0] = ml = new MyList(p, 101);
ml.list = check3(pais, n, j + 1);
//++pais[p];
return list;
}
return list;
}
function check2(pais, n, o) {
var j, i = 0, p, ml, k = -1;
var list = new Array();
for (j = o; j < 9; ++j) {
if ((k >= 0) && (j > k)) {
break;
}
p = j + n;
if (pais[p] == 0) {
continue;
}
if ((j < 7) && (pais[p + 2] > 0)) {
if (pais[p + 1] > 0) {
list = new Array();
list[0] = ml = new MyList(p, -302);
ml.list = new Array();
return list;
}
--pais[p]; --pais[p + 2];
list[i++] = ml = new MyList(p, 203);
ml.list = check2(pais, n, j);
++pais[p]; ++pais[p + 2];
if (k < 0) {
k = j + 2;
}
}
if ((j < 8) && (pais[p + 1] > 0)) {
--pais[p]; --pais[p + 1];
list[i++] = ml = new MyList(p, 202);
ml.list = check2(pais, n, j);
++pais[p]; ++pais[p + 1];
if (k < 0) {
k = j + 1;
}
}
if (pais[p] == 2) {
pais[p] -= 2;
list[i++] = ml = new MyList(p, 201);
ml.list = check2(pais, n, j + 1);
pais[p] += 2;
break;
}
}
if (i == 0) {
return check3(pais, n, 0);
}
return list;
}
function check1(pais, n, o) {
var j, i = 0, p, ml, k = -1;
var list = new Array();
for (j = o; j < 9; ++j) {
if ((k >= 0) && (j - k > 2)) {
break;
}
p = j + n;
if (pais[p] == 0) {
continue;
}
if ((j < 7) && (pais[p + 1] > 0) && (pais[p + 2] > 0)) {
--pais[p]; --pais[p + 1]; --pais[p + 2];
list[i++] = ml = new MyList(p, 302);
ml.list = check1(pais, n, j);
++pais[p]; ++pais[p + 1]; ++pais[p + 2];
if (k < 0) {
k = j;
}
}
if (pais[p] > 2) {
pais[p] -= 3;
list[i++] = ml = new MyList(p, 301);
ml.list = check1(pais, n, j);
pais[p] += 3;
break;
}
}
if (i == 0) {
return check2(pais, n, 0);
}
return list;
}
function check4(pais) {
var j, i = 0, ml;
var list = new Array();
for (j = 27; j < 34; ++j) {
if (pais[j] == 0) {
continue;
}
switch (pais[j]) {
case 2:
pais[j] -= 2;
list[i++] = ml = new MyList(j, 201);
ml.list = check4(pais);
pais[j] += 2;
case 1:
--pais[j];
list[i++] = ml = new MyList(j, 101);
ml.list = check4(pais);
++pais[j];
break;
case 3:
pais[j] -= 2;
list[i++] = ml = new MyList(j, 201);
ml.list = check4(pais);
pais[j] += 2;
case 4:
pais[j] -= 3;
list[i++] = ml = new MyList(j, 301);
ml.list = check4(pais);
pais[j] += 3;
break;
}
break;
}
return list;
}
function str1(kk) {
var list = new Array();
var j, i = 0, k, ls;
for (j = 0; j < kk.length; ++j) {
ls = str1(kk[j].list);
if (ls.length == 0) {
list[i++] = "[" +kk[j].name + "]";
} else {
for (k = 0; k < ls.length; ++k) {
list[i++] = "[" + kk[j].name + "]" + ls[k];
}
}
}
return list;
}
function con1(kk) {
var list = new Array();
var j, i = 0, k, ls;
for (j = 0; j < kk.length; ++j) {
ls = con1(kk[j].list);
if (ls.length == 0) {
list[i++] = kk[j].clone();
} else {
for (k = 0; k < ls.length; ++k) {
list[i] = kk[j].clone();
list[i++].next = ls[k];
}
}
}
return list;
}
var ss = "---- MANZ ----";
var ls = con1(check1(pais, 0 ,0));
var rs = new Array();
var rsi = 0, mn = 99, sh = 0;
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
ss += ls[j].conString() + "(" + sh + ")---- ----";
if (sh < 0) {
continue;
}
if (sh < mn) {
mn = sh;
}
}
if (mn == 99) {
rs = ls;
} else {
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh == mn) {
rs[rsi++] = ls[j];
}
}
}
ss += " " + rs.length + " ----";
ss += " PINZ ----";
var tp = new Array();
var tpi = 0, k;
ls = con1(check1(pais, 9, 0));
mn = 99;
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
ss += ls[j].conString() + "(" + sh + ")---- ----";
if (sh < 0) {
continue;
}
if (sh < mn) {
mn = sh;
}
}
if (ls.length == 0) {
tp = rs;
} else if (rs.length == 0) {
tp = ls;
} else if (mn == 99) {
for (j = 0; j < ls.length; ++j) {
for (k = 0; k < rs.length; ++k) {
tp[tpi++] = rs[k].conClone().append(ls[j]);
}
}
} else {
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh == mn) {
for (k = 0; k < rs.length; ++k) {
tp[tpi++] = rs[k].conClone().append(ls[j]);
}
}
}
}
ss += " " + tp.length + " ----";
ss += " SOUZ ----";
rs = new Array();
rsi = 0;
mn = 99;
ls = con1(check1(pais, 18, 0));
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
ss += ls[j].conString() + "(" + sh + ")---- ----";
if (sh < 0) {
continue;
}
if (sh < mn) {
mn = sh;
}
}
if (ls.length == 0) {
rs = tp;
} else if (tp.length == 0) {
rs = ls;
} else if (mn == 99) {
for (j = 0; j < ls.length; ++j) {
for (k = 0; k < tp.length; ++k) {
rs[rsi++] = tp[k].conClone().append(ls[j]);
}
}
} else {
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh == mn) {
for (k = 0; k < tp.length; ++k) {
rs[rsi++] = tp[k].conClone().append(ls[j]);
}
}
}
}
ss += " " + rs.length + " ----";
ss += " JIHAI ----";
tp = new Array();
tpi = 0;
ls = con1(check4(pais));
mn = 99;
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
ss += ls[j].conString() + "(" + sh + ")---- ----";
if (sh < 0) {
continue;
}
if (sh < mn) {
mn = sh;
}
}
if (ls.length == 0) {
tp = rs;
} else if (rs.length == 0) {
tp = ls;
} else if (mn == 99) {
for (j = 0; j < ls.length; ++j) {
for (k = 0; k < rs.length; ++k) {
tp[tpi++] = rs[k].conClone().append(ls[j]);
}
}
} else {
for (j = 0; j < ls.length; ++j) {
sh = ls[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh == mn) {
for (k = 0; k < rs.length; ++k) {
tp[tpi++] = rs[k].conClone().append(ls[j]);
}
}
}
}
ss += " " + tp.length + " ----";
ss += " ALL RESULT ----";
mn = 99;
for (j = 0; j < tp.length; ++j) {
sh = tp[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh < mn) {
mn = sh;
}
}
for (j = 0; j < tp.length; ++j) {
sh = tp[j].getTInfo().getShanten();
if (sh < 0) {
continue;
}
if (sh == mn) {
ss += tp[j].conString() + "(" + tp[j].getTInfo().getShanten() + ")---- ----";
}
}
if (mn == 0) {
ss += " 和了";
} else if (mn == 1) {
ss += " 聴牌";
} else if (mn > 1) {
ss += " " + (mn - 1) + " 向聴";
}
return ss;
}