From 5b9d2e0f5a91080294380397c0ffeede34859635 Mon Sep 17 00:00:00 2001 From: Paolo Capriotti Date: Wed, 24 Jun 2009 17:53:31 +0200 Subject: [PATCH] Movelist is now reenabled and working. --- lib/board/table.rb | 6 +- lib/controller.rb | 21 ++++- lib/games/shogi/main.rb | 1 + lib/games/shogi/state.rb | 4 + lib/history.rb | 67 +++++--------- lib/mainwindow.rb | 9 ++ lib/plugins/movelist/simple_movelist.rb | 157 ++++++++++++++++++++------------ 7 files changed, 162 insertions(+), 103 deletions(-) rewrite lib/plugins/movelist/simple_movelist.rb (86%) diff --git a/lib/board/table.rb b/lib/board/table.rb index 38d38fa..b18fece 100644 --- a/lib/board/table.rb +++ b/lib/board/table.rb @@ -1,4 +1,6 @@ class Table < Qt::GraphicsView + include Observable + attr_reader :elements Theme = Struct.new(:pieces, :board, :layout) @@ -8,7 +10,8 @@ class Table < Qt::GraphicsView @loader = loader end - def reset(game) + def reset(match) + game = match.game # destroy old elements if @elements @scene.remove_element(@elements[:board]) @@ -50,6 +53,7 @@ class Table < Qt::GraphicsView end relayout + fire :reset => match end def flip(value) diff --git a/lib/controller.rb b/lib/controller.rb index fde1713..729ca2c 100644 --- a/lib/controller.rb +++ b/lib/controller.rb @@ -10,6 +10,7 @@ class Controller attr_reader :history attr_reader :color attr_reader :controlled + attr_reader :table def initialize(table) @table = table @@ -44,7 +45,7 @@ class Controller def reset(match) @match = match - @table.reset(match.game) + @table.reset(@match) @board = @table.elements[:board] @pools = @table.elements[:pools] @clocks = @table.elements[:clocks] @@ -108,6 +109,24 @@ class Controller puts "error: last move" end + def go_to(index) + cur = @match.history.current + state, move = @match.history.go_to(index) + if index > cur + (cur + 1..index).each do |i| + animate(:forward, @match.history[i].state, @match.history[i].move) + end + @board.highlight(move) + elsif index < cur + (cur).downto(index + 1).each do |i| + animate(:back, @match.history[i - 1].state, @match.history[i].move) + end + @board.highlight(@match.history.move) + end + rescue History::OutOfBound + puts "error: no such index #{index}" + end + def animate(direction, state, move, opts = {}) anim = @animator.send(direction, state, move, opts) @field.run anim diff --git a/lib/games/shogi/main.rb b/lib/games/shogi/main.rb index e75914f..a473ae7 100644 --- a/lib/games/shogi/main.rb +++ b/lib/games/shogi/main.rb @@ -18,6 +18,7 @@ Game.add :shogi, [:chess] do |chess| :piece => chess.piece, :keywords => %w(shogi), :players => [:black, :white], + :serializer => chess.serializer, :types => [:pawn, :lance, :horse, :silver, :gold, :bishop, :rook, :king] end diff --git a/lib/games/shogi/state.rb b/lib/games/shogi/state.rb index 0bbcd96..18e8878 100644 --- a/lib/games/shogi/state.rb +++ b/lib/games/shogi/state.rb @@ -92,6 +92,10 @@ module Shogi (row(6, color) <=> p.y) != (color == :black ? -1 : 1) end + def capture_square(move) + move.dst + end + def promoted(piece) piece_factory.new( piece.color, diff --git a/lib/history.rb b/lib/history.rb index e28a9a8..b33e6f6 100644 --- a/lib/history.rb +++ b/lib/history.rb @@ -1,9 +1,8 @@ require 'observer_utils.rb' -class History < Qt::AbstractListModel +class History include Enumerable - include Observer - include ModelUtils + include Observable attr_reader :current @@ -11,7 +10,6 @@ class History < Qt::AbstractListModel OutOfBound = Class.new(Exception) def initialize(state) - super(nil) @history = [Item.new(state.dup, nil, "Mainline")] @current = 0 end @@ -22,21 +20,22 @@ class History < Qt::AbstractListModel def add_move(state, move) item = Item.new(state.dup, move, nil) + old_size = @history.size - removing_rows(nil, @current + 1, @history.size - 1) do - @history = @history[0..@current] - end + @history = @history[0..@current] - inserting_rows(nil, @current + 1, @current + 1) do - @history << item - @current = @history.size - 1 - end + @history << item + @current = @history.size - 1 + + fire :new_move end def forward raise OutOfBound if @current >= @history.size - 1 @current += 1 item = @history[@current] + + fire :current_changed [item.state, item.move] end @@ -44,9 +43,18 @@ class History < Qt::AbstractListModel raise OutOfBound if @current <= 0 move = @history[@current].move @current -= 1 + + fire :current_changed [@history[@current].state, move] end + def go_to(index) + item = self[index] + @current = index + fire :current_changed + [item.state, item.move] + end + def state @history[current].state end @@ -60,40 +68,9 @@ class History < Qt::AbstractListModel end def [](index) - @history[index] - end - - # model interface - - # set a serializer for this model - # if no serializer has been set, it will - # be impossible to use it with a view - def serializer=(ser) - @serializer = ser - end - - def data(index, role) - if @serializer and role == Qt::DisplayRole - unless @history[index.row].text - state = @history[index.row - 1].state - move = @history[index.row].move - san = @serializer.serialize(move, state) - - count = index.row / 2 + 1 - dots = if index.row % 2 == 0 - '.' - else - '...' - end - - @history[index.row].text = "#{count}#{dots} #{san}" - end - @history[index.row].text + if index >= @history.size || index < 0 + raise OutOfBound end + @history[index] end - - def rowCount(parent) - size - end - end diff --git a/lib/mainwindow.rb b/lib/mainwindow.rb index 1b1d7f7..df2e849 100644 --- a/lib/mainwindow.rb +++ b/lib/mainwindow.rb @@ -61,6 +61,15 @@ private scene = Scene.new @table = Table.new scene, @loader, self @controller = Controller.new(@table) + + movelist = @loader.get_matching(%w(movelist)).new(@controller) + movelist_dock = Qt::DockWidget.new(self) + movelist_dock.widget = movelist + movelist_dock.window_title = KDE.i18n("Move list") + movelist_dock.object_name = "movelist" + add_dock_widget(Qt::LeftDockWidgetArea, movelist_dock, Qt::Vertical) + movelist_dock.show + new_game(game) self.central_widget = @table diff --git a/lib/plugins/movelist/simple_movelist.rb b/lib/plugins/movelist/simple_movelist.rb dissimilarity index 86% index a6791fb..a2c7902 100644 --- a/lib/plugins/movelist/simple_movelist.rb +++ b/lib/plugins/movelist/simple_movelist.rb @@ -1,56 +1,101 @@ -require 'plugins/plugin' - -class SimpleMoveList < Qt::ListView - include Plugin - - plugin :name => 'Simple Move List', - :keywords => %w(movelist) - - def initialize(parent, history, game, opts = {}) - super(parent) -# self.model = Qt::StringListModel.new -# @history.add_observer(self) -# moves = (1...@history.size).map do |index| -# move(index) -# end -# self.model.set_string_list(moves) - - history.serializer = game.serializer.new(:compact) - self.model = history - -# if opts[:font] - self.font = opts[:font] if opts[:font] -# else -# f = font -# f.point_size = 16 -# self.font = f -# end - end - -# def on_added(index) -# index -= 1 -# self.model.remove_rows(index, @history.size - index - 1) -# self.model.insert_rows(index, 1) -# self.model.set_data(self.model.index(index, 0), -# move(index), -# Qt::DisplayRole) -# end - -# private - -# def move(index) -# state = @history[index].state -# move = @history[index+ 1].move -# san = @serializer.serialize(move, state) -# -# count = index/ 2 + 1 -# dots = if index% 2 == 0 -# '.' -# else -# '...' -# end -# -# "#{count}#{dots} #{san}" -# end -end - +require 'plugins/plugin' + +class SimpleMoveList < Qt::ListView + include Plugin + include Observer + + plugin :name => 'Simple Move List', + :keywords => %w(movelist) + + class LinearHistoryModel < Qt::StringListModel + include Observer + include Observable + + def initialize(match) + super([]) + @history = match.history + @serializer = match.game.serializer.new(:compact) + + @history.add_observer(self) + + insert_rows(0, @history.size) + (0...@history.size).each do |i| + update_row(i) + end + end + + def on_new_move + if @history.size > rowCount + insert_rows(rowCount, @history.size - rowCount) + else + remove_rows(@history.size, rowCount - @history.size) + end + update_row(@history.current) + fire_changed + end + + def on_forward + fire_changed + end + + def on_back + fire_changed + end + + def fire_changed + fire :change_current => index(@history.current, 0) + end + + def move(i) + if i == 0 + 'Mainline' + else + state = @history[i - 1].state + move = @history[i].move + san = @serializer.serialize(move, state) + + count = i / 2 + 1 + dots = if i % 2 == 0 + '.' + else + '...' + end + + "#{count}#{dots} #{san}" + end + end + + def update_row(i) + set_data(index(i, 0), move(i), Qt::DisplayRole) + end + + def flags(index) + if index.isValid + Qt::ItemIsSelectable | Qt::ItemIsEnabled + else + Qt::NoItemFlags + end + end + end + + def initialize(controller, opts = {}) + super(controller.table) + @controller = controller + self.font = opts[:font] if opts[:font] + + @controller.table.add_observer(self) + end + + def on_reset(match) + self.model = LinearHistoryModel.new(match) + model.observe(:change_current) do |current| + selection_model.select(current, + Qt::ItemSelectionModel::ClearAndSelect) + end + sig = 'selectionChanged(QItemSelection, QItemSelection)' + selection_model.on(sig) do |selected, deselected| + @controller.go_to(selected.indexes.first.row) + end + end +end + -- 2.11.4.GIT