deepbeige 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/neural_net.rb ADDED
@@ -0,0 +1,174 @@
1
+ require 'rubygems'
2
+ require 'uuid'
3
+ require 'node'
4
+
5
+ class NeuralNet
6
+ attr_accessor :input, :id
7
+ attr_reader :network
8
+
9
+ def initialize
10
+ @id = UUID.new.to_s.split(':')[1].chop
11
+ @network = []
12
+ end
13
+
14
+ def evaluate
15
+ #we expect to find one input value in input for each of our input nodes
16
+ input_nodes = @network.first
17
+
18
+ i = 0
19
+ input_nodes.each do |node|
20
+ node.input_value = @input[i]
21
+ i += 1
22
+ end
23
+
24
+ @network.each do |tier|
25
+ tier.each do |node|
26
+ node.evaluate
27
+ end
28
+ end
29
+
30
+ self.output
31
+ end
32
+
33
+ def output
34
+ @network.last
35
+ end
36
+
37
+ def output_value
38
+ value = 0
39
+ self.output.each do |node|
40
+ value += node.output_value
41
+ end
42
+ value
43
+ end
44
+
45
+ def generate inputs, outputs, tiers
46
+ @network = []
47
+ input_nodes = []
48
+ inputs.times do
49
+ input_nodes << Node.new
50
+ end
51
+ if input_nodes.count > 0
52
+ @network << input_nodes
53
+ end
54
+ (tiers - 2).times do
55
+ tier = []
56
+ 10.times do
57
+ tier << Node.new
58
+ end
59
+ @network << tier
60
+ end
61
+
62
+ output_nodes = []
63
+ outputs.times do
64
+ output_nodes << Node.new
65
+ end
66
+ if output_nodes.count >0
67
+ @network << output_nodes
68
+ end
69
+ link_tiers
70
+ end
71
+
72
+ def fingerprint
73
+ topline = ""
74
+ fingerprint = ""
75
+ @network.each do |tier|
76
+ topline << "#{tier.count},"
77
+ tier.each do |node|
78
+ fingerprint << node.fingerprint
79
+ end
80
+ end
81
+ topline.chop + "\n" + fingerprint
82
+ end
83
+
84
+ def reload fingerprint
85
+ #fingerprint contains an array of strings
86
+ i = 0
87
+ tiers = fingerprint[i].split(',').to_a
88
+ i += 1
89
+
90
+ @network = []
91
+ tiers.each do |tier|
92
+ nodes = []
93
+ tier.to_i.times do
94
+ node_fingerprint = fingerprint[i]
95
+ i += 1
96
+ node = Node.new
97
+ node.reload node_fingerprint
98
+ nodes << node
99
+ end
100
+ @network << nodes
101
+ end
102
+
103
+ link_tiers
104
+ true
105
+ end
106
+
107
+ #Nets can make small changes (mutations) to themselves
108
+ def mutate
109
+ #for the time being we won't take on
110
+ #the ability to mutate the number of
111
+ #nodes and their configuration
112
+ #focussing instead on simple node weight mutation
113
+ @network.each do |tier|
114
+ tier.each do |node|
115
+ node.mutate
116
+ end
117
+ end
118
+ self
119
+ end
120
+
121
+ def clone
122
+ clone = NeuralNet.new
123
+ #iterate in through each tier
124
+ @network.each do |tier|
125
+ nodes = []
126
+ tier.each do |node|
127
+ cloned_node = node.clone
128
+ cloned_node.detatch_all_forward_nodes
129
+ nodes << cloned_node
130
+ end
131
+ clone.network << nodes
132
+ end
133
+ #now relink the network
134
+ clone.link_tiers
135
+ #and send back our clone
136
+ clone
137
+ end
138
+
139
+ def save_to_file file
140
+ File.open(file, 'w') do |f|
141
+ f.puts id
142
+ f.write(self.fingerprint)
143
+ end
144
+ end
145
+
146
+ def load_from_file file
147
+ fingerprint = []
148
+ File.open(file, 'r') do |f|
149
+ @id = f.gets.chop
150
+ while line = f.gets do
151
+ fingerprint << line
152
+ end
153
+ end
154
+ reload fingerprint
155
+ end
156
+
157
+ protected
158
+ def link_tiers
159
+ #first cut lets link every node on a tier to each node on the subsequent tier
160
+ i = 1
161
+ @network.each do |tier|
162
+ if i < @network.count
163
+ tier.each do |node|
164
+ j = 0
165
+ @network[i].each do |next_node|
166
+ node.attach_forward_node next_node, j
167
+ j += 1
168
+ end
169
+ end
170
+ end
171
+ i +=1
172
+ end
173
+ end
174
+ end
data/node.rb ADDED
@@ -0,0 +1,106 @@
1
+ class Node
2
+ attr_reader :forward_nodes, :output_value
3
+ attr_accessor :input_value, :deviation, :weights
4
+ def initialize
5
+ @forward_nodes = {}
6
+ @weights =[]
7
+ @input_value = 0
8
+ @deviation = rand / 4
9
+ end
10
+ #take our input value, pass it through our sigmoid function (tanh)
11
+ #and then pass on our output value to each of our forward nodes
12
+ def evaluate
13
+ @output_value = Math.tanh(@input_value)
14
+ #p "output value #{@output_value}"
15
+ @forward_nodes.each do |node, weight|
16
+ #p "weight #{weight} old input #{node.input_value}"
17
+ node.input_value += @output_value * weight
18
+ #p "new input #{node.input_value}"
19
+ end
20
+ @input_value = 0
21
+ end
22
+
23
+ def attach_forward_node node, sequence
24
+ if @weights.count <= sequence
25
+ @weights << rand
26
+ end
27
+
28
+ @forward_nodes[node] = @weights[sequence]
29
+ end
30
+
31
+ def detatch_all_forward_nodes
32
+ @forward_nodes = {}
33
+ end
34
+
35
+ def mutate
36
+ new_weights = []
37
+ @weights.each do |weight|
38
+ new_weights << gaussian_random * @deviation + weight # new_random_number = gaussian_rand * standard_deviation + average
39
+ end
40
+ @weights = new_weights
41
+ if @forward_values
42
+ i = 0
43
+ @forward_values.each do |key,value|
44
+ @forward_values[key] = @weights[i]
45
+ i += 1
46
+ end
47
+ end
48
+
49
+ #and now mutate the deviation
50
+ @deviation = (gaussian_random * @deviation)/2 + @deviation
51
+ end
52
+
53
+ def breed
54
+ end
55
+
56
+ def clone
57
+ clone = Node.new
58
+
59
+ clone.deviation = self.deviation
60
+ @weights.each do |weight|
61
+ clone.weights << weight
62
+ end
63
+
64
+ #being pure we clone the forward node refs as well
65
+ #although in practice these are about to be updated with new nodes
66
+ self.forward_nodes.each do |key,value|
67
+ clone.forward_nodes[key] = value
68
+ end
69
+
70
+ clone
71
+ end
72
+
73
+ def fingerprint
74
+ fingerprint = "#{@deviation}:"
75
+ @weights.each do |weight|
76
+ fingerprint += "#{weight.to_s},"
77
+ end
78
+ fingerprint = fingerprint.chop + "\n"
79
+ end
80
+
81
+ def reload fingerprint
82
+ self.detatch_all_forward_nodes
83
+ @weights = []
84
+ self.deviation = fingerprint.split(':')[0].to_f
85
+ if fingerprint.split(":").count == 2
86
+ fingerprint.split(":")[1].split(',').each do |weight|
87
+ @weights << weight.to_f
88
+ end
89
+ end
90
+ end
91
+
92
+ private
93
+ def gaussian_random
94
+ u1 = u2 = w = g1 = g2 = 0 # declare
95
+ begin
96
+ u1 = 2 * rand - 1
97
+ u2 = 2 * rand - 1
98
+ w = u1 * u1 + u2 * u2
99
+ end while w >= 1
100
+
101
+ w = Math::sqrt( ( -2 * Math::log(w)) / w )
102
+ g2 = u1 * w;
103
+ g1 = u2 * w;
104
+ # g1 is returned
105
+ end
106
+ end
@@ -0,0 +1,141 @@
1
+ require 'game'
2
+ class NoughtsAndCrosses < Game
3
+
4
+ attr_reader :winner, :move_list, :next_player
5
+ attr_accessor :quiet, :verbose
6
+ def initialize
7
+ @position = {:A1 => 0, :B1 => 0, :C1 => 0, :A2 => 0, :B2 => 0, :C2 => 0, :A3 => 0, :B3 => 0, :C3 => 0}
8
+ @next_player = 0
9
+ @move_list = []
10
+ end
11
+
12
+ def name
13
+ "NoughtsAndCrosses"
14
+ end
15
+
16
+ def show_board
17
+ board = " - - - \n"
18
+ i = 0
19
+ @position.each do |move|
20
+ i += 1
21
+ board += "|"
22
+ if move[1] == 0
23
+ board += " "
24
+ elsif move[1] == 1
25
+ board += "X"
26
+ else
27
+ board += "O"
28
+ end
29
+
30
+ if i == 3
31
+ board += "|\n _ _ _\n"
32
+ i = 0
33
+ end
34
+
35
+ end
36
+ board
37
+ end
38
+
39
+ def legal_moves
40
+ legal_moves = []
41
+ @position.each do |move|
42
+ if move[1] == 0
43
+ legal_moves << move[0].to_s
44
+ end
45
+ end
46
+ legal_moves
47
+ end
48
+
49
+ def play_move(player, move)
50
+ sym_move = move.to_sym
51
+ unless player == @next_player
52
+ display "not player #{player}'s turn"
53
+ return false
54
+ end
55
+ unless @position[sym_move] == 0
56
+ display "illegal move by player #{player}"
57
+ return false
58
+ end
59
+ if won?
60
+ display "player #{winner} has already won"
61
+ return false
62
+ elsif drawn?
63
+ display "game was drawn"
64
+ return false
65
+ end
66
+
67
+ @move_list << [player,move]
68
+
69
+ if player == 1
70
+ @position[sym_move] = 1
71
+ else
72
+ @position[sym_move] = -1
73
+ end
74
+ if won?
75
+ display "player #{player} wins!"
76
+ @winner = player
77
+ elsif drawn?
78
+ display "game drawn"
79
+ end
80
+
81
+ if @next_player == 1
82
+ @next_player = 0
83
+ else
84
+ @next_player = 1
85
+ end
86
+ if @verbose
87
+ display show_board
88
+ display @position
89
+ end
90
+ true
91
+ end
92
+
93
+ def current_position
94
+ return @position
95
+ end
96
+
97
+ def won?
98
+ if @position[:A1] != 0
99
+ if @position[:A1] == @position[:A2] && @position[:A2] == @position[:A3]
100
+ return true
101
+ elsif @position[:A1] == @position[:B2] && @position[:B2] == @position[:C3]
102
+ return true
103
+ elsif @position[:A1] == @position[:B1] && @position[:B1] == @position[:C1]
104
+ return true
105
+ end
106
+ end
107
+ if @position[:B1] != 0
108
+ if @position[:B1] == @position[:B2] && @position[:B2] == @position[:B3]
109
+ return true
110
+ end
111
+ end
112
+ if @position[:C1] != 0
113
+ if @position[:C1] == @position[:C2] && @position[:C2] == @position[:C3]
114
+ return true
115
+ elsif @position[:C1] == @position[:B2] && @position[:B2] == @position[:A3]
116
+ return true
117
+ end
118
+ end
119
+ if @position[:A2] != 0
120
+ if @position[:A2] == @position[:B2] && @position[:B2] == @position[:C2]
121
+ return true
122
+ end
123
+ end
124
+ if @position[:A3] != 0
125
+ if @position[:A3] == @position[:B3] && @position[:B3] == @position[:C3]
126
+ return true
127
+ end
128
+ end
129
+ false
130
+ end
131
+
132
+ def drawn?
133
+ unless legal_moves.count == 0
134
+ return false
135
+ end
136
+ if won?
137
+ return false
138
+ end
139
+ true
140
+ end
141
+ end
data/pick_a_number.rb ADDED
@@ -0,0 +1,97 @@
1
+ require 'game'
2
+
3
+ class PickANumber < Game
4
+
5
+ attr_reader :winner, :move_list, :next_player
6
+ attr_accessor :quiet, :verbose
7
+ def initialize
8
+ @position = {"1" => 0,"2" => 0, "3" => 0}
9
+ @next_player = 0
10
+ @move_list = []
11
+ end
12
+
13
+ def name
14
+ "PickANumber"
15
+ end
16
+
17
+ def legal_moves
18
+ legal_moves = []
19
+ @position.each do |move|
20
+ if move[1] == 0
21
+ legal_moves << move[0].to_s
22
+ end
23
+ end
24
+ legal_moves
25
+ end
26
+
27
+ def show_board
28
+ board = "Please Pick from the following Numbers:\n"
29
+
30
+ @position.each do |move|
31
+ if move[1] == 0
32
+ board += "#{move[0]},"
33
+ end
34
+ end
35
+ board +"\n"
36
+ end
37
+
38
+ def play_move(player, move)
39
+ unless player == @next_player
40
+ display "not player #{player}'s turn"
41
+ return false
42
+ end
43
+ unless @position[move] == 0
44
+ display "illegal move by player #{player}"
45
+ return false
46
+ end
47
+ if won?
48
+ display "player #{winner} has already won"
49
+ return false
50
+ elsif drawn?
51
+ display "game was drawn"
52
+ return false
53
+ end
54
+
55
+ @move_list << [player,move]
56
+
57
+ if player == 1
58
+ @position[move] = 1
59
+ else
60
+ @position[move] = -1
61
+ end
62
+ if won?
63
+ display "player #{player} wins!"
64
+ @winner = player
65
+ elsif drawn?
66
+ display "game drawn"
67
+ end
68
+
69
+ if @next_player == 1
70
+ @next_player = 0
71
+ else
72
+ @next_player = 1
73
+ end
74
+ if @verbose
75
+ display @position
76
+ end
77
+ true
78
+ end
79
+
80
+ def current_position
81
+ return @position
82
+ end
83
+
84
+ def won?
85
+ if @position["3"] != 0
86
+ return true
87
+ end
88
+ false
89
+ end
90
+
91
+ def drawn?
92
+ if @position["2"] != 0
93
+ return true
94
+ end
95
+ false
96
+ end
97
+ end
data/player.rb ADDED
@@ -0,0 +1,4 @@
1
+ class Player
2
+ def initialize
3
+ end
4
+ end
@@ -0,0 +1,20 @@
1
+ 9,9,1
2
+ 1.9888959877114751:1.1713694063264486,0.2131550943633837,-1.4389857774549193,-2.3761064404471623,1.4125388307828852,1.7962657856192086,3.98673652586089,-0.710563267563527,-4.693733927431782
3
+ -0.5537104997469708:4.353881179541187,-3.7749306975412615,3.9092173844936307,-1.5574066495330294,-1.9867317023123854,2.4016056161982515,0.19093366894771083,2.583574894805702,-0.7814428807197851
4
+ -3.718402720378594:0.21375589104869108,-0.5952570280952669,3.163222183572866,-2.0666315462205604,1.8466894347641758,2.5737190736563127,0.09083797921525782,-1.7152005515495705,-1.9147906116034963
5
+ -1.1774113223565559:0.9684176432281265,1.2633322113651906,0.9105205858738161,0.9952880033669778,2.428832023642873,1.1378171183057832,1.2346794709653666,1.614577823722882,-0.5727461748243102
6
+ -4.240095691598348:5.619686966308787,2.496099436318761,4.236594219999468,-4.089909848411157,-8.583782402447191,7.909784634413837,3.709149525845639,-0.1221209138110586,-1.7739191236891263
7
+ -0.45644848049775455:0.7525477703501269,0.4416094908434702,0.5151634042799693,0.6494784464984971,-0.21066540646710413,0.9328293326003011,0.4934365894119864,-0.5075989699963754,0.2534248521563641
8
+ 2.000438515839109:-0.18715599814429473,-4.079321241532847,3.0082374216290035,1.6554995963981736,1.2134208468740142,-0.7234607792621472,0.9168360804604427,-0.5284806911574953,3.6316017295618748
9
+ 0.9920544697574241:-0.15133215482382756,0.9977877837645512,-0.06456539820799904,-1.0288035250624143,0.9008138652841244,0.6826185088601288,0.8553527568600676,0.21975379677495055,1.0495630337690707
10
+ 3.8437737235828924:-2.429075885974877,3.0482320934712477,-9.512832982617503,-8.273686259303359,1.5413233764892178,-2.2156195050047747,-7.2849426757667315,5.202236097167509,-0.9365606034293558
11
+ 2.4821899389695874:2.1743832447567346
12
+ -2.9564446473766672:-3.2541845089551904
13
+ 3.2605627963240384:-0.20795953070592393
14
+ 2.605813320828736:3.154050922464929
15
+ -0.4579599997104075:2.349414728456047
16
+ 2.653465191369256:4.365018317781122
17
+ 0.6373485836872791:1.7163198231060346
18
+ 0.711515408592374:0.8702577537323323
19
+ -1.7351499679943323:1.24799151515672
20
+ 2.902919261517124
data/table.rb ADDED
@@ -0,0 +1,22 @@
1
+ #A Table is where players come to play a game (possibly as part of a match as part of a tournament if required)
2
+ #Essentially a Table is a Game Controller
3
+ class Table
4
+ attr_reader :players, :games
5
+ attr_accessor :quiet
6
+
7
+ def initialize game, players
8
+ @game = game
9
+ @players = players
10
+ end
11
+
12
+ def play_game
13
+ until @game.won? || @game.drawn?
14
+ next_player = @players[@game.next_player]
15
+ move = next_player.get_move @game.current_position, @game.move_list
16
+ unless @quiet
17
+ p "player #{@game.next_player} plays move #{move }"
18
+ end
19
+ @game.play_move @game.next_player, move
20
+ end
21
+ end
22
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'deepbeige'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestDeepbeige < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
data/tournament.rb ADDED
@@ -0,0 +1 @@
1
+ #A tournament is a series of matches between a set of players
data/ui/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'hotcocoa/application_builder'
3
+ require 'hotcocoa/standard_rake_tasks'
4
+
5
+ task :default => [:run]
@@ -0,0 +1,8 @@
1
+ name: DeepBeige
2
+ load: lib/application.rb
3
+ version: "1.0"
4
+ icon: resources/DeepBeige.icns
5
+ resources:
6
+ - resources/**/*.*
7
+ sources:
8
+ - lib/**/*.rb
@@ -0,0 +1,47 @@
1
+ $Cocoa = true
2
+ require 'rubygems'
3
+ require 'hotcocoa'
4
+ $: << File.expand_path(File.dirname(__FILE__)) + "/../../"
5
+ require 'main.rb'
6
+
7
+
8
+ class Application
9
+
10
+ include HotCocoa
11
+
12
+ def start
13
+ application :name => "Deep Beige" do |app|
14
+ app.delegate = self
15
+ window :frame => [100, 100, 500, 500], :title => "Test" do |win|
16
+ win << label(:text => "Hello from Deep Beige", :layout => {:start => false})
17
+ win.will_close { exit }
18
+ end
19
+ end
20
+ end
21
+
22
+ # file/open
23
+ def on_open(menu)
24
+ end
25
+
26
+ # file/new
27
+ def on_new(menu)
28
+ end
29
+
30
+ # help menu item
31
+ def on_help(menu)
32
+ end
33
+
34
+ # This is commented out, so the minimize menu item is disabled
35
+ #def on_minimize(menu)
36
+ #end
37
+
38
+ # window/zoom
39
+ def on_zoom(menu)
40
+ end
41
+
42
+ # window/bring_all_to_front
43
+ def on_bring_all_to_front(menu)
44
+ end
45
+ end
46
+
47
+ Application.new.start
data/ui/lib/menu.rb ADDED
@@ -0,0 +1,32 @@
1
+ module HotCocoa
2
+ def application_menu
3
+ menu do |main|
4
+ main.submenu :apple do |apple|
5
+ apple.item :about, :title => "About #{NSApp.name}"
6
+ apple.separator
7
+ apple.item :preferences, :key => ","
8
+ apple.separator
9
+ apple.submenu :services
10
+ apple.separator
11
+ apple.item :hide, :title => "Hide #{NSApp.name}", :key => "h"
12
+ apple.item :hide_others, :title => "Hide Others", :key => "h", :modifiers => [:command, :alt]
13
+ apple.item :show_all, :title => "Show All"
14
+ apple.separator
15
+ apple.item :quit, :title => "Quit #{NSApp.name}", :key => "q"
16
+ end
17
+ main.submenu :file do |file|
18
+ file.item :new, :key => "n"
19
+ file.item :open, :key => "o"
20
+ end
21
+ main.submenu :window do |win|
22
+ win.item :minimize, :key => "m"
23
+ win.item :zoom
24
+ win.separator
25
+ win.item :bring_all_to_front, :title => "Bring All to Front", :key => "o"
26
+ end
27
+ main.submenu :help do |help|
28
+ help.item :help, :title => "#{NSApp.name} Help"
29
+ end
30
+ end
31
+ end
32
+ end
Binary file