console-shogi 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +19 -0
  4. data/exe/console-shogi +7 -0
  5. data/images/active/gote/fu.png +0 -0
  6. data/images/active/gote/gin.png +0 -0
  7. data/images/active/gote/gyoku.png +0 -0
  8. data/images/active/gote/hisha.png +0 -0
  9. data/images/active/gote/kaku.png +0 -0
  10. data/images/active/gote/keima.png +0 -0
  11. data/images/active/gote/kin.png +0 -0
  12. data/images/active/gote/kyosha.png +0 -0
  13. data/images/active/gote/narigin.png +0 -0
  14. data/images/active/gote/narikei.png +0 -0
  15. data/images/active/gote/narikyo.png +0 -0
  16. data/images/active/gote/ohsho.png +0 -0
  17. data/images/active/gote/ryu.png +0 -0
  18. data/images/active/gote/tokin.png +0 -0
  19. data/images/active/gote/uma.png +0 -0
  20. data/images/active/nonepiece.png +0 -0
  21. data/images/active/sente/fu.png +0 -0
  22. data/images/active/sente/gin.png +0 -0
  23. data/images/active/sente/gyoku.png +0 -0
  24. data/images/active/sente/hisha.png +0 -0
  25. data/images/active/sente/kaku.png +0 -0
  26. data/images/active/sente/keima.png +0 -0
  27. data/images/active/sente/kin.png +0 -0
  28. data/images/active/sente/kyosha.png +0 -0
  29. data/images/active/sente/narigin.png +0 -0
  30. data/images/active/sente/narikei.png +0 -0
  31. data/images/active/sente/narikyo.png +0 -0
  32. data/images/active/sente/ohsho.png +0 -0
  33. data/images/active/sente/ryu.png +0 -0
  34. data/images/active/sente/tokin.png +0 -0
  35. data/images/active/sente/uma.png +0 -0
  36. data/images/focused/gote/fu.png +0 -0
  37. data/images/focused/gote/gin.png +0 -0
  38. data/images/focused/gote/gyoku.png +0 -0
  39. data/images/focused/gote/hisha.png +0 -0
  40. data/images/focused/gote/kaku.png +0 -0
  41. data/images/focused/gote/keima.png +0 -0
  42. data/images/focused/gote/kin.png +0 -0
  43. data/images/focused/gote/kyosha.png +0 -0
  44. data/images/focused/gote/narigin.png +0 -0
  45. data/images/focused/gote/narikei.png +0 -0
  46. data/images/focused/gote/narikyo.png +0 -0
  47. data/images/focused/gote/ohsho.png +0 -0
  48. data/images/focused/gote/ryu.png +0 -0
  49. data/images/focused/gote/tokin.png +0 -0
  50. data/images/focused/gote/uma.png +0 -0
  51. data/images/focused/nonepiece.png +0 -0
  52. data/images/focused/sente/fu.png +0 -0
  53. data/images/focused/sente/gin.png +0 -0
  54. data/images/focused/sente/gyoku.png +0 -0
  55. data/images/focused/sente/hisha.png +0 -0
  56. data/images/focused/sente/kaku.png +0 -0
  57. data/images/focused/sente/keima.png +0 -0
  58. data/images/focused/sente/kin.png +0 -0
  59. data/images/focused/sente/kyosha.png +0 -0
  60. data/images/focused/sente/narigin.png +0 -0
  61. data/images/focused/sente/narikei.png +0 -0
  62. data/images/focused/sente/narikyo.png +0 -0
  63. data/images/focused/sente/ohsho.png +0 -0
  64. data/images/focused/sente/ryu.png +0 -0
  65. data/images/focused/sente/tokin.png +0 -0
  66. data/images/focused/sente/uma.png +0 -0
  67. data/lib/console_shogi/board.rb +5 -9
  68. data/lib/console_shogi/game.rb +118 -19
  69. data/lib/console_shogi/komadai.rb +11 -9
  70. data/lib/console_shogi/new_board_builder.rb +41 -41
  71. data/lib/console_shogi/piece.rb +34 -23
  72. data/lib/console_shogi/piece_movement_checker.rb +46 -0
  73. data/lib/console_shogi/piece_mover.rb +31 -48
  74. data/lib/console_shogi/piece_mover_on_komadai.rb +30 -36
  75. data/lib/console_shogi/player.rb +5 -13
  76. data/lib/console_shogi/teban.rb +8 -0
  77. data/lib/console_shogi/terminal/cursor.rb +80 -0
  78. data/lib/console_shogi/terminal/display_area.rb +30 -0
  79. data/lib/console_shogi/terminal/operator.rb +209 -0
  80. data/lib/console_shogi/version.rb +1 -1
  81. data/lib/console_shogi.rb +6 -1
  82. metadata +105 -38
  83. data/images/gote/nonepiece.png +0 -0
  84. data/lib/console_shogi/terminal_operator.rb +0 -211
  85. /data/images/{gote/shori.png → gote_shori.png} +0 -0
  86. /data/images/{gote → nomal/gote}/fu.png +0 -0
  87. /data/images/{gote → nomal/gote}/gin.png +0 -0
  88. /data/images/{gote → nomal/gote}/gyoku.png +0 -0
  89. /data/images/{gote → nomal/gote}/hisha.png +0 -0
  90. /data/images/{gote → nomal/gote}/kaku.png +0 -0
  91. /data/images/{gote → nomal/gote}/keima.png +0 -0
  92. /data/images/{gote → nomal/gote}/kin.png +0 -0
  93. /data/images/{gote → nomal/gote}/kyosha.png +0 -0
  94. /data/images/{gote → nomal/gote}/narigin.png +0 -0
  95. /data/images/{gote → nomal/gote}/narikei.png +0 -0
  96. /data/images/{gote → nomal/gote}/narikyo.png +0 -0
  97. /data/images/{gote → nomal/gote}/ohsho.png +0 -0
  98. /data/images/{gote → nomal/gote}/ryu.png +0 -0
  99. /data/images/{gote → nomal/gote}/tokin.png +0 -0
  100. /data/images/{gote → nomal/gote}/uma.png +0 -0
  101. /data/images/{sente → nomal}/nonepiece.png +0 -0
  102. /data/images/{sente → nomal/sente}/fu.png +0 -0
  103. /data/images/{sente → nomal/sente}/gin.png +0 -0
  104. /data/images/{sente → nomal/sente}/gyoku.png +0 -0
  105. /data/images/{sente → nomal/sente}/hisha.png +0 -0
  106. /data/images/{sente → nomal/sente}/kaku.png +0 -0
  107. /data/images/{sente → nomal/sente}/keima.png +0 -0
  108. /data/images/{sente → nomal/sente}/kin.png +0 -0
  109. /data/images/{sente → nomal/sente}/kyosha.png +0 -0
  110. /data/images/{sente → nomal/sente}/narigin.png +0 -0
  111. /data/images/{sente → nomal/sente}/narikei.png +0 -0
  112. /data/images/{sente → nomal/sente}/narikyo.png +0 -0
  113. /data/images/{sente → nomal/sente}/ohsho.png +0 -0
  114. /data/images/{sente → nomal/sente}/ryu.png +0 -0
  115. /data/images/{sente → nomal/sente}/tokin.png +0 -0
  116. /data/images/{sente → nomal/sente}/uma.png +0 -0
  117. /data/images/{sente/shori.png → sente_shori.png} +0 -0
@@ -2,10 +2,10 @@
2
2
 
3
3
  module ConsoleShogi
4
4
  class Piece
5
- attr_reader :player
5
+ attr_accessor :teban
6
6
 
7
- def initialize(player: nil)
8
- @player = player
7
+ def initialize(teban: nil)
8
+ @teban = teban
9
9
  end
10
10
 
11
11
  def move
@@ -27,27 +27,19 @@ module ConsoleShogi
27
27
  end
28
28
 
29
29
  def image
30
- if player.sente?
31
- File.read("images/sente/#{self::class.name.split('::').last.downcase}.png")
32
- else
33
- File.read("images/gote/#{self::class.name.split('::').last.downcase}.png")
34
- end
35
- end
36
-
37
- def none?
38
- self::class == NonePiece
30
+ File.read("images/nomal/#{teban}/#{self::class.name.split('::').last.downcase}.png")
39
31
  end
40
32
 
41
- def kaku?
42
- self::class == Kaku
33
+ def active_image
34
+ File.read("images/active/#{teban}/#{self::class.name.split('::').last.downcase}.png")
43
35
  end
44
36
 
45
- def hisha?
46
- self::class == Hisha
37
+ def focused_image
38
+ File.read("images/focused/#{teban}/#{self::class.name.split('::').last.downcase}.png")
47
39
  end
48
40
 
49
- def kyosha?
50
- self::class == Kyosha
41
+ def none?
42
+ self::class == NonePiece
51
43
  end
52
44
 
53
45
  def fu?
@@ -57,7 +49,7 @@ module ConsoleShogi
57
49
  def moves
58
50
  ms = base_moves
59
51
 
60
- if player.sente?
52
+ if teban == Teban::SENTE
61
53
  ms
62
54
  else
63
55
  ms.map {|m| m.transform_values {|v| v * -1 } }
@@ -67,6 +59,10 @@ module ConsoleShogi
67
59
  def change_player!(player)
68
60
  @player = player
69
61
  end
62
+
63
+ def can_move_long_distance?
64
+ [Kaku, Hisha, Kyosha, PromotedPiece::Uma, PromotedPiece::Ryu].include?(self::class)
65
+ end
70
66
  end
71
67
 
72
68
  class NonePiece < Piece
@@ -76,8 +72,16 @@ module ConsoleShogi
76
72
  []
77
73
  end
78
74
 
79
- def player
80
- NonPlayer.new
75
+ def image
76
+ File.read("images/nomal/nonepiece.png")
77
+ end
78
+
79
+ def active_image
80
+ File.read("images/active/nonepiece.png")
81
+ end
82
+
83
+ def focused_image
84
+ File.read("images/focused/nonepiece.png")
81
85
  end
82
86
 
83
87
  def can_promote?
@@ -249,13 +253,20 @@ module ConsoleShogi
249
253
  end
250
254
 
251
255
  class PromotedPiece < Piece
252
- attr_reader :player, :original
256
+ attr_reader :original
253
257
 
254
258
  def initialize(original: nil)
255
- @player = original.player
256
259
  @original = original
257
260
  end
258
261
 
262
+ def teban
263
+ original.teban
264
+ end
265
+
266
+ def teban=(val)
267
+ original.teban = val
268
+ end
269
+
259
270
  def can_promote?
260
271
  false
261
272
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConsoleShogi
4
+ class PieceMovementChecker
5
+ def initialize(board:, from:, to:)
6
+ @board = board
7
+ @from = from
8
+ @to = to
9
+ end
10
+
11
+ def can_move?
12
+ return false unless board.within_range?(x: to[:x], y: to[:y])
13
+
14
+ diff = {x: to[:x] - from[:x], y: to[:y] - from[:y]}
15
+
16
+ return false if from_piece.moves.none? {|m| m[:x] == diff[:x] && m[:y] == diff[:y] }
17
+
18
+ return false if from_piece.teban == to_piece.teban
19
+
20
+ return true unless from_piece.can_move_long_distance?
21
+
22
+ distance = (diff[:x].nonzero? || diff[:y]).abs
23
+ element = [diff[:x] / distance, diff[:y] / distance]
24
+
25
+ 1.upto(distance - 1) do |d|
26
+ piece = board.fetch_piece(x: from[:x] + element[0] * d, y: from[:y] + element[1] * d)
27
+
28
+ return false unless piece.none?
29
+ end
30
+
31
+ true
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :board, :from, :to
37
+
38
+ def from_piece
39
+ @from_piece ||= board.fetch_piece(x: from[:x], y: from[:y])
40
+ end
41
+
42
+ def to_piece
43
+ @to_piece ||= board.fetch_piece(x: to[:x], y: to[:y])
44
+ end
45
+ end
46
+ end
@@ -2,79 +2,62 @@
2
2
 
3
3
  module ConsoleShogi
4
4
  class PieceMover
5
- def initialize(board:, from:)
5
+ def initialize(board:, player:, from:, to:)
6
6
  @board = board
7
- @from_piece_index = from
7
+ @player = player
8
+ @from = from
9
+ @to = to
10
+ @moved_piece = false
8
11
  end
9
12
 
10
13
  def move!
11
- return if target_piece.nil? || target_piece.none?
12
-
13
- while key = STDIN.getch
14
- if key == "\e" && STDIN.getch == "["
15
- key = STDIN.getch
16
-
17
- TerminalOperator.move_cursor(key)
18
- elsif key == "\r"
19
- to_piece_index = TerminalOperator.squares_index
20
-
21
- return unless can_move?(piece: target_piece, to_piece_index: to_piece_index)
22
-
23
- board.move_piece!(
24
- from: {x: from_piece_index[:x], y: from_piece_index[:y]},
25
- to: {x: to_piece_index[:x], y: to_piece_index[:y]}
26
- )
27
-
28
- # TODO とりあえずここに実装してしまっている。整理したい
29
- piece = board.fetch_piece(x: to_piece_index[:x], y: to_piece_index[:y])
30
- return unless can_promote?(piece, from_piece_index, to_piece_index)
31
-
32
- board.promote_piece!(x: to_piece_index[:x], y: to_piece_index[:y]) if TerminalOperator.select_promotion
14
+ @moved_piece = move_piece!
15
+ end
33
16
 
34
- return
35
- end
36
- end
17
+ def moved_piece?
18
+ @moved_piece
37
19
  end
38
20
 
39
- def can_move?(piece:, to_piece_index:)
40
- return false unless board.within_range?(x: to_piece_index[:x], y: to_piece_index[:y])
21
+ private
41
22
 
42
- diff = {x: to_piece_index[:x] - from_piece_index[:x], y: to_piece_index[:y] - from_piece_index[:y]}
23
+ attr_reader :board, :player, :from, :to
43
24
 
44
- return false if piece.moves.none? {|m| m[:x] == diff[:x] && m[:y] == diff[:y] }
25
+ def from_piece
26
+ @from_piece ||= board.fetch_piece(x: from[:x], y: from[:y])
27
+ end
45
28
 
46
- to_piece = board.fetch_piece(x: to_piece_index[:x], y: to_piece_index[:y])
29
+ def move_piece!
30
+ return false if from_piece.nil? || from_piece.none?
31
+ return false if from_piece.teban != player.teban
47
32
 
48
- return false if piece.player.teban == to_piece.player.teban
33
+ return false unless piece_movement_checker.can_move?
49
34
 
50
- return true unless piece.kaku? || piece.hisha? || piece.kyosha?
35
+ to_piece = board.fetch_piece(x: to[:x], y: to[:y])
36
+ player.capture_piece!(to_piece) unless to_piece.none?
51
37
 
52
- distance = (diff[:x].nonzero? || diff[:y]).abs
53
- element = [diff[:x] / distance, diff[:y] / distance]
38
+ board.move_piece!(
39
+ from: {x: from[:x], y: from[:y]},
40
+ to: {x: to[:x], y: to[:y]}
41
+ )
54
42
 
55
- 1.upto(distance - 1) do |d|
56
- piece = board.fetch_piece(x: from_piece_index[:x] + element[0] * d, y: from_piece_index[:y] + element[1] * d)
43
+ # TODO とりあえずここに実装してしまっている。整理したい
44
+ return true unless can_promote?(from_piece, from, to)
57
45
 
58
- return false unless piece.none?
59
- end
46
+ board.promote_piece!(x: to[:x], y: to[:y]) if Terminal::Operator.select_promotion
60
47
 
61
48
  true
62
49
  end
63
50
 
64
- private
65
-
66
- attr_reader :board, :from_piece_index
67
-
68
- def target_piece
69
- @target_piece ||= board.fetch_piece(x: from_piece_index[:x], y: from_piece_index[:y])
51
+ def piece_movement_checker
52
+ PieceMovementChecker.new(board: board, from: from, to: to)
70
53
  end
71
54
 
72
55
  def can_promote?(piece, from, to)
73
56
  return false unless piece.can_promote?
74
57
 
75
- if piece.player.sente?
58
+ if piece.teban == Teban::SENTE
76
59
  from[:y].between?(0, 2) || to[:y].between?(0, 2)
77
- elsif piece.player.gote?
60
+ elsif piece.teban == Teban::GOTE
78
61
  from[:y].between?(6, 8) || to[:y].between?(6, 8)
79
62
  end
80
63
  end
@@ -2,64 +2,58 @@
2
2
 
3
3
  module ConsoleShogi
4
4
  class PieceMoverOnKomadai
5
- def initialize(board:, komadai:, from:)
5
+ def initialize(board:, komadai:, from:, to:)
6
6
  @board = board
7
7
  @komadai = komadai
8
8
  # 駒台の index に直す必要がある
9
- @from_piece_index = from
9
+ @from = from
10
+ @to = to
11
+ @moved_piece = false
10
12
  end
11
13
 
12
- def drop!
13
- return if target_piece.nil? || target_piece.none?
14
+ def move!
15
+ @moved_piece = move_piece!
16
+ end
14
17
 
15
- while key = STDIN.getch
16
- if key == "\e" && STDIN.getch == "["
17
- key = STDIN.getch
18
+ def moved_piece?
19
+ @moved_piece
20
+ end
18
21
 
19
- TerminalOperator.move_cursor(key)
20
- elsif key == "\r"
21
- to_piece_index = TerminalOperator.squares_index
22
+ private
22
23
 
23
- return if to_piece_index[:location] != :board
24
- return unless can_drop?(piece: target_piece, to_piece_index: to_piece_index)
24
+ attr_reader :board, :komadai, :from, :to
25
25
 
26
- komadai.pick_up_piece!(from: from_piece_index)
27
- board.put_piece!(piece: target_piece, to: to_piece_index)
26
+ def move_piece!
27
+ return false if from_piece.nil? || from_piece.none?
28
28
 
29
- return
30
- end
31
- end
32
- end
29
+ # TODO ここで location の key もってるの期待してるの酷い、修正する
30
+ return false if to[:location] != :board
31
+ return false unless can_drop?(piece: from_piece, to: to)
33
32
 
34
- private
33
+ komadai.pick_up_piece!(from: from)
34
+ board.put_piece!(piece: from_piece, to: to)
35
35
 
36
- attr_reader :board, :komadai, :from_piece_index
36
+ true
37
+ end
37
38
 
38
- def target_piece
39
- @target_piece ||= komadai.fetch_piece(x: from_piece_index[:x], y: from_piece_index[:y])
39
+ def from_piece
40
+ @from_piece ||= komadai.fetch_piece(x: from[:x], y: from[:y])
40
41
  end
41
42
 
42
- def can_drop?(piece:, to_piece_index:)
43
- to_piece = board.fetch_piece(x: to_piece_index[:x], y: to_piece_index[:y])
43
+ def can_drop?(piece:, to:)
44
+ to_piece = board.fetch_piece(x: to[:x], y: to[:y])
44
45
 
45
46
  return false unless to_piece.none?
46
47
 
47
- return false if nifu?(piece, to_piece_index)
48
-
49
- can_move_next_turn?(piece, to_piece_index)
50
- end
51
-
52
- def can_move_next_turn?(piece, to_piece_index)
53
- piece_mover = PieceMover.new(board: board, from: to_piece_index)
48
+ return false if nifu?(piece, to)
54
49
 
55
- piece.moves.any? {|m|
56
- piece_mover.can_move?(piece: piece, to_piece_index: {x: to_piece_index[:x] + m[:x], y: to_piece_index[:y] + m[:y]})
57
- }
50
+ # TODO 動かせない場所に打つことはできないようにする
51
+ true
58
52
  end
59
53
 
60
- def nifu?(piece, to_piece_index)
54
+ def nifu?(piece, to)
61
55
  piece.fu? &&
62
- board.matrix.column(to_piece_index[:x]).any? {|p| p.fu? && piece.player == p.player }
56
+ board.matrix.column(to[:x]).any? {|p| p.fu? && piece.teban == p.teban }
63
57
  end
64
58
  end
65
59
  end
@@ -2,11 +2,6 @@
2
2
 
3
3
  module ConsoleShogi
4
4
  class Player
5
- module Teban
6
- SENTE = :sente
7
- GOTE = :gote
8
- end
9
-
10
5
  attr_reader :teban, :komadai
11
6
 
12
7
  def initialize(teban: nil)
@@ -27,16 +22,13 @@ module ConsoleShogi
27
22
  komadai.pieces.any? {|p| p.class == Ohsho }
28
23
  end
29
24
 
30
- def capture_piece!(piece)
31
- @komadai.expand! unless komadai.have_space?
32
-
33
- piece = piece.original if piece.promoted?
25
+ def win_image
26
+ File.read("images/#{teban}_shori.png")
27
+ end
34
28
 
35
- piece.change_player!(self)
29
+ def capture_piece!(piece)
30
+ piece.teban = teban
36
31
  komadai.put(piece: piece)
37
32
  end
38
33
  end
39
-
40
- class NonPlayer < Player
41
- end
42
34
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConsoleShogi
4
+ module Teban
5
+ SENTE = :sente
6
+ GOTE = :gote
7
+ end
8
+ end
@@ -0,0 +1,80 @@
1
+ module ConsoleShogi
2
+ module Terminal
3
+ class Cursor
4
+ module Location
5
+ NONE = :none
6
+ BOARD = :board
7
+ SENTE_KOMADAI = :sente_komadai
8
+ GOTE_KOMADAI = :gote_komadai
9
+ end
10
+
11
+ TerminalPosition = Struct.new(:x, :y)
12
+ SquaresPosition = Struct.new(:x, :y, :location)
13
+
14
+ VERTICAL_DISTANCE = 1
15
+ HORIZONTAL_DISTANCE = 2
16
+ CURSOR_DIRECTIONS = %w(A B C D)
17
+
18
+ attr_reader :terminal_position, :squares_position
19
+
20
+ def initialize(terminal_index_x: 1, terminal_index_y: 1)
21
+ @terminal_position = TerminalPosition.new(x: 1, y: 1)
22
+ @squares_position = SquaresPosition.new(**calculate_squares_position)
23
+ end
24
+
25
+ def move(direction)
26
+ return unless CURSOR_DIRECTIONS.include?(direction)
27
+
28
+ distance =
29
+ case direction
30
+ when 'A', 'B'
31
+ VERTICAL_DISTANCE
32
+ when 'C', 'D'
33
+ HORIZONTAL_DISTANCE
34
+ end
35
+
36
+ print "\e[#{distance}#{direction}"
37
+
38
+ update_terminal_position!
39
+ end
40
+
41
+ private
42
+
43
+ def update_terminal_position!
44
+ positions = fetch_cursor_position_in_stdin
45
+
46
+ @terminal_position = TerminalPosition.new(x: positions[2].to_i, y: positions[1].to_i)
47
+ @squares_position = SquaresPosition.new(**calculate_squares_position)
48
+ end
49
+
50
+ def calculate_squares_position
51
+ case terminal_position.to_h
52
+ in x: 1..18, y: 1..9
53
+ {x: (terminal_position.x - 1) / HORIZONTAL_DISTANCE, y: terminal_position.y - 1, location: Location::BOARD}
54
+ in x: 21..38, y: 1..3
55
+ {x: (terminal_position.x - 21) / HORIZONTAL_DISTANCE, y: terminal_position.y - 1, location: Location::GOTE_KOMADAI}
56
+ in x: 21..38, y: 7..9
57
+ {x: (terminal_position.x - 21) / HORIZONTAL_DISTANCE, y: terminal_position.y - 7, location: Location::SENTE_KOMADAI}
58
+ else
59
+ {x: (terminal_position.x - 1) / HORIZONTAL_DISTANCE, y: terminal_position.y - 1, location: Location::NONE}
60
+ end
61
+ end
62
+
63
+ def fetch_cursor_position_in_stdin
64
+ stdout = ''
65
+
66
+ $stdin.raw do |stdin|
67
+ $stdout << "\e[6n"
68
+ $stdout.flush
69
+
70
+ # NOTE \e[n;mR という形式で現在位置が返ってくる
71
+ while (c = stdin.getc) != 'R'
72
+ stdout += c
73
+ end
74
+ end
75
+
76
+ stdout.match /(\d+);(\d+)/
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,30 @@
1
+ module ConsoleShogi
2
+ module Terminal
3
+ module DisplayArea
4
+ module Board
5
+ START_INDEX = {x: 1, y: 1}
6
+ END_INDEX = {x: 18, y: 9}
7
+ RANGE = {x: Range.new(START_INDEX[:x], END_INDEX[:x]), y: Range.new(START_INDEX[:y], END_INDEX[:y])}
8
+ end
9
+
10
+ module Komadai
11
+ module Gote
12
+ START_INDEX = {x: 21, y: 1}
13
+ END_INDEX = {x: 38, y: 3}
14
+ RANGE = {x: Range.new(START_INDEX[:x], END_INDEX[:x]), y: Range.new(START_INDEX[:y], END_INDEX[:y])}
15
+ end
16
+
17
+ module Sente
18
+ START_INDEX = {x: 21, y: 7}
19
+ END_INDEX = {x: 38, y: 9}
20
+ RANGE = {x: Range.new(START_INDEX[:x], END_INDEX[:x]), y: Range.new(START_INDEX[:y], END_INDEX[:y])}
21
+ end
22
+ end
23
+
24
+ module OutSide
25
+ START_INDEX = {x: 10, y: 1}
26
+ RANGE = {x: Range.new(START_INDEX[:x], nil), y: Range.new(START_INDEX[:y], nil)}
27
+ end
28
+ end
29
+ end
30
+ end