lib/tennis.rb in tennis-0.1.4 vs lib/tennis.rb in tennis-0.1.5
- old
+ new
@@ -1,25 +1,26 @@
require "tennis/version"
class Tennis
+ # player 1 is the home player(0) , player 2 is the away player(1)
+ # winner is either 0 or 1
+ # points is an array: [points for 0 , points for 1]
+ # set_count is an array: [sets won by 0, sets won by 1]
+ # game_count is an array: [games won by 0, games won by 1]
+
+ attr_reader :winner, :points, :set_count, :game_count
+
def initialize(scores)
- @scores = scores != 'default-1' && scores != 'default-2' ? scores.split(/[-,,]/).map(&:to_i) : scores
- @result = (1 if scores == 'default-1') || (2 if scores == 'default-2') || :default
- if @result == :default
- # check blank input ''
- @result = :error if @scores.any? { |score| score.nil? }
- # to check if score for only 1 set has been input
- validation_1 = @scores.length == 2
- # to check if any input > 7
- validation_2 = @scores.any? { |score| score > 7 }
- # to check if one of the input is 7 and the other is not 6
- # bad tie break input
- validation_3 = false
- @scores.each_slice(2).each {|r| validation_3 = true if r.any? {|score| score == 7} && !r.any? {|score| score == 6} }
- @result = :error if validation_1 || validation_2 || validation_3
- # if set score is not complete eg: 4-6,7-6,4-1
- @scores.each_slice(2).each {|r| @result = :incomplete_match if r[0] < 6 && r[1] < 6 } if @result != :error
+ # dfh -> default win for home player(0)
+ # dfa -> default win for away player(1)
+ @winner = :default
+ @scores = validate_score(scores)
+ @winner = match_winner if @winner == :default
+ @points = match_points
+ unless @scores.is_a? String
+ @set_count = sets_won
+ @game_count = games_won
end
end
# to_s
# return the score in string format
@@ -31,42 +32,85 @@
# returns the flipped score as a string
def flipped
(0...@scores.length).step(2).map{ |i| [@scores[i+1], @scores[i]].join('-') }.join(', ')
end
+ private
+
+ # helper method: to check score validation
+ def validate_score(scores_string)
+ set_scores = scores_string.split(/[-,,]/).map(&:to_i)
+ if set_scores == [0]
+ # checks bad default string value reported
+ @winner = (0 if scores == 'dfh') || (1 if scores == 'dfa') || :error
+ scores_string
+ else
+ # check blank input ''
+ validation_1 = set_scores.any? {|score| score.nil?}
+ # to check if score for only 1 set has been input
+ validation_2 = set_scores.length == 2
+ # to check if any input > 7
+ validation_3 = set_scores.any? {|score| score > 7}
+ # to check if one of the input is 7 and the other is not 6
+ # bad tie break input
+ validation_4 = false
+ set_scores.each_slice(2).each {|r| validation_4 = true if r.any? {|score| score == 7} && !r.any? {|score| score == 6} }
+ @winner = :error if validation_1 || validation_2 || validation_3 || validation_4
+ # if set score is not complete eg: 4-6,7-6,4-1
+ set_scores.each_slice(2).each {|r| @winner = :incomplete_match if r[0] < 6 && r[1] < 6 } unless @winner == :error
+ set_scores
+ end
+ end
+
# returns who won the match
# :incomplete_match (bad input/incomplete match)
# :error (bad input for sure)
- # 1 (player-1 won)
- # 2 (player-2 won)
- def winner
- return @result if @result != :default
- @result = (@scores.length == 4) ? two_sets : three_sets
+ # 0 (player-1 won)
+ # 1 (player-2 won)
+ def match_winner
+ @scores.length == 4 ? two_sets : three_sets
end
# returns an array of points
# returns (points_player_1 , points_player_2)
# returns (0,0) for bad input
- def points
- @result = winner
- (return [0, 0]) if @result == :error
- (complete_match_points if @result == 1 || @result == 2) || incomplete_match_points
+ def match_points
+ return [0, 0] if @winner == :error
+ return [@scores == 'dfh' ? 12 : 0 , @scores == 'dfa' ? 12 : 0] if @scores.is_a? String
+ @winner == 0 || @winner == 1 ? complete_match_points : incomplete_match_points
end
- private
+ # returns the number of sets won by the given player (0 or 1)
+ def sets_won
+ sets = [0, 0]
+ (0...@scores.length).step(2).each do |i|
+ @scores[0 + i] > @scores[1 + i] ? sets[0] += 1 : sets[1] += 1
+ end
+ sets
+ end
+ # returns the number of won by the given player (0 or 1)
+ def games_won
+ games = [0, 0]
+ (0...@scores.length).step(2).each do |i|
+ games[0] += @scores[0 + i]
+ games[1] += @scores[1 + i]
+ end
+ games
+ end
+
# helper method: called by RESULT method for valid matches with 2 sets
def two_sets
set_results = []
(0...@scores.length).step(2).each do |i|
# tie breaker (assuming a 7 point tie breaker) or a 7-5 scores
- if @scores[i] == 7 || @scores[i+1] == 7
- set_results << (@scores[i] == 7 ? 1 : 2)
+ if @scores[i] == 7 || @scores[i + 1] == 7
+ set_results << (@scores[i] == 7 ? 0 : 1)
# regular set victory - 6 games with a margin of 2
else
return :incomplete_match if ( @scores[i] - @scores[i + 1] ).abs < 2
- set_results << (@scores[i] == 6 ? 1 : 2)
+ set_results << (@scores[i] == 6 ? 0 : 1)
end
end
# incomplete match e.g: 6-4,5-3
(set_results[0] if set_results[0] == set_results[1]) || :incomplete_match
end
@@ -75,47 +119,46 @@
def three_sets
set_results = []
(0...@scores.length).step(2).each do |i|
# tie breaker (assuming a 7 point tie breaker) or a 7-5 score
if @scores[i] == 7 || @scores[i + 1] == 7
- set_results << (@scores[i] == 7 ? 1 : 2)
+ set_results << (@scores[i] == 7 ? 0 : 1)
# regular set victory - 6 games with a margin of 2
else
return :incomplete_match if (@scores[i] - @scores[i + 1]).abs < 2
- set_results << (@scores[i] == 6 ? 1 : 2)
+ set_results << (@scores[i] == 6 ? 0 : 1)
end
end
# checks if the result has been decided in the first 2 sets
# but the 3rd set is also present in the input
return :error if set_results[0] == set_results[1]
- set_results.count(1) == 2 ? 1 : 2
+ set_results.count(0) == 2 ? 0 : 1
end
# helper method: called by POINTS for complete matches
def complete_match_points
points = [0, 0]
- @result = winner
- points[@result - 1] = (@scores.length == 6) ? 12 : 14
- runner_up = (@result == 1) ? 2 : 1
+ points[@winner] = (@scores.length == 6) ? 12 : 14
+ runner_up = 1 - @winner
runner_up_points = player_points(runner_up)
- points[runner_up - 1] = runner_up_points < 8 ? runner_up_points : 8
+ points[runner_up] = runner_up_points < 8 ? runner_up_points : 8
points
end
# helper method: called by POINTS for incomplete matches
def incomplete_match_points
points = [0, 0]
- player_1_points = player_points(1)
- player_2_points = player_points(2)
+ player_1_points = player_points(0)
+ player_2_points = player_points(1)
points[0] = player_1_points < 10 ? player_1_points : 10
points[1] = player_2_points < 10 ? player_2_points : 10
points
end
# helper method: returns the POINTS of a player given the player number
def player_points(player)
player_scores = []
- @scores.each_with_index { |score, index| (player_scores << score; player +=2) if index == (player - 1) }
+ @scores.each_with_index { |score, index| (player_scores << score; player += 2) if index == (player) }
player_scores = player_scores.sort! { |x, y| y <=> x }
player_scores[0] + player_scores[1]
end
end