# == Synopsis # # Use a GA to breed a good potential player # # == Author # Neil Smith # # == Change history # Version 1.1:: 23 April 2008 require 'libttc' require 'libpplayer' require 'libgenetics' require 'play' class Population # Use tournament selection to pick an individual for the next generation def tournament_select_one(winner_success_chance = 0.8, max_game_length= 1000, verbose = false) player_count = rand(5) + 2 pool_size = @individuals.length players = [] 1.upto(player_count) { players << @individuals[rand(pool_size)].to_potential_player } game = GameHandler.new(players, max_game_length, false, false) winner, length = game.play puts "Winner = #{winner} in #{length} moves. Game had #{player_count} players" if verbose # If the game was a draw, or the winner is unlucky, pick a parent at random if winner == :draw or rand > winner_success_chance successful_player = players[rand(player_count)] else successful_player = winner end successful_player end # Select a new population the same size as the current population def tournament_select_population(winner_success_chance = 0.8, max_game_length = 1000, verbose = false) new_population = [] 1.upto(@individuals.length) do new_population << tournament_select_one(winner_success_chance, max_game_length, verbose).to_genome puts "Created #{new_population.length} indivduals" if verbose end new_population end end class Potential_player # Convert a player to a bitstring def to_bitstring (@friend_pull * 4).to_i.to_bitstring(4).gray_encode + (@enemy_pull * 4).to_i.to_bitstring(4).gray_encode + (@base_pull * 4).to_i.to_bitstring(4).gray_encode + @safe_bonus.to_bitstring(4).gray_encode + @capture_bonus.to_bitstring(4).gray_encode end # Convert a player to a genome def to_genome Genome.new(self.to_bitstring) end end class Genome # Create a potential player from a genome def to_potential_player friend_pull = @genome[0, 4].gray_decode.to_decimal.to_f / 4 enemy_pull = @genome[4, 4].gray_decode.to_decimal.to_f / 4 base_pull = @genome[8, 4].gray_decode.to_decimal.to_f / 4 safe_bonus = @genome[12, 4].gray_decode.to_decimal capture_bonus = @genome[16, 4].gray_decode.to_decimal Potential_player.new({:friend_pull => friend_pull, :enemy_pull => enemy_pull, :base_pull => base_pull, :safe_bonus => safe_bonus, :capture_bonus => capture_bonus}) end end