Advertisement
Guest User

Untitled

a guest
Jul 1st, 2015
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.80 KB | None | 0 0
  1. module YWF
  2. class Board
  3. ROW_MIN = 1
  4. ROW_MAX = 9
  5. COL_MIN = 1
  6. COL_MAX = 9
  7.  
  8. WALL = -1
  9. EMPTY = 0
  10. BLACK = 1
  11. GRAY = 2
  12. WHITE = 3
  13.  
  14. Direction = [
  15. [-1, -1], [-1, 0], [-1, 1],
  16. [ 0, -1], [ 0, 1],
  17. [ 1, -1], [ 1, 0], [ 1, 1],
  18. ]
  19.  
  20. def initialize(other=nil)
  21. @board = [
  22. [WALL, WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL],
  23. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  24. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  25. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  26. [WALL, EMPTY, EMPTY, EMPTY, GRAY , BLACK, WHITE, EMPTY, EMPTY, EMPTY, WALL],
  27. [WALL, EMPTY, EMPTY, EMPTY, WHITE, GRAY , BLACK, EMPTY, EMPTY, EMPTY, WALL],
  28. [WALL, EMPTY, EMPTY, EMPTY, BLACK, WHITE, GRAY , EMPTY, EMPTY, EMPTY, WALL],
  29. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  30. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  31. [WALL, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, WALL],
  32. [WALL, WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL , WALL],
  33. ]
  34. @move = 1
  35. @turn = BLACK
  36. @token = GRAY
  37. if other
  38. copy(other)
  39. end
  40. end
  41.  
  42. attr_reader :move, :turn, :token
  43.  
  44. def opponent
  45. (@turn + 2) % 4
  46. end
  47.  
  48. def color(row, col)
  49. if (row < ROW_MIN) || (ROW_MAX < row)
  50. raise "invalid row. [row: #{row}]"
  51. end
  52. if (col < COL_MIN) || (COL_MAX < col)
  53. raise "invalid col. [col: #{col}]"
  54. end
  55. @board[row][col]
  56. end
  57.  
  58. def count(color)
  59. if (color != EMPTY) && (color != BLACK) && (color != GRAY) && (color != WHITE)
  60. raise "invalid color. [color: #{color}]"
  61. end
  62.  
  63. count = 0
  64. (ROW_MIN..ROW_MAX).each do |row|
  65. (COL_MIN..COL_MAX).each do |col|
  66. if self.color(row, col) == color
  67. count += 1
  68. end
  69. end
  70. end
  71.  
  72. count
  73. end
  74.  
  75. def playable?(row, col)
  76. if self.color(row, col) != EMPTY
  77. return false
  78. end
  79.  
  80. has_color_from?(row, col)
  81. end
  82.  
  83. def changeable?(row, col)
  84. if self.color(row, col) != GRAY
  85. return false
  86. end
  87.  
  88. if (@token != GRAY) && (@token != @turn)
  89. return false
  90. end
  91.  
  92. has_color_from?(row, col)
  93. end
  94.  
  95. def must_pass?
  96. (self.playable_places.size == 0) && (self.changeable_places.size == 0)
  97. end
  98.  
  99. def playable_places
  100. places = []
  101. (ROW_MIN..ROW_MAX).each do |row|
  102. (COL_MIN..COL_MAX).each do |col|
  103. if self.playable?(row, col)
  104. places.push [row, col]
  105. end
  106. end
  107. end
  108. places
  109. end
  110.  
  111. def changeable_places
  112. places = []
  113. if @token != opponent
  114. (ROW_MIN..ROW_MAX).each do |row|
  115. (COL_MIN..COL_MAX).each do |col|
  116. if self.changeable?(row, col)
  117. places.push [row, col]
  118. end
  119. end
  120. end
  121. end
  122. places
  123. end
  124.  
  125. def legal_actions
  126. actions = Array.new
  127. if self.must_pass?
  128. actions.push [:pass, nil]
  129. else
  130. self.playable_places.each do |place|
  131. actions.push [:play, place]
  132. end
  133. self.changeable_places.each do |place|
  134. actions.push [:change, place]
  135. end
  136. end
  137. actions
  138. end
  139.  
  140. def play(row, col)
  141. unless self.playable?(row, col)
  142. raise "not playable. [row: #{row}, col: #{col}]"
  143. end
  144.  
  145. new_board = self.class.new(self)
  146. new_board.put_piece(row, col)
  147. new_board.change_turn
  148. new_board.add_move
  149.  
  150. new_board
  151. end
  152.  
  153. def change(row, col)
  154. unless self.changeable?(row, col)
  155. raise "not changeable. [row: #{row}, col: #{col}]"
  156. end
  157.  
  158. new_board = self.class.new(self)
  159. new_board.put_piece(row, col)
  160. new_board.change_token
  161. new_board.change_turn
  162. new_board.add_move
  163.  
  164. new_board
  165. end
  166.  
  167. def pass
  168. unless self.must_pass?
  169. raise "cannot pass."
  170. end
  171.  
  172. new_board = self.class.new(self)
  173. new_board.change_turn
  174. new_board.add_move
  175.  
  176. new_board
  177. end
  178.  
  179. def game_end?
  180. if self.count(EMPTY) == 0
  181. return true
  182. end
  183.  
  184. if self.must_pass?
  185. passed = self.pass
  186. if passed.must_pass?
  187. return true
  188. end
  189. end
  190.  
  191. false
  192. end
  193.  
  194. def win?(color)
  195. if (color != BLACK) && (color != WHITE)
  196. raise "invalid color. [color: #{color}]"
  197. end
  198.  
  199. unless self.game_end?
  200. return false
  201. end
  202.  
  203. if color == BLACK
  204. (self.count(BLACK) > self.count(WHITE)) ||
  205. ((self.count(BLACK) == self.count(WHITE)) && (@token == BLACK))
  206. else
  207. (self.count(BLACK) < self.count(WHITE)) ||
  208. ((self.count(BLACK) == self.count(WHITE)) && (@token == WHITE))
  209. end
  210. end
  211.  
  212. protected
  213.  
  214. def put_piece(row, col)
  215. @board[row][col] = @turn
  216.  
  217. color_diff = (@turn == BLACK) ? -1 : +1
  218. Direction.each do |direction|
  219. if has_color_from_to?(row, col, direction)
  220. traverse_to(row, col, direction) do |step_count, traverse_row, traverse_col, traverse_color|
  221. if traverse_color == @turn
  222. break
  223. else
  224. @board[traverse_row][traverse_col] += color_diff
  225. end
  226. end
  227. end
  228. end
  229. end
  230.  
  231. def change_turn
  232. @turn = self.opponent
  233. end
  234.  
  235. def change_token
  236. @token += (@turn == BLACK) ? +1 : -1
  237. end
  238.  
  239. def add_move
  240. @move += 1
  241. end
  242.  
  243. private
  244.  
  245. def copy(other)
  246. (ROW_MIN..ROW_MAX).each do |row|
  247. (COL_MIN..COL_MAX).each do |col|
  248. @board[row][col] = other.color(row, col)
  249. end
  250. end
  251. @move = other.move
  252. @turn = other.turn
  253. @token = other.token
  254. end
  255.  
  256. def has_color_from?(row, col)
  257. Direction.each do |direction|
  258. if has_color_from_to?(row, col, direction)
  259. return true
  260. end
  261. end
  262. return false
  263. end
  264.  
  265. def has_color_from_to?(row, col, direction)
  266. traverse_to(row, col, direction) do |step_count, traverse_row, traverse_col, traverse_color|
  267. if traverse_color == @turn
  268. if step_count == 1
  269. return false
  270. else
  271. return true
  272. end
  273. end
  274. end
  275. return false
  276. end
  277.  
  278. def traverse_to(row, col, direction, &block)
  279. # NOTE:
  280. # 'traverse_to' accesses to 'WALL',
  281. # so 'color' cannot be used.
  282. traverse_row = row + direction[0]
  283. traverse_col = col + direction[1]
  284. traverse_color = @board[traverse_row][traverse_col]
  285. step_count = 1
  286. while (traverse_color != WALL) && (traverse_color != EMPTY)
  287. block.call(step_count, traverse_row, traverse_col, traverse_color)
  288. traverse_row += direction[0]
  289. traverse_col += direction[1]
  290. traverse_color = @board[traverse_row][traverse_col]
  291. step_count += 1
  292. end
  293. end
  294. end
  295.  
  296. module BoardViewer
  297. COL_INDEX = " 1 2 3 4 5 6 7 8 9"
  298. LINE = " +---+---+---+---+---+---+---+---+---+"
  299.  
  300. def view(board)
  301. puts "[#{sprintf '%03d', board.move}] turn: #{mark(board.turn)}, token: #{mark(board.token)}"
  302. puts COL_INDEX
  303. puts LINE
  304. (Board::ROW_MIN..Board::ROW_MAX).each do |row|
  305. print " #{row} "
  306. (Board::COL_MIN..Board::COL_MAX).each do |col|
  307. color = board.color(row, col)
  308. print "| #{mark(color)} "
  309. end
  310. puts "|"
  311. puts LINE
  312. end
  313. end
  314.  
  315. def mark(color)
  316. case color
  317. when Board::EMPTY
  318. " "
  319. when Board::BLACK
  320. "O"
  321. when Board::GRAY
  322. "-"
  323. when Board::WHITE
  324. "X"
  325. else
  326. raise "invalid color. [color: #{color}]"
  327. end
  328. end
  329.  
  330. module_function :view, :mark
  331. end
  332. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement