glitch-game 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: a60d336dfa3cba758f03c1b349b8aa6ad6a6878d
4
+ data.tar.gz: b9411ce3b606516596dc824747021001056b8aa5
5
+ SHA512:
6
+ metadata.gz: b42c21aa73bab39ec7bbe80067eea39e914b90f87dda61e95040cb2a62e91b81bd5d84bb3bb42b74845f00bfc6ba4a966538c251c6f232a1f8574a4ba20ae784
7
+ data.tar.gz: 0340ad3857521fd1296b5446604cf7b2631bff8400e7755a0f8ae8804c0a833e1c9df245ac2f37bb84a02355fda0edd0f5d3ad596054c3257f6f56a46205f43f
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg
2
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,16 @@
1
+ # g̠̼͕̋ḻͤi͖͊̄̕t̞ͫͪ̆c̹̎̀h̞͙̀̚
2
+
3
+ A terminal based [Cookie Clicker] style game.
4
+
5
+ [![Build Status](https://travis-ci.org/twe4ked/glitch.svg?branch=master)](https://travis-ci.org/twe4ked/glitch)
6
+
7
+ ### Installing and Running
8
+
9
+ ```
10
+ git clone git@github.com:twe4ked/glitch.git
11
+ cd glitch
12
+ bundle install
13
+ bundle exec ./bin/glitch
14
+ ```
15
+
16
+ [Cookie Clicker]: http://en.wikipedia.org/wiki/Cookie_Clicker
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
7
+ rescue LoadError
8
+ end
data/bin/glitch ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/glitch'
4
+
5
+ Glitch::Game.run
@@ -0,0 +1,19 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'glitch'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'glitch-game'
8
+ spec.version = Glitch::VERSION
9
+ spec.authors = ['Odin Dutton']
10
+ spec.summary = 'A terminal based Cookie Clicker style game.'
11
+ spec.homepage = 'https://github.com/twe4ked/glitch'
12
+ spec.license = 'MIT'
13
+ spec.files = `git ls-files -z`.split("\x0")
14
+ spec.executables << 'glitch'
15
+ spec.require_paths = ['.']
16
+ spec.add_runtime_dependency 'curses', '~> 1.0'
17
+ spec.add_development_dependency 'rake', '~> 10.0'
18
+ spec.add_development_dependency 'rspec', '~> 3.0'
19
+ end
data/lib/game.rb ADDED
@@ -0,0 +1,169 @@
1
+ require 'curses'
2
+
3
+ module Glitch
4
+ class Game
5
+ def initialize
6
+ @player = Glitch::Player.new
7
+ @bit_multiplier = 0
8
+ @last_second = 0
9
+
10
+ @types = {}
11
+ [
12
+ Glitch::Type.new('atom', initial_price: 10, multiplier: 1, count_available: 20, :description => 'a boring little atom, so lonely'),
13
+ Glitch::Type.new('uber', initial_price: 100, multiplier: 10),
14
+ Glitch::Type.new('matrix', initial_price: 150, multiplier: 11),
15
+ Glitch::Type.new('hundo', initial_price: 99999, multiplier: 100),
16
+ Glitch::Type.new('board', initial_price: 500, multiplier: 0, count_available: 4, price_calc: -> (type) { [type.initial_price * (type.count + 1), 2000].min }),
17
+ Glitch::Type.new('clock', initial_price: 1337, multiplier: 0, count_available: 1, price_calc: -> (type) { type.initial_price }),
18
+ ].each { |type| @types[type.shortcut] = type }
19
+
20
+ @message_board_length = 30
21
+ @messages = [
22
+ 'welcome to glitch',
23
+ 'you need bits',
24
+ "you're not sure why",
25
+ 'you know you do',
26
+ 'survive...',
27
+ ]
28
+ end
29
+
30
+ def self.run
31
+ self.new.run
32
+ end
33
+
34
+ def run
35
+ draw_screen
36
+
37
+ Curses.curs_set 0
38
+ Curses.timeout = 1000
39
+ Curses.start_color
40
+
41
+ loop do
42
+ tick
43
+ end
44
+ end
45
+
46
+ def tick
47
+ input = Curses.getch
48
+
49
+ if input
50
+ case
51
+ when input == ' '
52
+ @player.increment_bits
53
+ add_message '1 bit'
54
+ when available_types.map(&:shortcut).include?(input)
55
+ type = @types[input]
56
+
57
+ case
58
+ when !type.available?
59
+ add_message 'none left :('
60
+ when @player.can_decrement_bits_by?(type.price)
61
+ @player.decrement_bits type.price
62
+ type.increment
63
+ @bit_multiplier = @bit_multiplier + type.multiplier
64
+ add_message "1 #{type.name}"
65
+ else
66
+ add_message "you've not enough bits for #{type.name}"
67
+ end
68
+ else
69
+ add_message 'nope'
70
+ end
71
+ end
72
+
73
+ # only once per second
74
+ this_second = Time.now.to_i
75
+ if this_second > @last_second
76
+ @player.increment_bits 1 * @bit_multiplier
77
+ @last_second = this_second
78
+ end
79
+
80
+ @messages = @messages.last(10)
81
+
82
+ draw_screen
83
+ end
84
+
85
+ def draw_screen
86
+ Curses.clear
87
+
88
+ print_line_break
89
+ print_glitch_string 'glitch!', 5
90
+ print_line_break
91
+
92
+ if @types['c'].count == 1
93
+ print_glitch_string 'clock: ', 1, false
94
+ print_glitch_string Time.now.to_s
95
+ end
96
+
97
+ @one_bit = true if !@one_bit && @player.bits > 0
98
+ if @one_bit
99
+ print_glitch_string 'bits: ', 1, false
100
+ print_glitch_string @player.bits.to_s + (@bit_multiplier > 5 ? " (#{@bit_multiplier}/bps)" : '')
101
+ print_line_break
102
+ end
103
+
104
+ print_glitch_string '-' * message_board_length
105
+ if @messages
106
+ @messages.each do |message|
107
+ print_glitch_string message[0..message_board_length-4], 3, false
108
+ if message.length > message_board_length-4
109
+ Curses.addstr '...'
110
+ end
111
+ print_line_break
112
+ end
113
+ else
114
+ print_glitch_string '...', 1, true, true
115
+ end
116
+ print_glitch_string '-' * message_board_length
117
+
118
+ draw_types
119
+
120
+ print_line_break
121
+ Curses.addstr ':'
122
+ end
123
+
124
+ private
125
+
126
+ def add_message(message)
127
+ @messages << message
128
+ end
129
+
130
+ def draw_types
131
+ unless available_types.empty?
132
+ print_line_break
133
+ available_types.each do |type|
134
+ print_type_info = -> (*args) {
135
+ Curses.addstr '- '
136
+ print_glitch_string type.info_string, 1, false
137
+ print_glitch_string " - #{type.description}"
138
+ }
139
+
140
+ if @player.can_decrement_bits_by?(type.price) && type.available?
141
+ print_type_info.call
142
+ else
143
+ Curses.attron(Curses.color_pair(8)|Curses::A_BOLD, &print_type_info)
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ def available_types
150
+ @types.values.select do |type|
151
+ @player.can_decrement_bits_by?(type.price - type.price/100.0*10) || type.count > 0
152
+ end
153
+ end
154
+
155
+ def message_board_length
156
+ @message_board_length + 10 * (@types['b'].count + 1)
157
+ end
158
+
159
+ def print_glitch_string(string, amount = 1, line_break = true, random = false)
160
+ string = Glitch::GlitchString.new.glitch(string, amount, random)
161
+ Curses.addstr string
162
+ print_line_break if line_break
163
+ end
164
+
165
+ def print_line_break
166
+ Curses.addstr "\n"
167
+ end
168
+ end
169
+ end
data/lib/glitch.rb ADDED
@@ -0,0 +1,8 @@
1
+ require_relative 'game'
2
+ require_relative 'player'
3
+ require_relative 'type'
4
+ require_relative 'glitch_string'
5
+
6
+ module Glitch
7
+ VERSION = '0.0.1'
8
+ end
@@ -0,0 +1,53 @@
1
+ module Glitch
2
+ class GlitchString
3
+ # http://en.wikipedia.org/wiki/Combining_Diacritical_Marks
4
+ COMBINING_DIACRITICAL_MARKS = ("\u0300".."\u036F").to_a
5
+
6
+ def glitch(string, amount = 1, random = false, index_offset = 0)
7
+ result = string.chars.map.each_with_index do |char, index|
8
+ index = index + index_offset
9
+ srand(string.chars.map(&:ord).join.to_i + index + (random ? Time.now.to_i : 0))
10
+
11
+ add_mark = case amount
12
+ when 1
13
+ index % 5 == 0
14
+ when 2
15
+ index % 4 == 0
16
+ when 3
17
+ index % 3 == 0
18
+ when 4
19
+ index % 3 == 0
20
+ when 5
21
+ true
22
+ else
23
+ raise 'invalid amount (0..5)'
24
+ end
25
+
26
+ case char
27
+ when ' '
28
+ char
29
+ else
30
+ if add_mark
31
+ mark = COMBINING_DIACRITICAL_MARKS.sample
32
+ char + mark
33
+ else
34
+ char
35
+ end
36
+ end
37
+ end.join
38
+
39
+ case amount
40
+ when 2
41
+ glitch result, 1, random, amount
42
+ when 3
43
+ glitch result, 2, random, amount
44
+ when 4
45
+ glitch result, 3, random, amount
46
+ when 5
47
+ glitch result, 4, random, amount
48
+ else
49
+ result
50
+ end
51
+ end
52
+ end
53
+ end
data/lib/player.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Glitch
2
+ class Player
3
+ attr_reader :bits
4
+
5
+ def initialize
6
+ @bits = 0
7
+ end
8
+
9
+ def increment_bits(number = 1)
10
+ @bits = @bits + number
11
+ end
12
+
13
+ def can_decrement_bits_by?(number)
14
+ @bits >= number
15
+ end
16
+
17
+ def decrement_bits(number)
18
+ @bits = @bits - number
19
+ end
20
+ end
21
+ end
data/lib/type.rb ADDED
@@ -0,0 +1,72 @@
1
+ module Glitch
2
+ class Type
3
+ attr_reader :name, :multiplier, :count, :initial_price
4
+
5
+ def initialize(name, options = {})
6
+ @name = name
7
+ @initial_price = options[:initial_price]
8
+ @multiplier = options[:multiplier]
9
+ @count_available = options[:count_available] || :infinite
10
+ @price_calc = options[:price_calc]
11
+ @description = options[:description]
12
+ @count = 0
13
+ end
14
+
15
+ def shortcut
16
+ @name[0]
17
+ end
18
+
19
+ def name_with_shortcut
20
+ @name.sub(shortcut, "[#{shortcut}]")
21
+ end
22
+
23
+ def price
24
+ if @price_calc
25
+ @price_calc.call(self)
26
+ else
27
+ [
28
+ @initial_price,
29
+ @initial_price * @count * (@count >= 10 ? 10 : 1) + @count
30
+ ].max
31
+ end
32
+ end
33
+
34
+ def increment
35
+ @count = @count + 1
36
+ if @count_available.is_a? Integer
37
+ @count_available = @count_available - 1
38
+ end
39
+ end
40
+
41
+ def available?
42
+ infinite? || @count_available > 0
43
+ end
44
+
45
+ def total_available
46
+ if infinite?
47
+ '??'
48
+ else
49
+ @count + @count_available
50
+ end
51
+ end
52
+
53
+ def info_string
54
+ string = []
55
+ string << name_with_shortcut
56
+ string << "[#{price} bits]"
57
+ string << "(#{@count}/#{total_available})" if @count > 0
58
+ string << "*#{@multiplier}"
59
+ string.join ' '
60
+ end
61
+
62
+ def description
63
+ @description || '??'
64
+ end
65
+
66
+ private
67
+
68
+ def infinite?
69
+ @count_available == :infinite
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ require_relative '../../lib/player.rb'
2
+
3
+ describe Glitch::Player do
4
+ let(:player) { Glitch::Player.new }
5
+
6
+ describe '#increment_bits' do
7
+ it 'increments by 1 if no argument is supplied' do
8
+ expect { player.increment_bits }.to change { player.bits }.from(0).to(1)
9
+ expect { player.increment_bits }.to change { player.bits }.from(1).to(2)
10
+ end
11
+
12
+ it 'increments by the number supplied as an argument' do
13
+ player.increment_bits
14
+ expect { player.increment_bits 41 }.to change { player.bits }.from(1).to(42)
15
+ end
16
+ end
17
+
18
+ describe '#can_decrement_bits_by?' do
19
+ it 'returns true if the player has enough bits' do
20
+ expect(player.can_decrement_bits_by? 0).to eq true
21
+ player.increment_bits
22
+ expect(player.can_decrement_bits_by? 1).to eq true
23
+ end
24
+
25
+ it "returns false if the player doesn't have enough bits" do
26
+ expect(player.can_decrement_bits_by? 42).to eq false
27
+ end
28
+ end
29
+
30
+ describe 'decrement_bits' do
31
+ it 'decrements bits by the number supplied' do
32
+ player.increment_bits
33
+ expect { player.decrement_bits 1 }.to change { player.bits }.from(1).to(0)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ require_relative '../../lib/type.rb'
2
+
3
+ describe Glitch::Type do
4
+ let(:type) { Glitch::Type.new 'foo', initial_price: 10, multiplier: 1 }
5
+
6
+ describe '#shortcut' do
7
+ it 'returns a single letter shortcut' do
8
+ expect(type.shortcut).to eq 'f'
9
+ end
10
+ end
11
+
12
+ describe '#name_with_shortcut' do
13
+ it 'returns the name with the shortcut surrounded in brackets' do
14
+ expect(type.name_with_shortcut).to eq '[f]oo'
15
+ end
16
+ end
17
+
18
+ describe '#price' do
19
+ it 'returns different amounts based on the count' do
20
+ expect(type.price).to eq 10
21
+
22
+ type.instance_variable_set('@count', 1)
23
+ expect(type.price).to eq 11
24
+
25
+ type.instance_variable_set('@count', 9)
26
+ expect(type.price).to eq 99
27
+
28
+ type.instance_variable_set('@count', 10)
29
+ expect(type.price).to eq 1010
30
+
31
+ type.instance_variable_set('@count', 11)
32
+ expect(type.price).to eq 1111
33
+
34
+ type.instance_variable_set('@count', 99)
35
+ expect(type.price).to eq 9999
36
+
37
+ type.instance_variable_set('@count', 100)
38
+ expect(type.price).to eq 10100
39
+ end
40
+
41
+ it 'allows adding a lambda to change the price' do
42
+ type = Glitch::Type.new 'foo', initial_price: 40, multiplier: 1, price_calc: -> (type) { type.initial_price + 2 }
43
+ expect(type.price).to eq 42
44
+
45
+ type.instance_variable_set('@count', 1)
46
+ expect(type.price).to eq 42
47
+
48
+ type.instance_variable_set('@count', 2)
49
+ expect(type.price).to eq 42
50
+ end
51
+ end
52
+
53
+ describe '#increment' do
54
+ it 'increments the count' do
55
+ expect { type.increment }.to change { type.count }.from(0).to(1)
56
+ expect { type.increment }.to change { type.count }.from(1).to(2)
57
+ end
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: glitch-game
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Odin Dutton
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: curses
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
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: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description:
56
+ email:
57
+ executables:
58
+ - glitch
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - Gemfile
65
+ - README.markdown
66
+ - Rakefile
67
+ - bin/glitch
68
+ - glitch-game.gemspec
69
+ - lib/game.rb
70
+ - lib/glitch.rb
71
+ - lib/glitch_string.rb
72
+ - lib/player.rb
73
+ - lib/type.rb
74
+ - spec/lib/player_spec.rb
75
+ - spec/lib/type_spec.rb
76
+ homepage: https://github.com/twe4ked/glitch
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - "."
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.2.2
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: A terminal based Cookie Clicker style game.
100
+ test_files: []