身の回りの困りごとを楽しく解決! by Works Human Intelligence Advent Calendar 2022
この記事は、身の回りの困りごとを楽しく解決! by Works Human Intelligence Advent Calendar 2022 の19日目の記事です。
初めに
みなさん遊戯王マスターデュエルはやっていますでしょうか?私は遊戯王が大好きで、一時期は毎シーズン最高ランク到達をするくらいやりこんでいました。
しかし、ランクマッチをただやるだけではデッキごとの正確な勝率や敗因などが分からず、むやみにデュエルを重ねるだけになってしまうという問題がありました。これを解決するために戦績管理アプリが欲しいと思っていました。
12月にデュエリストカップという公式競技イベントが開催されるにあたって、マスターデュエルの戦績を管理してくれるアプリを作ろうと思いました。
戦績管理に必要な機能
具体的に戦績管理アプリに欲しい機能を考えたところ、大体以下のような機能があればいいだろうと思いましたので、これらを実現することを目標にします。
- デッキを登録できる
- 勝率を算出できる
- 先手率・後手率を算出できる
- 勝因・敗因をまとめてくれる
- 対面したデッキをまとめてくれる
アプリの構成
あまりフロントエンドに詳しくないので、今回は勉強も兼ねてReact+TypeScriptで作ることにしました。データの保存にはLocalStrageを使っています。(本当はDBを立てるべきだと思うのですが手軽さを優先しました)
作ったもの
リポジトリ
https://github.com/SparrowDev514/duel-log
結果の入力
以下のような画面で一戦ごとの勝ち負けや勝因・敗因を選択します。
勝因などのまとめ
グラフの表示にはChart.jsを使っています。
コードは一部切り抜いています。
ChartJS.register(ArcElement, Tooltip, Legend);
const makeDataForPieChart = (
label: string,
labels: string[],
data: number[]
): ChartDataType => {
const dataForPieChart: ChartDataType = {
labels: labels,
datasets: [
{
label: label,
data: data,
backgroundColor: [
"rgba(255, 99, 132, 0.2)",
"rgba(54, 162, 235, 0.2)",
"rgba(255, 206, 86, 0.2)",
"rgba(75, 192, 192, 0.2)",
"rgba(153, 102, 255, 0.2)",
"rgba(255, 159, 64, 0.2)",
],
borderColor: [
"rgba(255, 99, 132, 1)",
"rgba(54, 162, 235, 1)",
"rgba(255, 206, 86, 1)",
"rgba(75, 192, 192, 1)",
"rgba(153, 102, 255, 1)",
"rgba(255, 159, 64, 1)",
],
borderWidth: 1,
},
],
};
return dataForPieChart;
};
const DuelResults = (): JSX.Element => {
const renderResults = (): JSX.Element => {
// 表示に必要な情報を詰めたオブジェクトを作る
const results: Result = makeResult();
// 勝因・敗因をまとめたオブジェクトを作る
const causeObject: Cause = makeCause();
const causeOfWinData: ChartDataType = makeDataForPieChart(
"勝因",
causeOfWinList,
[
causeObject.causeOfWin.earlySurrenderNum,
causeObject.causeOfWin.lateSurrenderNum,
causeObject.causeOfWin.LuckyNum,
causeObject.causeOfWin.NuturalWinNum,
]
);
const defeatData: ChartDataType = makeDataForPieChart("敗因", defeatList, [
causeObject.defeat.accidentNum,
causeObject.defeat.missNum,
causeObject.defeat.opponentLuckyNum,
]);
return (
<>
<Typography align="center" variant="h6" component="div">
{selectedDeckName}の成績
</Typography>
<Grid container spacing={2} justifyContent="center">
<Grid item xs={12}>
<Typography align="center" variant="h6" component="div">
戦績
</Typography>
<Typography align="center" variant="body1" component="div">
対戦数:{results.totalDuelNum}
</Typography>
<Typography align="center" variant="body1" component="div">
勝率:{results.winRate}
</Typography>
<Typography align="center" variant="body1" component="div">
先手率:{results.firstRate}
</Typography>
</Grid>
<Grid item xs={6} sx={resultStyle}>
<div>勝因</div>
<Pie data={causeOfWinData} />
</Grid>
<Grid item xs={6} sx={resultStyle}>
<div>敗因</div>
<Pie data={defeatData} />
</Grid>
</Grid>
</>
);
};
};
export default DuelResults;
デッキ分布の確認
使ってみて・改修したい点
アプリ使用感
使ってみての感想ですが、入力できる敗因が大まかすぎて分析に足りうるものではないです。今後はもっと詳細に敗因を入力したり分析できるような方法を考えるべきだと思いました。また、勝因は見ても面白くないので項目自体を削除してもいいかと思いました。
対面したデッキをまとめる機能はとても便利で、環境読みに重宝しています。10戦ごとに区切っていますが、今後は時間帯ごとに区切って表示しても面白いと思います。
また、対面したデッキごとの勝率などが表示できるとより良いかと思いました。
改修したい点
コードの何箇所かにany型を使用しているので修正したいです。TypeScriptの型への理解がまだ足りていないですね。UIの点でも使いにくい点があるので、改善したいです。UIは単にコードを書けるだけでは修正できないのでそこも勉強したいですね。