require 'othello.rb' # 評価関数計算 module Evaluator def serialize(state) result = [] # 縦 for j in 0...(state.board_size) score = state[0, j].to_i state.down(0, j){|item, move| score += (item.to_i * (3 ** move)) } result << score end # 横 for i in 0...(state.board_size) score = state[i, 0].to_i state.right(i, 0){|item, move| score += (item.to_i * (3 ** move)) } result << score end # 右下 i = state.board_size - 2 j = 0 while i > 0 i -= 1 score = state[i, j].to_i state.right_down(i, j){|item, move| score += (item.to_i * (3 ** move)) } result << score end while j < (state.board_size - 2) j += 1 score = state[i, j].to_i state.right_down(i, j){|item, move| score += (item.to_i * (3 ** move)) } result << score end # 右上 i = 1 j = 0 while i < (state.board_size - 1) i += 1 score = state[i, j].to_i state.right_up(i, j){|item, move| score += (item.to_i * (3 ** move)) } result << score end while j < (state.board_size - 3) j += 1 score = state[i, j].to_i state.right_up(i, j){|item, move| score += (item.to_i * (3 ** move)) } result << score end return result end module_function :serialize class Bayes BACKUP_FILE = 'bayes.dat' @auto_save attr_accessor :auto_save def load(file) open(file, 'r'){|io| temp = Marshal::load(io.read) @black_win = temp[0] @white_win = temp[1] @trained = temp[2] @auto_save = temp[3] } puts "Bayes loaded with #{@trained} datas." end def save(file = @backup_file) puts "Bayes trained with #{@trained} datas." open(file, 'w'){|io| io << Marshal::dump([@black_win, @white_win, @trained, @auto_save])} end def initialize(file = BACKUP_FILE, auto_save = 100) begin load(file) rescue @black_win = [] @white_win = [] @trained = 0 @auto_save = auto_save end @backup_file = file end def train_black_win(state, enforce = 1) Evaluator::serialize(state).each_with_index{|item, i| @black_win[i] ||= {} @black_win[i][item] ||= 0 @black_win[i][item] += enforce } @trained += 1 if @auto_save > 0 and (@trained % @auto_save == 0) then save end end alias train_white_loose train_black_win def train_white_win(state, enforce = 1) Evaluator::serialize(state).each_with_index{|item, i| @white_win[i] ||= {} @white_win[i][item] ||= 0 @white_win[i][item] += enforce } @trained += 1 if @auto_save > 0 and (@trained % @auto_save == 0) then save end end alias train_black_loose train_white_win def evaluate(state, target = state.order) serialized = Evaluator::serialize(state) score = [0.0, 0.0] @black_win.each_with_index{|item, i| temp = item[serialized[i]] total = item.values.inject(0){|sum, elm| sum + elm.abs} score[0] += Math::log((temp || 0.1) / total.to_f) } @white_win.each_with_index{|item, i| temp = item[serialized[i]] total = item.values.inject(0){|sum, elm| sum + elm.abs} score[1] += Math::log((temp || 0.1) / total.to_f) } return (target == Othello::Stone::black) ? score[0] - score[1] : score[1] - score[0] end end end if $0 == __FILE__ then othello = Othello::new(6, 1) p othello for i in (0...100) p Evaluator::serialize(othello.state) end =begin bayes = Evaluator::Bayes::new bayes.train_black_win(othello.state) bayes.train_black_win(othello.state) bayes.train_white_win(othello.state) p bayes p bayes.evaluate(othello.state) #bayes.save =end end