Permalink
Browse files

adding SGF download to games - closes #12

  • Loading branch information...
1 parent 9e6d875 commit f693b13642d1146d934a32e02c00f9b034a811d7 @ryanb committed Oct 26, 2010
View
4 app/controllers/games_controller.rb
@@ -58,7 +58,11 @@ def my
end
def resources
+ end
+ def sgf
+ @game = Game.find(params[:id])
+ render :text => @game.sgf, :content_type => 'application/x-go-sgf'
end
private
View
44 app/models/game.rb
@@ -77,13 +77,11 @@ def prepare
self.black_player = opponent
self.white_player = creator
end
- GameEngine.run(attributes.symbolize_keys) do |engine|
- if handicap.to_i.nonzero?
- self.black_positions = engine.positions(:black)
- self.current_player = white_player
- else
- self.current_player = black_player
- end
+ if handicap.to_i > 0
+ self.black_positions = handicap_positions
+ self.current_player = white_player
+ else
+ self.current_player = black_player
end
self.update_thumbnail = true
end
@@ -154,4 +152,36 @@ def profiles
def profiles_with_current_first
profiles.sort_by { |p| p.current ? 0 : 1 }
end
+
+ def sgf
+ sgf = ";FF[4]GM[1]CA[utf-8]AP[govsgo:0.1]RU[Japanese]"
+ sgf << "SZ[#{board_size}]KM[#{komi}]HA[#{handicap.to_i}]"
+ colors = %w[B W].cycle
+ if handicap.to_i > 0
+ colors.next
+ sgf << "AB" + handicap_positions.gsub(/../, "[\\0]")
+ end
+ {"B" => black_player, "W" => white_player}.each do |color, player|
+ name = player ? (player.username.blank? ? "Guest" : player.username) : "GNU Go"
+ sgf << "P#{color}[#{name}]#{color}R[#{player.try(:rank)}]"
+ end
+ if finished?
+ score = last_move == "RESIGN" ? "R" : [white_score.to_f, black_score.to_f].max
+ sgf << "RE[#{black_score.to_i == 0 ? 'W' : 'B'}+#{score}]"
+ end
+ moves.to_s.split("-").each do |move|
+ unless move == "RESIGN"
+ sgf << ";#{colors.next}[#{move == 'PASS' ? '' : move[0..1]}]"
+ end
+ end
+ "(#{sgf})"
+ end
+
+ def handicap_positions
+ positions = ""
+ GameEngine.run(attributes.symbolize_keys) do |engine|
+ positions << engine.positions(:black)
+ end
+ positions
+ end
end
View
1 app/views/games/show.html.erb
@@ -27,6 +27,7 @@
<% end %>
<%= link_to image_tag("game/sound_on.png", :size => "18x16"), '#', :id => "sound_switch" %>
<div id="move_nav">
+ <%= link_to "SGF", game_sgf_path(@game), :id => "sgf" %>
<%= link_to "<<", '#', :id => "first_move" %>
<%= link_to "<", '#', :id => "previous_move" %>
<%= link_to ">", '#', :id => "next_move" %>
View
1 config/routes.rb
@@ -6,6 +6,7 @@
match 'logout' => 'sessions#destroy', :as => :logout
match 'login' => 'sessions#new', :as => :login
match 'go_resources' => 'games#resources', :as => :go_resources
+ match '/games/:id.sgf' => 'games#sgf', :format => "sgf", :as => "game_sgf"
resources :authentications
resources :sessions
resources :users
View
5 public/stylesheets/game.css
@@ -145,9 +145,10 @@ body {
#move_nav {
position: absolute;
- left: 402px;
+ left: 345px;
top: 828px;
- width: 175px;
+ width: 230px;
+ z-index: 30;
}
#move_nav a, #player_actions a {
View
7 spec/controllers/games_controller_spec.rb
@@ -31,4 +31,11 @@
post :create
response.should redirect_to(game_url(assigns[:game]))
end
+
+ it "sgf action should return SGF data" do
+ Game.any_instance.stubs(:sgf).returns("sgf data")
+ get :sgf, :id => Game.first
+ response.content_type.should == "application/x-go-sgf"
+ response.body.should == "sgf data"
+ end
end
View
21 spec/models/game_spec.rb
@@ -89,4 +89,25 @@
game = Factory(:game, :white_player => Factory(:user), :moves => "RESIGN")
game.profile_for(:white).last_status.should == "resigned"
end
+
+ it "should return SGF format for normal play" do
+ game = Factory(:game, :moves => "aa-bbcc-PASS-dd", :handicap => 0, :board_size => 9, :komi => 6.5, :finished_at => Time.now, :white_score => 30.5, :black_score => 0)
+ game.black_player.username = "foo"
+ game.black_player.rank = "4k"
+ game.white_player.username = ""
+ game.white_player.rank = ""
+ sgf = game.sgf
+ sgf.should include("(;FF[4]GM[1]CA[utf-8]AP[govsgo:0.1]RU[Japanese]SZ[9]KM[6.5]HA[0]")
+ sgf.should include("PB[foo]BR[4k]PW[Guest]WR[]")
+ sgf.should include("RE[W+30.5]")
+ sgf.should include(";B[aa];W[bb];B[];W[dd])")
+ end
+
+ it "should return SGF format for handicap game" do
+ game = Factory(:game, :moves => "aa-RESIGN", :handicap => 2, :board_size => 19, :white_player => nil, :black_score => 0, :white_score => 1, :finished_at => Time.now)
+ sgf = game.sgf
+ sgf.should include("RE[W+R]")
+ sgf.should include("HA[2]AB[pd][dp]")
+ sgf.should include(";W[aa])")
+ end
end

0 comments on commit f693b13

Please sign in to comment.