咳@Rubyリハビリ中です。

同僚が Windows で遊んでいた 箱入り娘 を見てたらなつかしくて
はじめて tk 使って作ってみました。

tkむずかしいっす。

# こういうの投稿しても良いのかな?



require 'tk' class House def initialize(parent=nil, unit=32) @w = 4 @h = 5 @unit_size = unit @widget = TkFrame.new(parent, 'width' => @unit_size * @w, 'height' => @unit_size * @h).pack @chips = [] end attr :widget attr :unit_size attr :chips def enter(chip) @chips.push chip end def wall hash = {} (-1..@w).each do |i| hash[[i, -1]] = true hash[[i, @h]] = true end (-1..@h).each do |i| hash[[-1, i]] = true hash[[@w, i]] = true end hash end def move?(chip, dx, dy) field = self.wall @chips.each do |c| unless c == chip c.area.each do |a| field[a] = chip end end end chip.area(dx, dy).each do |a| return false if field[a] end return true end end $house = house = House.new(nil, 64) class Chip def initialize(house, name, x, y, w=1, h=1) @name = name @w = w @h = h @widget = TkLabel.new(house.widget, 'text' => name, 'relief' => 'raised') @house = house @unit = @house.unit_size moveto(x, y) @house = house.enter(self) @widget.bind('1', proc{|e| do_press e.x, e.y}) @widget.bind('B1-Motion', proc{|x, y| do_motion x, y}, "%x %y") @widget.bind('ButtonRelease-1', proc{|x, y| do_release x, y}, "%x %y") end attr :name def area(dx=0, dy=0) v = [] for i in (1..@h) for j in (1..@w) v.push([dx + @x + j - 1, dy + @y + i - 1]) end end v end def moveto(x, y) @x = x @y = y @widget.place('x' => @unit * x, 'y' => @unit * y, 'width' => @unit * @w, 'height' => @unit * @h) end def move(dx, dy) x = @x + dx y = @y + dy moveto(x, y) end def do_press(x, y) end def do_motion(x, y) if x >= @unit * @w dx = 1 elsif x < 0 dx = -1 else dx = 0 end if y >= @unit * @h dy = 1 elsif y < 0 dy = -1 else dy = 0 end if (dx != 0) dy = 0 end return if (dx == 0) and (dy == 0) try_move(dx, dy) end def do_release(x, y) end def try_move(dx, dy) if $house.move?(self, dx, dy) move(dx, dy) end end end she = Chip.new(house, '娘', 1, 0, 2, 2) father = Chip.new(house, "父\n親", 0, 0, 1, 2) mother = Chip.new(house, "母\n親", 3, 0, 1, 2) kozou = [] (0..3).each do |i| kozou.push Chip.new(house, "小僧", i, 2) end genan = [] (0..1).each do |i| genan.push Chip.new(house, "下\n男", i * 3, 3, 1, 2) end bantou = Chip.new(house, "番頭", 1, 3, 2, 1) Tk.mainloop