Q&Aで3人でのじゃんけんの勝敗処理についての質問を見かけたので、自分なりに考えてみました。
多人数での勝敗判定は
- 出された手の種類が2種類の場合のみ勝敗が決定、それ以外はあいこ
- 勝敗が決定する場合はどの手が勝ちか調べ、同じ手を出していたプレイヤーは勝ち、それ以外は負け
こんな感じで判定するのが簡単そうかな、とJavaScriptで作成してみたのが以下。
(Q&AはJavaでの質問でしたが、私はJavaは分かりませんので)
index.html
<!DOCTYPE html>
<html lang='ja'>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>多人数じゃんけんsample</title>
<style>
#computersArea {
display: inline-flex;
flex-wrap: wrap;
}
#computersArea div{
width: 150px;
margin: 2px;
padding: 4px;
background-color: #ddd;
}
.main {
display: none;
}
#player0 {
margin-top: 8px;
}
</style>
</head>
<body>
<div class='npSelect'>
<p>自分を除いた相手プレイヤー(コンピューター)数</p>
<select id='np'>
<option value='1'>1</option>
<option value='2' selected>2</option>
<option value='3'>3</option>
<option value='4'>4</option>
<option value='5'>5</option>
<option value='6'>6</option>
<option value='7'>7</option>
<option value='8'>8</option>
<option value='9'>9</option>
</select>人
<button id='start'>開始</button>
</div>
<div class='main' >
<div id='computersArea'>
</div>
<div>
<div id='player0'>
プレイヤー<br>
 出した手: <span class='hand'></span><br>
 結果: <span class='result'></span><br>
 勝数: <span class='winCount'>0</span><br>
<button value='0'>グー</button>
<button value='1'>チョキ</button>
<button value='2'>パー</button>
</div>
</div>
</div>
<script>
'use strict';
const obj = {
players: [],
};
// 相手人数選択 ~ 初期設定
document.getElementById('start').addEventListener('click', () => {
const np = + document.getElementById('np')?.value ?? 1;
obj.players = [];
for(let i = 0; i <= np; i++) {
obj.players[i] = {
winCount: 0,
};
}
document.querySelector('.npSelect').style.display = 'none';
document.querySelector('.main').style.display = 'block';
const comArea = document.getElementById('computersArea');
comArea.innerHTML = '';
for(let i = 1; i <= np; i++) {
document.getElementById('computersArea').insertAdjacentHTML('beforeend', `
<div id='player${i}'>
コンピューター ${i}<br>
 出した手: <span class='hand'></span><br>
 結果: <span class='result'></span><br>
 勝数: <span class='winCount'>0</span><br>
</div>
`);
}
for(const button of document.querySelectorAll('#player0 button')) {
button.addEventListener('click', () => {
judge(+button.value);
})
}
});
// 勝敗判定
const judge = n => {
const handsCheck = [0, 0, 0];
// 自分の出した手
obj.players[0].hand = n;
handsCheck[n]++;
// コンピューターの手をランダムに決定
for(let i = 1; i < obj.players.length; i++) {
const hand = Math.floor(Math.random() * 3);
obj.players[i].hand = hand;
handsCheck[hand]++;
}
// 全プレイヤーで出された手の種類数
const numberOfHandTypes = handsCheck.filter(v => v !== 0).length;
// 2種類の場合は勝敗決定
if(numberOfHandTypes === 2) {
const hands = [];
for(const n in handsCheck) {
if(handsCheck[n] > 0) hands.push(+n);
}
// '勝ち'の手を決定
const winHand = (3 + hands[1] - hands[0]) % 3 === 1 ? hands[0] : hands[1];
// 勝敗結果を各プレイヤーに反映
for(let i = 0; i < obj.players.length; i++) {
const p = obj.players[i];
const flag = p.hand === winHand;
p.result = flag ? 1 : 2;
if(flag) p.winCount++;
}
}
// 2種類以外の場合は引き分け
else {
for(let i = 0; i < obj.players.length; i++) {
obj.players[i].result = 0;
}
}
// 表示反映
for(let i = 0; i < obj.players.length; i++) {
const d = document.getElementById('player' + i);
d.querySelector('.hand').textContent = ['グー', 'チョキ', 'パー'][obj.players[i].hand];
d.querySelector('.result').textContent = ['あいこ', '勝ち', '負け'][obj.players[i].result];
d.querySelector('.result').style.color = ['black', 'blue', 'red'][obj.players[i].result];
d.querySelector('.winCount').textContent = obj.players[i].winCount;
}
};
</script>
</body>
</html>
####実動デモ####
想定通り動いているようですが、多人数での勝敗判定を考えるのが目的でしたので、負けたプレイヤーが脱落する勝ち抜きや、最初に何勝したプレイヤーが優勝、といった処理はありません。