console-tetris 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ea4f8df04182b22ced1835e19e5a7af68e68a2e
4
+ data.tar.gz: 368d6f29f2b770bc4ea68b365abedd5a4d4b7f74
5
+ SHA512:
6
+ metadata.gz: 90e1228d4f0373fc82fd2b2ca02d3cba89ddfd15d532d6209f0816579306b32b780efceb1d71e6328dda0af5f1870edcd48b7464e42f537e2f909442757a9872
7
+ data.tar.gz: 8a624b0564031794f2d6068987f82ae23c49cab44f13e11195193a56aee0e27ec7536985bf8204e572db3ef20391af50a5734c79cb848df92bce08da22c05ee2
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in console-tetris.gemspec
4
+ gemspec
@@ -0,0 +1,36 @@
1
+ # Console::Tetris
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/console_tetris`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'console-tetris'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install console-tetris
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/console-tetris. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "console_tetris"
5
+
6
+ ConsoleTetris.start
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'console_tetris/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "console-tetris"
8
+ spec.version = ConsoleTetris::VERSION
9
+ spec.authors = ["pekepek"]
10
+ spec.email = ["ishihata@33i.co.jp"]
11
+
12
+ spec.summary = %q{you can play Tetris}
13
+ spec.description = %q{you can play Tetris}
14
+ spec.homepage = "https://github.com/pekepek/console-tetris"
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.13"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_dependency 'io-console'
27
+ end
@@ -0,0 +1,78 @@
1
+ require_relative './console_tetris/version'
2
+ require_relative './console_tetris/tetrimino'
3
+ require_relative './console_tetris/background_board'
4
+ require 'io/console'
5
+
6
+ class ConsoleTetris
7
+ BLOCK_TYPES = %w(i j l o s t z)
8
+
9
+ def self.start
10
+ @background_board = BackgroundBoard.new
11
+
12
+ type = "type_#{BLOCK_TYPES.sample}"
13
+ @tetrimino = Tetrimino.new(block_type: type)
14
+
15
+ @background_board.print_block(@tetrimino.block)
16
+
17
+ Thread.new do
18
+ catch :gameover do
19
+ loop do
20
+ loop.with_index do |_, i|
21
+ @tetrimino.down
22
+
23
+ @background_board.print_block(@tetrimino.block) unless @background_board.overlap?(@tetrimino.block)
24
+
25
+ sleep 0.1
26
+
27
+ if @tetrimino.bottom_edge? || @background_board.overlap?(@tetrimino.block)
28
+ throw :gameover if i == 0
29
+
30
+ @tetrimino.back_vertically if @background_board.overlap?(@tetrimino.block)
31
+
32
+ break
33
+ end
34
+ end
35
+
36
+ @background_board.stack!(@tetrimino.block)
37
+ @background_board.remove_filled_line!
38
+
39
+ @background_board.print_block(@tetrimino.block)
40
+
41
+ type = "type_#{BLOCK_TYPES.sample}"
42
+ @tetrimino = Tetrimino.new(block_type: type)
43
+ end
44
+ end
45
+
46
+ @background_board.print_gameover
47
+
48
+ exit
49
+ end
50
+
51
+ while (str = STDIN.getch) != "\C-c"
52
+ case str
53
+ when '.'
54
+ next if @tetrimino.right_edge?
55
+
56
+ @tetrimino.move_right
57
+ @tetrimino.back_horizontally if @background_board.overlap?(@tetrimino.block)
58
+ when 'z'
59
+ next if @tetrimino.left_edge?
60
+
61
+ @tetrimino.move_left
62
+ @tetrimino.back_horizontally if @background_board.overlap?(@tetrimino.block)
63
+ when "\r"
64
+ @tetrimino.rotate
65
+
66
+ loop do
67
+ if @background_board.overlap?(@tetrimino.block)
68
+ @tetrimino.up
69
+ else
70
+ break
71
+ end
72
+ end
73
+ end
74
+
75
+ @background_board.print_block(@tetrimino.block)
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,85 @@
1
+ class ConsoleTetris
2
+ class BackgroundBoard
3
+ attr_accessor :point
4
+
5
+ BOARD_SIZE = {x: 10, y: 20}
6
+ GAMEOVER = <<-'EOS'
7
+ _____ __ __ _____ ______ ________ _____
8
+ / ____| /\ | \/ || ___| / __ \ \ / / ____|| __ \
9
+ | | __ / \ | \ / || |__ | | | \ \ / /| |__ | |__) |
10
+ | | |_ | / /\ \ | |\/| || __| | | | |\ \/ / | __| | _ /
11
+ | |__| |/ ____ \| | | || |___ | |__| | \ / | |____ | | \ \
12
+ \_____/_/ \_\_| |_||_____| \____/ \/ |______||_| \_\
13
+ EOS
14
+
15
+ class << self
16
+ def blank_board
17
+ BOARD_SIZE[:y].times.map { blank_line }
18
+ end
19
+
20
+ def blank_line
21
+ Array.new(BOARD_SIZE[:x]).fill(0)
22
+ end
23
+ end
24
+
25
+ def initialize
26
+ @board = self.class.blank_board
27
+ @point = 0
28
+ end
29
+
30
+ def stack!(block)
31
+ @board = @board.map.with_index {|a, i| a.map.with_index {|e, j| e | block[i][j] } }
32
+ end
33
+
34
+ def overlap?(block)
35
+ @board.map.with_index {|a, i| a.map.with_index {|e, j| e & block[i][j] } }.any? {|a| a.any? {|e| e > 0 } }
36
+ end
37
+
38
+ def remove_filled_line!
39
+ @board.reject! {|a| a.all? {|e| e == 1 } }
40
+
41
+ remove_size = BOARD_SIZE[:y] - @board.count
42
+
43
+ @point = @point + remove_size * 1000
44
+ remove_size.times { @board.unshift(self.class.blank_line) }
45
+ end
46
+
47
+ def print_block(block)
48
+ print "\e[2J"
49
+ print "\e[1;1H"
50
+
51
+ print "\e[G _____________ \n"
52
+ print "\e[G| #{@point.to_s.rjust(11, ' ')} |\n"
53
+ print "\e[G ‾‾‾‾‾‾‾‾‾‾‾‾‾ \n"
54
+
55
+ print "\e[G"
56
+ print '__' * BOARD_SIZE[:x]
57
+ print "\n"
58
+
59
+ @board.map.with_index {|a, i| a.map.with_index {|e, j| e | block[i][j] } }.each do |elements|
60
+ print "\e[G"
61
+
62
+ elements.each do |el|
63
+ print case el
64
+ when 0
65
+ ' '
66
+ when 1
67
+ '[]'
68
+ end
69
+ end
70
+
71
+ print "|\n"
72
+ end
73
+
74
+ print "\e[G"
75
+ print '‾‾' * BOARD_SIZE[:x]
76
+ end
77
+
78
+ def print_gameover
79
+ print "\e[2J"
80
+ print "\e[1;1H"
81
+ print "\e[G#{point.to_s.rjust(7, ' ')} 点!!!!\n"
82
+ print GAMEOVER.gsub(/^/, "\e[G")
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,218 @@
1
+ require_relative './background_board'
2
+
3
+ class ConsoleTetris
4
+ class Tetrimino
5
+ def initialize(x = 0, y = 0, degree = 0, block_type:)
6
+ @x_coordinate = x
7
+ @y_coordinate = y
8
+ @degree = degree
9
+ @block_type = block_type
10
+ @previous_state = {x: x, y: y, degree: degree}
11
+ end
12
+
13
+ def down
14
+ @previous_state[:y] = @y_coordinate
15
+
16
+ @y_coordinate += 1
17
+ end
18
+
19
+ def up
20
+ @previous_state[:y] = @y_coordinate
21
+
22
+ @y_coordinate -= 1
23
+ end
24
+
25
+ def move_right
26
+ @previous_state[:x] = @x_coordinate
27
+
28
+ @x_coordinate += 1
29
+ end
30
+
31
+ def move_left
32
+ @previous_state[:x] = @x_coordinate
33
+
34
+ @x_coordinate -= 1
35
+ end
36
+
37
+ def back_vertically
38
+ @y_coordinate = @previous_state[:y]
39
+ end
40
+
41
+ def back_horizontally
42
+ @x_coordinate = @previous_state[:x]
43
+ end
44
+
45
+ def rotate
46
+ before_block = block
47
+
48
+ @previous_state = {x: @x_coordinate, y: @y_coordinate, degree: @degree}
49
+ @degree += 90
50
+ @degree = 0 if @degree == 360
51
+
52
+ @y_coordinate = @y_coordinate - before_block.max.count(1).times.count {|i| BackgroundBoard.blank_board[@y_coordinate + i].nil? }
53
+ @x_coordinate = @x_coordinate - before_block.map {|a| a.any? {|e| e == 1} ? 1 : 0 }.count(1).times.count {|i| BackgroundBoard.blank_board[@y_coordinate][@x_coordinate + i].nil? }
54
+
55
+ @y_coordinate = 0 if @y_coordinate.negative?
56
+ @x_coordinate = 0 if @x_coordinate.negative?
57
+ end
58
+
59
+ def block
60
+ send(@block_type)
61
+ end
62
+
63
+ def left_edge?
64
+ block.any? {|a| a.first == 1 }
65
+ end
66
+
67
+ def right_edge?
68
+ block.any? {|a| a.last == 1 }
69
+ end
70
+
71
+ def bottom_edge?
72
+ block.last.any? {|e| e == 1 }
73
+ end
74
+
75
+ private
76
+
77
+ def type_j
78
+ board = BackgroundBoard.blank_board
79
+
80
+ case @degree
81
+ when 0
82
+ 4.times {|i| board[@y_coordinate][@x_coordinate + i] = 1 }
83
+
84
+ board[@y_coordinate + 1][@x_coordinate + 3] = 1
85
+ when 90
86
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate + 1] = 1 }
87
+
88
+ board[@y_coordinate + 3][@x_coordinate] = 1
89
+ when 180
90
+ 4.times {|i| board[@y_coordinate][@x_coordinate + i] = 1 }
91
+
92
+ board[@y_coordinate - 1][@x_coordinate] = 1
93
+ when 270
94
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate] = 1 }
95
+
96
+ board[@y_coordinate][@x_coordinate + 1] = 1
97
+ end
98
+
99
+ board
100
+ end
101
+
102
+ def type_l
103
+ board = BackgroundBoard.blank_board
104
+
105
+ case @degree
106
+ when 0
107
+ 4.times {|i| board[@y_coordinate][@x_coordinate + i] = 1 }
108
+
109
+ board[@y_coordinate + 1][@x_coordinate] = 1
110
+ when 90
111
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate + 1] = 1 }
112
+
113
+ board[@y_coordinate][@x_coordinate] = 1
114
+ when 180
115
+ 4.times {|i| board[@y_coordinate + 1][@x_coordinate + i] = 1 }
116
+
117
+ board[@y_coordinate][@x_coordinate + 3] = 1
118
+ when 270
119
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate] = 1 }
120
+
121
+ board[@y_coordinate + 3][@x_coordinate + 1] = 1
122
+ end
123
+
124
+ board
125
+ end
126
+
127
+ def type_i
128
+ board = BackgroundBoard.blank_board
129
+
130
+ case @degree
131
+ when 0
132
+ 4.times {|i| board[@y_coordinate][@x_coordinate + i] = 1 }
133
+ when 90
134
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate + 2] = 1 }
135
+ when 180
136
+ 4.times {|i| board[@y_coordinate + 2][@x_coordinate + i] = 1 }
137
+ when 270
138
+ 4.times {|i| board[@y_coordinate + i][@x_coordinate] = 1 }
139
+ end
140
+
141
+ board
142
+ end
143
+
144
+ def type_o
145
+ board = BackgroundBoard.blank_board
146
+
147
+ 2.times {|i|
148
+ board[@y_coordinate][@x_coordinate + i] = 1
149
+ board[@y_coordinate + 1][@x_coordinate + i] = 1
150
+ }
151
+
152
+ board
153
+ end
154
+
155
+ def type_s
156
+ board = BackgroundBoard.blank_board
157
+
158
+ case @degree
159
+ when 0, 180
160
+ 2.times {|i|
161
+ board[@y_coordinate][@x_coordinate + i + 1] = 1
162
+ board[@y_coordinate + 1][@x_coordinate + i] = 1
163
+ }
164
+ when 90, 270
165
+ 2.times {|i|
166
+ board[@y_coordinate + i][@x_coordinate] = 1
167
+ board[@y_coordinate + i + 1][@x_coordinate + 1] = 1
168
+ }
169
+ end
170
+
171
+ board
172
+ end
173
+
174
+ def type_z
175
+ board = BackgroundBoard.blank_board
176
+
177
+ case @degree
178
+ when 0, 180
179
+ 2.times {|i|
180
+ board[@y_coordinate][@x_coordinate + i] = 1
181
+ board[@y_coordinate + 1][@x_coordinate + i + 1] = 1
182
+ }
183
+ when 90, 270
184
+ 2.times {|i|
185
+ board[@y_coordinate + i + 1][@x_coordinate] = 1
186
+ board[@y_coordinate + i][@x_coordinate + 1] = 1
187
+ }
188
+ end
189
+
190
+ board
191
+ end
192
+
193
+ def type_t
194
+ board = BackgroundBoard.blank_board
195
+
196
+ case @degree
197
+ when 0
198
+ 3.times {|i| board[@y_coordinate + 1][@x_coordinate + i] = 1 }
199
+
200
+ board[@y_coordinate + 2][@x_coordinate + 1] = 1
201
+ when 90
202
+ 3.times {|i| board[@y_coordinate + i][@x_coordinate + 1] = 1 }
203
+
204
+ board[@y_coordinate + 1][@x_coordinate] = 1
205
+ when 180
206
+ 3.times {|i| board[@y_coordinate + 1][@x_coordinate + i] = 1 }
207
+
208
+ board[@y_coordinate][@x_coordinate + 1] = 1
209
+ when 270
210
+ 3.times {|i| board[@y_coordinate + i][@x_coordinate + 1] = 1 }
211
+
212
+ board[@y_coordinate + 1][@x_coordinate + 2] = 1
213
+ end
214
+
215
+ board
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,3 @@
1
+ class ConsoleTetris
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: console-tetris
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - pekepek
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-01-16 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.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
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: io-console
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: you can play Tetris
56
+ email:
57
+ - ishihata@33i.co.jp
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - bin/console_tetris
67
+ - console-tetris.gemspec
68
+ - lib/console_tetris.rb
69
+ - lib/console_tetris/background_board.rb
70
+ - lib/console_tetris/tetrimino.rb
71
+ - lib/console_tetris/version.rb
72
+ homepage: https://github.com/pekepek/console-tetris
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.5.1
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: you can play Tetris
96
+ test_files: []