glitch-game 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: 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: []