コールバックを利用した数増やしゲームをつくろう

問題1

次の要件を満たす apply 関数を実装しなさい。

apply は、数値 ab、および操作を行う関数 operation を引数として受け取ります。 そして、operationab に適用した結果を返します。 例:

function apply(a, b, operation) {
  // ...
}
// 5と3に対して足し算を適用します。
console.log(apply(5, 3, function(x, y) { return x + y; })); // 8
// 5と3に対して掛け算を適用します。
console.log(apply(5, 3,  function(x, y) { return x * y; })); // 15
// 5と3に対して掛け算したあと、10を足します。
console.log(apply(5, 3,  function(x, y) { return x * y + 10; })); // 25
// 5と3を掛けた後、その結果に対してさらに5と3を掛けます。
console.log(apply(5, 3,  function(x, y) { return x * y * x * y; })); // 225

問題2

次の要件を満たす selectApply関数を実装しなさい。

apply は、数値 ab、および操作を行う関数 operation1, operation2 を引数として受け取ります。 そして、1が入力された場合はoperation1 を、2が入力された場合はoperation2を、 ab に適用した結果を返します。

function selectApply(a, b, operation1, operation2) {
  let s = window.prompt("どちらの操作か選択してください。1 または 2")
  // ...
}
console.log(apply(5, 3,   function(x, y) { return x + y; }, function(x, y) { return x * y; })); // 15

問題3

次の要件を満たす setOperation, applyOperation 関数を実装しなさい。 setOperation は、操作を行う関数 operationを引数として受け取り、operationを変数に保存します。それ以外には何もしません。

applyOperationは、数値a, bを受け取り、setOperationで保存しておいた関数を実行します。

ヒント: ここでは、operationの内容にconsole.log等を使わないと実行結果が確認できません。

問題4

次の要件を満たす setOperationHidari, setOperationMigi, setValue関数を実装しなさい。

setValue は、window.promptによりふたつの数字を入力させ、保存します。(ヒント:Number(...)で文字列から数値に変換)

setOperationHidariは、操作を行う関数 operationを引数として受け取り、左のボタンが押されたときに実行する関数として保存します。 setOperationMigiは、操作を行う関数 operationを引数として受け取り、右のボタンが押されたときに実行する関数として保存します。

ヒント: 以下のテキストを.htmlの拡張子を付けて保存してください。これでボタンを二つ表示することができます。

<html>
<head>
<style>
<!--
.row { display: flex; flex-direction: row; gap: 10px;}
.row div, .row button { width: 300px; padding: 5px; margin: 5px; background: #ddd; box-sizing: border-box; }
--></style>
<script><!--

addEventListener('load', () => {

  // この部分にJavaScriptプログラムを記入

});

--></script>
</head>
<body>
<div class="row"><button id="buttonHidari">左のボタン</button><button id="buttonMigi">右のボタン</button></div>
</body>
</html>

左のボタンが押されたときに実行する関数として保存するには、addEventListner('click', ...)を使用します。問題3で実装した関数であるsetOperationと、ブラウザが提供している関数であるaddEventListenerの類似性を理解してください。

const buttonHidari = document.getElementById('buttonHidari');

function hidariOshita() {
  alert('左が押されたよ');
};

buttonHidari.addEventListener('click', hidariOshita);

問題5

つぎのようなゲームをつくりなさい。

最初に、画面に「1」が左右に二つ表示されています。これをnumberHidari (←)とnumberMigi (→)と呼ぶことにします。

ふたつの数を受け取り、一つの数を返す関数が5種類ありますが、その中から2つの関数がランダムに選ばれ、画面に表示されています。operationHidarioperationMigiと呼ぶことにします。

左のボタンを押すと、二つの数がoperationHidari により計算され、numberHidariに計算結果が保存されます。 右のボタンを押すと、二つの数がoperationMigiにより計算され、numberMigiに計算結果が保存されます。

これを20回繰り返したあと、numberHidariNumberMigiの合計をスコアとして計算し、ハイスコアを保存します。 そのあと、数字をそれぞれ「1」にリセットします。

ヒント: 以下のテキストを.htmlの拡張子を付けて保存してください。これで数字を表示する場所、関数を表示する場所、ボタン表示することができます。

<html>
<head>
<style>
<!--
.row { display: flex; flex-direction: row; gap: 10px;}
.row div, .row pre, .row button { width: 300px; padding: 5px; margin: 5px; background: #ddd; box-sizing: border-box; }
--></style>
<script><!--

addEventListener('load', () => {

  // この部分にJavaScriptプログラムを記入

});

--></script>
</head>
<body>
<div class="row"><div id="showNumberHidari">1</div> <div id="showNumberMigi">1</div></div>
<div class="row"><pre id="showOperationHidari">...</pre><pre id="showOperationMigi">...</pre></div>
<div class="row"><button id="buttonHidari">左のボタン</button><button id="buttonMigi">右のボタン</button></div>
</body>
</html>

数字を表示するコード

const showNumberHidari = document.getElementById("showNumberHidari");
showNumberHidari.textContent = 16;

関数を表示するコード

const showOperationHidari = document.getElementById("showOperationHidari");
showOperationHidari.textContent = operationHidari.toString();