Skip to content

Commit

Permalink
Refactor UI somewhat
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviershay committed Oct 14, 2010
1 parent 2e95913 commit 740146b
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 160 deletions.
176 changes: 16 additions & 160 deletions lib/dominion/ui.rb
@@ -1,5 +1,9 @@
require 'ffi-ncurses'
require 'dominion/engine'
require 'dominion/ui/ncurses/window'
require 'dominion/ui/ncurses/board_window'
require 'dominion/ui/ncurses/play_area_window'
require 'dominion/ui/ncurses/input_window'

module Dominion; module UI; end; end;
class Dominion::UI::NCurses < Dominion::Engine
Expand Down Expand Up @@ -53,186 +57,38 @@ def finalize
endwin
end

def colors
{
:white => 0,
:yellow => 3,
:blue => 4,
:red => 1,
:cyan_back => 14,
:green_back => 10,
:magenta_back => 13,
:yellow_back => 11
}
end

def bold_with_color(window, game, color, text)
color_index = colors[color] || raise("Unknown color: #{color}")
wattr_set window, A_BOLD, color_index, nil

waddstr(window, text.to_s)
end

def print_with_color(window, game, color, text)
color_index = colors[color] || raise("Unknown color: #{color}")
wattr_set window, A_NORMAL, color_index, nil

waddstr(window, text.to_s)
end

def draw(game, ctx = {})
ctx[:windows] ||= {}
curs_set 0
refresh

drawn = [{
:coords => [14, 80, 0, 0],
:title => 'Board',
:draw => lambda do |window, game|
bwc = lambda {|color, text| bold_with_color(window, game, color, text)}
pwc = lambda {|color, text| print_with_color(window, game, color, text)}

type_char = [
[:reaction, 'R'],
[:attack, 'X'],
[:treasure, 'T'],
[:victory, 'V'],
[:action, 'A']
]

max_name_length = game.board.map {|pile|
pile[0][:name].length
}.max

header, body = game.board.partition {|x|
[
:copper,
:silver,
:gold,
:estate,
:duchy,
:provence,
:curse
].include?(x.first[:key])
}

header.each_with_index do |pile, i|
card = pile.first

pwc[:white, ' '] if i > 0
pwc[:yellow, card[:cost]]
pwc[:red, type_char.detect {|x| [*card[:type]].include?(x[0]) }[1]]
pwc[:blue, pile.size]
pwc[:white, " %s" % card[:name]]
end
pwc[:white, "\n"]
body.sort_by {|x| [x[0][:cost], x[0][:name]] }.each do |pile|
card = pile.first

pwc[:white, ' ']
pwc[:yellow, card[:cost]]
pwc[:red, type_char.detect {|x| [*card[:type]].include?(x[0]) }[1]]
pwc[:blue, '%-2i' % pile.size]
if game.card_active?(card)
bwc[:white, " %-#{max_name_length}s " % card[:name]]
else
pwc[:white, " %-#{max_name_length}s " % card[:name]]
end

pwc[:cyan_back, card[:cards] || ' ']
pwc[:green_back, card[:actions] || ' ']
pwc[:magenta_back, card[:buys] || ' ']
pwc[:yellow_back, card[:gold] || ' ']

pwc[:white, " %-#{max_name_length}s\n" % card[:description]]
end
end
}, {
:title => "Turn %i (%i Action, %i Buy, %i Treasure, %i Discard, %i Deck)" % [
game.turn,
game.player[:actions],
game.player[:buys],
game.treasure(game.player),
game.player[:discard].length,
game.player[:deck].length
],
:coords => [10, 80, 14, 0],
:draw => lambda do |window, game|
bwc = lambda {|color, text| bold_with_color(window, game, color, text)}
pwc = lambda {|color, text| print_with_color(window, game, color, text)}

pwc[:white, "Hand: "]
line_length = 6
game.player[:hand].each_with_index do |card, index|
suffix = index == game.player[:hand].length - 1 ? '' : ', '
if game.card_active?(card)
bwc[:white, card[:name] + suffix]
else
pwc[:white, card[:name] + suffix]
end
line_length += (card[:name] + suffix).length
end

# TODO: print ' ' doesn't work :(
pwc[:white, " " * (77 - line_length)] if line_length < 76
pwc[:white, "\n"]
played = "Played: %s" % game.player[:played].map {|x| x[:name] }.join(", ")
pwc[:white, played]
pwc[:white, " " * (77 - played.length)] if played.length < 76
pwc[:white, "\n"]

unless game.player[:revealed].empty?
revealed = "Revealed: %s\n" % game.player[:revealed].map {|x| x[:name] }.join(", ")
pwc[:white, revealed]
pwc[:white, " " * (77 - revealed.length)]
end

end
}, {
:coords => [1, 80, 24, 0],
:border => false,
:draw => lambda do |window, game|
pwc = lambda {|color, text| print_with_color(window, game, color, text)}

if game.prompt
suggest = game.prompt[:autocomplete][:strategy][input_buffer].to_s

pwc[game.prompt[:color] || :yellow_back, "%s %s" % [
game.prompt[:prompt],
input_buffer]]

fill = suggest[input_buffer.length..-1]

if fill && fill.length > 0
pwc[:red, "%s" % fill]
end
else
pwc[:green_back, "%-80s" % " "]
end
end
}].map do |window|
window[:border] = true unless window.has_key?(:border)

c = window[:coords]
drawn = [
BoardWindow.new(game),
PlayAreaWindow.new(game),
InputWindow.new(game, input_buffer)
].map do |window|
c = window.coords
board_frame = (ctx[:windows][[:outer] + c] ||= newwin(*c))

if window[:border]
if window.border
board = (ctx[:windows][[:inner] + c] ||= newwin(c[0] - 2, c[1] - 2, c[2] + 1, c[3] + 1))

window[:draw][board, game]
window.window = board
window.draw

wattr_set board_frame, A_NORMAL, 7, nil
box(board_frame, c[2], c[3])
wmove(board_frame, 0, 2)
waddstr(board_frame, "| #{window[:title]} |")
waddstr(board_frame, "| #{window.title} |")
wrefresh(board_frame)
wrefresh(board)
{
:frame => board_frame,
:inner => board
}
else
window[:draw][board_frame, game]
window.window = board_frame
window.draw
wrefresh(board_frame)
{
:frame => nil,
Expand Down
73 changes: 73 additions & 0 deletions lib/dominion/ui/ncurses/board_window.rb
@@ -0,0 +1,73 @@
module Dominion; module UI; end; end;
class Dominion::UI::NCurses < Dominion::Engine
class BoardWindow < Window
def initialize(*args)
super
end

def coords
[14, 80, 0, 0]
end

def title
'Board'
end

def draw
type_char = [
[:reaction, 'R'],
[:attack, 'X'],
[:treasure, 'T'],
[:victory, 'V'],
[:action, 'A']
]

max_name_length = game.board.map {|pile|
pile[0][:name].length
}.max

header, body = game.board.partition {|x|
[
:copper,
:silver,
:gold,
:estate,
:duchy,
:provence,
:curse
].include?(x.first[:key])
}

header.each_with_index do |pile, i|
card = pile.first

print( :white, ' ' ) if i > 0
print( :yellow, card[:cost] )
print( :red, type_char.detect {|x| [*card[:type]].include?(x[0]) }[1] )
print( :blue, pile.size )
print( :white, " %s" % card[:name] )
end
print( :white, "\n" )
body.sort_by {|x| [x[0][:cost], x[0][:name]] }.each do |pile|
card = pile.first

print( :white, ' ' )
print( :yellow, card[:cost] )
print( :red, type_char.detect {|x| [*card[:type]].include?(x[0]) }[1] )
print( :blue, '%-2i' % pile.size )
if game.card_active?(card)
print( :white, " %-#{max_name_length}s " % card[:name], true )
else
print( :white, " %-#{max_name_length}s " % card[:name] )
end

print( :cyan_back, card[:cards] || ' ' )
print( :green_back, card[:actions] || ' ' )
print( :magenta_back, card[:buys] || ' ' )
print( :yellow_back, card[:gold] || ' ' )

print( :white, " %-#{max_name_length}s\n" % card[:description] )
end
end
end
end
38 changes: 38 additions & 0 deletions lib/dominion/ui/ncurses/input_window.rb
@@ -0,0 +1,38 @@
module Dominion; module UI; end; end;
class Dominion::UI::NCurses < Dominion::Engine
class InputWindow < Window
attr_accessor :input_buffer

def initialize(game, input_buffer)
super(game)
self.input_buffer = input_buffer
end

def coords
[1, 80, 24, 0]
end

def border
false
end

def draw
if game.prompt
suggest = game.prompt[:autocomplete][:strategy][input_buffer].to_s

print( game.prompt[:color] || :yellow_back, "%s %s" % [
game.prompt[:prompt],
input_buffer
])

fill = suggest[input_buffer.length..-1]

if fill && fill.length > 0
print( :red, "%s" % fill )
end
else
print( :green_back, "%-80s" % " " )
end
end
end
end
48 changes: 48 additions & 0 deletions lib/dominion/ui/ncurses/play_area_window.rb
@@ -0,0 +1,48 @@
module Dominion; module UI; end; end;
class Dominion::UI::NCurses < Dominion::Engine
class PlayAreaWindow < Window
def initialize(*args)
super
end

def coords
[10, 80, 14, 0]
end

def title
"Turn %i (%i Action, %i Buy, %i Treasure, %i Discard, %i Deck)" % [
game.turn,
game.player[:actions],
game.player[:buys],
game.treasure(game.player),
game.player[:discard].length,
game.player[:deck].length
]
end

def draw
print( :white, "Hand: " )
line_length = 6
game.player[:hand].each_with_index do |card, index|
suffix = index == game.player[:hand].length - 1 ? '' : ', '
print( :white, card[:name] + suffix, game.card_active?(card) )
line_length += (card[:name] + suffix).length
end

# TODO: print ' ' doesn't work :(
print( :white, " " * (77 - line_length) ) if line_length < 76
print( :white, "\n" )

played = "Played: %s" % game.player[:played].map {|x| x[:name] }.join(", ")
print( :white, played )
print( :white, " " * (77 - played.length) ) if played.length < 76
print( :white, "\n" )

unless game.player[:revealed].empty?
revealed = "Revealed: %s\n" % game.player[:revealed].map {|x| x[:name] }.join(", ")
print( :white, revealed )
print( :white, " " * (77 - revealed.length) )
end
end
end
end

0 comments on commit 740146b

Please sign in to comment.