Implement PrecisionEvaluator for evaluating player input
This commit is contained in:
		
							parent
							
								
									76a69b534d
								
							
						
					
					
						commit
						89e9002b5e
					
				
							
								
								
									
										19
									
								
								include/game.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								include/game.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #ifndef GAME_H | ||||
| #define GAME_H | ||||
| 
 | ||||
| #include <SFML/Graphics/RenderWindow.hpp> | ||||
| #include <SFML/Window/Event.hpp> | ||||
| 
 | ||||
| class Game | ||||
| { | ||||
| public: | ||||
|     virtual ~Game() = default; | ||||
| 
 | ||||
|     virtual void run() = 0; | ||||
| 
 | ||||
|     virtual void input(const sf::Event& event) = 0; | ||||
|     virtual void update() = 0; | ||||
|     virtual void draw(const sf::RenderWindow& window) const = 0; | ||||
| }; | ||||
| 
 | ||||
| #endif // GAME_H
 | ||||
| @ -1,29 +0,0 @@ | ||||
| #ifndef PRECISIONEVALUATOR_H | ||||
| #define PRECISIONEVALUATOR_H | ||||
| 
 | ||||
| #include <SFML/System/Clock.hpp> | ||||
| 
 | ||||
| using microsec = sf::Int64; | ||||
| 
 | ||||
| template<typename GRADE> | ||||
| class PrecisionEvaluator | ||||
| { | ||||
| public: | ||||
| 
 | ||||
|     PrecisionEvaluator(microsec offset, microsec life_span_offset); | ||||
| 
 | ||||
|     microsec offset() const noexcept; | ||||
|     bool isActive(microsec music_play_offset) const noexcept; | ||||
|     GRADE calculatePrecision(microsec odds) const; | ||||
| 
 | ||||
|     static void resetPrecisionQualifier(microsec qualifier = 500000); | ||||
| 
 | ||||
| private: | ||||
|     microsec _offset; | ||||
|     microsec _start_handling_offset; | ||||
|     microsec _end_handling_offset; | ||||
| 
 | ||||
|     static microsec _precision_qualifier; | ||||
| }; | ||||
| 
 | ||||
| #endif // PRECISIONEVALUATOR_H
 | ||||
							
								
								
									
										66
									
								
								include/precisionevaluator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								include/precisionevaluator.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | ||||
| #ifndef PRECISIONEVALUATOR_H | ||||
| #define PRECISIONEVALUATOR_H | ||||
| 
 | ||||
| #include <numeric> | ||||
| #include <type_traits> | ||||
| #include <vector> | ||||
| #include <cmath> | ||||
| 
 | ||||
| #include <SFML/System/Clock.hpp> | ||||
| 
 | ||||
| using microsec = sf::Int64; | ||||
| 
 | ||||
| template<typename GRADE, typename = std::enable_if_t<std::is_enum<GRADE>::value>> | ||||
| class PrecisionEvaluator | ||||
| { | ||||
| public: | ||||
|     PrecisionEvaluator(std::vector<microsec>&& intervals, microsec offset) : | ||||
|         _offset(offset), | ||||
|         _intervals(std::move(intervals)) | ||||
|     { | ||||
|         microsec&& handling_offset = std::accumulate(intervals.begin(), intervals.end(), 0); | ||||
|         _start_handling_offset = _offset - handling_offset; | ||||
|         _end_handling_offset = _offset + handling_offset; | ||||
|     } | ||||
| 
 | ||||
|     inline microsec offset() const noexcept | ||||
|     { | ||||
|         return _offset; | ||||
|     } | ||||
| 
 | ||||
|     inline bool isActive(microsec music_play_offset) const noexcept | ||||
|     { | ||||
|         return music_play_offset > _start_handling_offset | ||||
|             && music_play_offset < _end_handling_offset; | ||||
|     } | ||||
| 
 | ||||
|     inline GRADE calculatePrecision(microsec odds) const | ||||
|     { | ||||
|         microsec shift_from_perfect = std::abs(odds - offset()); | ||||
| 
 | ||||
|         std::size_t raw_grade; | ||||
|         for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade) | ||||
|         { | ||||
|             if (shift_from_perfect <= _intervals[raw_grade]) | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         return static_cast<GRADE>(raw_grade); | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     microsec _offset; | ||||
|     microsec _start_handling_offset; | ||||
|     microsec _end_handling_offset; | ||||
| 
 | ||||
|     /* Amount of values in enum instanced as GRADES
 | ||||
|      * represents capacity of _intervals. | ||||
|      * So, for each V value in GRADES enum, _intervals[V] | ||||
|      * should return time shift from V - 1. | ||||
|      * V0 is PERFECT SCORE and the last V represents the worst | ||||
|      * grades which is death of note by expiration */ | ||||
| 
 | ||||
|     std::vector<microsec> _intervals; | ||||
| }; | ||||
| 
 | ||||
| #endif // PRECISIONEVALUATOR_H
 | ||||
| @ -173,9 +173,5 @@ void Application::update() | ||||
| 
 | ||||
| void Application::draw() | ||||
| { | ||||
|     _game_window.clear(); | ||||
|     _game_window.draw(*_timeline); | ||||
|     _game_window.draw(_debug); | ||||
|     _game_window.draw(_grade); | ||||
|     _game_window.display(); | ||||
| 
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										6
									
								
								src/classicgame/classicgame.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/classicgame/classicgame.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| #include "classicgame.h" | ||||
| 
 | ||||
| ClassicGame::ClassicGame() | ||||
| { | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										19
									
								
								src/classicgame/classicgame.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/classicgame/classicgame.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #ifndef CLASSICGAME_H | ||||
| #define CLASSICGAME_H | ||||
| 
 | ||||
| #include "game.h" | ||||
| 
 | ||||
| class ClassicGame : public Game | ||||
| { | ||||
| public: | ||||
|     explicit ClassicGame(); | ||||
|     virtual ~ClassicGame() override; | ||||
| 
 | ||||
|     virtual void run() override; | ||||
| 
 | ||||
|     virtual void input(const sf::Event& event) override; | ||||
|     virtual void update() override; | ||||
|     virtual void draw(const sf::RenderWindow& window) const override; | ||||
| }; | ||||
| 
 | ||||
| #endif // CLASSICGAME_H
 | ||||
							
								
								
									
										80
									
								
								src/note.cpp
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								src/note.cpp
									
									
									
									
									
								
							| @ -1,80 +0,0 @@ | ||||
| #include "note.h" | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| 
 | ||||
| Note::Note(microsec offset, microsec life_span_offset, Note::Arrow type) : | ||||
|     _offset(offset), | ||||
|     _start_handling_offset(_offset - life_span_offset), | ||||
|     _end_handling_offset(_offset + life_span_offset), | ||||
|     _type(type) | ||||
| {} | ||||
| 
 | ||||
| void Note::setPosition(coordinates position) | ||||
| { | ||||
|     _position = position; | ||||
| } | ||||
| 
 | ||||
| coordinates Note::position() const noexcept | ||||
| { | ||||
|     return _position; | ||||
| } | ||||
| 
 | ||||
| microsec Note::offset() const noexcept | ||||
| { | ||||
|     return _offset; | ||||
| } | ||||
| 
 | ||||
| NoteGrade Note::onTap(Arrow arrow_type, microsec tap_time_stamp) | ||||
| { | ||||
|     if (arrow_type != _type) | ||||
|         return {0, NoteGrade::Rating::WRONG}; | ||||
| 
 | ||||
|     microsec odds = std::abs(tap_time_stamp - _offset); | ||||
|     return calculatePrecision(odds); | ||||
| } | ||||
| 
 | ||||
| NoteGrade Note::calculatePrecision(microsec odds) const | ||||
| { | ||||
|     NoteGrade ret(0, NoteGrade::Rating::BAD); | ||||
| 
 | ||||
|     if (odds < _precision_qualifier) | ||||
|     { | ||||
|         ret = {50, NoteGrade::Rating::GREAT}; | ||||
|     } | ||||
| 
 | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| bool Note::isActive(microsec music_play_offset) const noexcept | ||||
| { | ||||
|     return music_play_offset > _start_handling_offset | ||||
|         && music_play_offset < _end_handling_offset; | ||||
| } | ||||
| 
 | ||||
| void Note::resetPrecisionQualifier(microsec qualifier) | ||||
| { | ||||
|     _precision_qualifier = qualifier; | ||||
| } | ||||
| 
 | ||||
| void Note::resetSprite(const std::shared_ptr<Sprite> &sprite) noexcept | ||||
| { | ||||
|     if (_sprite) | ||||
|         _sprite->setAttachment(false); | ||||
| 
 | ||||
|     _sprite = sprite; | ||||
| 
 | ||||
|     if (_sprite) | ||||
|         _sprite->setAttachment(true); | ||||
| } | ||||
| 
 | ||||
| Note::Arrow Note::type() const noexcept | ||||
| { | ||||
|     return _type; | ||||
| } | ||||
| 
 | ||||
| void Note::draw(sf::RenderTarget &target, sf::RenderStates states) const | ||||
| { | ||||
|     target.draw(*_sprite, states); | ||||
| } | ||||
| 
 | ||||
| microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second.
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user