TwentyFortyEight 0.2.0 → 0.2.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 +4 -4
- data/.coveralls.yml +1 -0
- data/.travis.yml +3 -0
- data/TwentyFortyEight.gemspec +3 -1
- data/bin/2048 +1 -0
- data/lib/TwentyFortyEight.rb +1 -1
- data/lib/TwentyFortyEight/board.rb +7 -5
- data/lib/TwentyFortyEight/cli.rb +1 -1
- data/lib/TwentyFortyEight/dsl.rb +35 -3
- data/lib/TwentyFortyEight/game.rb +4 -3
- data/lib/TwentyFortyEight/logger.rb +23 -4
- data/lib/TwentyFortyEight/options.rb +1 -0
- data/lib/TwentyFortyEight/version.rb +1 -1
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f437369fa63361bbb433fd5498ef7107eca3072b
|
4
|
+
data.tar.gz: 5f1eda15fb4412d3e070a092cae332a0f22e8b60
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dae1eb27a154ce03fc9e5c2dbe0d1930745d02556e5bb0535b3455a4ac21e10fe4afc5e680f9b4b2c7045c675531c0b27bf691b2ca040e74fb13e9e57a7bd1dd
|
7
|
+
data.tar.gz: 1164df02da194b7dea1d22e6cd0ac27994b3a6fd98fa5fa2c69f7f7fff0546cf90a100fa6b5b829aa656216f54622b020cd58988730e782c6927c738e7b1af6b
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.travis.yml
CHANGED
data/TwentyFortyEight.gemspec
CHANGED
@@ -4,6 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'TwentyFortyEight/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
+
spec.required_ruby_version = '>= 2.1'
|
7
8
|
spec.name = 'TwentyFortyEight'
|
8
9
|
spec.version = TwentyFortyEight::VERSION
|
9
10
|
spec.authors = ['Sidney Liebrand']
|
@@ -18,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
18
19
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
20
|
f.match(%r{^(test|spec|features)/})
|
20
21
|
end
|
21
|
-
spec.bindir =
|
22
|
+
spec.bindir = 'bin'
|
22
23
|
spec.executables = ['2048']
|
23
24
|
spec.require_paths = ['lib']
|
24
25
|
|
@@ -26,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
26
27
|
spec.add_development_dependency 'rake', '~> 10.0'
|
27
28
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
29
|
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'coveralls'
|
29
31
|
|
30
32
|
spec.add_runtime_dependency 'curses'
|
31
33
|
spec.add_runtime_dependency 'json'
|
data/bin/2048
CHANGED
data/lib/TwentyFortyEight.rb
CHANGED
@@ -103,7 +103,7 @@ module TwentyFortyEight
|
|
103
103
|
def self.load_highscore(path = '~/.2048')
|
104
104
|
path = File.expand_path path
|
105
105
|
|
106
|
-
if File.
|
106
|
+
if File.exist? path
|
107
107
|
contents = File.read path
|
108
108
|
hsh = JSON.parse contents.start_with?('{') && contents || '{}'
|
109
109
|
else
|
@@ -4,7 +4,10 @@ module TwentyFortyEight
|
|
4
4
|
class Board
|
5
5
|
attr_reader :board, :settings
|
6
6
|
|
7
|
+
DEFAULTS = { size: 4, fill: 0, empty: 0 }
|
8
|
+
|
7
9
|
def initialize(opts = {})
|
10
|
+
opts = Options.new DEFAULTS.merge(opts)
|
8
11
|
@settings = opts
|
9
12
|
@settings[:size] = settings.board.size if settings.board?
|
10
13
|
@board = settings.board || Board.generate(settings)
|
@@ -39,15 +42,14 @@ module TwentyFortyEight
|
|
39
42
|
end
|
40
43
|
|
41
44
|
def dup
|
42
|
-
|
45
|
+
new settings.merge(board: board.dup)
|
43
46
|
end
|
44
47
|
|
45
48
|
private
|
46
49
|
|
47
|
-
def self.generate(**opts)
|
48
|
-
|
49
|
-
|
50
|
-
end
|
50
|
+
def self.generate(opts_hsh, **opts)
|
51
|
+
opts = opts_hsh.merge opts
|
52
|
+
Array.new(opts.size) { Array.new(opts.size) { opts.fill } }
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
data/lib/TwentyFortyEight/cli.rb
CHANGED
data/lib/TwentyFortyEight/dsl.rb
CHANGED
@@ -6,6 +6,7 @@ module TwentyFortyEight
|
|
6
6
|
|
7
7
|
def initialize(game, settings = {}, &block)
|
8
8
|
@callable = block
|
9
|
+
@sequence = []
|
9
10
|
@settings = settings
|
10
11
|
@game = game
|
11
12
|
end
|
@@ -15,14 +16,45 @@ module TwentyFortyEight
|
|
15
16
|
instance_eval(&@callable)
|
16
17
|
end
|
17
18
|
|
19
|
+
def sequence(*directions)
|
20
|
+
@sequence = directions.flatten.map(&:to_sym)
|
21
|
+
run_sequence
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_sequence
|
25
|
+
return @poss.shift if @poss && @poss.any?
|
26
|
+
|
27
|
+
copy = @sequence.dup
|
28
|
+
sample = game.dup
|
29
|
+
@poss = []
|
30
|
+
|
31
|
+
while (next_move = copy.shift)
|
32
|
+
unless sample.move(next_move).changed?
|
33
|
+
@poss = nil
|
34
|
+
break
|
35
|
+
end
|
36
|
+
|
37
|
+
@poss << next_move
|
38
|
+
end
|
39
|
+
|
40
|
+
@poss && @poss.shift
|
41
|
+
end
|
42
|
+
|
43
|
+
def info?(sym)
|
44
|
+
[:won?, :lost?, :changed?, :available, :score, :prev_score].include? sym
|
45
|
+
end
|
46
|
+
|
47
|
+
def info(sym)
|
48
|
+
game.send sym
|
49
|
+
end
|
50
|
+
|
18
51
|
def quit!
|
19
52
|
game.quit! && :quit
|
20
53
|
end
|
21
54
|
|
22
55
|
def method_missing(sym, *args, &block)
|
23
|
-
return
|
24
|
-
|
25
|
-
return sym if game.dup.action(sym, insert: false).changed?
|
56
|
+
return info sym if info? sym
|
57
|
+
return sym if game.dup.action(sym, insert: false).changed?
|
26
58
|
end
|
27
59
|
|
28
60
|
def respond_to_missing?(sym, *args, &block)
|
@@ -5,6 +5,7 @@ module TwentyFortyEight
|
|
5
5
|
attr_reader :id, :board, :settings, :score, :prev_score, :prev_available,
|
6
6
|
:moves, :log, :current_dir
|
7
7
|
|
8
|
+
DEFAULTS = { fill: 0, empty: 0 }.freeze
|
8
9
|
MOVES = [:up, :down, :left, :right].freeze
|
9
10
|
ACTIONS = [*MOVES, :quit].freeze
|
10
11
|
|
@@ -13,7 +14,7 @@ module TwentyFortyEight
|
|
13
14
|
@score = 0
|
14
15
|
@prev_score = 0
|
15
16
|
@moves = 0
|
16
|
-
@settings = Options.new opts.merge(rest_opts)
|
17
|
+
@settings = Options.new DEFAULTS.merge(opts.merge(rest_opts))
|
17
18
|
@board = Board.new(settings)
|
18
19
|
@prev_available = available
|
19
20
|
@current_dir = nil
|
@@ -34,7 +35,7 @@ module TwentyFortyEight
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def won?
|
37
|
-
board.flatten.max >= 2048
|
38
|
+
board.board.flatten.max >= 2048
|
38
39
|
end
|
39
40
|
|
40
41
|
def lost?
|
@@ -102,7 +103,7 @@ module TwentyFortyEight
|
|
102
103
|
end
|
103
104
|
|
104
105
|
def dup
|
105
|
-
|
106
|
+
Game.new settings.merge(board: board.to_a)
|
106
107
|
end
|
107
108
|
|
108
109
|
private
|
@@ -4,8 +4,8 @@ module TwentyFortyEight
|
|
4
4
|
class Logger
|
5
5
|
attr_reader :entries
|
6
6
|
|
7
|
-
def initialize
|
8
|
-
@entries =
|
7
|
+
def initialize(entries = [])
|
8
|
+
@entries = entries
|
9
9
|
end
|
10
10
|
|
11
11
|
def <<(info_hsh)
|
@@ -14,11 +14,30 @@ module TwentyFortyEight
|
|
14
14
|
|
15
15
|
def write!(options = {})
|
16
16
|
name = (options[:name] || "2048-#{Time.now.to_i}") + '.log.json'
|
17
|
-
path = File.expand_path(options[:path]) if options[:path]
|
18
|
-
path = File.join(Dir.pwd, name) unless options[:dir]
|
17
|
+
path = File.join File.expand_path(options[:path]), name if options[:path]
|
18
|
+
path = File.join(Dir.pwd, name) unless options[:dir] || options[:path]
|
19
19
|
path = (File.join Dir.pwd, options[:dir], name) if options[:dir]
|
20
20
|
|
21
21
|
File.open(path, 'w') { |f| f.write @entries.to_json }
|
22
22
|
end
|
23
|
+
|
24
|
+
def self.load!(path)
|
25
|
+
full_path = File.expand_path path
|
26
|
+
check_file_existence! full_path
|
27
|
+
|
28
|
+
new JSON.parse(File.read(full_path), symbolize_names: true)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.destroy!(path)
|
32
|
+
full_path = File.expand_path path
|
33
|
+
check_file_existence! full_path
|
34
|
+
File.delete full_path
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.check_file_existence!(path)
|
38
|
+
raise FileNotFound, 'Log does not exist' unless File.exist? path
|
39
|
+
end
|
40
|
+
|
41
|
+
class FileNotFound < StandardError; end
|
23
42
|
end
|
24
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: TwentyFortyEight
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sidney Liebrand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-03-
|
11
|
+
date: 2017-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
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'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: curses
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -103,6 +117,7 @@ executables:
|
|
103
117
|
extensions: []
|
104
118
|
extra_rdoc_files: []
|
105
119
|
files:
|
120
|
+
- ".coveralls.yml"
|
106
121
|
- ".gitignore"
|
107
122
|
- ".rspec"
|
108
123
|
- ".travis.yml"
|
@@ -136,7 +151,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
136
151
|
requirements:
|
137
152
|
- - ">="
|
138
153
|
- !ruby/object:Gem::Version
|
139
|
-
version: '
|
154
|
+
version: '2.1'
|
140
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
156
|
requirements:
|
142
157
|
- - ">="
|