Mostly stylistic changes

This commit is contained in:
teejusb
2025-02-11 19:39:03 -08:00
parent 53ebe4cce1
commit 49263f3c3e
12 changed files with 172 additions and 194 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ RString MeasureInfo::ToString() const
return join(",", asMeasureInfo); return join(",", asMeasureInfo);
} }
void MeasureInfo::FromString(RString sValues) void MeasureInfo::FromString(const RString& sValues)
{ {
std::vector<RString> asValues; std::vector<RString> asValues;
split( sValues, ",", asValues, true ); split( sValues, ",", asValues, true );
+2 -2
View File
@@ -2,7 +2,7 @@
#define MEASURE_INFO_H #define MEASURE_INFO_H
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
class NoteData; #include "NoteData.h"
/** This is a container for per-measure stats of a stepchart. /** This is a container for per-measure stats of a stepchart.
This data is calculated and saved to the song cache files as the #MEASUREINFO tag. This data is calculated and saved to the song cache files as the #MEASUREINFO tag.
@@ -30,7 +30,7 @@ struct MeasureInfo
} }
RString ToString() const; RString ToString() const;
void FromString( RString sValues ); void FromString(const RString& sValues );
static void CalculateMeasureInfo(const NoteData &in, MeasureInfo &out); static void CalculateMeasureInfo(const NoteData &in, MeasureInfo &out);
}; };
+1 -1
View File
@@ -311,7 +311,7 @@ public:
int GetNumTapNotesNoTiming( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; int GetNumTapNotesNoTiming( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const;
int GetNumTapNotesInRow( int iRow ) const; int GetNumTapNotesInRow( int iRow ) const;
int GetNumMinesInRow( int iRow ) const; int GetNumMinesInRow( int iRow ) const;
int GetNumMines( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; int GetNumMines( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const;
int GetNumRowsWithTap( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; int GetNumRowsWithTap( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const;
int GetNumRowsWithTapOrHoldHead( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; int GetNumRowsWithTapOrHoldHead( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const;
/* Optimization: for the default of start to end, use the second (faster). XXX: Second what? -- Steve */ /* Optimization: for the default of start to end, use the second (faster). XXX: Second what? -- Steve */
-1
View File
@@ -419,7 +419,6 @@ void SetMeasureInfo(StepsTagInfo& info)
FOREACH_PlayerNumber(pn) FOREACH_PlayerNumber(pn)
{ {
v[pn].FromString(values[pn]); v[pn].FromString(values[pn]);
} }
info.steps->SetCachedMeasureInfo(v); info.steps->SetCachedMeasureInfo(v);
} }
+1 -1
View File
@@ -448,7 +448,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
} }
lines.push_back(ssprintf("#MEASUREINFO:%s;", join("|", asMeasureInfo).c_str())); lines.push_back(ssprintf("#MEASUREINFO:%s;", join("|", asMeasureInfo).c_str()));
// MV: #STEPFILENAME has to be at the end of the cache tags, // NOTE(MV): #STEPFILENAME has to be at the end of the cache tags,
// because it's used in SSCLoader::LoadFromSimfile to determine when // because it's used in SSCLoader::LoadFromSimfile to determine when
// to switch the state back to GETTING_SONG_INFO, which means any tags // to switch the state back to GETTING_SONG_INFO, which means any tags
// after it will be ignored. // after it will be ignored.
+6 -10
View File
@@ -6,8 +6,6 @@
namespace StepParity namespace StepParity
{ {
const int DOUBLESTEP= 850; const int DOUBLESTEP= 850;
const int BRACKETJACK= 20; const int BRACKETJACK= 20;
const int JACK= 30; const int JACK= 30;
@@ -23,15 +21,14 @@ namespace StepParity
const int DISTANCE= 6; const int DISTANCE= 6;
const int SPIN= 1000; const int SPIN= 1000;
const int SIDESWITCH= 130; const int SIDESWITCH= 130;
const int CROWDED_BRACKET = 0; const int CROWDED_BRACKET = 0;
const int OTHER = 0; const int OTHER = 0;
// 0.1 = 1/16th note at 150bpm. Jacks quicker than this are harder. // 0.1 = 1/16th note at 150bpm. Jacks quicker than this are harder.
// Above this speed, footswitches should be prioritized // Above this speed, footswitches should be prioritized
const float JACK_THRESHOLD = 0.1; const float JACK_THRESHOLD = 0.1;
// 0.15 = 1/8th at 200bpm, or 3/16th at 150bpm. Below this speed, jumps should be prioritized // 0.15 = 1/8th at 200bpm, or 3/16th at 150bpm. Below this speed, jumps should be prioritized
const float SLOW_BRACKET_THRESHOLD = 0.15; const float SLOW_BRACKET_THRESHOLD = 0.15;
// 0.2 = 1/8th at 150bpm. Footswitches slower than this are harder. // 0.2 = 1/8th at 150bpm. Footswitches slower than this are harder.
// Below this speed, jacks should be prioritized // Below this speed, jacks should be prioritized
const float SLOW_FOOTSWITCH_THRESHOLD = 0.2; const float SLOW_FOOTSWITCH_THRESHOLD = 0.2;
@@ -45,8 +42,7 @@ namespace StepParity
StageLayout layout; StageLayout layout;
public: public:
StepParityCost(const StageLayout& _layout): layout(_layout){ StepParityCost(const StageLayout& _layout): layout(_layout) {}
}
/// @brief Computes and returns a cost value for the player moving from initialState to resultState. /// @brief Computes and returns a cost value for the player moving from initialState to resultState.
/// @param initialState The starting position of the player /// @param initialState The starting position of the player
@@ -63,18 +59,18 @@ namespace StepParity
float calcBracketTapCost(State * initialState, State * resultState, Row &row, int leftHeel, int leftToe, int rightHeel, int rightToe, float elapsedTime, int columnCount); float calcBracketTapCost(State * initialState, State * resultState, Row &row, int leftHeel, int leftToe, int rightHeel, int rightToe, float elapsedTime, int columnCount);
float calcMovingFootWhileOtherIsntOnPadCost(State * initialState, State * resultState, int columnCount); float calcMovingFootWhileOtherIsntOnPadCost(State * initialState, State * resultState, int columnCount);
float calcBracketJackCost(State * initialState, State * resultState, std::vector<Row> &rows, int rowIndex, bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, bool didJump, int columnCount); float calcBracketJackCost(State * initialState, State * resultState, std::vector<Row> &rows, int rowIndex, bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, bool didJump, int columnCount);
float calcDoublestepCost(State * initialState, State * resultState, std::vector<Row> & rows, int rowIndex, bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, bool didJump, int columnCount); float calcDoublestepCost(State * initialState, State * resultState, std::vector<Row> & rows, int rowIndex, bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, bool didJump, int columnCount);
float calcJumpCost(Row &row, bool movedLeft, bool movedRight, float elapsedTime, int columnCount); float calcJumpCost(Row &row, bool movedLeft, bool movedRight, float elapsedTime, int columnCount);
float calcSlowBracketCost(Row & row, bool movedLeft, bool movedRight, float elapsedTime); float calcSlowBracketCost(Row & row, bool movedLeft, bool movedRight, float elapsedTime);
float calcTwistedFootCost(State * resultState); float calcTwistedFootCost(State * resultState);
float calcMissedFootswitchCost(Row &row, bool jackedLeft, bool jackedRight, int columnCount); float calcMissedFootswitchCost(Row &row, bool jackedLeft, bool jackedRight, int columnCount);
float calcFacingCosts(State * initialState, State * resultState, std::vector<StepParity::Foot> &combinedColumns, int columnCount); float calcFacingCosts(State * initialState, State * resultState, std::vector<StepParity::Foot> &combinedColumns, int columnCount);
float calcSpinCosts(State * initialState, State * resultState, std::vector<StepParity::Foot> & combinedColumns, int columnCount); float calcSpinCosts(State * initialState, State * resultState, std::vector<StepParity::Foot> & combinedColumns, int columnCount);
float caclFootswitchCost(State * initialState, State * resultState, Row &row, std::vector<StepParity::Foot> &combinedColumns, float elapsedTime, int columnCount); float caclFootswitchCost(State * initialState, State * resultState, Row &row, std::vector<StepParity::Foot> &combinedColumns, float elapsedTime, int columnCount);
float calcSideswitchCost(State * initialState, State * resultState, int columnCount); float calcSideswitchCost(State * initialState, State * resultState, int columnCount);
float calcJackCost(bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, float elapsedTime, int columnCount); float calcJackCost(bool movedLeft, bool movedRight, bool jackedLeft, bool jackedRight, float elapsedTime, int columnCount);
float calcBigMovementsQuicklyCost(State * initialState, State * resultState, float elapsedTime, int columnCount); float calcBigMovementsQuicklyCost(State * initialState, State * resultState, float elapsedTime, int columnCount);
float calcCrowdedBracketCost(State * initialState, State * resultState, float elapsedTime, int columnCount); float calcCrowdedBracketCost(State * initialState, State * resultState, float elapsedTime, int columnCount);
bool didDoubleStep(State * initialState, State * resultState, std::vector<Row> &rows, int rowIndex, bool movedLeft, bool jackedLeft, bool movedRight, bool jackedRight, int columnCount); bool didDoubleStep(State * initialState, State * resultState, std::vector<Row> &rows, int rowIndex, bool movedLeft, bool jackedLeft, bool movedRight, bool jackedRight, int columnCount);
bool didJackLeft(State * initialState, State * resultState, int leftHeel, int leftToe, bool movedLeft, bool didJump, int columnCount); bool didJackLeft(State * initialState, State * resultState, int leftHeel, int leftToe, bool movedLeft, bool didJump, int columnCount);
+20 -36
View File
@@ -3,10 +3,7 @@
using namespace StepParity; using namespace StepParity;
//
// Graph/Node methods // Graph/Node methods
//
int calculateVectorHash(const std::vector<Foot> &vec) int calculateVectorHash(const std::vector<Foot> &vec)
{ {
int value = 0; int value = 0;
@@ -53,7 +50,7 @@ void State::calculateHashes()
StepParityNode * StepParityGraph::addOrGetExistingNode(const State &state) StepParityNode * StepParityGraph::addOrGetExistingNode(const State &state)
{ {
// this is silly, but the start node has a rowIndex of -1 // This is silly, but the start node has a rowIndex of -1
// which doesn't work as an array index. // which doesn't work as an array index.
int rowIndex = state.rowIndex + 1; int rowIndex = state.rowIndex + 1;
while (static_cast<int>(stateNodeMap.size()) <= rowIndex) while (static_cast<int>(stateNodeMap.size()) <= rowIndex)
@@ -74,10 +71,7 @@ StepParityNode * StepParityGraph::addOrGetExistingNode(const State &state)
return stateNodeMap[rowIndex][state]; return stateNodeMap[rowIndex][state];
} }
//
// StageLayout // StageLayout
//
bool StageLayout::bracketCheck(int column1, int column2) bool StageLayout::bracketCheck(int column1, int column2)
{ {
StagePoint p1 = columns[column1]; StagePoint p1 = columns[column1];
@@ -169,10 +163,7 @@ float StageLayout::getPlayerAngle(StepParity::StagePoint left, StepParity::Stage
return atan2f(det, dot); return atan2f(det, dot);
} }
//
// Row // Row
//
void Row::setFootPlacement(const std::vector<Foot> & footPlacement) void Row::setFootPlacement(const std::vector<Foot> & footPlacement)
{ {
for (int c = 0; c < columnCount; c++) { for (int c = 0; c < columnCount; c++) {
@@ -185,12 +176,7 @@ void Row::setFootPlacement(const std::vector<Foot> & footPlacement)
} }
} }
//
// Json methods // Json methods
//
template<typename Container> template<typename Container>
Json::Value FeetToJson(const Container& feets, bool useStrings) Json::Value FeetToJson(const Container& feets, bool useStrings)
{ {
@@ -216,8 +202,8 @@ Json::Value State::ToJson(bool useStrings)
Json::Value jsonMovedFeet = FeetToJson(movedFeet, useStrings); Json::Value jsonMovedFeet = FeetToJson(movedFeet, useStrings);
Json::Value jsonHoldFeet = FeetToJson(holdFeet, useStrings); Json::Value jsonHoldFeet = FeetToJson(holdFeet, useStrings);
root["idx"] = idx; root["idx"] = idx;
root["columns"] = jsonColumns; root["columns"] = jsonColumns;
root["movedFeet"] = jsonMovedFeet; root["movedFeet"] = jsonMovedFeet;
root["holdFeet"] = jsonHoldFeet; root["holdFeet"] = jsonHoldFeet;
root["second"] = second; root["second"] = second;
@@ -286,22 +272,21 @@ Json::Value StepParityNode::ToJson()
{ {
Json::Value n; Json::Value n;
n["id"] = it->first->id; n["id"] = it->first->id;
Json::Value jsonCosts; Json::Value jsonCosts;
float * costs = it->second; float * costs = it->second;
for(int i = 0; i < NUM_Cost; i++) for(int i = 0; i < NUM_Cost; i++)
{ {
jsonCosts[COST_LABELS[i]] = costs[i]; jsonCosts[COST_LABELS[i]] = costs[i];
} }
n["costs"] = jsonCosts; n["costs"] = jsonCosts;
jsonNeighbors.append(n); jsonNeighbors.append(n);
} }
root["id"] = id; root["id"] = id;
root["stateIdx"] = state.idx; root["stateIdx"] = state.idx;
root["neighbors"] = jsonNeighbors; root["neighbors"] = jsonNeighbors;
return root; return root;
} }
Json::Value Row::ToJsonRows(const std::vector<Row> & rows, bool useStrings) Json::Value Row::ToJsonRows(const std::vector<Row> & rows, bool useStrings)
{ {
Json::Value root; Json::Value root;
@@ -327,23 +312,22 @@ Json::Value Row::ParityRowsJson(const std::vector<Row> & rows)
return root; return root;
} }
Json::Value StepParityGraph::ToJson() Json::Value StepParityGraph::ToJson()
{ {
Json::Value jsonNodes; Json::Value jsonNodes;
for(auto node: nodes) for(auto node: nodes)
{ {
jsonNodes.append(node->ToJson()); jsonNodes.append(node->ToJson());
}
Json::Value jsonStates;
for(auto state: states)
{
jsonStates.append(state->ToJson(false));
} }
Json::Value jsonStates;
for(auto state: states)
{
jsonStates.append(state->ToJson(false));
}
Json::Value root; Json::Value root;
root["nodes"] = jsonNodes; root["nodes"] = jsonNodes;
root["states"] = jsonStates; root["states"] = jsonStates;
return root; return root;
} }
+90 -81
View File
@@ -8,7 +8,6 @@
#include <queue> #include <queue>
#include <unordered_map> #include <unordered_map>
namespace StepParity { namespace StepParity {
const float CLM_SECOND_INVALID = -1; const float CLM_SECOND_INVALID = -1;
@@ -33,48 +32,48 @@ namespace StepParity {
const RString TapNoteTypeShortNames[] = { "Empty", "Tap", "Mine", "Attack", "AutoKeySound", "Fake", "", "" }; const RString TapNoteTypeShortNames[] = { "Empty", "Tap", "Mine", "Attack", "AutoKeySound", "Fake", "", "" };
const RString TapNoteSubTypeShortNames[] = { "Hold", "Roll", "", "" }; const RString TapNoteSubTypeShortNames[] = { "Hold", "Roll", "", "" };
enum Cost enum Cost
{ {
COST_DOUBLESTEP = 0, COST_DOUBLESTEP = 0,
COST_BRACKETJACK, COST_BRACKETJACK,
COST_JACK, COST_JACK,
COST_JUMP, COST_JUMP,
COST_SLOW_BRACKET, COST_SLOW_BRACKET,
COST_TWISTED_FOOT, COST_TWISTED_FOOT,
COST_BRACKETTAP, COST_BRACKETTAP,
COST_HOLDSWITCH, COST_HOLDSWITCH,
COST_MINE, COST_MINE,
COST_FOOTSWITCH, COST_FOOTSWITCH,
COST_MISSED_FOOTSWITCH, COST_MISSED_FOOTSWITCH,
COST_FACING, COST_FACING,
COST_DISTANCE, COST_DISTANCE,
COST_SPIN, COST_SPIN,
COST_SIDESWITCH, COST_SIDESWITCH,
COST_CROWDED_BRACKET , COST_CROWDED_BRACKET ,
COST_OTHER, COST_OTHER,
COST_TOTAL, COST_TOTAL,
NUM_Cost NUM_Cost
}; };
const RString COST_LABELS[] = { const RString COST_LABELS[] = {
"DOUBLESTEP", "DOUBLESTEP",
"BRACKETJACK", "BRACKETJACK",
"JACK", "JACK",
"JUMP", "JUMP",
"SLOW_BRACKET", "SLOW_BRACKET",
"TWISTED_FOOT", "TWISTED_FOOT",
"BRACKETTAP", "BRACKETTAP",
"HOLDSWITCH", "HOLDSWITCH",
"MINE", "MINE",
"FOOTSWITCH", "FOOTSWITCH",
"MISSED_FOOTSWITCH", "MISSED_FOOTSWITCH",
"FACING", "FACING",
"DISTANCE", "DISTANCE",
"SPIN", "SPIN",
"SIDESWITCH", "SIDESWITCH",
"CROWDED_BRACKET", "CROWDED_BRACKET",
"OTHER", "OTHER",
"TOTAL" "TOTAL"
}; };
struct StagePoint { struct StagePoint {
float x; float x;
@@ -91,12 +90,11 @@ namespace StepParity {
std::vector<int> downArrows; std::vector<int> downArrows;
std::vector<int> sideArrows; std::vector<int> sideArrows;
StageLayout(StepsType t, StageLayout(StepsType t,
const std::vector<StagePoint>& c, const std::vector<StagePoint>& c,
const std::vector<int> & u, const std::vector<int> & u,
const std::vector<int> & d, const std::vector<int> & d,
const std::vector<int> & s) :type(t), columns(c), upArrows(u), downArrows(d), sideArrows(s) { const std::vector<int> & s) : type(t), columns(c), upArrows(u), downArrows(d), sideArrows(s) {
this->columnCount = static_cast<int>(this->columns.size()); this->columnCount = static_cast<int>(this->columns.size());
} }
@@ -126,11 +124,11 @@ namespace StepParity {
FootPlacement holdFeet; // Any feet that stayed in place due to a hold/roll note. FootPlacement holdFeet; // Any feet that stayed in place due to a hold/roll note.
float second; // The time of the song represented by this state float second; // The time of the song represented by this state
int rowIndex; // The index of the row represented by this state int rowIndex; // The index of the row represented by this state
int idx; int idx;
int whereTheFeetAre[NUM_Foot]; // the inverse of columns int whereTheFeetAre[NUM_Foot]; // the inverse of columns
bool didTheFootMove[NUM_Foot]; // the inverse of movedFeet bool didTheFootMove[NUM_Foot]; // the inverse of movedFeet
bool isTheFootHolding[NUM_Foot]; //inverse of holdFeet bool isTheFootHolding[NUM_Foot]; //inverse of holdFeet
// These hashes are used in operator<() to speed up the comparison of the vectors. // These hashes are used in operator<() to speed up the comparison of the vectors.
// Their values are computed by calculateHashes(), which is used in StepParityGenerator::buildStateGraph(). // Their values are computed by calculateHashes(), which is used in StepParityGenerator::buildStateGraph().
int columnsHash = 0; int columnsHash = 0;
@@ -149,13 +147,13 @@ namespace StepParity {
holdFeet = FootPlacement(columnCount, NONE); holdFeet = FootPlacement(columnCount, NONE);
second = 0; second = 0;
rowIndex = 0; rowIndex = 0;
idx = -1; idx = -1;
for(int i = 0; i < NUM_Foot; i++) for(int i = 0; i < NUM_Foot; i++)
{ {
whereTheFeetAre[i] = -1; whereTheFeetAre[i] = -1;
didTheFootMove[i] = false; didTheFootMove[i] = false;
isTheFootHolding[i] = false; isTheFootHolding[i] = false;
} }
} }
Json::Value ToJson(bool useStrings); Json::Value ToJson(bool useStrings);
@@ -191,14 +189,17 @@ namespace StepParity {
/// This shouldn't be confused with the idea of "rows" elsewhere in SM. Here, we only use /// This shouldn't be confused with the idea of "rows" elsewhere in SM. Here, we only use
/// these Rows to represent a row that isn't empty. /// these Rows to represent a row that isn't empty.
struct Row { struct Row {
// notes for the given row
std::vector<IntermediateNoteData> notes;
std::vector<IntermediateNoteData> notes; // notes for the given row // Any active hold notes, including ones that started before this row
std::vector<IntermediateNoteData> holds; // Any active hold notes, including ones that started before this row std::vector<IntermediateNoteData> holds;
std::set<int> holdTails; // Column index of any holds that end on this row // Column index of any holds that end on this row
std::vector<float> mines; // If a mine occurred either on this row, or on a row on its own immediately std::set<int> holdTails;
// preceding this one, the time of when that mine occurred, indexed by column. // If a mine occurred either on this row, or on a row on its own immediately
std::vector<float> fakeMines; // The same thing, but for fake mines // preceding this one, the time of when that mine occurred, indexed by column.
std::vector<float> mines;
// The same thing, but for fake mines
std::vector<float> fakeMines;
FootPlacement columns; FootPlacement columns;
std::vector<int> whereTheFeetAre; std::vector<int> whereTheFeetAre;
@@ -235,24 +236,30 @@ namespace StepParity {
/// @brief A counter used while creating rows /// @brief A counter used while creating rows
struct RowCounter struct RowCounter
{ {
std::vector<IntermediateNoteData> notes; // Notes for the "current" row being generated // Notes for the "current" row being generated
std::vector<IntermediateNoteData> activeHolds; // Any holds that are active for the current row std::vector<IntermediateNoteData> notes;
// Any holds that are active for the current row
std::vector<IntermediateNoteData> activeHolds;
float lastColumnSecond = CLM_SECOND_INVALID; float lastColumnSecond = CLM_SECOND_INVALID;
float lastColumnBeat = CLM_SECOND_INVALID; float lastColumnBeat = CLM_SECOND_INVALID;
std::vector<float> mines; // The time at which a mine occurred for the current row, // The time at which a mine occurred for the current row,
// indexed by column // indexed by column
std::vector<float> fakeMines; // The time at which a fake mine occurred for the current row, std::vector<float> mines;
// indexed by column // The time at which a fake mine occurred for the current row,
// indexed by column
std::vector<float> fakeMines;
std::vector<float> nextMines; // The time at which a mine occurred in the _previous_ row, // The time at which a mine occurred in the _previous_ row,
// indexed by column // indexed by column
std::vector<float> nextFakeMines; // The time at which a fake mine occurred in the _previous_ row, std::vector<float> nextMines;
// indexed by column // The time at which a fake mine occurred in the _previous_ row,
int noteCount = 0; // number of "notes" added to the counter for the current row. // indexed by column
std::vector<float> nextFakeMines;
// number of "notes" added to the counter for the current row.
int noteCount = 0;
RowCounter(int columnCount) RowCounter(int columnCount)
{ {
notes = std::vector<IntermediateNoteData>(columnCount); notes = std::vector<IntermediateNoteData>(columnCount);
activeHolds = std::vector<IntermediateNoteData>(columnCount); activeHolds = std::vector<IntermediateNoteData>(columnCount);
mines = std::vector<float>(columnCount, 0); mines = std::vector<float>(columnCount, 0);
@@ -270,10 +277,12 @@ namespace StepParity {
/// following row of the step chart. /// following row of the step chart.
struct StepParityNode struct StepParityNode
{ {
int id = 0; // The index of this node in its graph // The index of this node in its graph
int id = 0;
State state; State state;
std::unordered_map<StepParityNode *, float*> neighbors; // Connections to, and the cost of moving to, the connected nodes // Connections to, and the cost of moving to, the connected nodes
std::unordered_map<StepParityNode *, float*> neighbors;
~StepParityNode() ~StepParityNode()
{ {
@@ -313,17 +322,18 @@ namespace StepParity {
std::vector<std::map<State, StepParityNode *, StateComparator>> stateNodeMap; std::vector<std::map<State, StepParityNode *, StateComparator>> stateNodeMap;
public: public:
StepParityNode * startNode; // This represents the very start of the song, before any notes // This represents the very start of the song, before any notes
StepParityNode *endNode; // This represents the end of the song, after all of the notes StepParityNode * startNode;
// This represents the end of the song, after all of the notes
StepParityNode *endNode;
~StepParityGraph() ~StepParityGraph()
{ {
states.clear(); states.clear();
for(StepParityNode * node: nodes) for(StepParityNode * node: nodes)
{ {
delete node; delete node;
} }
} }
/// @brief Returns a pointer to a StepParityNode that represents the given state within the graph. /// @brief Returns a pointer to a StepParityNode that represents the given state within the graph.
@@ -332,7 +342,8 @@ namespace StepParity {
/// @return /// @return
StepParityNode *addOrGetExistingNode(const State &state); StepParityNode *addOrGetExistingNode(const State &state);
void addEdge(StepParityNode* from, StepParityNode* to, float* costs) { void addEdge(StepParityNode* from, StepParityNode* to, float* costs)
{
from->neighbors[to] = costs; from->neighbors[to] = costs;
} }
@@ -348,8 +359,6 @@ namespace StepParity {
return nodes[index]; return nodes[index];
} }
}; };
}; };
#endif #endif
+31 -29
View File
@@ -5,11 +5,8 @@
#include "TechCounts.h" #include "TechCounts.h"
#include "GameState.h" #include "GameState.h"
using namespace StepParity; using namespace StepParity;
void StepParityGenerator::analyzeNoteData(const NoteData &in) void StepParityGenerator::analyzeNoteData(const NoteData &in)
{ {
columnCount = in.GetNumTracks(); columnCount = in.GetNumTracks();
@@ -25,7 +22,6 @@ void StepParityGenerator::analyzeNoteData(const NoteData &in)
analyzeGraph(); analyzeGraph();
} }
void StepParityGenerator::analyzeGraph() { void StepParityGenerator::analyzeGraph() {
nodes_for_rows = computeCheapestPath(); nodes_for_rows = computeCheapestPath();
ASSERT_M(nodes_for_rows.size() == rows.size(), "nodes_for_rows should be the same length as rows!"); ASSERT_M(nodes_for_rows.size() == rows.size(), "nodes_for_rows should be the same length as rows!");
@@ -37,7 +33,6 @@ void StepParityGenerator::analyzeGraph() {
} }
} }
void StepParityGenerator::buildStateGraph() void StepParityGenerator::buildStateGraph()
{ {
// The first node of the graph is beginningState, which represents the time before // The first node of the graph is beginningState, which represents the time before
@@ -95,17 +90,16 @@ void StepParityGenerator::buildStateGraph()
{ {
State state = previousStates.front(); State state = previousStates.front();
StepParityNode *node = graph.addOrGetExistingNode(state); StepParityNode *node = graph.addOrGetExistingNode(state);
float * emptyCosts = new float[NUM_Cost]; float * emptyCosts = new float[NUM_Cost];
for(int i = 0; i < NUM_Cost; i++) for(int i = 0; i < NUM_Cost; i++)
{ {
emptyCosts[i] = 0; emptyCosts[i] = 0;
} }
graph.addEdge(node, endNode, emptyCosts); graph.addEdge(node, endNode, emptyCosts);
previousStates.pop(); previousStates.pop();
} }
} }
State StepParityGenerator::initResultState(State &initialState, Row &row, const FootPlacement &columns) State StepParityGenerator::initResultState(State &initialState, Row &row, const FootPlacement &columns)
{ {
State resultState(row.columnCount); State resultState(row.columnCount);
@@ -117,18 +111,18 @@ State StepParityGenerator::initResultState(State &initialState, Row &row, const
if(columns[i] == NONE) { if(columns[i] == NONE) {
continue; continue;
} }
resultState.whereTheFeetAre[columns[i]] = i; resultState.whereTheFeetAre[columns[i]] = i;
if(row.holds[i].type == TapNoteType_Empty) if(row.holds[i].type == TapNoteType_Empty)
{ {
resultState.movedFeet[i] = columns[i]; resultState.movedFeet[i] = columns[i];
resultState.didTheFootMove[columns[i]] = true; resultState.didTheFootMove[columns[i]] = true;
continue; continue;
} }
if(initialState.columns[i] != columns[i]) if(initialState.columns[i] != columns[i])
{ {
resultState.movedFeet[i] = columns[i]; resultState.movedFeet[i] = columns[i];
resultState.didTheFootMove[columns[i]] = true; resultState.didTheFootMove[columns[i]] = true;
} }
} }
@@ -141,14 +135,13 @@ State StepParityGenerator::initResultState(State &initialState, Row &row, const
if(row.holds[i].type != TapNoteType_Empty) if(row.holds[i].type != TapNoteType_Empty)
{ {
resultState.holdFeet[i] = columns[i]; resultState.holdFeet[i] = columns[i];
resultState.isTheFootHolding[columns[i]] = true; resultState.isTheFootHolding[columns[i]] = true;
} }
} }
resultState.second = row.second; resultState.second = row.second;
return resultState; return resultState;
} }
std::vector<FootPlacement>* StepParityGenerator::getFootPlacementPermutations(const Row &row) std::vector<FootPlacement>* StepParityGenerator::getFootPlacementPermutations(const Row &row)
{ {
int cacheKey = getPermuteCacheKey(row); int cacheKey = getPermuteCacheKey(row);
@@ -175,15 +168,25 @@ std::vector<FootPlacement> StepParityGenerator::PermuteFootPlacements(const Row
for (unsigned long i = 0; i < columns.size(); i++) for (unsigned long i = 0; i < columns.size(); i++)
{ {
if (columns[i] == NONE) if (columns[i] == NONE)
{
continue; continue;
}
if (columns[i] == LEFT_HEEL) if (columns[i] == LEFT_HEEL)
{
leftHeelIndex = i; leftHeelIndex = i;
}
if (columns[i] == LEFT_TOE) if (columns[i] == LEFT_TOE)
{
leftToeIndex = i; leftToeIndex = i;
}
if (columns[i] == RIGHT_HEEL) if (columns[i] == RIGHT_HEEL)
{
rightHeelIndex = i; rightHeelIndex = i;
}
if (columns[i] == RIGHT_TOE) if (columns[i] == RIGHT_TOE)
{
rightToeIndex = i; rightToeIndex = i;
}
} }
if ( if (
(leftHeelIndex == -1 && leftToeIndex != -1) || (leftHeelIndex == -1 && leftToeIndex != -1) ||
@@ -194,19 +197,24 @@ std::vector<FootPlacement> StepParityGenerator::PermuteFootPlacements(const Row
if (leftHeelIndex != -1 && leftToeIndex != -1) if (leftHeelIndex != -1 && leftToeIndex != -1)
{ {
if (!layout.bracketCheck(leftHeelIndex, leftToeIndex)) if (!layout.bracketCheck(leftHeelIndex, leftToeIndex))
{
return std::vector<FootPlacement>(); return std::vector<FootPlacement>();
}
} }
if (rightHeelIndex != -1 && rightToeIndex != -1) if (rightHeelIndex != -1 && rightToeIndex != -1)
{ {
if (!layout.bracketCheck(rightHeelIndex, rightToeIndex)) if (!layout.bracketCheck(rightHeelIndex, rightToeIndex))
{
return std::vector<FootPlacement>(); return std::vector<FootPlacement>();
}
} }
return {columns}; return {columns};
} }
std::vector<FootPlacement> permutations; std::vector<FootPlacement> permutations;
if (row.notes[column].type != TapNoteType_Empty || row.holds[column].type != TapNoteType_Empty) { if (row.notes[column].type != TapNoteType_Empty ||
row.holds[column].type != TapNoteType_Empty)
{
for (StepParity::Foot foot: FEET) { for (StepParity::Foot foot: FEET) {
if(std::find(columns.begin(), columns.end(), foot) != columns.end()) if(std::find(columns.begin(), columns.end(), foot) != columns.end())
{ {
@@ -224,7 +232,6 @@ std::vector<FootPlacement> StepParityGenerator::PermuteFootPlacements(const Row
return PermuteFootPlacements(row, columns, column + 1); return PermuteFootPlacements(row, columns, column + 1);
} }
std::vector<int> StepParityGenerator::computeCheapestPath() std::vector<int> StepParityGenerator::computeCheapestPath()
{ {
int start = graph.startNode->id; int start = graph.startNode->id;
@@ -241,7 +248,6 @@ std::vector<int> StepParityGenerator::computeCheapestPath()
{ {
int neighbor_id = neighbor.first->id; int neighbor_id = neighbor.first->id;
float weight = neighbor.second[COST_TOTAL]; float weight = neighbor.second[COST_TOTAL];
// printf("computeCheapestPath:: weight = %f", weight);
if(cost[i] + weight < cost[neighbor_id]) if(cost[i] + weight < cost[neighbor_id])
{ {
cost[neighbor_id] = cost[i] + weight; cost[neighbor_id] = cost[i] + weight;
@@ -264,8 +270,8 @@ std::vector<int> StepParityGenerator::computeCheapestPath()
return shortest_path; return shortest_path;
} }
void StepParityGenerator::CreateIntermediateNoteData(
void StepParityGenerator::CreateIntermediateNoteData(const NoteData &in, std::vector<IntermediateNoteData> &out) const NoteData &in, std::vector<IntermediateNoteData> &out)
{ {
TimingData *timing = GAMESTATE->GetProcessedTimingData(); TimingData *timing = GAMESTATE->GetProcessedTimingData();
int columnCount = in.GetNumTracks(); int columnCount = in.GetNumTracks();
@@ -302,7 +308,6 @@ void StepParityGenerator::CreateIntermediateNoteData(const NoteData &in, std::ve
out.assign(notes.begin(), notes.end()); out.assign(notes.begin(), notes.end());
} }
void StepParityGenerator::CreateRows(const NoteData &in) void StepParityGenerator::CreateRows(const NoteData &in)
{ {
TimingData *timing = GAMESTATE->GetProcessedTimingData(); TimingData *timing = GAMESTATE->GetProcessedTimingData();
@@ -332,7 +337,6 @@ void StepParityGenerator::CreateRows(const NoteData &in)
// before checking whether or not this note represens a new row. // before checking whether or not this note represens a new row.
// But we only want to create a new Row if it has at least one note. // But we only want to create a new Row if it has at least one note.
// So probably something like // So probably something like
/* /*
for(note of notes) for(note of notes)
@@ -349,7 +353,6 @@ void StepParityGenerator::CreateRows(const NoteData &in)
check if note is a mine or fake mine check if note is a mine or fake mine
if note is fake continue if note is fake continue
put note into counter.notes put note into counter.notes
} }
*/ */
if (note.second == counter.lastColumnSecond && rows.size() > 0) if (note.second == counter.lastColumnSecond && rows.size() > 0)
@@ -384,14 +387,13 @@ void StepParityGenerator::CreateRows(const NoteData &in)
if (counter.lastColumnSecond != note.second) if (counter.lastColumnSecond != note.second)
{ {
// We're past the previous row, so save all of the previous row's data.
// we're past the previous row, so save all of the previous row's data
if (counter.lastColumnSecond != CLM_SECOND_INVALID) if (counter.lastColumnSecond != CLM_SECOND_INVALID)
{ {
AddRow(counter); AddRow(counter);
} }
// Move mines and fakeMines to "next", and reset counters // Move mines and fakeMines to "next", and reset counters.
counter.lastColumnSecond = note.second; counter.lastColumnSecond = note.second;
counter.lastColumnBeat = note.beat; counter.lastColumnBeat = note.beat;
counter.nextMines.assign(counter.mines.begin(), counter.mines.end()); counter.nextMines.assign(counter.mines.begin(), counter.mines.end());
@@ -400,7 +402,7 @@ void StepParityGenerator::CreateRows(const NoteData &in)
counter.mines = std::vector<float>(columnCount); counter.mines = std::vector<float>(columnCount);
counter.fakeMines = std::vector<float>(columnCount); counter.fakeMines = std::vector<float>(columnCount);
// reset any now-inactive holds to empty values // Reset any now-inactive holds to empty values.
for (int c = 0; c < columnCount; c++) for (int c = 0; c < columnCount; c++)
{ {
if (counter.activeHolds[c].type == TapNoteType_Empty || note.beat > counter.activeHolds[c].beat + counter.activeHolds[c].hold_length) if (counter.activeHolds[c].type == TapNoteType_Empty || note.beat > counter.activeHolds[c].beat + counter.activeHolds[c].hold_length)
+3 -4
View File
@@ -332,8 +332,7 @@ void Steps::CalculateRadarValues( float fMusicLengthSeconds )
this->GetNoteData( tempNoteData ); this->GetNoteData( tempNoteData );
FOREACH_PlayerNumber(pn) FOREACH_PlayerNumber(pn)
m_CachedRadarValues[pn] m_CachedRadarValues[pn].Zero();
.Zero();
GAMESTATE->SetProcessedTimingData(this->GetTimingData()); GAMESTATE->SetProcessedTimingData(this->GetTimingData());
if( tempNoteData.IsComposite() ) if( tempNoteData.IsComposite() )
@@ -1045,8 +1044,8 @@ public:
ADD_METHOD( HasAttacks ); ADD_METHOD( HasAttacks );
ADD_METHOD( GetRadarValues ); ADD_METHOD( GetRadarValues );
ADD_METHOD( GetTechCounts ); ADD_METHOD( GetTechCounts );
ADD_METHOD(CalculateTechCounts); ADD_METHOD( CalculateTechCounts );
ADD_METHOD(GetTimingData); ADD_METHOD( GetTimingData );
ADD_METHOD( GetChartName ); ADD_METHOD( GetChartName );
//ADD_METHOD( GetSMNoteData ); //ADD_METHOD( GetSMNoteData );
ADD_METHOD( GetStepsType ); ADD_METHOD( GetStepsType );
+9 -19
View File
@@ -8,7 +8,6 @@
#include "GameState.h" #include "GameState.h"
#include "RageTimer.h" #include "RageTimer.h"
static const char *TechCountsCategoryNames[] = { static const char *TechCountsCategoryNames[] = {
"Crossovers", "Crossovers",
"HalfCrossovers", "HalfCrossovers",
@@ -27,7 +26,6 @@ XToLocalizedString( TechCountsCategory );
LuaFunction(TechCountsCategoryToLocalizedString, TechCountsCategoryToLocalizedString(Enum::Check<TechCountsCategory>(L, 1)) ); LuaFunction(TechCountsCategoryToLocalizedString, TechCountsCategoryToLocalizedString(Enum::Check<TechCountsCategory>(L, 1)) );
LuaXType( TechCountsCategory ); LuaXType( TechCountsCategory );
// 0.176 ~= 1/8th at 175bpm // 0.176 ~= 1/8th at 175bpm
// Anything slower isn't counted as a jack // Anything slower isn't counted as a jack
const float JACK_CUTOFF = 0.176; const float JACK_CUTOFF = 0.176;
@@ -90,10 +88,8 @@ void TechCounts::FromString( RString sTechCounts )
{ {
(*this)[rc] = StringToFloat(saValues[rc]); (*this)[rc] = StringToFloat(saValues[rc]);
} }
} }
void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row> &rows, StepParity::StageLayout & layout, TechCounts &out) void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row> &rows, StepParity::StageLayout & layout, TechCounts &out)
{ {
for (unsigned long i = 1; i < rows.size(); i++) for (unsigned long i = 1; i < rows.size(); i++)
@@ -103,17 +99,15 @@ void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row>
float elapsedTime = currentRow.second - previousRow.second; float elapsedTime = currentRow.second - previousRow.second;
/* // Jacks are same arrow same foot
Jacks are same arrow same foot // Doublestep is same foot on successive arrows
Doublestep is same foot on successive arrows // Brackets are jumps with one foot
Brackets are jumps with one foot
Footswitch is different foot on the up or down arrow // Footswitch is different foot on the up or down arrow
Sideswitch is footswitch on left or right arrow // Sideswitch is footswitch on left or right arrow
Crossovers are left foot on right arrow or vice versa // Crossovers are left foot on right arrow or vice versa
*/
// check for jacks and doublesteps // Check for jacks and doublesteps
if(currentRow.noteCount == 1 && previousRow.noteCount == 1) if(currentRow.noteCount == 1 && previousRow.noteCount == 1)
{ {
for (StepParity::Foot foot: StepParity::FEET) for (StepParity::Foot foot: StepParity::FEET)
@@ -140,7 +134,7 @@ void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row>
} }
} }
// check for brackets // Check for brackets
if(currentRow.noteCount >= 2) if(currentRow.noteCount >= 2)
{ {
if(currentRow.whereTheFeetAre[StepParity::LEFT_HEEL] != -1 && currentRow.whereTheFeetAre[StepParity::LEFT_TOE] != -1) if(currentRow.whereTheFeetAre[StepParity::LEFT_HEEL] != -1 && currentRow.whereTheFeetAre[StepParity::LEFT_TOE] != -1)
@@ -183,7 +177,6 @@ void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row>
} }
// Check for crossovers // Check for crossovers
int leftHeel = currentRow.whereTheFeetAre[StepParity::LEFT_HEEL]; int leftHeel = currentRow.whereTheFeetAre[StepParity::LEFT_HEEL];
int leftToe = currentRow.whereTheFeetAre[StepParity::LEFT_TOE]; int leftToe = currentRow.whereTheFeetAre[StepParity::LEFT_TOE];
int rightHeel = currentRow.whereTheFeetAre[StepParity::RIGHT_HEEL]; int rightHeel = currentRow.whereTheFeetAre[StepParity::RIGHT_HEEL];
@@ -235,7 +228,7 @@ void TechCounts::CalculateTechCountsFromRows(const std::vector<StepParity::Row>
} }
} }
} }
// and check the same thing, starting with left foot // And check the same thing, starting with left foot
else if(leftHeel != -1 && previousRightHeel != -1 && previousLeftHeel == -1) else if(leftHeel != -1 && previousRightHeel != -1 && previousLeftHeel == -1)
{ {
StepParity::StagePoint leftPos = layout.averagePoint(leftHeel, leftToe); StepParity::StagePoint leftPos = layout.averagePoint(leftHeel, leftToe);
@@ -287,12 +280,9 @@ bool TechCounts::isFootswitch(int c, const StepParity::Row & currentRow, const S
} }
// lua start // lua start
class LunaTechCounts: public Luna<TechCounts> class LunaTechCounts: public Luna<TechCounts>
{ {
public: public:
static int GetValue( T* p, lua_State *L ) { lua_pushnumber( L, (*p)[Enum::Check<TechCountsCategory>(L, 1)] ); return 1; } static int GetValue( T* p, lua_State *L ) { lua_pushnumber( L, (*p)[Enum::Check<TechCountsCategory>(L, 1)] ); return 1; }
LunaTechCounts() LunaTechCounts()
+1 -2
View File
@@ -3,8 +3,7 @@
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "StepParityGenerator.h" #include "StepParityGenerator.h"
class NoteData; #include "NoteData.h"
/** @brief Unknown radar values are given a default value. */ /** @brief Unknown radar values are given a default value. */
#define TECHCOUNTS_VAL_UNKNOWN -1 #define TECHCOUNTS_VAL_UNKNOWN -1