Open ignisan opened 8 years ago
#include "4moku.hpp"
std::tuple<int,int> AI_FUNCTION(const Board& board,int player) {
// ・自分が勝つことが確定するような置き場所があるならそこに置く。
// ・自分が置くことで、次に相手が勝つことが確定する置き場所があるならそこは置かない。
// ・そうでなければ、置ける場所に置く。
int nx,ny;
std::tie(nx,ny) = board.size();
std::tuple<int,int> random_choice, tmp_choice;
std::mt19937 mt(std::time(0));
std::uniform_real_distribution<> rnd(0, 1);
int candidates = 0;
for(int i = 0; i < nx; ++i){
for(int j = 0; j < ny; ++j){
if(placeable(board, i, j)){
Board board_tmp(board);
board_tmp(i, j) = player_id(player);
tmp_choice = std::make_tuple(i, j);
// 自分の勝ちが確定できるならそこに置く
if(finished(board_tmp)) return tmp_choice;
// 相手の勝ちが確定できるならそこに置かない
for(int p = 0; p < nx; ++p){
for(int q = 0; q < ny; ++q){
if(placeable(board_tmp, p, q)){
Board board_tmp2(board_tmp);
board_tmp2(p, q) = player_id((player+1) % 2);
if(finished(board_tmp2)){
tmp_choice = std::make_tuple(-1, -1);
std::cerr << "Placing at (" << i << ", " << j << ") lets the opponent win!" << std::endl;
break;
}
}
}
}
// もしどちらの勝ちも確定しないなら、ランダム選択
if(std::get<0>(tmp_choice) != -1){
++candidates;
if(rnd(mt) < 1.0/candidates) random_choice = tmp_choice;
}
}
}
}
return random_choice;
}