半个月不写代码果然生疏了,居然在if
里出现了=
,而且还检查了好久才发现。。。
这是一个跑在终端里的2048游戏,本来想用C++写的,但是想了想和Ruby相比C++处理字符串不要太蛋疼,所以就用Ruby写了一个,果然轻松随意~
游戏的实现还是比较简单的,上下左右键操作,q
退出,操作后按回车确定。
如果按下没反应,请自行修改方向键的判断字符串。
实现了2048游戏的大部分功能,还有两个地方没有解决:
-
成功玩到2048,没有相应的提示。其实我已经写好了判断胜利的方法,但是我目前还没有玩到过,就懒得调用这个方法了。
-
游戏失败的判断方法没有完成。我现在只写了一个判断又没有空格的语句,实际的2048游戏在格子被填满后,还要判断是否有相邻的相同的数字,如果有就不算失败,略麻烦懒得写了。
当然,这次写这个小游戏还是有点小收获的,比如Ruby的清屏方法,找到了两个:
exec 'clear'
system('clear')
这两个方法是有区别的,同样是清空shell的当前窗口,第一个相当于在shell中输入clear
,会结束掉当前shell语句的进程;而第二个,仅仅只是把输出内容清空,并不会结束掉语句。
话不多说,代码如下:
class Game2048
attr_reader :board, :win_flag, :lose_flag, :move_flag
def initialize
@board = Array.new(16, '-')
pos1 = (rand * 100).to_i % 16
pos2 = (rand * 100).to_i % 16
while pos2 == pos1
pos2 = (rand * 100).to_i % 16
end
num1 = ((rand * 100).to_i % 2 + 1) * 2
num2 = ((rand * 100).to_i % 2 + 1) * 2
@board[pos1] = num1
@board[pos2] = num2
@cal_arr = Array.new
end
def print_borad
system('clear')
puts "\n\n ======== 2048 by TDFJ =======\n\n"
0.upto(3) do |i1|
((4 * i1)..(4 * i1 + 3)).each do |i2|
(4 - @board[i2].to_s.length).times { print ' ' }
print @board[i2], ' '
end
print "\n\n\n\n"
end
end
def create_piece
empty_place = Array.new
(0..15).each do |i|
empty_place.push(i) if @board[i] == '-'
end
create_place = (rand * 100).to_i % empty_place.length
@board[empty_place[create_place]] = ((rand * 100).to_i % 2 + 1) * 2
end
def win?
@win_flag = false
(0..15).each { |i| @win_flag = true if @board[i] == 2048 }
@win_flag
end
def lose?
@lose_flag = true
(0..15).each { |i| @lose_flag = false if @board[i] == '-' }
@lose_flag
end
def cal
0.upto(@cal_arr.length - 2) do |i|
if @cal_arr[i] != '-' && @cal_arr[i] == @cal_arr[i + 1]
@move_flag = true
@cal_arr[i] = @cal_arr[i] * 2
@cal_arr.delete_at(i + 1)
@cal_arr.push('-')
end
end
(4 - @cal_arr.length).times { @cal_arr.push('-') }
end
def step(ori)
@move_flag = false
case ori
when 'up' then
(0..3).each do |i1|
@cal_arr.clear
0.step(12, 4) { |i2| @cal_arr.push(@board[i1 + i2]) if @board[i1 + i2] != '-' }
@move_flag = true if @board[i1 + 0] == '-' && @cal_arr.length != 0
self.cal
0.step(12, 4) { |i2| @board[i1 + i2] = @cal_arr[i2 / 4] }
end
when 'down' then
(0..3).each do |i1|
@cal_arr.clear
12.step(0, -4) { |i2| @cal_arr.push(@board[i1 + i2]) if @board[i1 + i2] != '-' }
@move_flag = true if @board[i1 + 12] == '-' && @cal_arr.length != 0
self.cal
12.step(0, -4) { |i2| @board[i1 + i2] = @cal_arr[(12 - i2) / 4] }
end
when 'left' then
0.step(12, 4) do |i1|
@cal_arr.clear
0.upto(3) { |i2| @cal_arr.push(@board[i1 + i2]) if @board[i1 + i2] != '-' }
@move_flag = true if @board[i1] == '-' && @cal_arr.length != 0
self.cal
0.upto(3) { |i2| @board[i1 + i2] = @cal_arr[i2] }
end
when 'right' then
0.step(12, 4) do |i1|
@cal_arr.clear
3.downto(0) { |i2| @cal_arr.push(@board[i1 + i2]) if @board[i1 + i2] != '-' }
@move_flag = true if @board[i1 + 3] == '-' && @cal_arr.length != 0
self.cal
3.downto(0) { |i2| @board[i1 + i2] = @cal_arr[3 - i2] }
end
end
end
end
game2048 = Game2048.new
game2048.print_borad
input = gets.chomp
while input != 'q'
case input
when "\e[A" then
game2048.step('up')
when "\e[B" then
game2048.step('down')
when "\e[D" then
game2048.step('left')
when "\e[C" then
game2048.step('right')
end
game2048.create_piece if game2048.move_flag
game2048.print_borad
input = gets.chomp
end