deepbeige 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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