180行ruby代码搞定游戏2048

来源:互联网 发布:2015网络彩票开售 编辑:程序博客网 时间:2024/05/29 05:06

最今在玩2048这款小游戏,游戏逻辑简单,非常适合我这种对于游戏新入行的人来实现逻辑。于是选择了最拿手的ruby语言来实现这款小游戏的主要逻辑。还是挺简单的,加起来4小时左右搞定。

上代码:

require 'optparse'module HelpHELP_TEXT =<<HELPpress buttons for move  l => move to left  r => move to right  t => move to top  b => move to bottompress e button to exit gameyou can see this help text if your input ruby ruby_2048.rb --helpHELPdef set_helpsOptionParser.new do |opts|opts.on_tail("-h", "--help", 'This help text.') do  puts HELP_TEXTexit!endend.parse!endendclass Objectdef invoke(need, method)if needself.send(method) elseselfendendendclass R2048extend Helpattr_reader :chessboardLEFT = "l"RIGHT = "r"TOP = "t"BOTTOM = "b"EXIT = "e"def initializeR2048.set_helps    @chessboard = Array.new(4){|x| Array.new(4){|y| 0}}    @init_moved = false1.upto(2){|i| generate_init_num}enddef generate_init_numreturn false unless @chessboard.flatten.uniq.select{|chess| chess == 0}.count > 0rand_position = rand(16)x, y = rand_position/4, rand_position % 4until @chessboard[x][y] == 0rand_position = rand(16)x, y = rand_position/4, rand_position % 4    end    @chessboard[x][y] = [2, 4][rand(2)]enddef check_and_merge(transpose, reverse)moved = falsetemp_chessboard = @chessboard.invoke(transpose, :transpose).map do |row|reversed_row = set_jump_step(row.invoke(reverse, :reverse)).invoke(reverse, :reverse)moved = true if reversed_row != row.invoke(reverse, :reverse)reversed_rowend.invoke(transpose, :transpose)if moved@chessboard = temp_chessboard trueelseif !@init_moved@init_moved = truetrueelse falseendendenddef generate_new_num(transpose, pos)ungenerated = trueright_positions = []@chessboard.invoke(transpose, :transpose).each_with_index{|row, i| right_positions << i if row[pos] == 0}right_position = right_positions[rand(right_positions.count)]row_index = 0@chessboard = @chessboard.invoke(transpose, :transpose).map do |row|if ungenerated && row_index == right_positionungenerated = falserow[pos] = [2, 4][rand(2)]endrow_index += 1rowend.invoke(transpose, :transpose)!ungeneratedenddef set_jump_step(row)  pured = row.select{|chess| chess != 0 }.inject([]) do |sum, chess|  if sum.last == chess  sum.pop   sum << chess * 2  else  sum << chess  end  end  pured.concat Array.new(4 - pured.count, 0)enddef display  puts "==============================="      @chessboard.each_with_index do |c, row|      puts "#{c[0]}#{c[1]}#{c[2]}#{c[3]}"      puts      endenddef failure_displayputs "you have failed!!!"enddef rundisplaykey = niluntil key == "e\n"key = getskey.gsub!("\n", "")return if key == EXITif ![LEFT, RIGHT, TOP, BOTTOM].include? keyputs "input error" nextendgenerate = case keywhen LEFTif check_and_merge(false, false)generate_new_num(false, 3)elsenilendwhen RIGHTif check_and_merge(false, true)generate_new_num(false, 0)elsenilendwhen TOPif check_and_merge(true, false)generate_new_num(true, 3)elsenilendwhen BOTTOMif check_and_merge(true, true)generate_new_num(true, 0)elsenilendendif generate == nil || generate  displayelse  failure_display  returnendendendendR2048.new.run

写了一些测试:

require 'ruby_2048'describe R2048 do   before(:each) do   @r2048 = R2048.new   end   it "should jump to [2, 0, 0, 0] when input [0, 0, 0, 2]" do       @r2048.set_jump_step([0, 0, 0, 2]).should == [2, 0, 0, 0]   end   it "should jump to [2, 4, 0, 0] when input [2, 0, 4, 0]" do   @r2048.set_jump_step([2, 0, 4, 0]).should == [2, 4, 0, 0]   end   it "should jump to [4, 0, 0, 0] when input [2, 0, 2, 0]" do   @r2048.set_jump_step([2, 0, 2, 0]).should == [4, 0, 0, 0]   end   it "should jump to [2, 4, 4, 0] when input [2, 4, 2, 2]" do   @r2048.set_jump_step([2, 4, 2, 2]).should == [2, 4, 4, 0]   end   it "should jump to [4, 4, 0, 0] when input [2, 2, 2, 2]" do   @r2048.set_jump_step([2, 2, 2, 2]).should == [4, 4, 0, 0]   end   it "should + 1 chess if generate_init_num" do   expect { @r2048.generate_init_num }.to change{@r2048.chessboard.flatten.count{|chess| chess!= 0} }.by(1)     end   it "should have already have two chess when inited" do   expect{@r2048.count} == 2   endend

貌似还不错,最新代码请见github:https://github.com/xumc/ruby_2048


后记:

  一篇博客介绍c++版命令行2048竟然写了500多行,见http://blog.csdn.net/yc7369/article/details/29416819, 恰恰证明了ruby的简洁。

0 0
原创粉丝点击