/lib/chingu/high_score_list.rb
Ruby | 143 lines | 69 code | 15 blank | 59 comment | 8 complexity | c35df47bda2f516f8c5104fe486d8ac4 MD5 | raw file
Possible License(s): LGPL-2.1
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 22module Chingu 23 # 24 # Highscore-class 25 # 26 # - Keeps a local YAML file with highscores, default highscores.yml in root game dir. 27 # - Add, delete, clear highscores 28 # - Iterate through highscores with simple HighScores#each 29 # 30 class HighScoreList 31 attr_reader :file, :high_scores 32 33 # 34 # Create a new high score list with 0 entries 35 # 36 def initialize(options = {}) 37 @file = options[:file] || "high_score_list.yml" 38 @size = options[:size] || 100 39 @sort_on = options[:sort_on] || :score 40 @high_scores = Array.new 41 end 42 43 # 44 # Create a new high score list and try to load content from :file-parameter 45 # If no :file is given, HighScoreList tries to load from file "high_score_list.yml" 46 # 47 def self.load(options = {}) 48 require 'yaml' 49 high_score_list = HighScoreList.new(options) 50 high_score_list.load 51 return high_score_list 52 end 53 54 # 55 # Adda a new high score to the local file 56 # 'data' is a hash of key/value-pairs that needs to contain at least the keys :name and :score 57 # Returns the position it got in the list, with 1 beeing the first positions 58 # 59 def add(data) 60 raise "No :name value in high score!" if data[:name].nil? 61 raise "No :score value in high score!" if data[:score].nil? 62 add_to_list(force_symbol_hash(data)) 63 save_to_file 64 position_by_score(data[:score]) 65 end 66 alias << add 67 68 # 69 # Returns the position of full data-hash data entry, used internally 70 # 71 def position_by_data(data) 72 position = @high_scores.rindex(data) 73 position += 1 if position 74 end 75 76 # 77 # Returns the position 'score' would get in among the high scores: 78 # @high_score_list.position_by_score(999999999) # most likely returns 1 for the number one spot 79 # @high_score_list.position_by_score(1) # most likely returns nil since no placement is found (didn't make it to the high scores) 80 # 81 def position_by_score(score) 82 position = 1 83 @high_scores.each do |high_score| 84 return position if score >= high_score[:score] 85 position += 1 86 end 87 return nil 88 end 89 90 # 91 # Load data from previously specified @file 92 # 93 def load 94 @high_scores = YAML.load_file(@file) if File.exists?(@file) 95 @high_scores = @high_scores[0..@size] 96 end 97 98 # 99 # Direct access to invidual high scores 100 # 101 def [](index) 102 @high_scores[index] 103 end 104 105 # 106 # Iterate through all high scores 107 # 108 def each 109 @high_scores.each { |high_score| yield high_score } 110 end 111 112 def each_with_index 113 @high_scores.each_with_index { |high_score, index| yield high_score, index } 114 end 115 116 # 117 # Save high score data into previously specified @file 118 # 119 def save_to_file 120 require 'yaml' 121 File.open(@file, 'w') do |out| 122 YAML.dump(@high_scores, out) 123 end 124 end 125 126 private 127 128 def add_to_list(data) 129 @high_scores.push(data) 130 @high_scores.sort! { |a, b| b[@sort_on] <=> a[@sort_on] } 131 @high_scores = @high_scores[0..@size] 132 end 133 134 def force_symbol_hash(hash) 135 symbol_hash = {} 136 hash.each_pair do |key, value| 137 symbol_hash[key.to_sym] = value 138 end 139 return symbol_hash 140 end 141 142 end 143end