【講座?】CoRを触ってみる16~三目並べを作る4~【自分用メモ?】

投稿者:Material 185033 3 mini 光楼(114) 投稿日:2017/05/06 12:23

【講座?】CoRを触ってみる15~三目並べを作る3~【自分用メモ?】←前回

あー、GWが終わっちゃうよー。

#このブログの情報は2017年4月29日現在のものです。今後変更になる可能性があります。

前回の続きです。
game.rbを開いてね!

敵に×を置かせる

とりあえず、〇も×も同じ変数で管理しようと思っているので、
変数circle_spritemark_spriteに書き換えてください。
#=====対戦=====#
scene 'game' do
  #変数定義
  bg_sprite = nil #背景
  mesh_sprite = nil #マス

  ##### ↓変更分↓  #####
  mark_sprite = nil #〇
  ##### ↑変更分↑  #####

  board_data = [0,0,0,0,0,0,0,0,0] #盤面情報 0:空白 1:〇 -1:×
  comparison_board_data = board_data.dup #盤面変化判定用配列

  #定数定義
  screen_width = 800 #ゲーム画面幅
  screen_high = 450 #ゲーム画面高
  board_size = 125 #盤面1マス当たりのサイズ

  #定数計算
  board_left_position = (screen_width / 2 - (board_size / 2 + board_size)).floor #盤面一番左の位置
  board_up_position = (screen_high / 2 - (board_size / 2 + board_size)).floor #盤面一番上の位置

  #デバッグ
  debug_log "ソースファイル読込み完了!"

  preload do 
    #背景素材読込み
    image 'メニュー背景画像', id: 318428, frame_size: [225, 400], frame_pattern: 11
    image 'マス画像', id: 319591
    image '〇画像', id: 202007
  end

  create do
    #背景画像配置
    bg_sprite = put_sprite 'メニュー背景' do
      position 0, 450
      scale 2.0, 2.0
      angle -90
      frame_index 0
    end

    #マス画像配置
    mesh_sprite = put_sprite 'マス' do
      position 800 / 2, 450 / 2
      frame_index 0
    end

    #背景アニメ開始
    bg_sprite.start_animation('通常アニメ')
  end

  update do
    comparison_board_data = board_data.dup #配列コピー

    #クリックまたはタップしたか
    if pointer.down?
      column = ((pointer.x - board_left_position) / board_size).floor #列を求める
      paragraph = ((pointer.y - board_up_position) / board_size).floor #段を求める

      #列が0~2、段も0~2の範囲か
      if (0..2) === column && (0..2) === paragraph
        block = column + paragraph * 3 #列・段からマス番号を求める
        if board_data[block] == 0 #選択したマスが空白か
          board_data[block] = 1
          debug_log "#{block}番のマスをクリック\n #{board_data}\n #{comparison_board_data}"
        end
      end
    end
  end

  render do
    if board_data != comparison_board_data #ターン開始前と現在の盤面が違っていたら
      #違うところを探す
      9.times do |i| #9回ループ
        if board_data[i] != comparison_board_data[i]
          #〇配置

          ##### ↓変更分↓  #####
          mark_sprite = put_sprite '〇' do
          ##### ↑変更分↑  #####

            position board_left_position + i % 3 * board_size, board_up_position + (i / 3).floor * board_size
            scale board_size / 150, board_size / 150
            frame_index 0
          end
        end
      end
    end
  end
end

#シーンスタート
start_scene 'game'


#=====定義=====#
#スプライト
sprite 'メニュー背景' do
  image 'メニュー背景画像'
  origin :left_top

  animation '通常アニメ', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 20, true
end

sprite 'マス' do
  image 'マス画像'
end

sprite '〇' do
  image '〇画像'
  origin :left_top
end


さて、早速敵に行動させましょう。
turnという変数を作り、その値が偶数ならプレーヤーのターン、奇数なら敵AIのターンとします。
#=====対戦=====#
scene 'game' do
  #変数定義
  bg_sprite = nil #背景
  mesh_sprite = nil #マス
  mark_sprite = nil #〇
  board_data = [0,0,0,0,0,0,0,0,0] #盤面情報 0:空白 1:〇 -1:×
  comparison_board_data = board_data.dup #盤面変化判定用配列

  ##### ↓追加分↓  #####
  turn = 0 #ターン
  ##### ↑追加分↑  #####
#後略#

#前略#
  update do
    comparison_board_data = board_data.dup #配列コピー

    ##### ↓追加分↓  #####
    if turn % 2 == 0
      ####プレーヤーのターン####
    ##### ↑追加分↑  #####

      #クリックまたはタップしたか
      if pointer.down?
        column = ((pointer.x - board_left_position) / board_size).floor #列を求める
        paragraph = ((pointer.y - board_up_position) / board_size).floor #段を求める
  
        #列が0~2、段も0~2の範囲か
        if (0..2) === column && (0..2) === paragraph
          block = column + paragraph * 3 #列・段からマス番号を求める
          if board_data[block] == 0 #選択したマスが空白か
            board_data[block] = 1

            ##### ↓追加分↓  #####
            turn += 1 #行動したらターン交代
            ##### ↑追加分↑  #####
            debug_log "#{block}番のマスをクリック\n #{board_data}\n #{comparison_board_data}"
          end
        end
      end

    ##### ↓追加分↓  #####
    else
      ####敵のターン####
    ##### ↑追加分↑  #####

    end
  end
#後略#

続いて敵の動作ですが、とりあえずランダムに置かせます。
#前略#
  update do
    comparison_board_data = board_data.dup #配列コピー

    if turn % 2 == 0
      ####プレーヤーのターン####

      #クリックまたはタップしたか
      if pointer.down?
        column = ((pointer.x - board_left_position) / board_size).floor #列を求める
        paragraph = ((pointer.y - board_up_position) / board_size).floor #段を求める
  
        #列が0~2、段も0~2の範囲か
        if (0..2) === column && (0..2) === paragraph
          block = column + paragraph * 3 #列・段からマス番号を求める
          if board_data[block] == 0 #選択したマスが空白か
            board_data[block] = 1

            turn += 1 #行動したらターン交代
            debug_log "#{block}番のマスをクリック\n #{board_data}\n #{comparison_board_data}"
          end
        end
      end

    else
      ####敵のターン####
      
      ##### ↓追加分↓  #####
      wait_time(500) #0.5秒待機

      #×配置場所選択
      while(board_data[result = rand(9)] != 0) do
        wait_time(100) #無限ループ対策
      end

      board_data[result] = -1 #盤面情報書き換え
      turn += 1 #ターン交代
      ##### ↑追加分↑  #####
    end
  end
#後略#

  • 無限ループ対策について
ここwait_timeメソッドのところを読めば分かります。
全てのマスが埋まってる状態になると無限ループになってしまうのでその対策です。

さてこれを実行すると敵も〇を置いてしまいます。
×を描画する処理を加えましょう。
#前略#
  preload do 
    #背景素材読込み
    image 'メニュー背景画像', id: 318428, frame_size: [225, 400], frame_pattern: 11
    image 'マス画像', id: 319591
    image '〇画像', id: 202007
    
    ##### ↓追加分↓  #####
    image '×画像', id: 202014
    ##### ↑追加分↑  #####
  end
#後略#

#前略#
#=====定義=====#
#スプライト
sprite 'メニュー背景' do
  image 'メニュー背景画像'
  origin :left_top

  animation '通常アニメ', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 20, true
end

sprite 'マス' do
  image 'マス画像'
end

sprite '〇' do
  image '〇画像'
  origin :left_top
end

##### ↓追加分↓  #####
sprite '×' do
  image '×画像'
  origin :left_top
end
##### ↑追加分↑  #####

さて早速描画処理を書くのですが、〇も×も定義名以外同じなので、定義名を変数にして扱います。
#前略#
  render do
    if board_data != comparison_board_data #ターン開始前と現在の盤面が違っていたら
      #違うところを探す
      9.times do |i| #9回ループ
        if board_data[i] != comparison_board_data[i]
          #〇×配置

          ##### ↓変更分↓  #####
          mark = board_data[i] == 1 ? '〇' : '×'
          mark_sprite = put_sprite mark do
          ##### ↑変更分↑  #####

            position board_left_position + i % 3 * board_size, board_up_position + (i / 3).floor * board_size
            scale board_size / 150, board_size / 150
            frame_index 0
          end
        end
      end
    end
  end
#後略#

mark = board_data[i] == 1 ? '〇' : '×'

この処理ではboard_data[i == 1]の時は'〇'、それ以外の時は'×'を変数markに入れています。

今回はここまで。
次回→【講座?】CoRを触ってみる17~三目並べを作る5~【自分用メモ?】

コメントする

コメントするには、ログインする必要があります。

コメント一覧

コメントはありません。