Class: Tak::Board
- Inherits:
-
Object
- Object
- Tak::Board
- Defined in:
- lib/tak/board.rb
Constant Summary collapse
- ROAD =
What constitutes a road-forming piece
{ white: %w(w Cw), black: %w(b Cb) }
Instance Attribute Summary collapse
-
#black_piece_set ⇒ Object
readonly
Returns the value of attribute black_piece_set.
-
#board ⇒ Object
Returns the value of attribute board.
-
#size ⇒ Object
Returns the value of attribute size.
-
#white_piece_set ⇒ Object
readonly
Returns the value of attribute white_piece_set.
Instance Method Summary collapse
-
#bit_board(color) ⇒ Array[Array[Integer]]
Converts the current board into a bit variant in which viable road pieces for ‘color` are represented as 1s.
-
#distribute_pieces(move) ⇒ Boolean
Distributes pieces from a stack move across the board.
-
#empty_piece_set? ⇒ Boolean
Checks to see if any piece sets are empty.
-
#flat_counts ⇒ Hash[Symbol, Integer]
Gets the current visible flat counts on the board.
-
#flat_winner ⇒ Boolean || Symbol
Returns who the flat winner is, or false if there is none yet.
-
#initialize(size, ptn = nil) ⇒ Board
constructor
Creates a new Tak Board.
-
#move!(ptn, color) ⇒ Boolean
Moves pieces according to PTN notation.
-
#pieces_at(x, y) ⇒ Array[String]
Retrieves the pieces present at a coordinate.
-
#place_piece(move, color) ⇒ Boolean
Places a piece at a given move coordinate.
-
#road_win?(color) ⇒ Boolean
Checks if a road win for ‘color` is present.
-
#square_owner(x, y) ⇒ Symbol
Checks which color player currently owns a square.
-
#to_s ⇒ Object
Consider moving this all out into a board formatter later.
Constructor Details
#initialize(size, ptn = nil) ⇒ Board
Creates a new Tak Board
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/tak/board.rb', line 19 def initialize(size, ptn = nil) @size = size @board = generate_board(ptn) @white_piece_set = Tak::PieceSet.new(board_size: size) @black_piece_set = Tak::PieceSet.new(board_size: size) @piece_sets = { white: white_piece_set, black: black_piece_set } end |
Instance Attribute Details
#black_piece_set ⇒ Object (readonly)
Returns the value of attribute black_piece_set.
7 8 9 |
# File 'lib/tak/board.rb', line 7 def black_piece_set @black_piece_set end |
#board ⇒ Object
Returns the value of attribute board.
4 5 6 |
# File 'lib/tak/board.rb', line 4 def board @board end |
#size ⇒ Object
Returns the value of attribute size.
3 4 5 |
# File 'lib/tak/board.rb', line 3 def size @size end |
#white_piece_set ⇒ Object (readonly)
Returns the value of attribute white_piece_set.
6 7 8 |
# File 'lib/tak/board.rb', line 6 def white_piece_set @white_piece_set end |
Instance Method Details
#bit_board(color) ⇒ Array[Array[Integer]]
Converts the current board into a bit variant in which viable road pieces for ‘color` are represented as 1s
75 76 77 78 79 |
# File 'lib/tak/board.rb', line 75 def bit_board(color) @board.map { |row| row.map { |cell| ROAD[color].include?(cell.last) ? 1 : 0 } } end |
#distribute_pieces(move) ⇒ Boolean
Distributes pieces from a stack move across the board
146 147 148 149 150 151 152 153 154 |
# File 'lib/tak/board.rb', line 146 def distribute_pieces(move) stack = pieces_at(*move.origin).pop(move.size) move.coordinates.each do |(x, y)| @board[x][y].push(stack.pop) end true end |
#empty_piece_set? ⇒ Boolean
Checks to see if any piece sets are empty
49 50 51 |
# File 'lib/tak/board.rb', line 49 def empty_piece_set? @piece_sets.any? { |c, piece_set| piece_set.empty? } end |
#flat_counts ⇒ Hash[Symbol, Integer]
Gets the current visible flat counts on the board
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/tak/board.rb', line 35 def flat_counts count_hash = Hash.new { |h,k| h[k] = 0 } @board.each_with_object(count_hash) do |row, counts| row.each do |cell| counts[:white] += 1 if cell.last == 'w' counts[:black] += 1 if cell.last == 'b' end end end |
#flat_winner ⇒ Boolean || Symbol
Returns who the flat winner is, or false if there is none yet
Not a fan of the Bool/Sym response, consider refactor later.
58 59 60 61 62 63 64 65 66 67 |
# File 'lib/tak/board.rb', line 58 def flat_winner return false unless empty_piece_set? white_flats, black_flats = flat_counts.values case white_flats <=> black_flats when 0 then :tie when 1 then :white when -1 then :black end end |
#move!(ptn, color) ⇒ Boolean
Moves pieces according to PTN notation
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/tak/board.rb', line 128 def move!(ptn, color) move = Tak::Move.new(ptn, self, color) return false unless move.valid? && square_owner(*move.origin) case move.type when 'movement' distribute_pieces(move) when 'placement' place_piece(move, color) end end |
#pieces_at(x, y) ⇒ Array[String]
Retrieves the pieces present at a coordinate
114 115 116 |
# File 'lib/tak/board.rb', line 114 def pieces_at(x, y) @board[x][y] end |
#place_piece(move, color) ⇒ Boolean
Places a piece at a given move coordinate
163 164 165 166 167 168 169 170 171 |
# File 'lib/tak/board.rb', line 163 def place_piece(move, color) square = pieces_at(*move.origin) return false unless square.empty? && @piece_sets[color].remove(move.piece_type) square.push(move.piece) true end |
#road_win?(color) ⇒ Boolean
Checks if a road win for ‘color` is present
86 87 88 89 90 91 92 93 94 |
# File 'lib/tak/board.rb', line 86 def road_win?(color) current_bit_board = bit_board(color) # Begin traversing through the board for potential roads. path_search(0, 0, nil, current_bit_board) || !!@size.times.find { |n| path_search(1, n, :horizontal, current_bit_board) || path_search(n, 1, :vertical, current_bit_board) } end |
#square_owner(x, y) ⇒ Symbol
Checks which color player currently owns a square
102 103 104 105 106 |
# File 'lib/tak/board.rb', line 102 def square_owner(x, y) return true if @board[x][y].empty? @board[x][y].last == 'b' ? :black : :white end |
#to_s ⇒ Object
Consider moving this all out into a board formatter later. It’d be cleaner.
May Matz forgive me for my debugging code here.
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/tak/board.rb', line 176 def to_s max_size = board.flatten(1).max.join(' ').size + 1 counts = flat_counts.map { |c, i| set = @piece_sets[c] "#{c}: #{i} flats, #{set.flats} remaining pieces, #{set.capstones} remaining capstones" }.join("\n") board_state = board.reverse.map.with_index { |row, i| row_head = " #{size - i} " row_head + row.map { |cell| "[%#{max_size}s]" % cell.join(' ') }.join(' ') }.join("\n") = ('a'..'h').take(size).map { |c| "%#{max_size + 2}s" % c }.join(' ') "#{counts}\n\n#{board_state}\n #{}" end |