From d4ef778cc8bb2aab4ecd7a992926d3c11ef69cd4 Mon Sep 17 00:00:00 2001
From: Paolo Capriotti
Date: Fri, 19 Jun 2009 11:55:18 +0200
Subject: [PATCH] Add path specification for movement animations.
Paths are functions that compute the increment in position at time i. A linear
path and an L-shaped path have been added. The L-shaped path has been mapped
to the chess knight movement.
---
lib/animations.rb | 36 ++++++++++++++++++++++++++++++++----
lib/animator_helper.rb | 4 ++--
lib/{games => }/factory.rb | 0
lib/games/chess/animator.rb | 13 +++++++++++--
lib/games/chess/chess.rb | 1 -
lib/games/games.rb | 2 ++
test/test_animations.rb | 2 +-
test/test_animator_helper.rb | 2 +-
8 files changed, 49 insertions(+), 11 deletions(-)
rename lib/{games => }/factory.rb (100%)
diff --git a/lib/animations.rb b/lib/animations.rb
index 7f66308..8321b91 100644
--- a/lib/animations.rb
+++ b/lib/animations.rb
@@ -1,4 +1,5 @@
require 'animation_field'
+require 'factory'
module Animations
LENGTH = 100
@@ -24,18 +25,18 @@ module Animations
end
end
- def movement(item, src, dst)
+ def movement(item, src, dst, path_factory)
if item
src = board.to_real(src)
dst = board.to_real(dst)
- delta = dst - src
+ path = path_factory.new(src, dst)
SimpleAnimation.new "move to #{dst}", LENGTH, nil,
- lambda {|i| item.pos = src + delta * i },
+ lambda {|i| item.pos = src + path[i] },
lambda { item.pos = dst }
end
end
-
+
def disappear(item, name = "disappear")
if item
SimpleAnimation.new name, LENGTH,
@@ -60,3 +61,30 @@ module Animations
Animation.new(name) { board.remove_item p }
end
end
+
+module Path
+ Linear = Factory.new do |src, dst|
+ delta = dst - src
+ lambda {|i| delta * i }
+ end
+
+ class LShape
+ FACTOR = Math.exp(3.0) - 1
+ def initialize(src, dst)
+ @delta = dst - src
+ nonlin = lambda{|i| (Math.exp(3.0 * i) - 1) / FACTOR }
+ lin = lambda {|i| i }
+ if @delta.x.abs < @delta.y.abs
+ @x = lin
+ @y = nonlin
+ else
+ @y = lin
+ @x = nonlin
+ end
+ end
+
+ def [](i)
+ Qt::PointF.new(@delta.x * @x[i], @delta.y * @y[i])
+ end
+ end
+end
diff --git a/lib/animator_helper.rb b/lib/animator_helper.rb
index 390dad2..40ea8fd 100644
--- a/lib/animator_helper.rb
+++ b/lib/animator_helper.rb
@@ -3,9 +3,9 @@ require 'animations'
module AnimatorHelper
include Animations
- def move!(src, dst)
+ def move!(src, dst, path)
piece = board.move_item(src, dst)
- movement(piece, src, dst)
+ movement(piece, src, dst, path)
end
def disappear_on!(p, opts = {})
diff --git a/lib/games/factory.rb b/lib/factory.rb
similarity index 100%
rename from lib/games/factory.rb
rename to lib/factory.rb
diff --git a/lib/games/chess/animator.rb b/lib/games/chess/animator.rb
index bdbdff0..719dbb1 100644
--- a/lib/games/chess/animator.rb
+++ b/lib/games/chess/animator.rb
@@ -8,7 +8,16 @@ module Chess
def initialize(board)
@board = board
end
-
+
+ def specific_move!(piece, src, dst)
+ path = if piece.type == :knight
+ Path::LShape
+ else
+ Path::Linear
+ end
+ move!(src, dst, path)
+ end
+
def warp(state, opts = { :instant => true })
res = []
@@ -32,7 +41,7 @@ module Chess
def forward(state, move)
capture = disappear_on! move.dst
- actual_move = move! move.src, move.dst
+ actual_move = specific_move! state.board[move.dst], move.src, move.dst
extra = if move.type == :king_side_castling
move! move.dst + Point.new(1, 0), move.dst - Point.new(1, 0)
elsif move.type == :queen_side_castling
diff --git a/lib/games/chess/chess.rb b/lib/games/chess/chess.rb
index dbc626b..c180f0c 100644
--- a/lib/games/chess/chess.rb
+++ b/lib/games/chess/chess.rb
@@ -6,7 +6,6 @@ require 'games/chess/policy'
require 'games/chess/animator'
require 'games/chess/validator'
require 'games/chess/serializer'
-require 'games/factory'
module Chess
diff --git a/lib/games/games.rb b/lib/games/games.rb
index 9d65921..3a5c4ed 100644
--- a/lib/games/games.rb
+++ b/lib/games/games.rb
@@ -1,3 +1,5 @@
+require 'factory'
+
class Game
GAMES = { }
diff --git a/test/test_animations.rb b/test/test_animations.rb
index c1df617..4f166e9 100644
--- a/test/test_animations.rb
+++ b/test/test_animations.rb
@@ -72,7 +72,7 @@ class TestAnimations < Test::Unit::TestCase
def test_movement
item = GeneralMock.new
- @field.run @c.movement(item, Point.new(3, 4), Point.new(5, 6))
+ @field.run @c.movement(item, Point.new(3, 4), Point.new(5, 6), Path::Linear)
@field.run_test
old_p = nil
diff --git a/test/test_animator_helper.rb b/test/test_animator_helper.rb
index ee5694d..980f6b2 100644
--- a/test/test_animator_helper.rb
+++ b/test/test_animator_helper.rb
@@ -44,7 +44,7 @@ class TestAnimatorHelper < Test::Unit::TestCase
def test_move
@items[Point.new(3, 3)] = "white knight"
- anim = @animator.move!(Point.new(3, 3), Point.new(5, 4))
+ anim = @animator.move!(Point.new(3, 3), Point.new(5, 4), Path::Linear)
assert_animation(:movement, anim) do |args|
piece, src, dst = args
assert_equal "white knight", piece
--
2.11.4.GIT