Class: Game2048::Tiles

Inherits:
Object
  • Object
show all
Defined in:
lib/game_2048/tiles.rb

Overview

Game

Constant Summary collapse

SIZE =
4**2
NO_TILE =
0
NEW_TILE_CHANCE =
90
NEW_TILE_2 =
2
NEW_TILE_4 =
4
WIN_SUM =
2048

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(items = nil, auto_new_tile: true) ⇒ Tiles

Returns a new instance of Tiles.

Raises:



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/game_2048/tiles.rb', line 18

def initialize(items = nil, auto_new_tile: true)
  raise TilesError, "Tile map size must be #{SIZE}" if !items.nil? && items.length != SIZE

  if items.nil?
    reset
  else
    @items = items
  end
  @auto_new_tile = auto_new_tile
  @items_prev = []
end

Instance Attribute Details

#itemsObject (readonly)

Returns the value of attribute items.



16
17
18
# File 'lib/game_2048/tiles.rb', line 16

def items
  @items
end

Instance Method Details

#game_over?Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/game_2048/tiles.rb', line 47

def game_over?
  return false if @items.index(NO_TILE)

  n = Math.sqrt(SIZE).to_i
  @items.each.with_index do |item, i|
    a = i + 1
    return false if a < @items.length && !(a % n).zero? && item == @items[a]

    b = i + n
    return false if b < @items.length && item == @items[b]
  end
  true
end

#move_downObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/game_2048/tiles.rb', line 93

def move_down
  items = @items.dup
  n = Math.sqrt(SIZE).to_i
  (n - 1).downto(0) do |row|
    move_zeroes(n)
    n.times do |column|
      tile = row * n + column
      tile_next = tile + n
      if tile_next < @items.length && @items[tile_next] == @items[tile]
        @items[tile_next] += @items[tile]
        @items[tile] = NO_TILE
      end
    end
    move_zeroes(n)
  end
  return if items == @items

  @items_prev = items
  new_tile if @auto_new_tile
end

#move_leftObject



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/game_2048/tiles.rb', line 135

def move_left
  items = @items.dup
  n = Math.sqrt(SIZE).to_i
  n.times do |row|
    move_zeroes(-1)
    n.times do |column|
      tile = row * n + column
      tile_prev = tile - 1
      if tile_prev >= row * n && @items[tile_prev] == @items[tile]
        @items[tile_prev] += @items[tile]
        @items[tile] = NO_TILE
      end
    end
    move_zeroes(-1)
  end
  return if items == @items

  @items_prev = items
  new_tile if @auto_new_tile
end

#move_rightObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/game_2048/tiles.rb', line 114

def move_right
  items = @items.dup
  n = Math.sqrt(SIZE).to_i
  n.times do |row|
    move_zeroes(1)
    (n - 1).downto(0) do |column|
      tile = row * n + column
      tile_next = tile + 1
      if tile_next < row * n + n && @items[tile_next] == @items[tile]
        @items[tile_next] += @items[tile]
        @items[tile] = NO_TILE
      end
    end
    move_zeroes(1)
  end
  return if items == @items

  @items_prev = items
  new_tile if @auto_new_tile
end

#move_upObject



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/game_2048/tiles.rb', line 72

def move_up
  items = @items.dup
  n = Math.sqrt(SIZE).to_i
  n.times do |row|
    move_zeroes(-n)
    n.times do |column|
      tile = row * n + column
      tile_prev = tile - n
      if !tile_prev.negative? && @items[tile_prev] == @items[tile]
        @items[tile_prev] += @items[tile]
        @items[tile] = NO_TILE
      end
    end
    move_zeroes(-n)
  end
  return if items == @items

  @items_prev = items
  new_tile if @auto_new_tile
end

#new_tileObject



39
40
41
42
43
44
45
# File 'lib/game_2048/tiles.rb', line 39

def new_tile
  items = []
  @items.each.with_index { |tile, i| items << i if tile == NO_TILE }
  return if items.empty?

  @items[items.sample] = SecureRandom.rand(1..100) <= NEW_TILE_CHANCE ? NEW_TILE_2 : NEW_TILE_4
end

#resetObject



34
35
36
37
# File 'lib/game_2048/tiles.rb', line 34

def reset
  @items = Array.new(SIZE, NO_TILE)
  new_tile
end

#scoreObject



30
31
32
# File 'lib/game_2048/tiles.rb', line 30

def score
  @items.sum
end

#undoObject



65
66
67
68
69
70
# File 'lib/game_2048/tiles.rb', line 65

def undo
  return if @items_prev.empty?

  @items = @items_prev.dup
  @items_prev.clear
end

#win?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/game_2048/tiles.rb', line 61

def win?
  items.count { |item| item >= WIN_SUM } >= 1
end