class GameBoard
	attr_reader :board

	def initialize size=5
		@size = size
		@board = []
		@size.times{|x| 
			@board[x] = []
			@size.times{|y| @board[x][y] = 0 }
		}
		@history = []
	end

	def click x,y
		@history << [x,y]
		surround(x,y) { |m,n| 
			t = rotate m,n 
			yield m,n,t if block_given? and not t.nil?
		}
	end

	def undo
		return false if @history.size == 0
		x,y = @history.pop
		surround(x,y) { |m,n| 
			t = unrotate m,n 
			yield m,n,t if block_given? and not t.nil?
		}
		return true
	end

	def scramble
		(@size*@size).times {
			surround( rand(@size), rand(@size) ) { |m,n| 
				t = unrotate m,n 
				yield m,n,t if block_given? and not t.nil?
			}
		}
	end

	def win?
		@size.times{|x| @size.times{|y| return false if @board[x][y] != 0 }}
		return true
	end

	def to_s
		horizontal = " "+"-"*(@size*3 + 2)
		rv = "  "
		@size.times{ |x| rv << " #{x} " }
		rv << "\n"
		rv << horizontal
		rv << "\n"
		@size.times { |y|
			rv << "#{y}|"
			@size.times { |x| rv << " #{@board[x][y]} " }
			rv << "|\n"
		}
		rv << horizontal
		rv << "\n"
	end

	def clear
		@size.times{|x| @size.times{|y|
			@board[x][y] = 0
			yield x,y,0 if block_given?
		}}
		@history.clear
	end

	private
	def rotate x,y
		return nil unless (0...@size) === x and (0...@size) === y
		@board[x][y] += 1
		@board[x][y] = 0 if @board[x][y] == 4
		@board[x][y]
	end

	def unrotate x,y
		return nil unless (0...@size) === x and (0...@size) === y
		@board[x][y] -= 1
		@board[x][y] = 3 if @board[x][y] == -1 
		@board[x][y]
	end

	def surround x,y
		yield x,y
		yield x-1,y
		yield x,y-1
		yield x+1,y
		yield x,y+1
	end	
end
