'use strict';
const p = console.log;
const dp = (obj, label = 'debug') => {
console.log(label + ' : ' + JSON.stringify(obj));
};
const nPercentProbability = percent => {
const randomDouble100 = Math.random() * 100;
return randomDouble100 < percent;
};
const spliceByName = (battlers, name) => {
for (let i = 0; i < battlers.length; i++) {
if (battlers[i].name === name) {
battlers.splice(i, 1);
return;
}
}
};
const battlerOfName = (battlers, name) => {
for (const battler of battlers) {
if (battler.name === name) {
return battler;
}
}
};
const getRanking = battlers => {
const battlersCopy = JSON.parse(JSON.stringify(battlers));
return battlersCopy.sort((a, b) => {
if (a.accuracy < b.accuracy) {
/* aはbより弱い */
return 1;
} else {
/* aはbより強い */
return -1;
}
});
};
const getMyRank = (battlers, myName) => {
const ranking = getRanking(battlers);
for (let i = 0; i < ranking.length; i++) {
if (ranking[i].name === myName) {
return i + 1;
}
}
};
const iAmWorst = (battlers, myName) => {
const myRank = getMyRank(battlers, myName);
return myRank === battlers.length;
};
const thinkAndDoCommand = (battlers, myName) => {
// 3人のうち自分が最弱である場合パスする
if (3 === battlers.length) {
/* 3人とも健在である */
if (iAmWorst(battlers, myName)) {
/* 自分が最弱である */
// パスする
return;
}
}
if (1 === battlers.length) {
/* 既に自分1人 */
// パスする
return;
}
/* 現在3人未満または自分が最弱でない */
// ランキング取得
const ranking = getRanking(battlers);
// 攻撃相手選定
let target;
if (ranking[0].name === myName) {
/* 自分が最強である */
// 攻撃相手は二番手
target = ranking[1];
} else {
/* 自分が最強でない */
// 攻撃相手は最強
target = ranking[0];
}
// 自分を取得
const my = battlerOfName(battlers, myName);
// 攻撃
if (nPercentProbability(my.accuracy)) {
/* 当たった */
// 相手を消す
spliceByName(battlers, target.name);
} else {
/* 外れた */
/* DO NOTHING */
}
};
// accuracyは0-100[%]
const createBattler = (name, accuracy) => {
return {
name,
accuracy
};
};
const createBattlers = myAccuracy => {
const battlers = [];
battlers.push(createBattler('a', myAccuracy));
battlers.push(createBattler('b', 70));
battlers.push(createBattler('c', 90));
return battlers;
};
const doSimulation = (myAccuracy, firstCommandIsPass) => {
// 自分はa
const battlers = createBattlers(myAccuracy);
// シミュレーション開始
while (true) {
for (const battler of battlers) {
// 初手パス判定
if (battler.name === 'a' && battlers.length === 3 && firstCommandIsPass) {
continue;
}
thinkAndDoCommand(battlers, battler.name);
}
if (battlers.length === 1) {
/* 最後の一人になった */
break;
}
}
// 勝者を返却する
return battlers[0];
};
const run = (myAccuracy, firstCommandIsPass, times) => {
// スコアボード
const score = {
a: 0,
b: 0,
c: 0
};
// 試行
for (let i = 0; i < times; i++) {
const winner = doSimulation(myAccuracy, firstCommandIsPass);
score[winner.name]++;
}
// 結果
p(`確率:${myAccuracy},初手をパスする:${firstCommandIsPass},試行回数:${times}`);
p(`aの勝率:` + (score.a * 100.0) / times + '%');
p(`bの勝率:` + (score.b * 100.0) / times + '%');
p(`cの勝率:` + (score.c * 100.0) / times + '%');
};
exports.run = run;