gomasio 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: 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: []