class Scene_Riversi < Scene_MenuBase
  
  BOARDWIDTH = 8
  BOARDHEIGHT = 8  
  
  #--------------------------------------------------------------------------
  # ● 開始処理
  #--------------------------------------------------------------------------
  def start
    super

    set_message_txt
    set_init
    create_reversi_window

  end
  
  #--------------------------------------------------------------------------
  # ● 変数などのセット
  #--------------------------------------------------------------------------
  def set_init
    @stage = 1
    @turn_count = 0 # 手数
    @board=[]
    @empty_cells = []
    @ai_puttable=[]
    @cpu_ai = []
    @end_flag =false
    @player_stone = 0
    @cpu_stone = 0
    @result_game = 0    #勝敗
    @current_turn = 1 # 1 : Player  , 2 : CPU
    
    @player = $game_party.members[0]
    @normal_people = Normal_People.new(0)
    
    @list = []
  end
   
  #--------------------------------------------------------------------------
  # ● コマンドウィンドウの作成
  #--------------------------------------------------------------------------
  def create_reversi_window
    
    set_start_stone

    @reversi_window = Window_Reversi.new(0, 0, Graphics.width, Graphics.height)
    @reversi_window.get_board_info(@board)
    @reversi_window.set_handler(:ok,     method(:on_category_ok))
    @reversi_window.set_handler(:cancel, method(:on_category_cancel))
    @reversi_window.get_players(@player ,@normal_people)

    
    @reversi_window.refresh
    @message_window = Window_Message.new

  end  
  #--------------------------------------------------------------------------
  # ● フレーム更新（ウェイト用）
  #--------------------------------------------------------------------------
  def update_for_wait
    update_basic
  end
  #--------------------------------------------------------------------------
  # ● ウェイト
  #--------------------------------------------------------------------------
  def wait(duration)
    duration.times {|i| update_for_wait if i < duration / 2 || !show_fast? }
  end
  #--------------------------------------------------------------------------
  # ● 早送り判定
  #--------------------------------------------------------------------------
  def show_fast?
    Input.press?(:A) || Input.press?(:C)
  end
  #--------------------------------------------------------------------------
  # ● ウェイト（早送り無効）
  #--------------------------------------------------------------------------
  def abs_wait(duration)
    duration.times {|i| update_for_wait }
  end
  #--------------------------------------------------------------------------
  # ● 短時間ウェイト（早送り無効）
  #--------------------------------------------------------------------------
  def abs_wait_short
    abs_wait(15)
  end
  #--------------------------------------------------------------------------
  # ● メッセージ表示が終わるまでウェイト
  #--------------------------------------------------------------------------
  def wait_for_message
    @message_window.update
    update_for_wait while $game_message.visible
  end
  #--------------------------------------------------------------------------
  # ● アニメーション表示が終わるまでウェイト
  #--------------------------------------------------------------------------
  def wait_for_animation
    update_for_wait
    update_for_wait while @spriteset.animation?
  end
  #--------------------------------------------------------------------------
  # ● エフェクト実行が終わるまでウェイト
  #--------------------------------------------------------------------------
  def wait_for_effect
    update_for_wait
    update_for_wait while @spriteset.effect?
  end
  
  #board
  
  #●ボードの石を取得 
  def get_board_data(x , y , board = @board) 
    
    return board[y * BOARDWIDTH + x]
    
  end  
  def set_board_data(x , y , value, board = @board) 
    
    board[y * BOARDWIDTH + x] = value
    
  end    
  #●プレイヤー石の色
  def player_color
    return 1
  end   
  #●相手の石の色
  def cpu_color
    return op_color(player_color)
  end  
  
  #●逆の石の色
  def op_color(color)
    if color == 1
      return 2
    elsif color ==2
      return 1
    end  
  end    
  
  #●開始時の石  
  def set_start_stone(board = @board)
    for i in 0..BOARDWIDTH * BOARDHEIGHT - 1
      @board[i] = 0
    end  
    set_board_data(3 , 3 , 2)
    set_board_data(3 , 4 , 1)
    set_board_data(4 , 3 , 1)
    set_board_data(4 , 4 , 2)

  end
  
  def on_category_ok
    index = @reversi_window.index
    ix = index % BOARDWIDTH
    iy = index / BOARDWIDTH
    if @stage == 0
      play_stage0(ix ,iy)
    elsif @stage == 1
      play_stage1(ix ,iy)
    end  
    

  end  
  
  def on_category_cancel
    if @stage == 0
      @stage = 1
      @reversi_window.activate 
    elsif @stage == 1
      return_scene
    end      
    

  end    
  
  #● stage0の進行
  def play_stage0(x, y)
    s_color = get_board_data(x , y)
    s_color += 1
    s_color %= 3
    Sound.play_ok
    set_board_data(x , y , s_color)
    @reversi_window.get_board_info(@board)
    @reversi_window.refresh


    @reversi_window.activate   
  end  
  
  #● stage1の進行
  def play_stage1(x, y)

    if reverse_stone_puttable?(x , y , player_color)
      Sound.play_ok
      set_board_data(x , y , player_color)
      @reversi_window.get_board_info(@board)
      @reversi_window.refresh
      wait(20)
      
      reverse_stone(x , y ,  player_color)
      @turn_count += 1 #ターン数の更新
      @reversi_window.get_board_info(@board)
      
      @reversi_window.refresh
      wait(20)
         
      play_reversi
#~       @reversi_window.activate
    else
      Sound.play_buzzer
      @reversi_window.activate
    end    
  end  
  
  #● ゲーム進行
  def play_reversi 
    @current_turn = next_turn(@current_turn)
    return reversi_end_after if @current_turn == 0
    if @current_turn == 2
      cpu_put_stone
    elsif @current_turn == 1
      @reversi_window.activate
   
    end 

  end
  #● ターンの管理
  def op_turn(turn_num)
    return 2 if turn_num == 1 
    return 1 if turn_num == 2  
    return 0  
  end   
  
  
  #● ターンに対応する色
  def turn_color(turn_num)
    return player_color if turn_num == 1 
    return cpu_color if turn_num == 2  
    return 0  
  end   
  
  #● ターンの管理
  def reversi_turn
    
    if @current_turn == 1
      @current_turn = 0 unless  puttable_cell_exist?(cpu_color)
    elsif @current_turn == 0
      @current_turn = 1 unless puttable_cell_exist?(player_color)    
    end  
  end 
  #● 次のターンを決定
  def next_turn(cturn)
    oturn = op_turn(cturn)
    return oturn if puttable_cell_exist?(turn_color(oturn))
    return cturn if puttable_cell_exist?(turn_color(cturn))  
    return 0
  
  end   

  #● 試合結果の判定
  def reversi_game_result
    
    if difference_stone > 0  
      @result_game = 1  #プレイヤーの勝利
    elsif difference_stone < 0
      @result_game = 2  #敵の勝利
    else           
      @result_game = 0  #引き分け
    end  
    $game_variables[$MINIGAMERESULT] = @result_game #変数へ勝敗結果を入れる
    result_message_txt
    reversi_message(@player.face_name,@player.face_index,2,0)
    wait_for_message

  end
  
  #● 石の個数カウント
  def number_stone(color , board = @board)
    num = 0
    for i in 0..BOARDWIDTH - 1
      for j in 0..BOARDHEIGHT - 1
        if get_board_data(i , j , board) == color 
          num += 1
        end  
      end
    end 
    return num
    
  end   
  
  #● empty cellのidリスト
  def get_empty_cells(board = @board)
    array = []
    id = 0
    board.each do |i| 
      array.push(id) if i == 0
      id += 1
    end
    return array
  end      
  
  #● 石の個数差
  def difference_stone(color = player_color , board = @board)
    return number_stone(color , board) - number_stone(op_color(color) , board)
    
  end   
  #● 終了後処理
  def reversi_end_after
    reversi_game_result
    return_scene
    
  end  
  
  
  
  #● 終了判定
  def reversi_end?(board = @board)
    if puttable_cell_exist?(player_color, board) || puttable_cell_exist?(cpu_color , board)
      return false
    end  
    return true
  end
    
  #● 置く場所があるのか判定
  def puttable_cell_exist?(color , board = @board)
    for i in 0..BOARDWIDTH - 1
      for j in 0..BOARDHEIGHT - 1
        if reverse_stone_puttable?(i , j , color , board)
          return true
        end  
      end
    end
    return false
  end  
  #● 置くことができるのか判定   
  def reverse_stone_puttable?(x , y , color , board = @board)
    if is_empty_cell?(x , y,board) && reverse_stone_exist?(x , y ,  color ,board)

      return true
    end  
    return false
  end  
  #● 空白地であるのか判定 
  def is_empty_cell?(x , y , board = @board)
    get_board_data(x , y ,board) == 0

  end  
  #● 返す石があるのか判定
  def reverse_stone_exist?(x , y ,  color, board = @board)
    for dx in -1..1
      for dy in -1..1
        if reverse_stone_exist_d?(x , y , dx , dy , color ,board)
          return true
        end
      end
    end 
    return false
  end
  
  #● 方向に返す石があるのか判定
  def reverse_stone_exist_d?(x , y , dx , dy , color , board = @board)
    
    hantei = false
    if x > 0 && dx < 0 
      hantei ||= true if reverse_stone_exist_y?(x , y , dx , dy , color , board) 
      
    end
    if dx == 0 
      hantei ||= true if reverse_stone_exist_y?(x , y , dx , dy , color , board)  
      
    end    
    if x < BOARDWIDTH - 1 && dx > 0 
      hantei ||= true if reverse_stone_exist_y?(x , y , dx , dy , color , board) 
    end    
    return hantei
  end  
  
  #● 返す石があるのか判定 （Y成分）
  def reverse_stone_exist_y?(x , y , dx , dy , color , board = @board)
    hantei = false 
    if y > 0 && dy < 0 
      if get_board_data(x + dx , y + dy ,board) == op_color(color)
       hantei ||= true if reverse_course_op_stone_exist?(x , y , dx , dy , color , board)
      end        
    end  
    if dy == 0 
      if get_board_data(x + dx , y + dy , board) == op_color(color)
       hantei ||= true if reverse_course_op_stone_exist?(x , y , dx , dy , color , board)        
      end 
    end  
    if y < BOARDHEIGHT - 1 && dy > 0 
      if get_board_data(x + dx , y + dy , board) == op_color(color)
       hantei ||= true if reverse_course_op_stone_exist?(x , y , dx , dy , color , board)      
      end        
    end      
    return hantei
  end  
  
  #● ひっくり返すコースに石が0または端になるまでに、自石があるか？
  def reverse_course_op_stone_exist?(x , y , dx , dy , color , board = @board)
    i = 1

    # 逆石でなくなるまでループ
    while  get_board_data(x + dx * i , y + dy * i ,board) == op_color(color) 
      i += 1

      if x + dx * i < 0 || x + dx * i > BOARDWIDTH - 1 
        return false
      end  
      if y + dy * i < 0 || y + dy * i > BOARDHEIGHT - 1 
        return false
      end  
    end
    
    if get_board_data(x + dx * i , y + dy * i ,board) == color
      return true
    else
      return false
    end  
    
  end
  
  #● ひっくり返しの実行 
  def reverse_stone(x , y ,  color , board = @board)
          
    for dx in -1..1
      for dy in -1..1

        if reverse_stone_exist_d?(x , y , dx , dy , color , board)
          reverse_stone_d(x , y , dx ,dy , color , board) 
        end  
      end  
    end  
  end  
  
  #● ひっくり返しの実行　方向別 
  def reverse_stone_d(x , y , dx ,dy , color , board = @board)
    i = 1
    # 逆石でなくなるまでひっくり返す
    while  get_board_data(x + dx * i , y + dy * i , board ) == op_color(color) 

      set_board_data(x + dx * i ,y + dy * i, color , board)
      i += 1
    end    
    
  end  
  

  
end  