【講座?】CoRを触ってみる21~三目並べを作る8~【自分用メモ?】
投稿者: 光楼(114) 投稿日:2017/06/17 12:19
【講座?】CoRを触ってみる20~三目並べを作る7~【自分用メモ?】←前回
#このブログの情報は2017年6月11日現在のものです。今後変更になる可能性があります。
今回は敵のAIを作っていきます。
いつものようにgame.rbを開いてね!
AIの処理の流れですが、
勝てる手を探す → 負けない手を探す
という流れにしようと思います。
方法は全ての空のマスに順番に×を入れて、勝敗判定の処理をさせます。
判定が2(プレイヤーの敗北)となれば、そのマスに×を入れるとAIが勝てるということになります。
では早速やってみましょう!
勝てる場所を見つけた後にランダム選択を行われると困るので、配置場所が決まってない時だけ行うようif文を追加しました。
さて続いては……
〇を置いてみてプレイヤーが勝ってしまう場所を探すんです。
なのでさっきのを
とすればいいのですが、ほとんど同じ処理を2度書くのはあまり賢くないやり方なので、ループと変数使ってもう一度処理を行わせます。
ループ回数を変数jで管理しています。
勝てる場所が見つかったならループを脱出・見つからなかったら負けを防ぐ処理へ移行します。
AIの負けを防げる位置が見つかった場合はループを脱出、見つからなかった場合もループ回数の条件に引っ掛かりループを脱出します。
変数resultがnilのままなのでランダム処理を行います。
AIはこれで完成です。
お疲れさまでした!
次回→【講座?】CoRを触ってみる22~三目並べを作る9(終)~【自分用メモ?】
ツイート
#このブログの情報は2017年6月11日現在のものです。今後変更になる可能性があります。
今回は敵のAIを作っていきます。
いつものようにgame.rbを開いてね!
AIの処理の流れですが、
勝てる手を探す → 負けない手を探す
という流れにしようと思います。
- 勝てる手を探す
方法は全ての空のマスに順番に×を入れて、勝敗判定の処理をさせます。
判定が2(プレイヤーの敗北)となれば、そのマスに×を入れるとAIが勝てるということになります。
では早速やってみましょう!
#前略 update do comparison_board_data = board_data.dup #配列コピー if decision % 2 == 0 #勝敗判定実行判断 ####プレーヤーor敵ターン#### 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 #行動したらターン交代 decision += 1 end end end else ####敵のターン#### wait_time(500) #0.5秒待機 ##### ↓追加分↓ ##### result = nil #×を入れるマス番号 temporary_board = nil #操作用盤面 #勝てる場所探索 9.times do |i| #9回ループ if board_data[i] == 0 #i番のマスは空か temporary_board = board_data.dup #操作用盤面に盤面データをコピー temporary_board[i] = -1 #×を入れてみる if win_or_loss(temporary_board) == 2 #プレイヤーが負けるか result = i #×配置場所確定 break #ループ脱出 end end end ##### ↑追加分↑ ##### ##### ↓変更分↓ ##### #ランダム選択 if result == nil while(board_data[result = rand(9)] != 0) do wait_time(100) #無限ループ対策 end end ##### ↑変更分↑ ##### board_data[result] = -1 #盤面情報書き換え turn += 1 #ターン交代 decision += 1 end #後略
勝てる場所を見つけた後にランダム選択を行われると困るので、配置場所が決まってない時だけ行うようif文を追加しました。
さて続いては……
- 負けない手を探す
〇を置いてみてプレイヤーが勝ってしまう場所を探すんです。
なのでさっきのを
#勝てる場所探索 9.times do |i| #9回ループ if board_data[i] == 0 #i番のマスは空か temporary_board = board_data.dup #操作用盤面に盤面データをコピー temporary_board[i] = 1 #〇を入れてみる if win_or_loss(temporary_board) == 1 #プレイヤーが勝つか result = i #×配置場所確定 break #ループ脱出 end end end
とすればいいのですが、ほとんど同じ処理を2度書くのはあまり賢くないやり方なので、ループと変数使ってもう一度処理を行わせます。
update do comparison_board_data = board_data.dup #配列コピー if decision % 2 == 0 #勝敗判定実行判断 ####プレーヤーor敵ターン#### 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 #行動したらターン交代 decision += 1 end end end else ####敵のターン#### wait_time(500) #0.5秒待機 result = nil #×を入れるマス番号 temporary_board = nil #操作用盤面 input_mark = -1 #配置するマーク required_decision = 2 #欲しい判定結果 ##### ↓変更分↓ ##### #勝てる場所・負けを防ぐ場所探索 j = 0 while 1 9.times do |i| #9回ループ if board_data[i] == 0 #i番のマスは空か temporary_board = board_data.dup #操作用盤面に盤面データをコピー temporary_board[i] = input_mark #×・〇を入れてみる if win_or_loss(temporary_board) == required_decision #欲しい判定が出るか result = i #×配置場所確定 break #ループ脱出 end end end if j == 0 && result == nil #負けを防ぐ処理へ j = 1 input_mark = 1 #配置するマークを〇に required_decision = 1 #欲しい判定を1に else break #ループ脱出 end end ##### ↑変更分↑ ##### #ランダム選択 if result == nil while(board_data[result = rand(9)] != 0) do wait_time(100) #無限ループ対策 end end board_data[result] = -1 #盤面情報書き換え turn += 1 #ターン交代 decision += 1 end
ループ回数を変数jで管理しています。
勝てる場所が見つかったならループを脱出・見つからなかったら負けを防ぐ処理へ移行します。
AIの負けを防げる位置が見つかった場合はループを脱出、見つからなかった場合もループ回数の条件に引っ掛かりループを脱出します。
変数resultがnilのままなのでランダム処理を行います。
AIはこれで完成です。
お疲れさまでした!
次回→【講座?】CoRを触ってみる22~三目並べを作る9(終)~【自分用メモ?】
コメントする
コメントするには、ログインする必要があります。
CoRならではの書き方の色々、参考にさせてもらいます