Initial commit
[trapthecap.git] / src / selection.rb
1 # == Synopsis
2 #
3 # Use a GA to breed a good potential player
4 #
5 # == Author
6 # Neil Smith
7 #
8 # == Change history
9 # Version 1.1:: 23 April 2008
10
11
12 require 'libttc'
13 require 'libpplayer'
14 require 'libgenetics'
15 require 'play'
16
17 class Population
18 # Use tournament selection to pick an individual for the next generation
19 def tournament_select_one(winner_success_chance = 0.8, max_game_length= 1000, verbose = false)
20 player_count = rand(5) + 2
21 pool_size = @individuals.length
22 players = []
23 1.upto(player_count) { players << @individuals[rand(pool_size)].to_potential_player }
24 game = GameHandler.new(players, max_game_length, false, false)
25 winner, length = game.play
26 puts "Winner = #{winner} in #{length} moves. Game had #{player_count} players" if verbose
27 # If the game was a draw, or the winner is unlucky, pick a parent at random
28 if winner == :draw or rand > winner_success_chance
29 successful_player = players[rand(player_count)]
30 else
31 successful_player = winner
32 end
33 successful_player
34 end
35
36 # Select a new population the same size as the current population
37 def tournament_select_population(winner_success_chance = 0.8, max_game_length = 1000, verbose = false)
38 new_population = []
39 1.upto(@individuals.length) do
40 new_population << tournament_select_one(winner_success_chance, max_game_length, verbose).to_genome
41 puts "Created #{new_population.length} indivduals" if verbose
42 end
43 new_population
44 end
45
46 end
47
48 class Potential_player
49 # Convert a player to a bitstring
50 def to_bitstring
51 (@friend_pull * 4).to_i.to_bitstring(4).gray_encode +
52 (@enemy_pull * 4).to_i.to_bitstring(4).gray_encode +
53 (@base_pull * 4).to_i.to_bitstring(4).gray_encode +
54 @safe_bonus.to_bitstring(4).gray_encode +
55 @capture_bonus.to_bitstring(4).gray_encode
56 end
57
58 # Convert a player to a genome
59 def to_genome
60 Genome.new(self.to_bitstring)
61 end
62 end
63
64
65 class Genome
66
67 # Create a potential player from a genome
68 def to_potential_player
69 friend_pull = @genome[0, 4].gray_decode.to_decimal.to_f / 4
70 enemy_pull = @genome[4, 4].gray_decode.to_decimal.to_f / 4
71 base_pull = @genome[8, 4].gray_decode.to_decimal.to_f / 4
72 safe_bonus = @genome[12, 4].gray_decode.to_decimal
73 capture_bonus = @genome[16, 4].gray_decode.to_decimal
74 Potential_player.new({:friend_pull => friend_pull,
75 :enemy_pull => enemy_pull, :base_pull => base_pull,
76 :safe_bonus => safe_bonus, :capture_bonus => capture_bonus})
77 end
78 end