shogi-ruby 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1e19666afd7c10c5196dd059f8fbd26b30051a95
4
+ data.tar.gz: a7c9cd4003dbf8831220a4b80a610af89487586b
5
+ SHA512:
6
+ metadata.gz: f51786284a2215ba437c801a2dcaae9a08b456d1d9227b1e0900b9325b74ed0bab0a6b080ae8789f6419585b015042f42f417dcf5df100048bacc96e97867cac
7
+ data.tar.gz: 2f751b50e67375844d25ce241d5e819859adb7caf228d51f4c64832fe7e7a16f9da262a3350f3bbbeda6290f1ae64289bb284272e203d273e21e5e820a122b34
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in shogi-ruby.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Masafumi Yokoyama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # Shogi Library for Ruby [![Build Status](https://secure.travis-ci.org/myokoym/shogi-ruby.png?branch=master)](http://travis-ci.org/myokoym/shogi-ruby)
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ gem 'shogi-ruby'
8
+
9
+ And then execute:
10
+
11
+ $ bundle
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install shogi-ruby
16
+
17
+ ## Ruby Version
18
+
19
+ Ruby 2.0.0 or later. (and 1.9.3)
20
+
21
+ ## Usage
22
+
23
+ require 'shogi'
24
+
25
+ board = Shogi::Board.new
26
+ puts board.to_csa
27
+ #=> P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
28
+ P2 * -HI * * * * * -KA *
29
+ P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
30
+ P4 * * * * * * * * *
31
+ P5 * * * * * * * * *
32
+ P6 * * * * * * * * *
33
+ P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
34
+ P8 * +KA * * * * * +HI *
35
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
36
+ P+
37
+ P-
38
+
39
+ board.move_from_csa("+7776FU")
40
+ puts board.to_csa
41
+ #=> P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
42
+ P2 * -HI * * * * * -KA *
43
+ P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
44
+ P4 * * * * * * * * *
45
+ P5 * * * * * * * * *
46
+ P6 * * +FU * * * * * *
47
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
48
+ P8 * +KA * * * * * +HI *
49
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
50
+ P+
51
+ P-
52
+
53
+ board.move_from_csa("+7776FU")
54
+ board.move_from_csa("-3334FU")
55
+ board.move_from_csa("+8822UM")
56
+ board.to_csa
57
+ #=> P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
58
+ P2 * -HI * * * * * +UM *
59
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
60
+ P4 * * * * * * -FU * *
61
+ P5 * * * * * * * * *
62
+ P6 * * +FU * * * * * *
63
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
64
+ P8 * * * * * * * +HI *
65
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
66
+ P+00KA
67
+ P-
68
+
69
+ board.move_from_csa("-3122GI")
70
+ board.move_from_csa("+0055KA")
71
+ board.to_csa
72
+ #=> P1-KY-KE-GI-KI-OU-KI * -KE-KY
73
+ P2 * -HI * * * * * -GI *
74
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
75
+ P4 * * * * * * -FU * *
76
+ P5 * * * * +KA * * * *
77
+ P6 * * +FU * * * * * *
78
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
79
+ P8 * * * * * * * +HI *
80
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
81
+ P+
82
+ P-00KA
83
+
84
+ ## Contributing
85
+
86
+ 1. Fork it
87
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
88
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
89
+ 4. Push to the branch (`git push origin my-new-feature`)
90
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ desc "Run test"
4
+ task :test do
5
+ Bundler::GemHelper.install_tasks
6
+ ruby("-rubygems", "test/run-test.rb")
7
+ end
8
+
9
+ task :default => :test
@@ -0,0 +1,169 @@
1
+ module Shogi
2
+ class Board
3
+ class Error < StandardError
4
+ end
5
+
6
+ def initialize
7
+ @position = default_position
8
+ @captured = []
9
+ end
10
+
11
+ def to_csa
12
+ csa_rows = ""
13
+
14
+ @position.each_with_index do |row, i|
15
+ csa_row = ""
16
+ row.each do |cell|
17
+ if cell == ""
18
+ csa_row << " * "
19
+ else
20
+ csa_row << cell
21
+ end
22
+ end
23
+ csa_rows << "P#{i + 1}#{csa_row}\n"
24
+ end
25
+
26
+ sente = "P+"
27
+ gote = "P-"
28
+ @captured.each do |piece|
29
+ if piece[0] == "+"
30
+ sente << "00#{piece[1..2]}"
31
+ else
32
+ gote << "00#{piece[1..2]}"
33
+ end
34
+ end
35
+ csa_rows << "#{sente}\n"
36
+ csa_rows << "#{gote}\n"
37
+
38
+ csa_rows
39
+ end
40
+
41
+ def to_usi
42
+ @position.map {|row|
43
+ usi_row = ""
44
+ space_count = 0
45
+ row.each do |cell|
46
+ if cell == ""
47
+ space_count += 1
48
+ else
49
+ if space_count > 0
50
+ usi_row << space_count.to_s
51
+ space_count = 0
52
+ end
53
+ usi = eval("Piece::#{cell[1..2]}").new.usi
54
+ if cell[0] == "-"
55
+ usi_row << usi.downcase
56
+ else
57
+ usi_row << usi
58
+ end
59
+ end
60
+ end
61
+ if space_count > 0
62
+ usi_row << space_count.to_s
63
+ space_count = 0
64
+ end
65
+ usi_row
66
+ }.join("/") << "\n"
67
+ end
68
+
69
+ def move_from_csa(csa)
70
+ unless /\A[+-](00|[1-9]{2})[1-9]{2}[A-Z]{2}\z/ =~ csa
71
+ raise Error, "Format Error"
72
+ end
73
+
74
+ unless Piece.const_defined?(csa[5..6])
75
+ raise Error, "No Defined Piece Error"
76
+ end
77
+
78
+ if csa[1..2] == "00"
79
+ before_piece = csa[0] + csa[5..6]
80
+ unless @captured.include?(before_piece)
81
+ return false
82
+ end
83
+ before_cell = before_piece
84
+ before_piece = eval("Piece::#{before_cell[1..2]}").new
85
+ else
86
+ before_x = 9 - csa[1].to_i
87
+ before_y = csa[2].to_i - 1
88
+ before_cell = @position[before_y][before_x]
89
+ return false if before_cell == ""
90
+ before_piece = eval("Piece::#{before_cell[1..2]}").new
91
+
92
+ unless csa[0] == before_cell[0]
93
+ return false
94
+ end
95
+ unless csa[5..6] == before_cell[1..2]
96
+ after_piece = eval("Piece::#{csa[5..6]}").new
97
+ unless before_piece.promoter == after_piece.class
98
+ return false
99
+ end
100
+ end
101
+ end
102
+
103
+ after_x = 9 - csa[3].to_i
104
+ after_y = csa[4].to_i - 1
105
+ after_cell = @position[after_y][after_x]
106
+ if csa[0] == after_cell[0]
107
+ return false
108
+ end
109
+
110
+ if csa[1..2] == "00"
111
+ return false unless after_cell == ""
112
+ else
113
+ if csa[0] == "+"
114
+ movement_x = after_x - before_x
115
+ movement_y = before_y - after_y
116
+ else
117
+ movement_x = before_x - after_x
118
+ movement_y = after_y - before_y
119
+ end
120
+
121
+ unless before_piece.move?(movement_x, movement_y)
122
+ return false
123
+ end
124
+ end
125
+
126
+ unless after_cell == ""
127
+ after_piece = eval("Piece::#{after_cell[1..2]}").new
128
+ if after_piece.class.const_defined?(:CHILD)
129
+ @captured << "#{csa[0]}#{after_piece.class::CHILD}"
130
+ else
131
+ @captured << "#{csa[0]}#{after_cell[1..2]}"
132
+ end
133
+ end
134
+ @position[after_y][after_x] = "#{csa[0]}#{csa[5..6]}"
135
+
136
+ if csa[1..2] == "00"
137
+ used = nil
138
+
139
+ @captured.each_with_index do |captured_piece, i|
140
+ if captured_piece == before_cell
141
+ used = @captured.delete_at(i)
142
+ break
143
+ end
144
+ end
145
+
146
+ unless used == before_cell
147
+ raise Error, "[Bug] missing piece in captured"
148
+ end
149
+ else
150
+ @position[before_y][before_x] = ""
151
+ end
152
+
153
+ true
154
+ end
155
+
156
+ private
157
+ def default_position
158
+ [["-KY", "-KE", "-GI", "-KI", "-OU", "-KI", "-GI", "-KE", "-KY"],
159
+ [ "", "-HI", "", "", "", "", "", "-KA", ""],
160
+ ["-FU", "-FU", "-FU", "-FU", "-FU", "-FU", "-FU", "-FU", "-FU"],
161
+ [ "", "", "", "", "", "", "", "", ""],
162
+ [ "", "", "", "", "", "", "", "", ""],
163
+ [ "", "", "", "", "", "", "", "", ""],
164
+ ["+FU", "+FU", "+FU", "+FU", "+FU", "+FU", "+FU", "+FU", "+FU"],
165
+ [ "", "+KA", "", "", "", "", "", "+HI", ""],
166
+ ["+KY", "+KE", "+GI", "+KI", "+OU", "+KI", "+GI", "+KE", "+KY"]]
167
+ end
168
+ end
169
+ end
data/lib/shogi/cell.rb ADDED
@@ -0,0 +1,53 @@
1
+ module Shogi
2
+ class Cell
3
+ USI_VERTICAL_LABELS = {
4
+ "1" => "a",
5
+ "2" => "b",
6
+ "3" => "c",
7
+ "4" => "d",
8
+ "5" => "e",
9
+ "6" => "f",
10
+ "7" => "g",
11
+ "8" => "h",
12
+ "9" => "i",
13
+ }
14
+
15
+ attr_reader :x, :y
16
+ attr_accessor :piece
17
+ attr_accessor :turn
18
+ def initialize(x, y, piece=nil, turn=nil)
19
+ @x = x
20
+ @y = y
21
+ @piece = piece
22
+ @turn = turn
23
+ end
24
+
25
+ def place_csa
26
+ "#{x}#{y}"
27
+ end
28
+
29
+ def place_usi
30
+ "#{x}#{USI_VERTICAL_LABELS[y]}"
31
+ end
32
+
33
+ def piece_csa
34
+ if @piece
35
+ "#{turn ? "+" : "-"}#{@piece.csa}"
36
+ else
37
+ " * "
38
+ end
39
+ end
40
+
41
+ def piece_usi
42
+ if @piece
43
+ if @turn
44
+ @piece.usi
45
+ else
46
+ @piece.usi.downcase
47
+ end
48
+ else
49
+ 1
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,17 @@
1
+ module Shogi
2
+ module Piece
3
+ class Base
4
+ attr_reader :csa, :usi, :promoter
5
+ def initialize(csa, usi, movements, promoter=nil)
6
+ @csa = csa
7
+ @usi = usi
8
+ @movements = movements
9
+ @promoter = promoter
10
+ end
11
+
12
+ def move?(width, height)
13
+ @movements.include?([width, height])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,87 @@
1
+ require "shogi/piece/base"
2
+
3
+ module Shogi
4
+ module Piece
5
+ MOVEMENTS_KI = [[ 0, 1],
6
+ [-1, 1],
7
+ [ 1, 1],
8
+ [-1, 0],
9
+ [ 1, 0],
10
+ [ 0, -1]]
11
+
12
+ class TO < Base
13
+ CSA_NAME = "TO"
14
+ USI_NAME = "+P"
15
+ MOVEMENTS = MOVEMENTS_KI
16
+ CHILD = "FU"
17
+
18
+ def initialize
19
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
20
+ end
21
+ end
22
+
23
+ class NY < Base
24
+ CSA_NAME = "NY"
25
+ USI_NAME = "+L"
26
+ MOVEMENTS = MOVEMENTS_KI
27
+ CHILD = "KY"
28
+
29
+ def initialize
30
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
31
+ end
32
+ end
33
+
34
+ class NK < Base
35
+ CSA_NAME = "NK"
36
+ USI_NAME = "+N"
37
+ MOVEMENTS = MOVEMENTS_KI
38
+ CHILD = "KE"
39
+
40
+ def initialize
41
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
42
+ end
43
+ end
44
+
45
+ class NG < Base
46
+ CSA_NAME = "NG"
47
+ USI_NAME = "+S"
48
+ MOVEMENTS = MOVEMENTS_KI
49
+ CHILD = "GI"
50
+
51
+ def initialize
52
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
53
+ end
54
+ end
55
+
56
+ class UM < Base
57
+ CSA_NAME = "UM"
58
+ USI_NAME = "+B"
59
+ MOVEMENTS = [(-8..-1).collect {|a| [a, a] },
60
+ ( 1.. 8).collect {|a| [a, a] },
61
+ (-8..-1).collect {|a| [a, -a] },
62
+ ( 1.. 8).collect {|a| [a, -a] },
63
+ [[-1, 0], [0, -1], [0, 1], [1, 0]]].flatten(1)
64
+ CHILD = "KA"
65
+
66
+ def initialize
67
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
68
+ end
69
+ end
70
+
71
+ class RY < Base
72
+ CSA_NAME = "RY"
73
+ USI_NAME = "+R"
74
+ MOVEMENTS = [(-8..-1).collect {|h| [0, h] },
75
+ ( 1.. 8).collect {|h| [0, h] },
76
+ (-8..-1).collect {|w| [w, 0] },
77
+ ( 1.. 8).collect {|w| [w, 0] },
78
+ [[-1, -1], [-1, 1], [1, -1], [1, 1]]].flatten(1)
79
+ CHILD = "HI"
80
+
81
+ def initialize
82
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
@@ -0,0 +1,116 @@
1
+ require "shogi/piece/base"
2
+ require "shogi/piece/promoter"
3
+
4
+ module Shogi
5
+ module Piece
6
+ class FU < Base
7
+ CSA_NAME = "FU"
8
+ USI_NAME = "P"
9
+ MOVEMENTS = [[0, 1]]
10
+ PROMOTER = TO
11
+
12
+ def initialize
13
+ super(CSA_NAME, USI_NAME, MOVEMENTS, PROMOTER)
14
+ end
15
+ end
16
+
17
+ class KY < Base
18
+ CSA_NAME = "KY"
19
+ USI_NAME = "L"
20
+ MOVEMENTS = [(1..8).map {|height| [0, height] }].flatten(1)
21
+ PROMOTER = NY
22
+
23
+ def initialize
24
+ super(CSA_NAME, USI_NAME, MOVEMENTS, PROMOTER)
25
+ end
26
+ end
27
+
28
+ class KE < Base
29
+ CSA_NAME = "KE"
30
+ USI_NAME = "N"
31
+ MOVEMENTS = [[-1, 2],
32
+ [ 1, 2]]
33
+ PROMOTER = NK
34
+
35
+ def initialize
36
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
37
+ end
38
+ end
39
+
40
+ class GI < Base
41
+ CSA_NAME = "GI"
42
+ USI_NAME = "S"
43
+ MOVEMENTS = [[-1, 1],
44
+ [ 0, 1],
45
+ [ 1, 1],
46
+ [-1, -1],
47
+ [ 1, -1]]
48
+ PROMOTER = NG
49
+
50
+ def initialize
51
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
52
+ end
53
+ end
54
+
55
+ class KI < Base
56
+ CSA_NAME = "KI"
57
+ USI_NAME = "G"
58
+ MOVEMENTS = [[-1, 1],
59
+ [ 0, 1],
60
+ [ 1, 1],
61
+ [-1, 0],
62
+ [ 1, 0],
63
+ [ 0, -1]]
64
+
65
+ def initialize
66
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
67
+ end
68
+ end
69
+
70
+ class KA < Base
71
+ CSA_NAME = "KA"
72
+ USI_NAME = "B"
73
+ MOVEMENTS = [(-8..-1).collect {|a| [a, a] },
74
+ ( 1.. 8).collect {|a| [a, a] },
75
+ (-8..-1).collect {|a| [a, -a] },
76
+ ( 1.. 8).collect {|a| [a, -a] }].flatten(1)
77
+ PROMOTER = UM
78
+
79
+ def initialize
80
+ super(CSA_NAME, USI_NAME, MOVEMENTS, PROMOTER)
81
+ end
82
+ end
83
+
84
+ class HI < Base
85
+ CSA_NAME = "HI"
86
+ USI_NAME = "R"
87
+ MOVEMENTS = [(-8..-1).collect {|h| [0, h] },
88
+ ( 1.. 8).collect {|h| [0, h] },
89
+ (-8..-1).collect {|w| [w, 0] },
90
+ ( 1.. 8).collect {|w| [w, 0] }].flatten(1)
91
+ PROMOTER = RY
92
+
93
+ def initialize
94
+ super(CSA_NAME, USI_NAME, MOVEMENTS, PROMOTER)
95
+ end
96
+ end
97
+
98
+ class OU < Base
99
+ CSA_NAME = "OU"
100
+ USI_NAME = "K"
101
+ MOVEMENTS = [[-1, 1],
102
+ [ 0, 1],
103
+ [ 1, 1],
104
+ [-1, 0],
105
+ [ 1, 0],
106
+ [-1, -1],
107
+ [ 0, -1],
108
+ [ 1, -1]]
109
+
110
+ def initialize
111
+ super(CSA_NAME, USI_NAME, MOVEMENTS)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
@@ -0,0 +1,3 @@
1
+ module Shogi
2
+ VERSION = "0.0.1"
3
+ end
data/lib/shogi.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "shogi/version"
2
+ require "shogi/board"
3
+ require "shogi/piece"
4
+
5
+ module Shogi
6
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'shogi/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "shogi-ruby"
8
+ spec.version = Shogi::VERSION
9
+ spec.authors = ["Masafumi Yokoyama"]
10
+ spec.email = ["myokoym@gmail.com"]
11
+ spec.summary = %q{Shogi Library for Ruby}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/myokoym/shogi-ruby"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency("test-unit")
22
+ spec.add_development_dependency("test-unit-notify")
23
+ spec.add_development_dependency("test-unit-rr")
24
+ spec.add_development_dependency("bundler", "~> 1.3")
25
+ spec.add_development_dependency("rake")
26
+ end
data/test/run-test.rb ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "test-unit"
4
+ require "test/unit/notify"
5
+ require "test/unit/rr"
6
+
7
+ base_dir = File.expand_path(File.join(File.dirname(__FILE__), ".."))
8
+ $LOAD_PATH.unshift(File.join(base_dir, "lib"))
9
+ $LOAD_PATH.unshift(File.join(base_dir, "test"))
10
+
11
+ exit Test::Unit::AutoRunner.run(true)
@@ -0,0 +1,136 @@
1
+ require "shogi/board"
2
+
3
+ class BoardTest < Test::Unit::TestCase
4
+ def setup
5
+ @board = Shogi::Board.new
6
+ end
7
+
8
+ def test_initialize
9
+ rows = @board.instance_variable_get(:@position)
10
+ assert_equal(9, rows.size)
11
+ assert_true(rows.all? {|row| row.size == 9 })
12
+ end
13
+
14
+ def test_to_csa
15
+ before_state = @board.instance_variable_get(:@position).dup
16
+ assert_equal(<<-EOT, @board.to_csa)
17
+ P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
18
+ P2 * -HI * * * * * -KA *
19
+ P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
20
+ P4 * * * * * * * * *
21
+ P5 * * * * * * * * *
22
+ P6 * * * * * * * * *
23
+ P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
24
+ P8 * +KA * * * * * +HI *
25
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
26
+ P+
27
+ P-
28
+ EOT
29
+ assert_equal(before_state, @board.instance_variable_get(:@position))
30
+ end
31
+
32
+ def test_to_usi
33
+ before_state = @board.instance_variable_get(:@position).dup
34
+ assert_equal(<<-EOT, @board.to_usi)
35
+ lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL
36
+ EOT
37
+ assert_equal(before_state, @board.instance_variable_get(:@position))
38
+ end
39
+
40
+ def test_move_from_csa
41
+ assert_raise Shogi::Board::Error do
42
+ @board.move_from_csa("+27FU")
43
+ end
44
+ assert_raise Shogi::Board::Error do
45
+ @board.move_from_csa("+2726AA")
46
+ end
47
+ assert_false(@board.move_from_csa("+2726HI"))
48
+ assert_false(@board.move_from_csa("+2827HI"))
49
+ assert_false(@board.move_from_csa("+2625FU"))
50
+ assert_false(@board.move_from_csa("+2725FU"))
51
+ assert_false(@board.move_from_csa("-4131KI"))
52
+ assert_true(@board.move_from_csa("+7776FU"))
53
+ assert_true(@board.move_from_csa("-4132KI"))
54
+ assert_true(@board.move_from_csa("+2868HI"))
55
+ assert_equal(<<-EOT, @board.to_csa)
56
+ P1-KY-KE-GI-KI-OU * -GI-KE-KY
57
+ P2 * -HI * * * * -KI-KA *
58
+ P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
59
+ P4 * * * * * * * * *
60
+ P5 * * * * * * * * *
61
+ P6 * * +FU * * * * * *
62
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
63
+ P8 * +KA * +HI * * * * *
64
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
65
+ P+
66
+ P-
67
+ EOT
68
+ end
69
+
70
+ def test_move_from_csa_at_captured
71
+ @board.move_from_csa("+7776FU")
72
+ @board.move_from_csa("-3334FU")
73
+ assert_true(@board.move_from_csa("+8822KA"))
74
+ assert_true(@board.move_from_csa("-3122GI"))
75
+ assert_equal(<<-EOT, @board.to_csa)
76
+ P1-KY-KE-GI-KI-OU-KI * -KE-KY
77
+ P2 * -HI * * * * * -GI *
78
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
79
+ P4 * * * * * * -FU * *
80
+ P5 * * * * * * * * *
81
+ P6 * * +FU * * * * * *
82
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
83
+ P8 * * * * * * * +HI *
84
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
85
+ P+00KA
86
+ P-00KA
87
+ EOT
88
+ assert_true(@board.move_from_csa("+0055KA"))
89
+ assert_equal(<<-EOT, @board.to_csa)
90
+ P1-KY-KE-GI-KI-OU-KI * -KE-KY
91
+ P2 * -HI * * * * * -GI *
92
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
93
+ P4 * * * * * * -FU * *
94
+ P5 * * * * +KA * * * *
95
+ P6 * * +FU * * * * * *
96
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
97
+ P8 * * * * * * * +HI *
98
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
99
+ P+
100
+ P-00KA
101
+ EOT
102
+ end
103
+
104
+ def test_move_from_csa_promote
105
+ @board.move_from_csa("+7776FU")
106
+ @board.move_from_csa("-3334FU")
107
+ assert_true(@board.move_from_csa("+8822UM"))
108
+ assert_equal(<<-EOT, @board.to_csa)
109
+ P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
110
+ P2 * -HI * * * * * +UM *
111
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
112
+ P4 * * * * * * -FU * *
113
+ P5 * * * * * * * * *
114
+ P6 * * +FU * * * * * *
115
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
116
+ P8 * * * * * * * +HI *
117
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
118
+ P+00KA
119
+ P-
120
+ EOT
121
+ assert_true(@board.move_from_csa("-3122GI"))
122
+ assert_equal(<<-EOT, @board.to_csa)
123
+ P1-KY-KE-GI-KI-OU-KI * -KE-KY
124
+ P2 * -HI * * * * * -GI *
125
+ P3-FU-FU-FU-FU-FU-FU * -FU-FU
126
+ P4 * * * * * * -FU * *
127
+ P5 * * * * * * * * *
128
+ P6 * * +FU * * * * * *
129
+ P7+FU+FU * +FU+FU+FU+FU+FU+FU
130
+ P8 * * * * * * * +HI *
131
+ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
132
+ P+00KA
133
+ P-00KA
134
+ EOT
135
+ end
136
+ end
data/test/test-cell.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "shogi/cell"
2
+ require "shogi/piece"
3
+
4
+ class CellTest < Test::Unit::TestCase
5
+ def setup
6
+ piece = Shogi::Piece::FU.new
7
+ @cell = Shogi::Cell.new("3", "9", piece, true)
8
+ end
9
+
10
+ def test_place_csa
11
+ assert_equal("39", @cell.place_csa)
12
+ end
13
+
14
+ def test_place_usi
15
+ assert_equal("3i", @cell.place_usi)
16
+ end
17
+
18
+ def test_piece_csa
19
+ assert_equal("+FU", @cell.piece_csa)
20
+ @cell.turn = false
21
+ assert_equal("-FU", @cell.piece_csa)
22
+ end
23
+
24
+ def test_piece_usi
25
+ assert_equal("P", @cell.piece_usi)
26
+ @cell.turn = false
27
+ assert_equal("p", @cell.piece_usi)
28
+ end
29
+ end
@@ -0,0 +1,169 @@
1
+ require "shogi/piece"
2
+
3
+ class PieceTest < Test::Unit::TestCase
4
+ def test_fu
5
+ fu = Shogi::Piece::FU.new
6
+ assert_equal("FU", fu.csa)
7
+ assert_equal("P", fu.usi)
8
+ assert_true(fu.move?(0, 1))
9
+ assert_false(fu.move?(1, 0))
10
+ end
11
+
12
+ def test_to
13
+ to = Shogi::Piece::TO.new
14
+ assert_equal("TO", to.csa)
15
+ assert_equal("+P", to.usi)
16
+ assert_true(to.move?(0, 1))
17
+ assert_true(to.move?(1, 0))
18
+ assert_false(to.move?(-1, -1))
19
+ end
20
+
21
+ def test_ky
22
+ ky = Shogi::Piece::KY.new
23
+ assert_equal("KY", ky.csa)
24
+ assert_equal("L", ky.usi)
25
+ assert_true(ky.move?(0, 1))
26
+ assert_true(ky.move?(0, 2))
27
+ assert_false(ky.move?(1, 0))
28
+ assert_false(ky.move?(0, -1))
29
+ end
30
+
31
+ def test_ny
32
+ ny = Shogi::Piece::NY.new
33
+ assert_equal("NY", ny.csa)
34
+ assert_equal("+L", ny.usi)
35
+ assert_ki(ny)
36
+ end
37
+
38
+ def test_ke
39
+ ke = Shogi::Piece::KE.new
40
+ assert_equal("KE", ke.csa)
41
+ assert_equal("N", ke.usi)
42
+ assert_true(ke.move?(-1, 2))
43
+ assert_true(ke.move?( 1, 2))
44
+ assert_false(ke.move?(0, 1))
45
+ assert_false(ke.move?(0, 2))
46
+ assert_false(ke.move?(1, 0))
47
+ assert_false(ke.move?(0,-1))
48
+ end
49
+
50
+ def test_nk
51
+ nk = Shogi::Piece::NK.new
52
+ assert_equal("NK", nk.csa)
53
+ assert_equal("+N", nk.usi)
54
+ assert_ki(nk)
55
+ end
56
+
57
+ def test_gi
58
+ gi = Shogi::Piece::GI.new
59
+ assert_equal("GI", gi.csa)
60
+ assert_equal("S", gi.usi)
61
+ assert_true(gi.move?( -1, 1))
62
+ assert_true(gi.move?( 0, 1))
63
+ assert_true(gi.move?( 1, 1))
64
+ assert_false(gi.move?(-1, 0))
65
+ assert_false(gi.move?( 1, 0))
66
+ assert_true(gi.move?( -1, -1))
67
+ assert_false(gi.move?( 0, -1))
68
+ assert_true(gi.move?( 1, -1))
69
+ end
70
+
71
+ def test_ng
72
+ ng = Shogi::Piece::NG.new
73
+ assert_equal("NG", ng.csa)
74
+ assert_equal("+S", ng.usi)
75
+ assert_ki(ng)
76
+ end
77
+
78
+ def test_ka
79
+ ka = Shogi::Piece::KA.new
80
+ assert_equal("KA", ka.csa)
81
+ assert_equal("B", ka.usi)
82
+ assert_true(ka.move?( -1, 1))
83
+ assert_true(ka.move?( -2, 2))
84
+ assert_false(ka.move?( 0, 1))
85
+ assert_true(ka.move?( 1, 1))
86
+ assert_false(ka.move?(-1, 0))
87
+ assert_false(ka.move?( 1, 0))
88
+ assert_true(ka.move?( -1, -1))
89
+ assert_false(ka.move?( 0, -1))
90
+ assert_true(ka.move?( 1, -1))
91
+ assert_true(ka.move?( 2, -2))
92
+ assert_true(ka.move?( 2, 2))
93
+ end
94
+
95
+ def test_um
96
+ um = Shogi::Piece::UM.new
97
+ assert_equal("UM", um.csa)
98
+ assert_equal("+B", um.usi)
99
+ assert_true(um.move?( -1, 1))
100
+ assert_true(um.move?( -2, 2))
101
+ assert_true(um.move?( 0, 1))
102
+ assert_true(um.move?( 1, 1))
103
+ assert_true(um.move?( -1, 0))
104
+ assert_true(um.move?( 1, 0))
105
+ assert_true(um.move?( -1, -1))
106
+ assert_true(um.move?( 0, -1))
107
+ assert_true(um.move?( 1, -1))
108
+ assert_true(um.move?( 2, -2))
109
+ assert_true(um.move?( 2, 2))
110
+ assert_false(um.move?( 1, 2))
111
+ end
112
+
113
+ def test_hi
114
+ hi = Shogi::Piece::HI.new
115
+ assert_equal("HI", hi.csa)
116
+ assert_equal("R", hi.usi)
117
+ assert_false(hi.move?(-1, 1))
118
+ assert_true(hi.move?( 0, 1))
119
+ assert_false(hi.move?( 1, 1))
120
+ assert_true(hi.move?( -1, 0))
121
+ assert_true(hi.move?( 1, 0))
122
+ assert_false(hi.move?(-1, -1))
123
+ assert_true(hi.move?( 0, -1))
124
+ assert_true(hi.move?( 0, -2))
125
+ assert_false(hi.move?( 1, -1))
126
+ end
127
+
128
+ def test_ry
129
+ ry = Shogi::Piece::RY.new
130
+ assert_equal("RY", ry.csa)
131
+ assert_equal("+R", ry.usi)
132
+ assert_true(ry.move?( -1, 1))
133
+ assert_true(ry.move?( 0, 1))
134
+ assert_true(ry.move?( 1, 1))
135
+ assert_true(ry.move?( -1, 0))
136
+ assert_true(ry.move?( 1, 0))
137
+ assert_true(ry.move?( -1, -1))
138
+ assert_true(ry.move?( 0, -1))
139
+ assert_true(ry.move?( 0, -2))
140
+ assert_true(ry.move?( 1, -1))
141
+ assert_false(ry.move?( 1, -2))
142
+ end
143
+
144
+ def test_ou
145
+ ou = Shogi::Piece::OU.new
146
+ assert_equal("OU", ou.csa)
147
+ assert_equal("K", ou.usi)
148
+ assert_true(ou.move?(-1, 1))
149
+ assert_true(ou.move?( 0, 1))
150
+ assert_true(ou.move?( 1, 1))
151
+ assert_true(ou.move?(-1, 0))
152
+ assert_true(ou.move?( 1, 0))
153
+ assert_true(ou.move?(-1, -1))
154
+ assert_true(ou.move?( 0, -1))
155
+ assert_true(ou.move?( 1, -1))
156
+ end
157
+
158
+ private
159
+ def assert_ki(piece)
160
+ assert_true(piece.move?(-1, 1))
161
+ assert_true(piece.move?( 0, 1))
162
+ assert_true(piece.move?( 1, 1))
163
+ assert_true(piece.move?(-1, 0))
164
+ assert_true(piece.move?( 1, 0))
165
+ assert_true(piece.move?( 0, -1))
166
+ assert_false(piece.move?(-1, -1))
167
+ assert_false(piece.move?( 1, -1))
168
+ end
169
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shogi-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Masafumi Yokoyama
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: test-unit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: test-unit-notify
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit-rr
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Shogi Library for Ruby
84
+ email:
85
+ - myokoym@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - .travis.yml
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - lib/shogi.rb
97
+ - lib/shogi/board.rb
98
+ - lib/shogi/cell.rb
99
+ - lib/shogi/piece.rb
100
+ - lib/shogi/piece/base.rb
101
+ - lib/shogi/piece/promoter.rb
102
+ - lib/shogi/version.rb
103
+ - shogi-ruby.gemspec
104
+ - test/run-test.rb
105
+ - test/test-board.rb
106
+ - test/test-cell.rb
107
+ - test/test-piece.rb
108
+ homepage: https://github.com/myokoym/shogi-ruby
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.0.0
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Shogi Library for Ruby
132
+ test_files:
133
+ - test/run-test.rb
134
+ - test/test-board.rb
135
+ - test/test-cell.rb
136
+ - test/test-piece.rb
137
+ has_rdoc: