04-02 配列の操作

例題4-2-1

勇者が冒険で5つのアイテムを順番に手に入れるプログラムを作りなさい。アイテムを手に入れるたびに、所持アイテムの一覧を表示しなさい。

function setup() {
  let items = ["やくそう"];  // 最初は「やくそう」だけ
  print("=== 冒険スタート! ===");
  print("所持アイテム: " + items);
  print("「たいまつ」を手に入れた!");
  items.push("たいまつ")
  print("所持アイテム:" + items)
  print("「せいすい」を手に入れた!");
  items.push("せいすい")
  print("所持アイテム:" + items)
  print("「かぎ」を手に入れた!");
  items.push("かぎ")
  print("所持アイテム:" + items)
  print("「ちからのたね」を手に入れた!");
  items.push("ちからのたね")
  print("所持アイテム:" + items)
  // 「たいまつ」「せいすい」「キメラのつばさ」「かぎ」「ちからのたね」を順番に手に入れる
}
表示する文字数が多かったので、結構見づらくなってしまいました。でも課題はクリアしていると思います。
それと、この課題は例題と書かれていたので、これはやるべき問題なのか疑いながら作りました。どうなのでしょうか?

練習問題4-2-2

配列 ["やくそう", "たいまつ", "せいすい"] から、アイテムが無くなるまで使い続けるプログラムを作りなさい。「アイテムを全て使い切りました!」と表示して終わりなさい。

function setup() {
  let items = ["やくそう", "たいまつ", "せいすい"];
  print("所持アイテム: " + items);
  let itemsused = 0
  while(items.length > 0){
    itemsused = items.pop()
    print("勇者は「"+itemsused+"」を使った!")
    if(items.length > 0){
      print("所持アイテム:"+items)
    }
    else{
      print("アイテムをすべて使い切りました!")
    }
  }
}
この課題は相当苦戦しました。とくにwhileの前にpopを書いてしまうと、lengthの値が減った状態でループに入ってしまうので、変数を一度0にしてからループの中でpopを使うことで解決しました。

例題4-2-3

勇者が特定のアイテムを持っているかどうかを確認するプログラムを作りなさい。「たいまつ」と「まほうのかぎ」を持っているかチェックして、結果を表示しなさい。

function setup() {
  let items = ["やくそう", "たいまつ", "せいすい", "キメラのつばさ", "かぎ"];
  print("所持アイテム: " + items);
  print("");

  if(items.indexOf("たいまつ")!==-1){
    print("勇者は「たいまつ」を持っている")
  }else{
    print("勇者は「たいまつ」を持っていない")
  }
  if(items.indexOf("まほうのかぎ")!==-1){
    print("勇者は「まほうのかぎ」を持っている")
  }else{
    print("勇者は「まほうのかぎ」を持っていない")
  }
}
indexOfの使い方の所を見て作ったので、難しくはありませんでしたが、indexOfのoが大文字だったおは意外でした。
この問題も例題だったので作るか少し迷いましたが、この書き方はおそらく問題だと思ったので作りました。

練習問題4-2-4

配列 ["やくそう", "たいまつ", "せいすい", "キメラのつばさ", "かぎ"] に対して、次の操作を順番に行いなさい:

  1. 「せいすい」を「まんげつそう」に交換する
  2. インデックス0の位置に「やくそう(大)」を挿入する
  3. 最後の要素を削除する

各操作後に配列の内容を表示しなさい

function setup() {
  let items = ["やくそう", "たいまつ", "せいすい", "キメラのつばさ", "かぎ"];
  print("最初: " + items);

  items.splice(2,1, "まんげつそう");
  print("せいすいとまんげつそうを交換した!現在所持しているアイテム:"+items);
  items.splice(0, 0, "やくそう(大)");
  print("やくそう(大)を手に入れた!現在所持しているアイテム:"+items);
  items.splice(5, 1)
  print("持っているアイテムで一番最後のアイテムを失ってしまった!現在所持しているアイテム:"+items);
  
}

いくつか凡ミスをしたりはしましたが、まったくわからないところなどはなかったです。

練習問題4-2-5

次の数値配列をsort()で並べ替え、結果について考察して先生に説明しなさい。

毎度のごとく今は教室にいないので、ここに書きます。
実行してみると

このようになりました。
sortの紹介と合わせると、sortは最初の一文字だけ見て、ひらがなやカタカナならば五十音順に並べて、数字なら1~9のように並べられると考えました。
そこで気になるのがアルファベットです。私の予想ではアルファベット順に並ぶと予想しました。
function setup() {
  let prices = ["i", "e", "b", "c", "l"];
  print("アルファベット: " + prices);

  prices.sort()
  print("変更後 アルファベット:" + prices)
}
この実験からやはり、アルファベットもアルファベット順に並べられることがわかりました。
そして、sortは数字を並べるにはあまり適していませんが、ひらがなやカタカナなどには使えると思いました。

練習問題4-2-6

アイテムの価格リスト [480, 120, 320, 80, 650] を作成し、次の順番で表示しなさい

function setup() {
  let prices = [480, 120, 320, 80, 650];
  print("元の順番");
  
  prices.sort(function(a, b){
    return a - b;
  });
  print("安い順"+prices);
  prices.sort(function(a, b){
    return b - a;
  });
  print("高い順"+prices);
}
このプログラムを作っている間に、どうすれば少なくても3桁までの数字が順番に並べられる方法は分かりましたが、どうしてそのような挙動をするのかはよくわからなかったので、今度聞こうと思います。
ちなみに気になって、四桁にしてみましたが動くみたいです。

練習問題4-2-7

今まで作ってきたガチャのシステムはレア度しか表示されませんでした。アイテム一覧の配列を作り、アイテムが排出するように作り直しなさい。ランク確定後、そのランクのアイテムの中から一つが抽選され排出されるようにしなさい。

function setup() {
  let rank1 = ["ピンスティック","ひのきのぼう"];
  let rank2 = ["きょうじゃのこん","せいどうのツメ","くさかりがま","シーブスナイフ"];
  let rank3 = ["バトルアックス","はがねのツメ","はがねのムチ","はがねのやり"];
  let rank4 = ["オルテガのオノ","パパスの剣","シルバークロー","あくまのムチ"];
  let rank5 = ["メタルキングの剣","ラーミアのムチ","ゾンビキラー","はやぶさの剣"];

  let tickets = 30;    // 手持ちチケット
  let n = 0;           // 累計回数

  while (tickets > 0) {
    tickets--;
    n++;

    let r = random();
    let item = "";
    if (r < 0.03) {
      print(n + "回目:" +rank5[Math.floor(random(rank5.length))]+ "(★★★★★)");
    } else if (r < 0.03 + 0.07) {
      print(n + "回目:" +rank4[Math.floor(random(rank4.length))]+ "(★★★★)");
    } else if (r < 0.03 + 0.07 + 0.15) {
      print(n + "回目:" +rank3[Math.floor(random(rank3.length))]+ "(★★★)");
    } else if (r < 0.03 + 0.07 + 0.15 + 0.30) {
      print(n + "回目:" +rank2[Math.floor(random(rank2.length))]+ "(★★)");
    } else {
      print(n + "回目:" +rank1[Math.floor(random(rank1.length))]+ "(★)");
    }
  }

  print("合計" + n + "回引きました");
}
ここまで実行結果が多いとすべてを見るのが大変なので、完全にランダム化は分かりませんが、もしも出るアイテムの数が変わってもいいように作りました。
完全にランダムかは、確かめるのがめんどくさいので、またの機会にやります。
後々見てみると、なんかもともと用意されている変数を使っていないような気がしてきました。気のせいかもしれません。

練習問題4-2-8(チャレンジ問題)

10連ガチャの結果をレアリティの高い順に並び替えて表示するプログラムを作りなさい。(ヒント:S、A、B、Cの順番で表示するには、配列を並び替えるか、レアリティごとに配列を分けて表示します)

function setup() {
  let rank1 = ["ピンスティック","ひのきのぼう"];
  let rank2 = ["きょうじゃのこん","せいどうのツメ","くさかりがま","シーブスナイフ"];
  let rank3 = ["バトルアックス","はがねのツメ","はがねのムチ","はがねのやり"];
  let rank4 = ["オルテガのオノ","パパスの剣","シルバークロー","あくまのムチ"];
  let rank5 = ["メタルキングの剣","ラーミアのムチ","ゾンビキラー","はやぶさの剣"];

  let tickets = 10;    // 手持ちチケット
  let n = 0;           // 累計回数
  let r5 =0
  let r4 =0
  let r3 =0
  let r2 =0
  let r1 =0
  
  while (tickets > 0) {
    tickets--;
    n++;

    let r = random();
    if (r < 0.03) {
      r5++
    } else if (r < 0.03 + 0.07) {
      r4++
    } else if (r < 0.03 + 0.07 + 0.15) {
      r3++
    } else if (r < 0.03 + 0.07 + 0.15 + 0.30) {
      r2++
    } else {
      r1++
    }
  }
  while(r5 > 0){
    print("星五:"+rank5[Math.floor(random(rank5.length))])
    r5--
  }
  while(r4> 0){
    print("星四:"+rank4[Math.floor(random(rank4.length))])
    r4--
  }
  while(r3 > 0){
    print("星三:"+rank3[Math.floor(random(rank3.length))])
    r3--
  }
  while(r2 > 0){
    print("星二:"+rank2[Math.floor(random(rank2.length))])
    r2--
  }
  while(r1 > 0){
    print("星一:"+rank1[Math.floor(random(rank1.length))])
    r1--
  }
  print("合計" + n + "回引きました");
}
私にできるのはここまでです。
本来なら同じものをまとめたりした方がいいのでしょうが、もう力尽きました。
私はあまりバグが起きてもショックを受けません。何故ならどこが間違ってたか気づいて直すのも嫌いではないからです。でもwhileを使うと毎回無限ループが起きてだいたい原因は凡ミスなので、疲れます。

練習問題4-2-9

今回学んだ配列の操作方法を表形式でまとめなさい。

  • push 配列に指定したものを入れることができる
  • pop  配列の一番最後のものを消すことができる。
  • ndexOf 指定した要素がどこにあるかを教えてくれる。
  • splice 指定した位置にあるものに干渉できる。「個人的には使い勝手が良くて好き」
  • sort 配列の中身を順番に並べ替えることができる。数字を最初以外も考慮させる仕組みがいまいちわからない
  • reverse 配列の中身を逆からならべなおすことができる。

表の作り方が全く分からなかったので、なんか違う感じになってしまいました。
それと今回学んだというのが配列なのか4-2なのかわからなかったのですが、とりあえず4-2の中で作りました。
この作り方でだめなら今度教えてください。

コメントする