gomasio 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: b3b18b414c1ec3004af0fd0e784e1d548815419d
4
+ data.tar.gz: 79cf54b11214a08568923794905abd1dd441bf51
5
+ SHA512:
6
+ metadata.gz: c4e9b90bb1c2bf257e8e32d7f4697d0db71076dab5816c3e39761a000d9635c0791a50f74e702889b2080382da5a3adac061af3a639d2bf5dc64481250e8bd35
7
+ data.tar.gz: 03f06f5fac6055d8d40fa57186978ffe04789768d29e1f9083a61174d69ec73d9378a7c153637f530d033166539dc1c0142231914d6351a4bae7ca66fb9711ae
data/lib/gomasio.rb ADDED
@@ -0,0 +1,15 @@
1
+ # coding: utf-8
2
+
3
+ #
4
+ module Gomasio
5
+ ROOT_PATH = File.expand_path(File.dirname(__FILE__)) + '/gomasio/'
6
+
7
+ %w(disk board player game version).each do |file|
8
+ require ROOT_PATH + file
9
+ end
10
+
11
+ class GomasioError < StandardError; end
12
+ class GameLoopError < GomasioError; end
13
+ class InSamePlaceError < GameLoopError; end
14
+ class OutOfRangeError < GameLoopError; end
15
+ end
@@ -0,0 +1,139 @@
1
+ # coding: utf-8
2
+
3
+ #
4
+ module Gomasio
5
+ DEFAULT_BOARD_SIZE = 19
6
+
7
+ #
8
+ class Board
9
+ attr_reader :size
10
+ attr_accessor :order
11
+
12
+ #
13
+ @directions = []
14
+ Offset = Struct.new(:down, :right) do
15
+ def reverse
16
+ Offset.new(-down, -right)
17
+ end
18
+ end
19
+
20
+ #
21
+ [-1, 0, 1].repeated_permutation(2) do |right, down|
22
+ next if right == 0 && down == 0
23
+ @directions << Offset.new(right, down)
24
+ end
25
+
26
+ #
27
+ def initialize(board_size = DEFAULT_BOARD_SIZE)
28
+ @size = board_size
29
+ @range = 0..(@size - 1)
30
+ clear
31
+ end
32
+
33
+ #
34
+ def clone
35
+ instance = Board.new(@size)
36
+ instance.load(@board.clone)
37
+ instance
38
+ end
39
+
40
+ #
41
+ def clear
42
+ @board = Array.new(@size**2, Gomasio::Disk.empty)
43
+ end
44
+
45
+ #
46
+ def count
47
+ black = white = 0
48
+ (@size**2).times do |index|
49
+ next if @board[index].empty?
50
+ @board[index].black? ? black += 1 : white += 1
51
+ end
52
+ [black, white]
53
+ end
54
+
55
+ #
56
+ def full?
57
+ (@size**2).times do |index|
58
+ return false if @board[index].empty?
59
+ end
60
+ true
61
+ end
62
+
63
+ #
64
+ def [](row, col)
65
+ row, col = cleansing(row, col)
66
+ fail OutOfRangeError.new unless include?(row, col)
67
+ @board[encode(row, col)]
68
+ end
69
+
70
+ #
71
+ def mount(row: nil, col: nil, disk: nil)
72
+ row, col = cleansing(row, col)
73
+ fail OutOfRangeError.new unless include?(row, col)
74
+ fail InSamePlaceError.new unless self[row, col].empty?
75
+
76
+ @board[encode(row, col)] = disk
77
+
78
+ point = Struct.new(:row, :col)
79
+ directions = Board.instance_variable_get(:@directions)
80
+ location = directions.each_with_object(Hash.new(0)) do |diff, item|
81
+ (1..4).each do |index|
82
+ dict = point.new(row + diff.down * index, col + diff.right * index)
83
+ break unless include?(dict.row, dict.col)
84
+ break if self[dict.row, dict.col] != disk
85
+ item[diff] = index
86
+ end
87
+ end
88
+ [location, win?(location)]
89
+ end
90
+
91
+ #
92
+ def include?(row, col)
93
+ row, col = cleansing(row, col)
94
+ @range.include?(row) && @range.include?(col)
95
+ end
96
+
97
+ #
98
+ def to_matrix
99
+ Array.new(@size).map{[]}.each_with_index do |item, row|
100
+ @size.times do |col|
101
+ item << @board[encode(row,col)]
102
+ end
103
+ end
104
+ end
105
+
106
+ protected
107
+
108
+ #
109
+ def load(board)
110
+ @board = board if board.kind_of?(Array)
111
+ end
112
+
113
+ private
114
+
115
+ #
116
+ def cleansing(row, col)
117
+ [row.to_i, col.to_i]
118
+ end
119
+
120
+ #
121
+ def win?(location)
122
+ [[1, 0], [0, 1], [1, 1], [1, -1]].each do |diff|
123
+ offset = Offset.new(diff[0], diff[1])
124
+ return true if (location[offset] + location[offset.reverse] >= 4)
125
+ end
126
+ false
127
+ end
128
+
129
+ #
130
+ def encode(row, col)
131
+ row * @size + col
132
+ end
133
+
134
+ #
135
+ def decode(index)
136
+ index.divmod(@size)
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,46 @@
1
+ # coding: utf-8
2
+
3
+ #
4
+ module Gomasio
5
+ #
6
+ class Disk
7
+ include(Comparable)
8
+ #
9
+ DISC_RAW_ID = { empty: 0, black: -1, white: 1 }
10
+ #
11
+ attr_reader :raw
12
+
13
+ #
14
+ def initialize(color)
15
+ @raw = DISC_RAW_ID[color]
16
+ end
17
+
18
+ #
19
+ def <=>(other)
20
+ raw <=> other.raw
21
+ end
22
+
23
+ #
24
+ def to_s
25
+ DISC_RAW_ID.invert[@raw].to_s
26
+ end
27
+
28
+ #
29
+ def reverse
30
+ self.class.send(DISC_RAW_ID.invert[-@raw])
31
+ end
32
+
33
+ %i(white empty black).each do |color|
34
+ instance_variable_set("@#{color}", Disk.new(color))
35
+ class_eval <<-EOL
36
+ def #{color}?
37
+ self == self.class.#{color}
38
+ end
39
+
40
+ def self.#{color}
41
+ instance_variable_get("@#{color}")
42
+ end
43
+ EOL
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,86 @@
1
+ # coding: utf-8
2
+ module Gomasio
3
+ #
4
+ class Game
5
+ attr_reader :order
6
+
7
+ #
8
+ Command = Struct.new(:row, :col, :disk)
9
+
10
+ #
11
+ Status = Struct.new(:retry, :in_same, :out_range) do
12
+ def clear
13
+ @retry = false
14
+ @in_same = false
15
+ @out_range = false
16
+ end
17
+ end
18
+
19
+ #
20
+ def initialize(size: 19, order: Gomasio::Disk.black)
21
+ @board = Gomasio::Board.new(size)
22
+ @order = order
23
+
24
+ yield self if block_given?
25
+
26
+ @runloop = Fiber.new do
27
+ @board.clear
28
+ runloop
29
+ end
30
+ end
31
+
32
+ #
33
+ def <<(other)
34
+ fail ArgumentError.new unless other[:player].is_a? Gomasio::Player
35
+ fail ArgumentError.new unless other[:order].is_a? Gomasio::Disk
36
+
37
+ @players ||= {}
38
+ @players[other[:order]] = other[:player]
39
+ end
40
+
41
+ #
42
+ def size
43
+ @board.size
44
+ end
45
+
46
+ #
47
+ def ready?
48
+ @players.count == 2
49
+ end
50
+
51
+ def board
52
+ @board.to_matrix
53
+ end
54
+
55
+ #
56
+ def run
57
+ @runloop.resume
58
+ end
59
+
60
+ private
61
+
62
+ #
63
+ def runloop
64
+ @commands ||= []
65
+ status = Status.new
66
+ begin
67
+ loop do
68
+ pos = @players[@order].turn_responding(order: @order, status: status, board: @board.clone)
69
+ raise OutOfRangeError.new unless @board.include?(pos.row, pos.col)
70
+
71
+ _, win = @board.mount(row: pos.row, col: pos.col, disk: @order)
72
+ @commands << Command.new(pos.row, pos.col, @order)
73
+ status.clear
74
+
75
+ Fiber.yield(win)
76
+ @order = @order.reverse
77
+ end
78
+ rescue InSamePlaceError, OutOfRangeError => e
79
+ status.retry = true
80
+ status.in_same = true if e.is_a? InSamePlaceError
81
+ status.out_range = true if e.is_a? OutOfRangeError
82
+ retry
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,9 @@
1
+ # coding: utf-8
2
+
3
+ module Gomasio
4
+ class Player
5
+ #
6
+ def turn_responding(order: nil, status: nil, board: nil)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+
3
+ #
4
+ module Gomasio
5
+
6
+ # Current major release.
7
+ # @return [Interger]
8
+ MAJOR = 0
9
+
10
+ # Current minor release.
11
+ # @return [Integer]
12
+ MINOR = 0
13
+
14
+ # Current patch level.
15
+ # @return [Integer]
16
+ PATCH = 1
17
+
18
+ # Full release version.
19
+ # @return [String]
20
+ VERSION = [MAJOR, MINOR, PATCH].join('.').freeze
21
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gomasio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - colchicus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-11-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
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
+ description: A Gomoku library using Ruby
56
+ email: colchicus.dev@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - lib/gomasio.rb
62
+ - lib/gomasio/board.rb
63
+ - lib/gomasio/disk.rb
64
+ - lib/gomasio/game.rb
65
+ - lib/gomasio/player.rb
66
+ - lib/gomasio/version.rb
67
+ homepage: http://github.com/colchicus/gomasio
68
+ licenses:
69
+ - MIT
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 2.0.0
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 2.4.5.1
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: A Gomoku library using Ruby
91
+ test_files: []