ソースコード:2022年度ゲーム部門審査員特別賞「デコピン野郎」

2022年度ゲーム部門審査員特別賞 「デコピン野郎」を元に、ブラウザ上でRubyグラフィックプログラミングができる「rbCanvas/p5」(https://rbcanvas.net/p5/)に移植しました。 そのソースコードの紹介をしています。

main



# 初期設定用のコード (your setup code here)
def setup
  createCanvas(800, 448)

  angleMode(DEGREES)
  @stage          = Stage.new   # ステージの生成
  @image_continue = loadImage("scene_continue.png")  # 選択画面用イメージのロード
  @sound_bgm      = loadSound("bgm.mp3")             # BGMのロード
  @sound_bgm.setLoop(true)                           # BGMの繰り返し再生
  @scene          = :continue   # 初期画面の設定
  @choi           = 1           # 選択ステージ番号
  @xyd            = 5           # 選択枠の太さ
end

# 画面描画用のコード (your draw code here)
def draw
  background(220)
  case @scene
  when :gamemain      # ゲームプレイ画面
    scene_gamemain
  when :gameover      # ゲームオーバー画面
    scene_gameover
  when :continue      # ゲーム継続選択画面
    scene_continue
  end
end

def scene_gamemain
  #@sound_bgm.play if !@sound_bgm.isPlaying
  status = @stage.play
  if status == false
    @scene = :gameover
    @choi = @stage.st_no
    @sound_bgm.stop
  end
end

def scene_gameover
  # ゲームオーバー
  push do
    fill("white")
    rect(0, 0, width, height)
    push do
      textAlign(CENTER)
      fill("brown")
      textSize(48)
      text("G A M E  O V E R", width / 2, 200)
      fill("black")
      textSize(20)
      text("つぎ頑張ろう", width / 2, 250)
    end
    fill("black")
    textSize(25)
    text("ENTERでステージ選択", 520, 410)
  end
end

def scene_continue
  image(@image_continue, 0, 0)
  push do
    strokeWeight(@xyd)
    stroke("yellow")
    noFill
    x = 50 + ((@choi - 1) % 3) * 250
    y = 28 + ((@choi - 1) / 3).floor * 140
    w = 200
    h = 112
    rect(x, y, w, h, 5)
  end
  # x = 50 + ((@choi - 1) % 3) * 250          # 50, 300, 550,  50, 300, 550,  50, 300, 550
  # y = 28 + ((@choi - 1) / 3).floor * 140    # 28,  28,  28, 168, 168, 168, 196, 196, 196
  # w = 200
  # h = 112

  # 枠の太さを変化(strokeWeight 8~0)
  @xyd -= 0.3
  @xyd = 8 if @xyd <= 0
end

def keyReleased
  case @scene
  when :gamemain
    if keyCode == ESCAPE   # ゲーム中止
      @scene = :continue   # ステージ選択
      @sound_bgm.stop
    end
  when :gameover
    if keyCode == ENTER
      @scene = :continue   # ステージ選択
    end
  when :continue
    # カーソルキーによるステージ選択
    if keyCode == RIGHT_ARROW
      @choi += 1
      @choi = 1 if @choi > 9      # ステージ9より大きい場合はステージ1
    end
    if keyCode == LEFT_ARROW
      @choi -= 1
      @choi = 9 if @choi < 1      # ステージ1より小さい場合はステージ9
    end
    #if keyCode == DOWN_ARROW
    #  if @choi == 9
    #    @choi = 1                 # ステージ9の場合はステージ1
    #  else
    #    @choi += 3                # 下列のステージ
    #    @choi -= 8 if @choi > 9   # 9より大きい場合は 8を引いた値のステージ
    #  end
    #end
    #if keyCode == UP_ARROW
    #  if @choi == 1
    #    @choi = 9                 # ステージ1の場合はステージ9
    #  else
    #    @choi -= 3                # 上列のステージ
    #    @choi += 8 if @choi < 1   # 1より小さい場合は 8を足した値のステージ
     #  end
    #end
    if keyCode == ENTER
      # ステージ決定
      @sound_bgm.play if !@sound_bgm.isPlaying
      @stage.select(@choi)
      @scene = :gamemain
    end
  end
end

 

face

# 追加のコード (your supplementary code here)
class Face
  FRICTION = 0.99   # 移動するときの減速率
  FALL     = 0.88   # 穴に入るときの縮小率
  attr_reader :x,:y, :r, :speed,:angle,:scale,:st_no

  def initialize
    @image = loadImage("face.png").colorKey("white")      # イメージのロード
    @sound_collision = loadSound("effect_collision.mp3")  # 効果音(衝突)
    @r = @image.width / 2  # 顔の半径
    _init                  # 初期化処理
  end

  # 初期化
  def _init
    @angle       = 0     # 顔のデコピンの角度の初期値
    @speed       = 0     # 顔の速度の初期値
    @roll        = 0     # 顔の回転の初期値
    @scale       = 1     # 顔の大きさの初期値
    @alpha       = 0     # 顔の透明度の初期値
  end

  #クリアしたときのリセット    
  def reset
    _init   # 初期化処理
  end   

  # 座標の設定
  def set_position(x, y)
    @x = x
    @y = y
  end

  # マップ情報の設定
  def set_map(map)
    @map = map
  end

  # ブロックかどうかの判定
  def block?(x, y)
   mx = floor(x / 32)
   my = floor(y / 32)
   if @map[my][mx] == 1
     return true   # 当該座標の位置はブロックである
   end
   return false    # 当該座標は位置はブロックではない
  end

  # デコピンされたときの初期処理
  def shoot(speed, angle)
    @speed = speed     # 速さ
    @angle = angle     # 角度
  end

  # 顔の動き
  def move
    @speed *= FRICTION #speedに摩擦係数をかけてだんだんと速度を落とす 
    if @speed <= 0.8
       @speed = 0
       @speed = 0
    end

    # 現在座標を退避
    tx = @x   # x座標
    ty = @y   # y座標

    # 移動量
    dx = -cos(@angle) * @speed * 0.3
    dy =  sin(@angle) * @speed * 0.3

    # 移動後座標
    @x += dx
    @y += dy

    # ブロックとの隙間(衝突判定時)
    gap = 1

    # キャンバス枠の処理  
    if @x > width - @r
      # 右側に当たった時の反射
      @x     = width - @r
      @angle = 180 - @angle
      if @sound_collision.isPlaying
        @sound_collision.stop
      else
        @sound_collision.play
      end
    end
    if @x < 0 + @r
      # 左側に当たった時の反射
      @x     = 0 + @r
      @angle = 180 - @angle
      if @sound_collision.isPlaying
        @sound_collision.stop
      else
        @sound_collision.play
      end
    end
    if @y > height - @r
      # 下に当たった時の反射
      @y     = height - @r
      @angle = 360 - @angle
      if @sound_collision.isPlaying
        @sound_collision.stop
      else
        @sound_collision.play
      end
    end
    if @y < 0 + @r
      # 上に当たった時の反射
      @y     = 0 + @r
      @angle = 360 - @angle
      if @sound_collision.isPlaying
        @sound_collision.stop
      else
        @sound_collision.play
      end
    end

    # ブロックとの衝突判定
    collision_r = false   # 右側面
    collision_l = false   # 左側面
    collision_u = false   # 上側面
    collision_d = false   # 下側面

    # 顔の上下左右から徐々に斜めのポイントをチェック
    (0..45).step(11.25) do |th|
      # 右側面
      th1 = 0 + th
      th2 = 0 - th
      if block?(@x + (@r - gap) * cos(th1), @y - (@r - gap) * sin(th1)) or
         block?(@x + (@r - gap) * cos(th2), @y - (@r - gap) * sin(th2))
        collision_r = true
        #noLoop
        break
      end
      # 左側面
      th1 = 180 + th
      th2 = 180 - th
      if block?(@x + (@r - gap) * cos(th1), @y - (@r - gap) * sin(th1)) or
         block?(@x + (@r - gap) * cos(th2), @y - (@r - gap) * sin(th2))
        collision_l = true
        #noLoop
        break
      end
      # 上側面
      th1 = 90 + th
      th2 = 90 - th
      if block?(@x + (@r - gap) * cos(th1), @y - (@r - gap) * sin(th1)) or
         block?(@x + (@r - gap) * cos(th2), @y - (@r - gap) * sin(th2))
        collision_u = true
        #noLoop
        break
      end
      # 下側面
      th1 = 270 + th
      th2 = 270 - th
      if block?(@x + (@r - gap) * cos(th1), @y - (@r - gap) * sin(th1)) or
         block?(@x + (@r - gap) * cos(th2), @y - (@r - gap) * sin(th2))
        collision_d = true
        #noLoop
        break
      end
    end

    # 跳ね返りによる座標と角度の変化
    if collision_r or collision_l or collision_u or collision_d
      @x = tx    # x座標復元
      @y = ty    # y座標復元
      if @sound_collision.isPlaying
        # 無条件に stop, playを繰り返すと
        #「DOMException: The play() request was interrupted by a call to pause()」エラー
        @sound_collision.stop
      else
        @sound_collision.play
      end
    end
    if collision_r or collision_l
      # 右側または左側が衝突
      @x     = floor(tx / 32) * 32 + 16   # x座標調整(メッシュの中央座標に調整)
      @angle = 180 - @angle               # x方向角度反転 
    end
    if collision_u or collision_d
      # 上側または下側が衝突
      @y     = floor(ty / 32) * 32 + 16   # y座標復元(メッシュの中央座標に調整)
      @angle = 360 - @angle               # y方向角度反転
    end

    # 回転の処理  
    @roll += (@speed * 0.3)
    if @roll <= 1
       @roll = 0
    end
  end

  # 穴に入ったときの吸い込み処理
  def fall(hx, hy)
    # 縮小
    @scale *= FALL
    # 追尾をして穴に入れる
    @x += 1 if @x < hx
    @x -= 1 if @x > hx
    @y += 1 if @y < hy
    @y -= 1 if @y > hy
  end

  # 顔の表示
  def draw
    @alpha += 1
    if @alpha >= 255
       @alpha = 255
    end
    push do
      angleMode(DEGREES)     # 角度の単位を度数に設定(デフォルトは弧度(ラジアン))
      translate(@x, @y)      # 顔の位置座標を原点に設定
      rotate(@roll)          # 座標軸の回転
      imageMode(CENTER)      # イメージの中心座標を基点に設定
      tint(255, @alpha)      # フェードイン
      sw = @image.width  * @scale
      sh = @image.height * @scale
      image(@image, 0, 0, sw, sh)    # イメージを描画
    end
  end
      
end

 

finger

# 追加のコード (your supplementary code here)
class Finger
  attr_reader :shot
  def initialize(face)
    @images = []
    @images << loadImage("finger.png").colorKey("white")
    @images << loadImage("pin1.png").colorKey("white")
    @images << loadImage("pin2.png").colorKey("white")
    @sound_beam = loadSound("effect_beam.mp3")  # 効果音
    @face = face
    _init
  end

  # 初期化
  def _init
    @shot      = 10         # デコピン回数
    @angle     =  0         # デコピン角度
    @strength  =  0         # デコピン強さ
    @inc       =  1         # デコピン強さの増分
    @animation =  0         # アニメーション用添字
  end

  # リセット
  def reset
    _init
  end

  # 描画
  def _draw
    push do
      translate(@face.x, @face.y)
      rotate(@angle)
      imageMode(CENTER)
      image(@images[@animation], 0, 30)
      noStroke
      fill(255, 215, 0, @strength * 2 + 100)   # ゴールド(強さに応じてα値変動)
      rect(10, 30, 10, -@strength, 3)
    end
  end

  # プレイヤーによる操作
  def _pin
    if keyIsDown(RIGHT_ARROW)
      @angle -= 1
    elsif keyIsDown(LEFT_ARROW)
      @angle += 1
    end
    if keyIsDown(SPACE)
      @strength += @inc
      if @strength > 50
        @inc = -1                 # 上限に達したら減少
      elsif @strength <= 0
        @inc = +1                 # 下限に達したら増加
      end
      if @strength < 20
        @animation = 0            # インデックス0(標準の指)
      elsif @strength < 35 
        @animation = 1            # インデックス1(中)
      else
        @animation = 2            # インデックス2(強)
      end
    else
      if @strength != 0
        @face.shoot(@strength, -(@angle + 90))   # デコピン!
        @strength = 0
        @animation = 0
        @shot -= 1
        @sound_beam.play
      end
    end
  end

  # デコピン
  def pin
    _draw
    _pin
  end
end

 

hole

# 追加のコード (your supplementary code here)
class Hole
  attr_reader :x, :y, :r

  def initialize
    @image = loadImage("hole.png").colorKey("white")
    @r     = @image.width / 2   # 穴の半径
    @scale = 1.5                # 穴の描画時の拡大率(顔との衝突判定は @rを使用)
    @alpha = 0                  # 穴の不透明度
  end

  # リセット
  def reset
    @alpha = 0
  end

  # 穴の位置を設定
  def set_position(x, y)
    @x = x
    @y = y
  end

  # 穴の描画
  def draw
    @alpha += 1    # 255まで1を足し続けてだんだんと穴が表示されるようにする
    if @alpha >= 255
      @alpha = 255
    end
    push do
      imageMode(CENTER)      # イメージの中心座標を基点に設定
      translate(@x, @y)
      scale(@scale)
      tint(255, @alpha)      # フェードイン
      image(@image, 0, 0)    # イメージを描画
    end
  end

end

 

stage

# 追加のコード (your supplementary code here)
class Stage
  attr_accessor :st_no

  def initialize
    _set_images      # イメージのロード
    _set_map_tile    # マップタイルのロード
    _set_map         # マップ情報の設定

    @h = @map[0].size      # ステージの高さ(縦タイル数) 14
    @w = @map[0][0].size   # ステージの幅(横タイル数)   25

    @face        = Face.new            # 顔の生成
    @hole        = Hole.new            # 穴の生成
    @finger      = Finger.new(@face)   # 指の生成
    @effect_fall = loadSound("effect_fall.mp3")       # 効果音(穴)
    @st_no = 1      # ステージ番号
    _init           # 初期化処理
  end

  # 初期化
  def _init
    _set_pos(@face, 2)
    _set_pos(@hole, 3)
    @face.set_map(@map[@st_no - 1])
    @face.reset
    @finger.reset
    @hole.reset
  end

  # 顔および穴の位置を設定
  def _set_pos(obj, number)
    @w.times do |i|
      @h.times do |j|
        value = @map[@st_no - 1][j][i]
        if value == number
          obj.set_position(i * 32 + 16, j * 32 + 16)
          return
        end
      end
    end
    # map上に情報がない場合はランダムに位置を決める(ステージ1~2)
    obj.set_position(rand(16..(width - 16)), rand(16..(height - 16)))
  end

  # 次のステージに遷移
  def _next_stage
    next_no = @st_no + 1
    next_no = 1 if next_no > 9
    @st_no = next_no
    _init
  end

  # ステージの選択
  def select(st_no)
    @st_no = st_no
    _init
  end

  # ステージ描画
  def _draw
    # 背景画像
    image(@images[@st_no], 0, 0)
    # ブロック
    @w.times do |i|
      @h.times do |j|
        value = @map[@st_no - 1][j][i]
        image(@map_tile[value], 32 * i, 32 * j)
      end
    end
    # 文字
    push do
      fill("gold")
      textFont("sans-serif")
      textStyle(BOLD)
      textSize(26)
      text("Stage#{@st_no}", 470, 30)
      text("残り#{@finger.shot}回", 600, 30)
    end
    # 穴
    @hole.draw
    # 顔
    @face.draw
    @face.move
  end

  # 顔が穴に入ったかどうかの判定
  def _fall?
    d = dist(@face.x, @face.y, @hole.x, @hole.y)
    if @face.speed <= 2 and d <= @face.r + @hole.r
      return true    # 穴に入った
    else
      return false   # 穴に入っていない
    end
  end

  # ゲームプレイ
  def play
    _draw                           # 描画
    if _fall?
      # 穴に入った場合
      @face.fall(@hole.x, @hole.y)  # 吸い込み処理
      if @face.speed <= 0           # 顔が停止したら次ステージに遷移
        _next_stage
      end
      @effect_fall.play
    else
      if @face.speed == 0           # 顔が停止した場合
        if @finger.shot > 0
          @finger.pin               # デコピン回数が残っていれば指を表示
        else
          return false              # デコピン回数が残っていなければゲームオーバー
        end
      end
    end
    return true                     # プレイ継続
  end

  # イメージのロードと配列への格納
  def _set_images
    @images = []
    @images << nil
    @images << loadImage("st01_mt.fuji.png")
    @images << loadImage("st02_jinja.png")
    @images << loadImage("st03_konjikidou.png")
    @images << loadImage("st04_tajimaha.png")
    @images << loadImage("st05_tenryou.png")
    @images << loadImage("st06_efferutou.png")
    @images << loadImage("st07_pisya.png")
    @images << loadImage("st08_colosseum.png")
    @images << loadImage("st09_moai.png")
  end

  # マップタイル情報の設定
  def _set_map_tile
    @map_tile = []
    @map_tile[0] = createImage(32, 32)           # 背景(透明)
    @map_tile[1] = loadImage("block.png")        # ブロック
    @map_tile[2] = createImage(32, 32)           # 顔
    @map_tile[3] = createImage(32, 32)           # 穴
  end

  # マップ情報の設定
  def _set_map
    #ブロックのマップデータ
    #  0: 背景(透明)
    #  1: ブロック
    #  2: 顔
    #  3: 穴
    @map = [
             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],

             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],

             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0],
              [0, 0, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
              [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]],

             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
              [0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
              [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0],
              [0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0],
              [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
              [0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]],

             [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
              [1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 1],
              [1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],

             [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1],
              [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],

             [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 1, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
              [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],

             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
              [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
              [0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0],
              [0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 2, 1, 0],
              [0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
              [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],

             [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
            ]
  end
end
こんな作品を作ってみたい人はRubyを学ぼうからチャレンジしてみよう。
 Ruby学習サイト(https://www.ruby-procon.net/study/category/siteinfo/rubyonrails/