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 +7 -0
- data/lib/gomasio.rb +15 -0
- data/lib/gomasio/board.rb +139 -0
- data/lib/gomasio/disk.rb +46 -0
- data/lib/gomasio/game.rb +86 -0
- data/lib/gomasio/player.rb +9 -0
- data/lib/gomasio/version.rb +21 -0
- metadata +91 -0
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
|
data/lib/gomasio/disk.rb
ADDED
@@ -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
|
data/lib/gomasio/game.rb
ADDED
@@ -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,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: []
|