⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sample2.rb

📁 ruby的源代码
💻 RB
字号:
#!/usr/local/bin/ruby#----------------------> pretty simple othello game <-----------------------# othello.rb## version 0.3# maeda shugo (shuto@po.aianet.ne.jp)#---------------------------------------------------------------------------#	Sep. 17, 1997	modified by Y. Shigehiro for tcltk library#	   maeda shugo (shugo@po.aianet.ne.jp) 会による#          (ruby/tk で今かれていた) ruby のサンプルプログラム#		http://www.aianet.or.jp/~shugo/ruby/othello.rb.gz#	   を tcltk ライブラリを蝗うように, 怠常弄に恃构してみました.##	   なるべくオリジナルと票じになるようにしてあります.require "observer"require "tcltk"$ip = TclTkInterpreter.new()$root = $ip.rootwidget()$button, $canvas, $checkbutton, $frame, $label, $pack, $update, $wm =   $ip.commands().indexes(   "button", "canvas", "checkbutton", "frame", "label", "pack", "update", "wm")class Othello      EMPTY = 0   BLACK = 1   WHITE = - BLACK      attr :in_com_turn   attr :game_over      class Board         include Observable            DIRECTIONS = [	 [-1, -1], [-1, 0], [-1, 1],	 [ 0, -1],          [ 0, 1],	 [ 1, -1], [ 1, 0], [ 1, 1]      ]            attr :com_disk, TRUE         def initialize(othello)	 @othello = othello	 reset      end         def notify_observers(*arg)	 if @observer_peers != nil	    super(*arg)	 end      end            def reset	 @data = [	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, WHITE, BLACK, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, BLACK, WHITE, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY],	    [EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY]	 ]	 changed	 notify_observers      end            def man_disk	 return - @com_disk      end            def other_disk(disk)	 return - disk      end            def get_disk(row, col)	 return @data[row][col]      end            def reverse_to(row, col, my_disk, dir_y, dir_x)	 y = row	 x = col	 begin	    y += dir_y	    x += dir_x	    if y < 0 || x < 0 || y > 7 || x > 7 ||		  @data[y][x] == EMPTY	       return	    end	 end until @data[y][x] == my_disk	 begin	    @data[y][x] = my_disk	    changed	    notify_observers(y, x)	    y -= dir_y	    x -= dir_x	 end until y == row && x == col      end            def put_disk(row, col, disk)	 @data[row][col] = disk	 changed	 notify_observers(row, col)	 DIRECTIONS.each do |dir|	    reverse_to(row, col, disk, *dir)	 end      end            def count_disk(disk)	 num = 0	 @data.each do |rows|	    rows.each do |d|	       if d == disk		  num += 1	       end	    end	 end	 return num      end            def count_point_to(row, col, my_disk, dir_y, dir_x)	 return 0 if @data[row][col] != EMPTY	 count = 0	 loop do	    row += dir_y	    col += dir_x	    break if row < 0 || col < 0 || row > 7 || col > 7	    case @data[row][col]	    when my_disk	       return count	    when other_disk(my_disk)	       count += 1	    when EMPTY	       break	    end	 end	 return 0      end            def count_point(row, col, my_disk)	 count = 0	 DIRECTIONS.each do |dir|	    count += count_point_to(row, col, my_disk, *dir)	 end	 return count      end            def corner?(row, col)	 return (row == 0 && col == 0) ||	    (row == 0 && col == 7) ||	    (row == 7 && col == 0) ||	    (row == 7 && col == 7)      end            def search(my_disk)	 max = 0	 max_row = nil	 max_col = nil	 for row in 0 .. 7	    for col in 0 .. 7	       buf = count_point(row, col, my_disk)	       if (corner?(row, col) && buf > 0) || max < buf		  max = buf		  max_row = row		  max_col = col	       end	    end	 end	 return max_row, max_col      end   end #--------------------------> class Board ends here      class BoardView < TclTkWidget            BACK_GROUND_COLOR = "DarkGreen"      HILIT_BG_COLOR = "green"      BORDER_COLOR = "black"      BLACK_COLOR = "black"      WHITE_COLOR = "white"      STOP_COLOR = "red"            attr :left      attr :top      attr :right      attr :bottom            class Square	 	 attr :oval, TRUE	 attr :row	 attr :col	 	 def initialize(view, row, col)	    @view = view	    @id = @view.e("create rectangle", *view.tk_rect(view.left + col,				      view.top + row,				      view.left + col + 1,				      view.top + row + 1))	    @row = row	    @col = col	    @view.e("itemconfigure", @id,	      "-width 0.5m -outline #{BORDER_COLOR}")	    @view.e("bind", @id, "<Any-Enter>", TclTkCallback.new($ip, proc{	       if @oval == nil		  view.e("itemconfigure", @id, "-fill #{HILIT_BG_COLOR}")	       end	    }))	    @view.e("bind", @id, "<Any-Leave>", TclTkCallback.new($ip, proc{	       view.e("itemconfigure", @id, "-fill #{BACK_GROUND_COLOR}")	    }))	    @view.e("bind", @id, "<ButtonRelease-1>", TclTkCallback.new($ip,	       proc{	       view.click_square(self)	    }))	 end	 	 def blink(color)	    @view.e("itemconfigure", @id, "-fill #{color}")	    $update.e()	    sleep(0.1)	    @view.e("itemconfigure", @id, "-fill #{BACK_GROUND_COLOR}")	 end      end #-----------------------> class Square ends here         def initialize(othello, board)	 super($ip, $root, $canvas)	 @othello = othello	 @board = board	 @board.add_observer(self)	 	 @squares = Array.new(8)	 for i in 0 .. 7	    @squares[i] = Array.new(8)	 end	 @left = 1	 @top = 0.5	 @right = @left + 8	 @bottom = @top + 8	 	 i = self.e("create rectangle", *tk_rect(@left, @top, @right, @bottom))	 self.e("itemconfigure", i,	    "-width 1m -outline #{BORDER_COLOR} -fill #{BACK_GROUND_COLOR}")	 for row in 0 .. 7	    for col in 0 .. 7	       @squares[row][col] = Square.new(self, row, col)	    end	 end	 	 update      end            def tk_rect(left, top, right, bottom)	 return left.to_s + "c", top.to_s + "c",	    right.to_s + "c", bottom.to_s + "c"      end            def clear	 each_square do |square|	    if square.oval != nil	       self.e("delete", square.oval)	       square.oval = nil	    end	 end      end            def draw_disk(row, col, disk)	 if disk == EMPTY	    if @squares[row][col].oval != nil	       self.e("delete", @squares[row][col].oval)	       @squares[row][col].oval = nil	    end	    return	 end	    	 $update.e()	 sleep(0.05)	 oval = @squares[row][col].oval	 if oval == nil	    oval = self.e("create oval", *tk_rect(@left + col + 0.2,					   @top + row + 0.2,					   @left + col + 0.8,					   @top + row + 0.8))	    @squares[row][col].oval = oval	 end	 case disk	 when BLACK	    color = BLACK_COLOR	 when WHITE	    color = WHITE_COLOR	 else	    fail format("Unknown disk type: %d", disk)	 end	 self.e("itemconfigure", oval, "-outline #{color} -fill #{color}")      end            def update(row = nil, col = nil)	 if row && col	    draw_disk(row, col, @board.get_disk(row, col))	 else	    each_square do |square|	       draw_disk(square.row, square.col,			 @board.get_disk(square.row, square.col))	    end	 end	 @othello.show_point      end            def each_square	 @squares.each do |rows|	    rows.each do |square|	       yield(square)	    end	 end      end            def click_square(square)	 if @othello.in_com_turn || @othello.game_over ||	       @board.count_point(square.row,				  square.col,				  @board.man_disk) == 0	    square.blink(STOP_COLOR)	    return	 end	 @board.put_disk(square.row, square.col, @board.man_disk)	 @othello.com_turn      end            private :draw_disk      public :update   end #----------------------> class BoardView ends here      def initialize      @msg_label = TclTkWidget.new($ip, $root, $label)      $pack.e(@msg_label)            @board = Board.new(self)      @board_view = BoardView.new(self, @board)      #### added by Y. Shigehiro      ## board_view の络きさを肋年する.      x1, y1, x2, y2 = @board_view.e("bbox all").split(/ /).collect{|i| i.to_f}      @board_view.e("configure -width", x2 - x1)      @board_view.e("configure -height", y2 - y1)      ## scrollregion を肋年する.      @board_view.e("configure -scrollregion {", @board_view.e("bbox all"),	 "}")      #### ここまで      $pack.e(@board_view, "-fill both -expand true")            panel = TclTkWidget.new($ip, $root, $frame)            @play_black = TclTkWidget.new($ip, panel, $checkbutton,        "-text {com is black} -command", TclTkCallback.new($ip, proc{	 switch_side      }))      $pack.e(@play_black, "-side left")                  quit = TclTkWidget.new($ip, panel, $button, "-text Quit -command",	 TclTkCallback.new($ip, proc{	 exit      }))      $pack.e(quit, "-side right -fill x")            reset = TclTkWidget.new($ip, panel, $button, "-text Reset -command",	 TclTkCallback.new($ip, proc{	 reset_game      }))      $pack.e(reset, "-side right -fill x")            $pack.e(panel, "-side bottom -fill x")      #      root = Tk.root      $wm.e("title", $root, "Othello")      $wm.e("iconname", $root, "Othello")            @board.com_disk = WHITE      @game_over = FALSE            TclTk.mainloop   end      def switch_side      if @in_com_turn	 @play_black.e("toggle")      else	 @board.com_disk = @board.man_disk	 com_turn unless @game_over      end   end      def reset_game      if @board.com_disk == BLACK	 @board.com_disk = WHITE	 @play_black.e("toggle")      end      @board_view.clear      @board.reset      $wm.e("title", $root, "Othello")      @game_over = FALSE   end         def com_turn      @in_com_turn = TRUE      $update.e()      sleep(0.5)      begin	 com_disk = @board.count_disk(@board.com_disk)	 man_disk = @board.count_disk(@board.man_disk)	 if @board.count_disk(EMPTY) == 0	    if man_disk == com_disk	       $wm.e("title", $root, "{Othello - Draw!}")	    elsif man_disk > com_disk	       $wm.e("title", $root, "{Othello - You Win!}")	    else	       $wm.e("title", $root, "{Othello - You Loose!}")	    end	    @game_over = TRUE	    break	 elsif com_disk == 0	    $wm.e("title", $root, "{Othello - You Win!}")	    @game_over = TRUE	    break	 elsif man_disk == 0	    $wm.e("title", $root, "{Othello - You Loose!}")	    @game_over = TRUE	    break	 end	 row, col = @board.search(@board.com_disk)	 break if row == nil || col == nil	 @board.put_disk(row, col, @board.com_disk)      end while @board.search(@board.man_disk) == [nil, nil]      @in_com_turn = FALSE   end   def show_point      black = @board.count_disk(BLACK)      white = @board.count_disk(WHITE)      @msg_label.e("configure -text",	 %Q/{#{format("BLACK: %.2d    WHITE: %.2d", black, white)}}/)   endend #----------------------> class Othello ends hereOthello.new#----------------------------------------------> othello.rb ends here

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -