本次作业是使用 Ruby 语言对 Tetris (俄罗斯方块)做拓展,增加以下功能
- 按下 u 可以旋转 180 °
- 增加 3 个形状
- 增加作弊功能(用 100 分换取一个 1×1 的块)
作业重点在于思考 Ruby 中类的设计,考虑何时需要 override
作业难度不大,功能实现了就可以拿到 80 分,通过测试,但是有些类的设计需要更合理,才能拿到满分,例如 cheat_piece_well_formed: The cheat piece should be a 3-deep nested array.
# University of Washington, Programming Languages, Homework 6, hw6runner.rb # This is the only file you turn in, so do not modify the other files as # part of your solution. class MyPiece < Piece # The constant All_My_Pieces should be declared here # the rotation should be centered, i.e., it should be [0,0], otherwise [[0,0],[1,0],[2,0]] rotates to [[0,0],[0,1],[0,2]] or [[-2,0],[-1,0],[0,0]] All_My_Pieces = All_Pieces + [ [ [[0, 0], [1, 0], [-1, 0], [2, 0], [-2, 0]], [[0, 0], [0, 1], [0, 2], [0, -1], [0, -2]] ], rotations([[0, 0], [1, 0], [0, 1]]), rotations([[0, 0], [1, 0], [0, 1], [1, 1], [-1, 0]]) ] # cheat_piece_well_formed: The cheat piece should be a 3-deep nested array. Cheat_Piece = [[[0, 0]]] # your enhancements here def self.next_piece(board) MyPiece.new(All_My_Pieces.sample, board) end def self.cheat_piece(board) MyPiece.new(Cheat_Piece, board) end end class MyBoard < Board # your enhancements here def initialize (game) super(game) @cheating = false end def cheat if @score >= 100 and !@cheating @cheating = true @score -= 100 end end def next_piece if @cheating @current_block = MyPiece.cheat_piece(self) @cheating = false else @current_block = MyPiece.next_piece(self) end @current_pos = nil end def store_current locations = @current_block.current_rotation displacement = @current_block.position # to override store_current in MyBoard because the provided code is broken if a Tetris piece does not have exactly 4 blocks in it. (0..(locations.size - 1)).each{|index| current = locations[index]; @grid[current[1]+displacement[1]][current[0]+displacement[0]] = @current_pos[index] } remove_filled @delay = [@delay - 2, 80].max end end class MyTetris < Tetris # enhancements here def set_board # cannot use super, because we do not want a @board = Board.new() and draw another board @canvas = TetrisCanvas.new @board = MyBoard.new(self) @canvas.place(@board.block_size * @board.num_rows + 3, @board.block_size * @board.num_columns + 6, 24, 80) @board.draw end def key_bindings super @root.bind('u' , proc { @board.rotate_clockwise @board.rotate_clockwise }) @root.bind('c' , proc { @board.cheat }) end end