/lib/chingu/high_score_list.rb

http://github.com/ippa/chingu · Ruby · 143 lines · 69 code · 15 blank · 59 comment · 8 complexity · c35df47bda2f516f8c5104fe486d8ac4 MD5 · raw file

  1. #--
  2. #
  3. # Chingu -- OpenGL accelerated 2D game framework for Ruby
  4. # Copyright (C) 2009 ippa / ippa@rubylicio.us
  5. #
  6. # This library is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU Lesser General Public
  8. # License as published by the Free Software Foundation; either
  9. # version 2.1 of the License, or (at your option) any later version.
  10. #
  11. # This library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. # Lesser General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public
  17. # License along with this library; if not, write to the Free Software
  18. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. #
  20. #++
  21. module Chingu
  22. #
  23. # Highscore-class
  24. #
  25. # - Keeps a local YAML file with highscores, default highscores.yml in root game dir.
  26. # - Add, delete, clear highscores
  27. # - Iterate through highscores with simple HighScores#each
  28. #
  29. class HighScoreList
  30. attr_reader :file, :high_scores
  31. #
  32. # Create a new high score list with 0 entries
  33. #
  34. def initialize(options = {})
  35. @file = options[:file] || "high_score_list.yml"
  36. @size = options[:size] || 100
  37. @sort_on = options[:sort_on] || :score
  38. @high_scores = Array.new
  39. end
  40. #
  41. # Create a new high score list and try to load content from :file-parameter
  42. # If no :file is given, HighScoreList tries to load from file "high_score_list.yml"
  43. #
  44. def self.load(options = {})
  45. require 'yaml'
  46. high_score_list = HighScoreList.new(options)
  47. high_score_list.load
  48. return high_score_list
  49. end
  50. #
  51. # Adda a new high score to the local file
  52. # 'data' is a hash of key/value-pairs that needs to contain at least the keys :name and :score
  53. # Returns the position it got in the list, with 1 beeing the first positions
  54. #
  55. def add(data)
  56. raise "No :name value in high score!" if data[:name].nil?
  57. raise "No :score value in high score!" if data[:score].nil?
  58. add_to_list(force_symbol_hash(data))
  59. save_to_file
  60. position_by_score(data[:score])
  61. end
  62. alias << add
  63. #
  64. # Returns the position of full data-hash data entry, used internally
  65. #
  66. def position_by_data(data)
  67. position = @high_scores.rindex(data)
  68. position += 1 if position
  69. end
  70. #
  71. # Returns the position 'score' would get in among the high scores:
  72. # @high_score_list.position_by_score(999999999) # most likely returns 1 for the number one spot
  73. # @high_score_list.position_by_score(1) # most likely returns nil since no placement is found (didn't make it to the high scores)
  74. #
  75. def position_by_score(score)
  76. position = 1
  77. @high_scores.each do |high_score|
  78. return position if score >= high_score[:score]
  79. position += 1
  80. end
  81. return nil
  82. end
  83. #
  84. # Load data from previously specified @file
  85. #
  86. def load
  87. @high_scores = YAML.load_file(@file) if File.exists?(@file)
  88. @high_scores = @high_scores[0..@size]
  89. end
  90. #
  91. # Direct access to invidual high scores
  92. #
  93. def [](index)
  94. @high_scores[index]
  95. end
  96. #
  97. # Iterate through all high scores
  98. #
  99. def each
  100. @high_scores.each { |high_score| yield high_score }
  101. end
  102. def each_with_index
  103. @high_scores.each_with_index { |high_score, index| yield high_score, index }
  104. end
  105. #
  106. # Save high score data into previously specified @file
  107. #
  108. def save_to_file
  109. require 'yaml'
  110. File.open(@file, 'w') do |out|
  111. YAML.dump(@high_scores, out)
  112. end
  113. end
  114. private
  115. def add_to_list(data)
  116. @high_scores.push(data)
  117. @high_scores.sort! { |a, b| b[@sort_on] <=> a[@sort_on] }
  118. @high_scores = @high_scores[0..@size]
  119. end
  120. def force_symbol_hash(hash)
  121. symbol_hash = {}
  122. hash.each_pair do |key, value|
  123. symbol_hash[key.to_sym] = value
  124. end
  125. return symbol_hash
  126. end
  127. end
  128. end