Class: EightyOne::Board
- Inherits:
-
Object
- Object
- EightyOne::Board
- Includes:
- Helper
- Defined in:
- lib/eighty_one/board.rb
Defined Under Namespace
Classes: Movement
Class Method Summary collapse
Instance Method Summary collapse
- #[](col, row) ⇒ Object (also: #at)
- #[]=(col, row, value) ⇒ Object
- #can_move_to_any_place?(piece, col, row) ⇒ Boolean
- #capture(piece) ⇒ Object
- #dests_from(col, row) ⇒ Object
- #double_fu?(piece, col, row) ⇒ Boolean
- #encode ⇒ Object
- #gote_hands ⇒ Object
- #initial_state ⇒ Object
-
#initialize ⇒ Board
constructor
A new instance of Board.
- #inside?(col, row) ⇒ Boolean
- #move_from(col, row) ⇒ Object
- #place(piece, col, row) ⇒ Object
- #placeable?(piece, col, row, from_hand = false) ⇒ Boolean
- #row(row) ⇒ Object
- #sente_hands ⇒ Object
- #to_csi ⇒ Object
- #to_s ⇒ Object
Methods included from Helper
Constructor Details
#initialize ⇒ Board
Returns a new instance of Board.
5 6 7 8 |
# File 'lib/eighty_one/board.rb', line 5 def initialize @board = Array.new(81) @hands = Struct.new(:sente, :gote).new([], []) end |
Class Method Details
.decode(code) ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/eighty_one/board.rb', line 131 def self.decode(code) board = Board.new (board_map, pieces) = code.unpack('a21a*') (on_board, hands) = pieces.split(?/).map{|x| x.chars.each_slice(3).map(&:join) } code[0,21].to_i(16).to_s(2).chars.each_slice(9).with_index do |row, y| row.each_with_index do |cell, x| board[9 - x, y + 1] = Piece.decode(on_board.shift) if cell == '1' end end hands.map{|s| Piece.decode(s) }.each do |piece| case piece.turn when :sente board.sente_hands << piece when :gote board.gote_hands << piece end end board end |
Instance Method Details
#[](col, row) ⇒ Object Also known as: at
63 64 65 |
# File 'lib/eighty_one/board.rb', line 63 def [](col, row) @board[(row - 1) * 9 + 9 - col] end |
#[]=(col, row, value) ⇒ Object
57 58 59 60 61 |
# File 'lib/eighty_one/board.rb', line 57 def []=(col, row, value) assert(inside?(col, row)) assert(value.nil? || Piece === value) @board[(row - 1) * 9 + 9 - col] = value end |
#can_move_to_any_place?(piece, col, row) ⇒ Boolean
47 48 49 |
# File 'lib/eighty_one/board.rb', line 47 def can_move_to_any_place?(piece, col, row) !([:FU, :KY].include?(piece.face.symbol) && (piece.sente? ? col == 1 : col == 9)) end |
#capture(piece) ⇒ Object
103 104 105 |
# File 'lib/eighty_one/board.rb', line 103 def capture(piece) @hands[piece.turn] << piece end |
#dests_from(col, row) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/eighty_one/board.rb', line 81 def dests_from(col, row) piece = self.at(col, row) assert(Piece === piece) dest = Proc.new{|(c, r)| [col + c, piece.sente? ? row - r : row + r] } piece.face.movements.map do |m| if EightyOne::Faces::Direction === m captured = false m.map{|p| dest[p] }.take_while do |p| (!captured && placeable?(piece, *p)).tap do |x| captured = x && self.at(*p) end end else dest[m].yield_self{|p| placeable?(piece, *p) ? [p] : [] } end end.flatten(1) end |
#double_fu?(piece, col, row) ⇒ Boolean
43 44 45 |
# File 'lib/eighty_one/board.rb', line 43 def double_fu?(piece, col, row) piece.face.symbol == :FU && (1..9).any?{|i| self[i, row]&.yield_self{|p| p.face.symbol == :FU && p.turn == piece.turn } } end |
#encode ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/eighty_one/board.rb', line 117 def encode board_map = (0..81).step(4).map do |i| @board.slice(i, 4).map.with_index{|piece, i| (piece ? 1 : 0) << (3 - i) }.sum.to_s(16) end.join on_board = (1..9).map do |row| row(row).compact.map(&:to_s).join end.join hands = @hands.sente.map(&:to_s).join + @hands.gote.map(&:to_s).join board_map + on_board + ?/ + hands end |
#gote_hands ⇒ Object
71 72 73 |
# File 'lib/eighty_one/board.rb', line 71 def gote_hands @hands.gote end |
#initial_state ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/eighty_one/board.rb', line 10 def initial_state (1..9).each do |i| self[i, 7] = Pieces::Fu.new(:sente) self[i, 3] = Pieces::Fu.new(:gote) end [1, 9].each do |i| self[i, 9] = Pieces::Ky.new(:sente) self[i, 1] = Pieces::Ky.new(:gote) end [2, 8].each do |i| self[i, 9] = Pieces::Ke.new(:sente) self[i, 1] = Pieces::Ke.new(:gote) end [3, 7].each do |i| self[i, 9] = Pieces::Gi.new(:sente) self[i, 1] = Pieces::Gi.new(:gote) end [4, 6].each do |i| self[i, 9] = Pieces::Ki.new(:sente) self[i, 1] = Pieces::Ki.new(:gote) end self[2, 8] = Pieces::Ka.new(:sente) self[8, 2] = Pieces::Ka.new(:gote) self[8, 8] = Pieces::Hi.new(:sente) self[2, 2] = Pieces::Hi.new(:gote) self[5, 9] = Pieces::Ou.new(:sente) self[5, 1] = Pieces::Ou.new(:gote) end |
#inside?(col, row) ⇒ Boolean
39 40 41 |
# File 'lib/eighty_one/board.rb', line 39 def inside?(col, row) 1 <= row && 9 >= row && 1 <= col && 9 >= col end |
#move_from(col, row) ⇒ Object
99 100 101 |
# File 'lib/eighty_one/board.rb', line 99 def move_from(col, row) Movement.new(self, col, row) end |
#place(piece, col, row) ⇒ Object
107 108 109 110 111 112 113 114 115 |
# File 'lib/eighty_one/board.rb', line 107 def place(piece, col, row) dest = self.at(col, row) if dest assert(Piece === dest) assert(dest.turn != piece.turn) capture(dest.reset(piece.turn)) end self[col, row] = piece end |
#placeable?(piece, col, row, from_hand = false) ⇒ Boolean
51 52 53 54 55 |
# File 'lib/eighty_one/board.rb', line 51 def placeable?(piece, col, row, from_hand = false) res = inside?(col, row) && !(self[col, row]&.turn == piece.turn) res &&= can_move_to_any_place?(piece, col, row) && !double_fu?(piece, col, row) if from_hand res end |
#row(row) ⇒ Object
77 78 79 |
# File 'lib/eighty_one/board.rb', line 77 def row(row) @board[(row - 1) * 9, 9].reverse end |
#sente_hands ⇒ Object
67 68 69 |
# File 'lib/eighty_one/board.rb', line 67 def sente_hands @hands.sente end |
#to_csi ⇒ Object
153 154 155 156 157 |
# File 'lib/eighty_one/board.rb', line 153 def to_csi (1..9).map do |i| "P#{i}" + row(i).map{|c| c ? c.to_s : ' * '}.join end.join(?\n) end |
#to_s ⇒ Object
159 160 161 |
# File 'lib/eighty_one/board.rb', line 159 def to_s self.to_csi end |