【講座?】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ならではの書き方の色々、参考にさせてもらいます