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
- 180行ruby代码搞定游戏2048
- 百行代码搞定“关灯游戏”!!!
- 200行代码搞定炸金花游戏(PHP版)
- Ruby用6行搞定P2P
- 游戏服务端IOCP模型,自己封装的一个类,3行代码搞定服务端。
- 游戏服务端IOCP模型,自己封装的一个类,3行代码搞定服务端
- 十二行代码搞定自动更新
- 几行代码搞定二级域名!!!!!!
- 100行代码搞定 activiti
- Ruby Warrior —— 用游戏学习Ruby (附全部关卡代码)
- 十行代码搞定 "冒泡排序"
- DotLucene:37行代码搞定全文搜索
- 两行代码搞定多级关联搜索
- 两行代码搞定MFC清屏功能
- 几十行代码搞定squid限速
- 5行代码搞定floyd算法
- python--10行代码搞定词频统计
- 几行代码搞定nodejs中的回调坑
- Master-Mind Hints
- Android NDK入门
- CoNLL Multi-lingual Dependency Parsing 格式
- mysql 源码编译安装
- 不错网站推荐不定期更新
- 180行ruby代码搞定游戏2048
- 嵌入Chrome cef之完整版(本教程基于cef1)
- sublime text3安装emmet,很简单实用
- 无法在web服务器上启动调试,web服务器配置不正确的解决办法
- 加string.h后出现string' : undeclared identifier的解决办法
- 1679: [Usaco2005 Jan]Moo Volume 牛的呼声 (差分序列)
- tiny4412 裸机程序 八、重定位到DRAM及LCD实验
- Java实现基数排序(桶排序)
- 注意语句顺序 防止Servlet Request Response乱码