paizaラーニング レベルアップ問題集 スタック・キューメニュー応用編 JavaScript カードゲーム

カードゲーム (paizaランク B 相当)

https://paiza.jp/works/mondai/stack_queue_advanced/stack_queue_advanced__card_game

# 解答例
山札に1-40までの数字を順番にセット。効果を発動する中で、手札に加えて、その中にキーカードの番号があるか判定するようにした。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);
let key = false;//キーカードが引けたか判定

let deck = Array(40).fill(1).map((v, i) => v = i + 1);//山札、キュー

let hands = [];//手札
let graveyard = [];//墓地、スタック
let excusion = [];//除外、スタック

//発動する効果
for (let i = 1; i <= K; i++) {
  const [event, X] = lines[i].split(" ").map((v, i) => i === 0 ? v : Number(v));
  
  if (event === "game_start") {
    //山札の上から 5 枚引く。
    for (let j = 0; j < 5; j++) {
      hands.push(deck.shift());
    }
  } else if (event === "draw") {
    //山札の上から X 枚引く。
    for (let j = 0; j < X; j++) {
      hands.push(deck.shift());
    }
  } else if (event === "discard") {
    //山札の上から X 枚を、一番上のカードから順番に墓地へ送る。
    for (let j = 0; j < X; j++) {
      graveyard.push(deck.shift());
    }
  } else if (event === "return_from_the_graveyard") {
    //墓地の上から X 枚を、一番上のカードから順番に山札の一番下に加える。
    for (let j = 0; j < X; j++) {
      deck.push(graveyard.pop());
    }
  } else if (event === "exclude") {
    //山札の上から X 枚を、一番上のカードから順番に除外する。
    for (let j = 0; j < X; j++) {
      excusion.push(deck.shift());
    }
  } else if (event === "return_from_the_exclusion") {
    //除外されているカードの上から X 枚を、一番上のカードから順番に山札の一番下に加える。
    for (let j = 0; j < X; j++) {
      deck.push(excusion.pop());
    }
  }
  
  //効果発動後、キーカード引けたか=手札にキーカードがあるかチェック
  if (hands.indexOf(N) > 0) {
    console.log(K);
    break;
  }
}

//キーカードを引くことができない=手札にキーカードがない場合は "Lose" と出力
if (hands.indexOf(N) === -1) console.log("Lose");
```


# 解答例(C++の場合参考)
キーカードを引いた判定に変数keyを採用した。手札は無しで、山札にキーカードをtrueでセットした。山札からカードを引くときに、カードがtrueならばkeyをtrueにする。効果発動後keyがtrueか判定し、効果発動回数を出力。全て効果発動してもkeyがfalseのままならLoseを出力。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);
let key = false;//キーカードが引けたか判定

let deck = [];//山札、キュー
let graveyard = [];//墓地、スタック
let exclusion = [];//除外、スタック

//山札セット、キーカードをtrueとする
for (let i = 0; i < 40; i++) {
  if (i === N - 1) {
    deck.push(true);
  } else {
    deck.push(false);
  }
}

//発動する効果
for (let i = 1; i <= K; i++) {
  
  const [event, X] = lines[i].split(" ").map((v, i) => i === 0 ? v : Number(v));
  
  if (event === "game_start") {
    //山札の上から 5 枚引く。
    for (let j = 0; j < 5; j++) {
      if (deck[0]) { //引いたカードがキーカードならば
        key = true;
      }
      deck.shift();
    }
    
  } else if (event === "draw") {
    //山札の上から X 枚引く。
   for (let j = 0; j < X; j++) {
      if (deck[0]) { //引いたカードがキーカードならば
        key = true;
      }
      deck.shift();
    }
    
  } else if (event === "discard") {
    //山札の上から X 枚を、一番上のカードから順番に墓地へ送る。
    for (let j = 0; j < X; j++) {
      graveyard.push(deck[0]);
      deck.shift();
    }
    
  } else if (event === "return_from_the_graveyard") {
    //墓地の上から X 枚を、一番上のカードから順番に山札の一番下に加える。
    for (let j = 0; j < X; j++) {
      deck.push(graveyard[graveyard.length - 1]);
      graveyard.pop();
    }
    
  } else if (event === "exclude") {
    //山札の上から X 枚を、一番上のカードから順番に除外する。
    for (let j = 0; j < X; j++) {
      exclusion.push(deck[0]);
      deck.shift();
    }
    
  } else if (event === "return_from_the_exclusion") {
    //除外されているカードの上から X 枚を、一番上のカードから順番に山札の一番下に加える。
    for (let j = 0; j < X; j++) {
      deck.push(exclusion[exclusion.length - 1]);
      exclusion.pop();
    }
  }
  
  //効果発動後、キーカード引けたかチェック
  if (key) {
    console.log(i);
    break;
  }
}

//キーカードを引くことができない場合は "Lose" と出力
if (!key) console.log("Lose");
```