timequiz 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,246 @@
1
+ #encoding: UTF-8
2
+
3
+ =begin
4
+ /***************************************************************************
5
+ * Copyright © 2017-2017, Michael Uplawski <michael.uplawski@uplawski.eu>*
6
+ * *
7
+ * This program is free software; you can redistribute it and/or modify *
8
+ * it under the terms of the GNU General Public License as published by *
9
+ * the Free Software Foundation; either version 3 of the License, or *
10
+ * (at your option) any later version. *
11
+ * *
12
+ * This program is distributed in the hope that it will be useful, *
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15
+ * GNU General Public License for more details. *
16
+ * *
17
+ * You should have received a copy of the GNU General Public License *
18
+ * along with this program; if not, write to the *
19
+ * Free Software Foundation, Inc., *
20
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21
+ ***************************************************************************/
22
+ =end
23
+
24
+ require 'io/wait'
25
+ require 'io/console'
26
+
27
+ # Provides functions to convert terminal input to desired data-types and does
28
+ # some verifications.
29
+ # Keyboard-input is always non-blocking, to allow syntax-checking on the fly
30
+ # and to accelerate the work-flow, wherever possible.
31
+ class UserInput
32
+ # Brutal log-function: See your desired message, then hit 'q' to exit program.
33
+ def self::debout(str)
34
+ if $DEBUG == :DEBUG
35
+ puts str
36
+ if(wait_for_user().chr == 'q')
37
+ exit true
38
+ end
39
+ end
40
+ end
41
+
42
+ def self::string_input
43
+ inp = ""
44
+ loop do
45
+ begin
46
+ char = wait_for_user()
47
+ if char == 10 || char == 13
48
+ return inp
49
+ elsif( 'q' == char.chr.downcase)
50
+ exit true
51
+ else
52
+ inp << char
53
+ end
54
+ rescue Interrupt
55
+ exit true
56
+ end
57
+ end
58
+ end
59
+
60
+ def self::int_input(range = nil)
61
+ ar = []
62
+ loop do
63
+ begin
64
+ char = wait_for_user()
65
+ if char == 10 || char == 13
66
+ if(range && range.min > ar.join.to_i)
67
+ puts "\n%d is too small. Choose a number from the list of events or 0 (zero)" %ar.join.to_i
68
+ ar.clear
69
+ else
70
+ return ar.join.to_i
71
+ end
72
+ elsif( 'q' == char.chr.downcase)
73
+ print "\n\tBye "
74
+ return :quit_game
75
+ else
76
+ num = char - 48
77
+ ar << num
78
+ print num
79
+ if(range && range.max < ar.join.to_i )
80
+ puts "\n%d is becoming too big. Choose a number from the list of events or 0 (zero)" %ar.join.to_i
81
+ ar.clear
82
+ end
83
+ end
84
+ rescue Interrupt
85
+ exit true
86
+ end
87
+ end
88
+ end
89
+
90
+ def self::float_input
91
+ ar = []
92
+ loop do
93
+ begin
94
+ char = wait_for_user()
95
+ if char == 10 || char == 13
96
+ return ar.join.to_f
97
+ elsif( 'q' == char.chr.downcase)
98
+ print "\n\tBye "
99
+ return :quit_game
100
+ else
101
+ ar << char
102
+ end
103
+ rescue Interrupt
104
+ exit true
105
+ end
106
+ end
107
+ end
108
+
109
+ def self::char_input
110
+ begin
111
+ char = wait_for_user()
112
+ if( 'q' == char.chr.downcase)
113
+ print "\n\tBye "
114
+ return :quit_game
115
+ elsif ('a'..'z').member?(char.chr.downcase)
116
+ return char
117
+ end
118
+ rescue Interrupt
119
+ exit true
120
+ end
121
+ end
122
+
123
+
124
+ def self::input
125
+ inp = []
126
+ loop do
127
+ begin
128
+ char = wait_for_user()
129
+ if char == 10 || char == 13
130
+ return inp
131
+ elsif( 'q' == char.chr.downcase)
132
+ print "\n\tBye. "
133
+ return :quit_game
134
+ elsif ('a'..'z').member?(char.chr.downcase)
135
+ return char.chr
136
+ else
137
+ inp << char - 48
138
+ end
139
+ rescue Interrupt
140
+ exit true
141
+ end
142
+
143
+ end
144
+ end
145
+
146
+ def self::int_array_input(len, range = nil)
147
+ ar = []
148
+ until ar.length == len
149
+ if(range)
150
+ print ' (Available: '
151
+ disp = range.to_a - ar
152
+ if disp.length > 2
153
+ puts disp.join(', ') << ')'
154
+ elsif disp.length == 2
155
+ puts disp.first.to_s << ' or ' << disp.last.to_s << ')'
156
+ else
157
+ puts disp.first.to_s << ')'
158
+ end
159
+ end
160
+
161
+ begin
162
+ char = wait_for_user()
163
+ if( 'q' == char.chr.downcase)
164
+ print "\n\tBye. "
165
+ return :quit_game
166
+ elsif range && range.member?(char - 48)
167
+ num = char - 48
168
+ if(ar.member?(num))
169
+ puts '%d cannot happen twice!' %num
170
+ puts 'Try again or push "q" to quit.'
171
+ else
172
+ ar << num
173
+ end
174
+ else
175
+ print "%s is not a valid input." %char.chr
176
+ if(range)
177
+ print ' (Available: '
178
+ disp = range.to_a - ar
179
+ if disp.length > 2
180
+ puts disp.join(', ') << ')'
181
+ elsif disp.length == 2
182
+ puts disp.first.to_s << ' or ' << disp.last.to_s << ')'
183
+ else
184
+ puts disp.first.to_s << ')'
185
+ end
186
+ end
187
+ puts 'Try again or push "q" to quit.'
188
+ end
189
+ rescue Interrupt
190
+ exit true
191
+ end
192
+ end
193
+ return ar
194
+ end
195
+
196
+ # For cases when no data-type can be imposed for the input, but ultimately an
197
+ # integer is needed. [4,3,2] becomes 432.
198
+ # Beware, that the character-values must have been converted to int, already,
199
+ # by substracting 48 from any number-symbol, or by converting its character
200
+ # incarnation to int.
201
+ def self::a2i(ar)
202
+ if ar.respond_to?(:to_ary)
203
+ ar.reverse!
204
+ res = 0
205
+ ar.each_with_index do |n, i|
206
+ res += (n * 10**i)
207
+ end
208
+ return res
209
+ else
210
+ puts "Invalid input " << ar.to_s
211
+ return 0
212
+ end
213
+ end
214
+
215
+ private
216
+
217
+ # The marvellous and mystic, heard-about so-long... unblocking read from STDIN!!
218
+ def self::wait_for_user()
219
+ char = nil
220
+ # There is a difference which makes me prefer the below code from STDIN.raw(args)
221
+ # You can try
222
+ # char = STDIN.raw(&:getc)
223
+ # .., which does *not* work the same way and it won't for me.
224
+
225
+ STDIN.raw do
226
+ STDIN.noecho do
227
+ until (STDIN.ready?)
228
+ sleep(0.1)
229
+ end
230
+ char = (STDIN.read_nonblock(1).ord rescue nil)
231
+ end
232
+ end
233
+ return char
234
+ end
235
+
236
+
237
+ end
238
+ # -------- TEST
239
+ if __FILE__ == $0
240
+ str = UserInput::input
241
+ puts "You say: " << str.to_s
242
+ puts "As Integer: " << UserInput::a2i(str).to_s
243
+ print 'an integer from 23 to 45: '
244
+ int = UserInput::int_input(23..45)
245
+ puts " You say " << int.to_s
246
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timequiz
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Michael Uplawski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Play a history quiz.
14
+ email: michael.uplawski@uplawski.eu
15
+ executables:
16
+ - timequiz
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - bin/timequiz
21
+ - doc/html/timequiz.html
22
+ - doc/license.txt
23
+ - doc/man/timequiz.6.gz
24
+ - doc/pdf/timequiz.pdf
25
+ - doc/rst/timequiz.rst
26
+ - lib/adder.rb
27
+ - lib/argparser.rb
28
+ - lib/busy_indicator.rb
29
+ - lib/color_output.rb
30
+ - lib/console.rb
31
+ - lib/constants.rb
32
+ - lib/event.rb
33
+ - lib/events.rb
34
+ - lib/extstring.rb
35
+ - lib/file_checking.rb
36
+ - lib/logging.rb
37
+ - lib/timequiz.rb
38
+ - lib/user_input.rb
39
+ homepage: http://rubygems.org
40
+ licenses:
41
+ - GPL-3.0
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 2.1.2
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.6.12
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Missing options lead to exception
63
+ test_files: []