1. Technology
You can opt-out at any time. Please refer to our privacy policy for contact information.

The Board Class

By

The following article is part of a series.  For more articles in this series, see Cloning the Game 2048 in Ruby.  For the complete and final code, see the gist.

Now that we have the algorithm sorted out, the ability to create two dimensional arrays and to rotate two dimensional arrays, it's time to start looking at the actual code. The code can be found on this gist, be we'll be pasting relevant parts of it here into the article. So if you want to see it in action or play around with it, get it from the gist.

The Board Class

The board class represents a standard 4x4 2048 board. It has the ability to do boards of any dimension, but if you don't specify a size you get a 4x4 board. It has three main members, the @board instance variable holds a row-indexed two dimensional array representing the board. By default, all tiles are 0, which show as blank in the final game. Second there's @size, which is not strictly necessary since we can just look at the size of the array, but since we access it often, we use @size to cut down on line noise in the program. And finally there's @score, which tracks the score as the game is played.


class Board
	attr_accessor :board, :size, :score

	# … 

	def initialize(size=4)
		@board = Array.new(size) { Array.new(size,0) }
		@size = size
		@score = 0

		spawn_new  # This method isn't discussed yet
		spawn_new  # We call it twice to spawn 2 starting tiles
	end

	# …

 

Displaying the Board

Before any serious work was started on the board, the code to display the board was written. Why? It's so much easier to debug when you can see what it's supposed to look like. Nothing fancy here, we're just iterating over the board and stuffing it into a string.


def to_s
	cell_size = @board.flatten.max.to_s.length + 2
	str = StringIO.new
	str.puts "Score: #{@score}"

	str.puts format_border(cell_size)

	(0...@size).each do|row|
		str.puts format_row(cell_size, row)
		str.puts format_border(cell_size)
	end

	str.string
end

 

The cell size is the longest number (in string form) plus 2 (so there's always a space on either side). A StringIO object is used, which is useful for building strings. Since we're not directly outputting the string here (this is the to_s method), we can still use the familiar puts type methods and still build a string.

The format_border method is rather self-explanatory. It just makes a string with a nice looking border between the cells and on the top and bottom of the board.


def format_border(cell_size)
	"+" + (['-' * cell_size] * @board.size).join('+') + "+"
end

 

The format_row method is a tiny bit more complicated. It iterates over the row and, if the cell is a zero, output spaces for that row, and if the cell is a number, center that number in the string. Then join all the string with | characters and put an extra two | characters on the ends.


def format_row(cell_size, row)
	row_strings = @board[row].map do|cell|
		if cell == 0
			" " * cell_size
		else
			padding_left = (cell_size - cell.to_s.length) / 2
			padding_right = cell_size - padding_left - cell.to_s.length

			(" " * padding_left) + cell.to_s + (" " * padding_right)
		end
	end

	"|" + row_strings.join('|') + "|"
end

 

More could be done here. You could make the cells taller, for example, or make them colored based on value, but this is the bare bones. A formatted board looks like this, which is adequate for this example code.


+----+----+----+----+
|    | 4  | 8  | 16 |
+----+----+----+----+
|    |    | 32 | 2  |
+----+----+----+----+
|    |    | 2  | 4  |
+----+----+----+----+
|    |    |    | 2  |
+----+----+----+----+

 

There's more!  To keep reading, see the next article in this series: The Core Algorithm.

  1. About.com
  2. Technology
  3. Ruby
  4. Tutorials
  5. Writing a 2048 Clone in Ruby
  6. The Board Class

©2014 About.com. All rights reserved.