console-shogi 0.2.0 → 0.4.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/README.md +21 -0
  4. data/images/active/gote/fu.png +0 -0
  5. data/images/active/gote/gin.png +0 -0
  6. data/images/active/gote/gyoku.png +0 -0
  7. data/images/active/gote/hisha.png +0 -0
  8. data/images/active/gote/kaku.png +0 -0
  9. data/images/active/gote/keima.png +0 -0
  10. data/images/active/gote/kin.png +0 -0
  11. data/images/active/gote/kyosha.png +0 -0
  12. data/images/active/gote/narigin.png +0 -0
  13. data/images/active/gote/narikei.png +0 -0
  14. data/images/active/gote/narikyo.png +0 -0
  15. data/images/active/gote/ohsho.png +0 -0
  16. data/images/active/gote/ryu.png +0 -0
  17. data/images/active/gote/tokin.png +0 -0
  18. data/images/active/gote/uma.png +0 -0
  19. data/images/active/nonepiece.png +0 -0
  20. data/images/active/sente/fu.png +0 -0
  21. data/images/active/sente/gin.png +0 -0
  22. data/images/active/sente/gyoku.png +0 -0
  23. data/images/active/sente/hisha.png +0 -0
  24. data/images/active/sente/kaku.png +0 -0
  25. data/images/active/sente/keima.png +0 -0
  26. data/images/active/sente/kin.png +0 -0
  27. data/images/active/sente/kyosha.png +0 -0
  28. data/images/active/sente/narigin.png +0 -0
  29. data/images/active/sente/narikei.png +0 -0
  30. data/images/active/sente/narikyo.png +0 -0
  31. data/images/active/sente/ohsho.png +0 -0
  32. data/images/active/sente/ryu.png +0 -0
  33. data/images/active/sente/tokin.png +0 -0
  34. data/images/active/sente/uma.png +0 -0
  35. data/images/focused/gote/fu.png +0 -0
  36. data/images/focused/gote/gin.png +0 -0
  37. data/images/focused/gote/gyoku.png +0 -0
  38. data/images/focused/gote/hisha.png +0 -0
  39. data/images/focused/gote/kaku.png +0 -0
  40. data/images/focused/gote/keima.png +0 -0
  41. data/images/focused/gote/kin.png +0 -0
  42. data/images/focused/gote/kyosha.png +0 -0
  43. data/images/focused/gote/narigin.png +0 -0
  44. data/images/focused/gote/narikei.png +0 -0
  45. data/images/focused/gote/narikyo.png +0 -0
  46. data/images/focused/gote/ohsho.png +0 -0
  47. data/images/focused/gote/ryu.png +0 -0
  48. data/images/focused/gote/tokin.png +0 -0
  49. data/images/focused/gote/uma.png +0 -0
  50. data/images/focused/nonepiece.png +0 -0
  51. data/images/focused/sente/fu.png +0 -0
  52. data/images/focused/sente/gin.png +0 -0
  53. data/images/focused/sente/gyoku.png +0 -0
  54. data/images/focused/sente/hisha.png +0 -0
  55. data/images/focused/sente/kaku.png +0 -0
  56. data/images/focused/sente/keima.png +0 -0
  57. data/images/focused/sente/kin.png +0 -0
  58. data/images/focused/sente/kyosha.png +0 -0
  59. data/images/focused/sente/narigin.png +0 -0
  60. data/images/focused/sente/narikei.png +0 -0
  61. data/images/focused/sente/narikyo.png +0 -0
  62. data/images/focused/sente/ohsho.png +0 -0
  63. data/images/focused/sente/ryu.png +0 -0
  64. data/images/focused/sente/tokin.png +0 -0
  65. data/images/focused/sente/uma.png +0 -0
  66. data/images/history_button/left.png +0 -0
  67. data/images/history_button/play.png +0 -0
  68. data/images/history_button/right.png +0 -0
  69. data/lib/console_shogi/board.rb +5 -9
  70. data/lib/console_shogi/game.rb +98 -24
  71. data/lib/console_shogi/game_history.rb +60 -0
  72. data/lib/console_shogi/grid_position.rb +6 -0
  73. data/lib/console_shogi/komadai.rb +22 -18
  74. data/lib/console_shogi/new_board_builder.rb +41 -41
  75. data/lib/console_shogi/piece.rb +39 -23
  76. data/lib/console_shogi/piece_movement_checker.rb +46 -0
  77. data/lib/console_shogi/piece_mover.rb +21 -68
  78. data/lib/console_shogi/piece_mover_from_board.rb +57 -0
  79. data/lib/console_shogi/piece_mover_from_komadai.rb +51 -0
  80. data/lib/console_shogi/player.rb +5 -13
  81. data/lib/console_shogi/teban.rb +8 -0
  82. data/lib/console_shogi/terminal/cursor.rb +74 -0
  83. data/lib/console_shogi/terminal/display_area.rb +122 -0
  84. data/lib/console_shogi/terminal/operator.rb +249 -0
  85. data/lib/console_shogi/version.rb +1 -1
  86. data/lib/console_shogi.rb +11 -3
  87. metadata +110 -39
  88. data/images/gote/nonepiece.png +0 -0
  89. data/lib/console_shogi/piece_mover_on_komadai.rb +0 -65
  90. data/lib/console_shogi/terminal_operator.rb +0 -211
  91. /data/images/{gote/shori.png → gote_shori.png} +0 -0
  92. /data/images/{gote → nomal/gote}/fu.png +0 -0
  93. /data/images/{gote → nomal/gote}/gin.png +0 -0
  94. /data/images/{gote → nomal/gote}/gyoku.png +0 -0
  95. /data/images/{gote → nomal/gote}/hisha.png +0 -0
  96. /data/images/{gote → nomal/gote}/kaku.png +0 -0
  97. /data/images/{gote → nomal/gote}/keima.png +0 -0
  98. /data/images/{gote → nomal/gote}/kin.png +0 -0
  99. /data/images/{gote → nomal/gote}/kyosha.png +0 -0
  100. /data/images/{gote → nomal/gote}/narigin.png +0 -0
  101. /data/images/{gote → nomal/gote}/narikei.png +0 -0
  102. /data/images/{gote → nomal/gote}/narikyo.png +0 -0
  103. /data/images/{gote → nomal/gote}/ohsho.png +0 -0
  104. /data/images/{gote → nomal/gote}/ryu.png +0 -0
  105. /data/images/{gote → nomal/gote}/tokin.png +0 -0
  106. /data/images/{gote → nomal/gote}/uma.png +0 -0
  107. /data/images/{sente → nomal}/nonepiece.png +0 -0
  108. /data/images/{sente → nomal/sente}/fu.png +0 -0
  109. /data/images/{sente → nomal/sente}/gin.png +0 -0
  110. /data/images/{sente → nomal/sente}/gyoku.png +0 -0
  111. /data/images/{sente → nomal/sente}/hisha.png +0 -0
  112. /data/images/{sente → nomal/sente}/kaku.png +0 -0
  113. /data/images/{sente → nomal/sente}/keima.png +0 -0
  114. /data/images/{sente → nomal/sente}/kin.png +0 -0
  115. /data/images/{sente → nomal/sente}/kyosha.png +0 -0
  116. /data/images/{sente → nomal/sente}/narigin.png +0 -0
  117. /data/images/{sente → nomal/sente}/narikei.png +0 -0
  118. /data/images/{sente → nomal/sente}/narikyo.png +0 -0
  119. /data/images/{sente → nomal/sente}/ohsho.png +0 -0
  120. /data/images/{sente → nomal/sente}/ryu.png +0 -0
  121. /data/images/{sente → nomal/sente}/tokin.png +0 -0
  122. /data/images/{sente → nomal/sente}/uma.png +0 -0
  123. /data/images/{sente/shori.png → sente_shori.png} +0 -0
@@ -1,211 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'base64'
4
- require 'tty-prompt'
5
-
6
- module ConsoleShogi
7
- class TerminalOperator
8
- class << self
9
- CursorPosition = Struct.new(:x, :y)
10
-
11
- HORIZONTAL_DISTANCE = 2
12
-
13
- KOMADAI_START_X = 21
14
- KOMADAI_GOTE_START_Y = 1
15
- KOMADAI_SENTE_START_Y = 7
16
-
17
- module EscapeSequence
18
- RESET = "\e[0m"
19
- RESET_CURSOR = "\e[1;1H"
20
- BACKGROUND_COLOR_YELLOW = "\e[43m"
21
- BACKGROUND_COLOR_GREEN = "\e[42m"
22
- TEXT_COLOR_SENTE = "\e[37m"
23
- TEXT_COLOR_GOTE = "\e[30m"
24
- end
25
-
26
- module Location
27
- NONE = :none
28
- BOARD = :board
29
- SENTE_KOMADAI = :sente_komadai
30
- GOTE_KOMADAI = :gote_komadai
31
- end
32
-
33
- def cursor_position
34
- @cursor_position ||= CursorPosition.new(x: 1, y: 1)
35
- end
36
-
37
- def image_height
38
- @image_height ||= calculate_fit_image_height
39
- end
40
-
41
- def print_board(board:, sente_komadai:, gote_komadai:)
42
- # NOTE 画面をクリア
43
- print "\e[2J"
44
-
45
- # NOTE カーソルを1行1列に移動
46
- print EscapeSequence::RESET_CURSOR
47
-
48
- board.matrix.row_vectors.each_with_index do |vector, i|
49
- vector.each_with_index do |piece, j|
50
- print_image(image: piece.image, height: image_height)
51
- end
52
-
53
- print "#{EscapeSequence::RESET}\n"
54
- end
55
-
56
- # NOTE 駒台を表示
57
- print_komadai(sente_komadai, KOMADAI_SENTE_START_Y, EscapeSequence::TEXT_COLOR_SENTE)
58
- print_komadai(gote_komadai, KOMADAI_GOTE_START_Y, EscapeSequence::TEXT_COLOR_GOTE)
59
-
60
- # NOTE back a cursor
61
- back_to_cursor
62
- end
63
-
64
- def active_piece(board:, piece_index:)
65
- back_to_cursor
66
-
67
- board.fetch_piece(x: piece_index[:x], y: piece_index[:y])
68
- end
69
-
70
- def move_cursor(key)
71
- return unless %w(A B C D).include?(key)
72
-
73
- direction =
74
- case key
75
- when 'A', 'B'
76
- key
77
- when 'C', 'D'
78
- "#{HORIZONTAL_DISTANCE}#{key}"
79
- end
80
-
81
- print "\e[#{direction}"
82
-
83
- reload_cursor_position_in_stdin!
84
- end
85
-
86
- # TODO 駒台の大きさが変わるのをどうするか考える、メソッド名考える
87
- def squares_index
88
- case cursor_position
89
- in x: 1..18, y: 1..9
90
- {x: (cursor_position.x - 1) / HORIZONTAL_DISTANCE, y: cursor_position.y - 1, location: Location::BOARD}
91
- in x: 21..38, y: 1..3
92
- {x: (cursor_position.x - 21) / HORIZONTAL_DISTANCE, y: cursor_position.y - 1, location: Location::GOTE_KOMADAI}
93
- in x: 21..38, y: 7..9
94
- {x: (cursor_position.x - 21) / HORIZONTAL_DISTANCE, y: cursor_position.y - 7, location: Location::SENTE_KOMADAI}
95
- else
96
- {x: (cursor_position.x - 1) / HORIZONTAL_DISTANCE, y: cursor_position.y - 1, location: Location::NONE}
97
- end
98
- end
99
-
100
- def select_promotion
101
- print "\e[10;1H"
102
-
103
- prompt = TTY::Prompt.new
104
-
105
- prompt.select('成りますか?', show_help: :never) {|menu|
106
- menu.choice '成る', true
107
- menu.choice '成らない', false
108
- }
109
- end
110
-
111
- def print_winner(teban)
112
- print "\e[4;7H"
113
-
114
- print_image(image: File.read("images/#{teban}/shori.png"), height: image_height * 3)
115
-
116
- print "\e[10;1H"
117
- end
118
-
119
- private
120
-
121
- IMAGE_HEIGHT_PIXEL = 240
122
-
123
- # TODO 無理やりなので、実現方法を再考する
124
- def calculate_fit_image_height
125
- start_position = fetch_cursor_position_in_stdin
126
- # NOTE NonePiece を選んでいることに意味はない
127
- print_image(image: NonePiece.new.image)
128
- end_position = fetch_cursor_position_in_stdin
129
-
130
- fixed_height = IMAGE_HEIGHT_PIXEL / (end_position[1].to_i - start_position[1].to_i)
131
-
132
- print "\e[2J"
133
- # NOTE カーソルを1行1列に移動
134
- print EscapeSequence::RESET_CURSOR
135
-
136
- fixed_height
137
- end
138
-
139
- # TODO view 用の Player 作って整理する
140
- def print_komadai(komadai, start_y, text_color)
141
- komadai.pieces.row_vectors.each_with_index do |row_pieces, i|
142
- print "\e[#{start_y + i};#{KOMADAI_START_X}H"
143
- print EscapeSequence::BACKGROUND_COLOR_YELLOW
144
- print text_color
145
-
146
- row_pieces.each do |p|
147
- print_image(image: p.image, height: image_height)
148
- end
149
-
150
- print EscapeSequence::RESET
151
- end
152
- end
153
-
154
- def fetch_cursor_position_in_stdin
155
- stdout = ''
156
-
157
- $stdin.raw do |stdin|
158
- $stdout << "\e[6n"
159
- $stdout.flush
160
-
161
- while (c = stdin.getc) != 'R'
162
- stdout += c
163
- end
164
- end
165
-
166
- stdout.match /(\d+);(\d+)/
167
- end
168
-
169
- def reload_cursor_position_in_stdin!
170
- positions = fetch_cursor_position_in_stdin
171
-
172
- @cursor_position = CursorPosition.new(x: positions[2].to_i, y: positions[1].to_i)
173
- end
174
-
175
- def back_to_cursor
176
- print "\e[#{cursor_position.y};#{cursor_position.x}H"
177
- end
178
-
179
- # TODO 画像を表示するためのメソッド、場所検討
180
- def print_image(image:, width: nil, height: nil)
181
- encoded_image = Base64.strict_encode64(image)
182
-
183
- print_osc
184
- print "1337;File=inline=1"
185
- print ";size=#{image.size}"
186
- print ";name=#{encoded_image}"
187
- print ";width=#{width}px" unless width.nil?
188
- print ";height=#{height}px" unless height.nil?
189
- print ":#{encoded_image}"
190
- print_st
191
- end
192
-
193
- def print_osc
194
- # NOTE \e] で始まるシーケンスは全てのターミナルで扱えるわけでは無い
195
- if ENV['TERM'].start_with?('screen') || ENV['TERM'].start_with?('tmux')
196
- print "\ePtmux;\e\e]"
197
- else
198
- print "\e]"
199
- end
200
- end
201
-
202
- def print_st
203
- if ENV['TERM'].start_with?('screen') || ENV['TERM'].start_with?('tmux')
204
- print "\a\e\\"
205
- else
206
- print "\a"
207
- end
208
- end
209
- end
210
- end
211
- end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes