class Scene_Riversi < Scene_MenuBase BOARDWIDTH = 8 BOARDHEIGHT = 8 #-------------------------------------------------------------------------- # ● 開始処理 #-------------------------------------------------------------------------- def start super set_init create_reversi_window set_player_color play_reversi end #-------------------------------------------------------------------------- # ● 変数などのセット #-------------------------------------------------------------------------- def set_init @stage = 1 @turn_count = 0 # 手数 @board=[] @empty_cells = [] @ai_puttable=[] @cpu_ai = [] @w_array = (0..(BOARDWIDTH - 1)) @h_array = (0..(BOARDHEIGHT - 1)) @pass_flag = 0 #~ @ai_board2 = [] @player_stone = 0 @cpu_stone = 0 @result_game = 0 #勝敗 @current_turn = 1 # 1 : Player , 2 : CPU @player = $game_party.members[0] person_id = $game_variables[$reversi_chara_id] @current_person = $data_normal_person[person_id] @ai_phase = 0 @list = [] @records = [] @opening_game = true init_opening(@current_person) #追加 end #-------------------------------------------------------------------------- # ● コマンドウィンドウの作成 #-------------------------------------------------------------------------- def create_reversi_window set_start_stone #~ wy = @category_window.y + @category_window.height #~ wh = Graphics.height - wy @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 ,@current_person) #~ @reversi_window.get_ai_board(@ai_board) #デバッグ用 @reversi_window.refresh @message_window = Window_Message.new @reversi_window.deactivate end #-------------------------------------------------------------------------- # ● フレーム更新(ウェイト用) #-------------------------------------------------------------------------- def update_for_wait update_basic end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update ai_thinking if @ai_phase == 1 update_basic end def ai_thinking ai_pre_thinking if @ai_phase == 2 cpu_put_stone end end def set_player_color if $game_variables[$REVERSIFIRST] == 0 @player_color = 1 @current_turn = 1 else @player_color = 2 @current_turn = 2 @reversi_window.deactivate end 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 inside_board(cx,cy) return 0 <= cx && cx < BOARDWIDTH && 0 <= cy && cy < BOARDHEIGHT end #●ボードの石を取得 def get_board_data(x , y , board = @board) if inside_board(x,y) return board[y * BOARDWIDTH + x] end return 0 end #●ボードの石を取得 insideのチェックなし def get_board_data2(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 @player_color 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) elsif @stage == 2 play_stage2(ix ,iy) end end def on_category_cancel if @stage == 0 @stage = 1 @reversi_window.activate elsif @stage == 1 if $reversi_chancel return_scene else @reversi_window.activate end elsif @stage == 2 return_scene end end #● stage2の進行 def play_stage2(x, y) if reverse_stone_puttable?(x , y , player_color) Sound.play_ok process_reverse_stone_in_stage2(x,y,player_color) else Sound.play_buzzer @reversi_window.activate 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 process_reverse_stone(x,y,player_color) #~ set_reaction if @current_turn > 0 #~ @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 == 1 #~ @reversi_window.activate #~ #~ end if reversi_end? set_msg_game_end reversi_end_after @current_turn = 0 else if @current_turn == 2 play_reversi_cpu elsif @current_turn == 1 @reversi_window.activate end end end def play_reversi_cpu @ai_phase = 1 end def process_reverse_stone(x,y,color) set_board_data(x , y , color) @reversi_window.get_board_info(@board) @reversi_window.refresh wait(20) reverse_stone(x , y , color) @records[@turn_count] = [color,x,y] @turn_count += 1 #ターン数の更新 @reversi_window.get_board_info(@board) @reversi_window.refresh process_msg_pass if @current_turn == 2 set_reaction if @current_turn == 1 put_stone_after wait(20) play_reversi end def process_reverse_stone_in_stage2(x,y,color) set_board_data(x , y , color) reverse_stone(x , y , color) @records[@turn_count] = [color,x,y] @turn_count += 1 #ターン数の更新 @reversi_window.get_board_info(@board) update_currentnode_in_stage2(x, y) @reversi_window.current_message = "stage2" @reversi_window.refresh put_stone_after change_color_in_stage2 @reversi_window.activate end def change_color_in_stage2 @player_color = @current_turn == 1 ? 1 : 2 end def put_stone_after reversi_turn 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 = @current_turn) return player_color if turn_num == 1 return cpu_color if turn_num == 2 return 0 end #● ターンの管理 def reversi_turn @pass_flag = 0 if reversi_end? @pass_flag = 3 return end if @current_turn == 1 if puttable_cell_exist?(cpu_color) @current_turn = 2 else @pass_flag = 1 end elsif @current_turn == 2 if puttable_cell_exist?(player_color) @current_turn = 1 else @pass_flag = 2 end 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 #~ dstone = number_stone(player_color) - number_stone(cpu_color) if difference_stone > 0 @result_game = 1 #プレイヤーの勝利 elsif difference_stone < 0 @result_game = 2 #敵の勝利 else @result_game = 0 #引き分け end $game_variables[$REVERSIRESULT] = @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 board.each do |col| num += 1 if col == color end return num end #● 空きの個数カウント def number_empty(board = @board) number_stone(0 , board ) 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 @opening_game = true reversi_game_result return_scene end #● 勝ちが決定しているか def check_win(col,board) return (reversi_end?(board)) && (get_sup_stone(board) == col) end #● 数が多いほうの石 def get_sup_stone(board) if difference_stone(player_color , board) > 0 return 1 elsif difference_stone(player_color , board) < 0 return 2 end return 0 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) @w_array.each do |i| @h_array.each do |j| 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) if reverse_stone_exist_d?(x , y , -1 , 0 , color ,board) return true elsif reverse_stone_exist_d?(x , y , 1 , 0 , color ,board) return true elsif reverse_stone_exist_d?(x , y , 0 , 1 , color ,board) return true elsif reverse_stone_exist_d?(x , y , 0 , -1 , color ,board) return true elsif reverse_stone_exist_d?(x , y , 1 , 1 , color ,board) return true elsif reverse_stone_exist_d?(x , y , 1 , -1 , color ,board) return true elsif reverse_stone_exist_d?(x , y , -1 , 1 , color ,board) return true elsif reverse_stone_exist_d?(x , y , -1 , -1 , color ,board) return true 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_data2(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_data2(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_data2(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_data2(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_data2(x + dx * i , y + dy * i ,board) == color return true else return false end end #● ひっくり返しの実行 def reverse_stone(x , y , color , board = @board) if reverse_stone_exist_d?(x , y , -1 , -1 , color , board) reverse_stone_d(x , y , -1 ,-1 , color , board) end if reverse_stone_exist_d?(x , y , -1 , 0 , color , board) reverse_stone_d(x , y , -1 ,0 , color , board) end if reverse_stone_exist_d?(x , y , -1 , 1 , color , board) reverse_stone_d(x , y , -1 ,1 , color , board) end if reverse_stone_exist_d?(x , y , 0 , -1 , color , board) reverse_stone_d(x , y , 0 ,-1 , color , board) end if reverse_stone_exist_d?(x , y , 0 , 1 , color , board) reverse_stone_d(x , y , 0 ,1 , color , board) end if reverse_stone_exist_d?(x , y , 1 , -1 , color , board) reverse_stone_d(x , y , 1 ,-1 , color , board) end if reverse_stone_exist_d?(x , y , 1 , 0 , color , board) reverse_stone_d(x , y , 1 ,0 , color , board) end if reverse_stone_exist_d?(x , y , 1 , 1 , color , board) reverse_stone_d(x , y , 1 ,1 , color , board) end end #● ひっくり返しの実行 方向別 def reverse_stone_d(x , y , dx ,dy , color , board = @board) i = 1 # 逆石でなくなるまでひっくり返す while get_board_data2(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