KeeperChallenge 0.0.2
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.
- data/KeeperChallenge-0.0.1.gem +0 -0
- data/KeeperChallenge.gemspec +20 -0
- data/bin/keeperchallenge +5 -0
- data/lib/KeeperChallenge.rb +160 -0
- data/lib/keeperchallenge/activity.rb +10 -0
- data/lib/keeperchallenge/database.rb +59 -0
- data/lib/keeperchallenge/player.rb +39 -0
- data/lib/keeperchallenge/score.rb +76 -0
- data/lib/keeperchallenge/version.rb +1 -0
- data/test/test_keeperchallenge.rb +17 -0
- metadata +57 -0
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "keeperchallenge/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "KeeperChallenge"
|
7
|
+
s.version = '0.0.2'
|
8
|
+
s.authors = ["Benjamin Combe"]
|
9
|
+
s.email = ["benjamin.combe@gmail.com"]
|
10
|
+
s.homepage = "http://arthion.fr"
|
11
|
+
s.summary = %q{KeeperChallenge is a prototype for running sports contests between friends}
|
12
|
+
s.description = %q{KeeperChallenge is a console based application that will allow the user to add participants, add activities and then determine the winner of the contest.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "KeeperChallenge"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
end
|
data/bin/keeperchallenge
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
#require './keeperchallenge/player'
|
2
|
+
#require './keeperchallenge/score'
|
3
|
+
#require './keeperchallenge/activity'
|
4
|
+
#require './keeperchallenge/database'
|
5
|
+
#TODO
|
6
|
+
#import activity and players from text file ?
|
7
|
+
require File.dirname(__FILE__) +'/keeperchallenge/player'
|
8
|
+
require File.dirname(__FILE__) +'/keeperchallenge/score'
|
9
|
+
require File.dirname(__FILE__) +'/keeperchallenge/activity'
|
10
|
+
require File.dirname(__FILE__) +'/keeperchallenge/database'
|
11
|
+
|
12
|
+
# will handle user input - will to quit the program, input from the console
|
13
|
+
class UserInput
|
14
|
+
attr_accessor :exit
|
15
|
+
def initialize
|
16
|
+
exit = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_input
|
20
|
+
print '> '
|
21
|
+
result = gets.chomp()
|
22
|
+
return result
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
#will handle display to the screen , main menu, sub menus ...
|
28
|
+
class Display
|
29
|
+
def initialize(input)
|
30
|
+
@input = input
|
31
|
+
end
|
32
|
+
#Hello
|
33
|
+
def hello
|
34
|
+
puts "Welcome to KeeperChallenge!\n"
|
35
|
+
end
|
36
|
+
#menu
|
37
|
+
def menu
|
38
|
+
puts "Please select your action"
|
39
|
+
puts "1. Add activity"
|
40
|
+
puts "2. Add player"
|
41
|
+
puts "3. Display scoreboard"
|
42
|
+
puts "4. Clear player database"
|
43
|
+
puts "5. Exit"
|
44
|
+
choice = @input.get_input
|
45
|
+
case choice.to_i
|
46
|
+
when 1 then return :add_activity
|
47
|
+
when 2 then return :add_player
|
48
|
+
when 3 then return :launch_scoreboard
|
49
|
+
when 4 then return :clean_database
|
50
|
+
when 5 then @input.exit = true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def select_player(players)
|
55
|
+
puts "Please select your player"
|
56
|
+
i=1
|
57
|
+
if !players.empty?
|
58
|
+
players.each do |player|
|
59
|
+
puts "#{i}. #{player.name}"
|
60
|
+
end
|
61
|
+
choice = @input.get_input
|
62
|
+
return choice.to_i-1
|
63
|
+
else
|
64
|
+
puts "There are no players in the database"
|
65
|
+
return nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_player
|
70
|
+
puts "Enter the new player name :"
|
71
|
+
name = @input.get_input
|
72
|
+
return name
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_activity(activities_type)
|
76
|
+
|
77
|
+
puts "Enter activity type"
|
78
|
+
puts "possible activities : "
|
79
|
+
puts activities_type
|
80
|
+
type = @input.get_input
|
81
|
+
while !activities_type.include?(type)
|
82
|
+
puts "activity invalid"
|
83
|
+
type = @input.get_input
|
84
|
+
end
|
85
|
+
puts "Enter time"
|
86
|
+
time = @input.get_input
|
87
|
+
puts "Enter cal"
|
88
|
+
cal = @input.get_input
|
89
|
+
puts "Enter Km"
|
90
|
+
km = @input.get_input
|
91
|
+
return type, time, cal, km
|
92
|
+
end
|
93
|
+
|
94
|
+
def display_scores(players)
|
95
|
+
puts "Scores :"
|
96
|
+
players.each do |player|
|
97
|
+
puts "#{player.name} : #{player.score}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Main program
|
105
|
+
class Main
|
106
|
+
|
107
|
+
def initialize
|
108
|
+
# load players
|
109
|
+
# load activities
|
110
|
+
@players = []
|
111
|
+
@activities_type = ["velo", "course" , "marche", "natation"]
|
112
|
+
#setup_test_users
|
113
|
+
|
114
|
+
end
|
115
|
+
def launch
|
116
|
+
input = UserInput.new()
|
117
|
+
screen = Display.new(input)
|
118
|
+
db = FileDatabase.new()
|
119
|
+
db.load(@players)
|
120
|
+
screen.hello
|
121
|
+
while !input.exit
|
122
|
+
action = screen.menu
|
123
|
+
case action
|
124
|
+
when :add_activity then
|
125
|
+
player = screen.select_player(@players)
|
126
|
+
if !player.nil?
|
127
|
+
type, time, cal, km = screen.add_activity(@activities_type)
|
128
|
+
@players[player].add_activity(type, time, cal, km)
|
129
|
+
end
|
130
|
+
when :add_player then
|
131
|
+
name = screen.add_player
|
132
|
+
new_player = Player.new(name)
|
133
|
+
@players.push(new_player)
|
134
|
+
#add player
|
135
|
+
when :launch_scoreboard then
|
136
|
+
score = Score.new(@players)
|
137
|
+
score.compute(@activities_type)
|
138
|
+
screen.display_scores(@players)
|
139
|
+
when :clean_database then
|
140
|
+
db.clear
|
141
|
+
@players.clear
|
142
|
+
|
143
|
+
end
|
144
|
+
db.save(@players)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def setup_test_users
|
149
|
+
@players.push(Player.new("Ben"))
|
150
|
+
@players.push(Player.new("Claire"))
|
151
|
+
|
152
|
+
@players[0].add_activity("velo", 15, 15, 15)
|
153
|
+
@players[0].add_activity("course", 10, 10, 10)
|
154
|
+
@players[0].add_activity("course", 20, 20, 20)
|
155
|
+
@players[1].add_activity("velo", 12, 12, 12)
|
156
|
+
@players[1].add_activity("natation", 30, 20, 10)
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class FileDatabase
|
2
|
+
|
3
|
+
# will create the db folder if not present on system
|
4
|
+
def initialize
|
5
|
+
#if db folder does not exist, create it
|
6
|
+
@folder_path = File.dirname(__FILE__) + "/db/"
|
7
|
+
unless File.directory?(@folder_path)
|
8
|
+
Dir.mkdir(@folder_path)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
#will load all files from db directory and load them as player and activities
|
14
|
+
def load(players)
|
15
|
+
index = 0
|
16
|
+
# read all files in database
|
17
|
+
|
18
|
+
Dir.foreach(@folder_path) do |file|
|
19
|
+
if !(file =='.' || file == '..')
|
20
|
+
# create an object per file (=player)
|
21
|
+
players.push(Player.new(file))
|
22
|
+
# populate with activities
|
23
|
+
content = File.open("#{@folder_path}#{file}")
|
24
|
+
content.each_line do |line|
|
25
|
+
activity = line.split(' ')
|
26
|
+
players[index].add_activity(activity[0], activity[1], activity[2], activity[3])
|
27
|
+
end
|
28
|
+
index += 1
|
29
|
+
content.close
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#will save player to static files in db directory
|
35
|
+
def save(players)
|
36
|
+
# create a file per player
|
37
|
+
players.each do |player|
|
38
|
+
file_name = "#{@folder_path}#{player.name}"
|
39
|
+
player_file = File.open(file_name,'w')
|
40
|
+
# in this file : one activity per line, each attribute separated by a space
|
41
|
+
player.activities.each do |activity|
|
42
|
+
activity_string = "#{activity.type} #{activity.time} #{activity.cal} #{activity.km}\n"
|
43
|
+
player_file.write(activity_string)
|
44
|
+
end
|
45
|
+
player_file.close
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
#Will remove all player files from the db directory
|
51
|
+
def clear
|
52
|
+
Dir.foreach(@folder_path) do |file|
|
53
|
+
unless (file =='.' || file == '..')
|
54
|
+
File.delete("#{@folder_path}#{file}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Player
|
2
|
+
attr_reader :name
|
3
|
+
attr_accessor :activities, :score
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
@name = name
|
7
|
+
@activities = []
|
8
|
+
@score = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_activity(type, time, cal, km)
|
12
|
+
new_activity = Activity.new(type, time, cal, km)
|
13
|
+
@activities.push(new_activity)
|
14
|
+
end
|
15
|
+
|
16
|
+
def list_by_type(type)
|
17
|
+
activity_by_type = []
|
18
|
+
@activities.each do |activity|
|
19
|
+
if activity.type == type
|
20
|
+
activity_by_type.push(activity)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return activity_by_type
|
24
|
+
end
|
25
|
+
|
26
|
+
def count_activity_type
|
27
|
+
total_activities_type = 0
|
28
|
+
previous_activity = ''
|
29
|
+
|
30
|
+
@activities.each do |activity|
|
31
|
+
if activity != previous_activity
|
32
|
+
activity = previous_activity
|
33
|
+
total_activities_type += 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return total_activities_type
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Score
|
2
|
+
|
3
|
+
def initialize(players)
|
4
|
+
@players = players
|
5
|
+
end
|
6
|
+
|
7
|
+
def compute(activities_type)
|
8
|
+
#reset to prevent abuse from calling the scoreboard multiple times
|
9
|
+
reset_player_scores()
|
10
|
+
|
11
|
+
# Parcours de toutes les activit�s pour d�terminer le meilleur dans chaque
|
12
|
+
activities_type.each do |activity|
|
13
|
+
#parcours chaque joueur et d�termine leur score dans l'activit�
|
14
|
+
total_time = {}
|
15
|
+
total_cal = {}
|
16
|
+
total_km = {}
|
17
|
+
@players.each do |player|
|
18
|
+
total_time[player.name] =0
|
19
|
+
total_cal[player.name] =0
|
20
|
+
total_km[player.name] =0
|
21
|
+
|
22
|
+
player.list_by_type(activity).each do |player_activity|
|
23
|
+
total_time[player.name] += player_activity.time.to_i
|
24
|
+
total_cal[player.name] += player_activity.cal.to_i
|
25
|
+
total_km[player.name] += player_activity.km.to_i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#d�termine le meilleur de chaque discipline
|
30
|
+
@players.each do |player|
|
31
|
+
if player.name == find_best_score(total_time)
|
32
|
+
puts "Best total time in #{activity} for #{player.name}, adding 3 points"
|
33
|
+
player.score += 3
|
34
|
+
end
|
35
|
+
if player.name == find_best_score(total_cal)
|
36
|
+
puts "Best total cal in #{activity} for #{player.name}, adding 3 points"
|
37
|
+
player.score += 3
|
38
|
+
end
|
39
|
+
if player.name == find_best_score(total_km)
|
40
|
+
puts "Best total km in #{activity} for #{player.name}, adding 3 points"
|
41
|
+
player.score += 3
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
#Incr�mentation du compteur pour le nombre d'activit�s diff�rentes effectu�es
|
49
|
+
@players.each do |player|
|
50
|
+
puts "Adding numbers of activity for #{player.name} = #{player.count_activity_type}"
|
51
|
+
player.score += player.count_activity_type
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_best_score(total_per_player)
|
57
|
+
best_score = 0
|
58
|
+
winner = ''
|
59
|
+
total_per_player.each do |player_name,total|
|
60
|
+
|
61
|
+
if total > best_score
|
62
|
+
best_score = total
|
63
|
+
winner = player_name
|
64
|
+
end
|
65
|
+
end
|
66
|
+
return winner
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
def reset_player_scores()
|
71
|
+
@players.each do |player|
|
72
|
+
player.score = 0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
0.1
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: KeeperChallenge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Benjamin Combe
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: KeeperChallenge is a console based application that will allow the user
|
15
|
+
to add participants, add activities and then determine the winner of the contest.
|
16
|
+
email:
|
17
|
+
- benjamin.combe@gmail.com
|
18
|
+
executables:
|
19
|
+
- keeperchallenge
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files: []
|
22
|
+
files:
|
23
|
+
- KeeperChallenge-0.0.1.gem
|
24
|
+
- KeeperChallenge.gemspec
|
25
|
+
- bin/keeperchallenge
|
26
|
+
- lib/KeeperChallenge.rb
|
27
|
+
- lib/keeperchallenge/activity.rb
|
28
|
+
- lib/keeperchallenge/database.rb
|
29
|
+
- lib/keeperchallenge/player.rb
|
30
|
+
- lib/keeperchallenge/score.rb
|
31
|
+
- lib/keeperchallenge/version.rb
|
32
|
+
- test/test_keeperchallenge.rb
|
33
|
+
homepage: http://arthion.fr
|
34
|
+
licenses: []
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options: []
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
47
|
+
requirements:
|
48
|
+
- - ! '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project: KeeperChallenge
|
53
|
+
rubygems_version: 1.8.24
|
54
|
+
signing_key:
|
55
|
+
specification_version: 3
|
56
|
+
summary: KeeperChallenge is a prototype for running sports contests between friends
|
57
|
+
test_files: []
|