shogi-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: