Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion docs/star-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,23 @@ or opposite order.
- Amount of size increase on correct selection
- Amount of size decrease on incorrect selection
- Colour for correct selection
- Colour for incorrect selection
- Colour for incorrect selection

## Save data

Data is saved to `StarMapScores.csv`, with one row per trial (i.e. one row per attempt at repeating a sequence of stars). This means there may be _multiple_ rows per played game. Values are:

- `gameNumber`: a unique id per played star map game
- `sessionNumber`: the session this game was played in (corresponds to sessionNumber in [`SessionSummary.csv`](./session-summary.md))
- `trialNumber`: a unique id per trial (i.e. per attempt at repeating a sequence of stars). This resets each time the game is played, so the first trial of each game has trialNumber=1.
- `date`: the date of the game session in format YYYY-MM-DD
- `startTime`: the game start time in format HH:MM:ss. This is the local time (e.g. if your computer is set to UK time - this is UK time).
- `endTime`: the game end time in format HH:MM:ss (local time - see startTime description)
- `gameCompleted`: whether this game was completed. If they exited early, this will be false.
- `sequenceType`: The order in which the player repeated the sequence - either Forward or Backward.
- `sequenceLength`: The number of stars in the sequence.
- `responseCorrect`: Whether the player repeated the sequence correctly (will be blank if the player exited before completing their response).
- `responseTimeSeconds`: The number of seconds the player took to repeat the sequence, rounded to 2 decimal places. This entry will be blank if the player exited before completing their response.
- `totalNumberTrials`: The total number of trials in this game (will be set to the same value for all rows from a single game).
- `maxSpan`: The maximum length of sequence _correctly_ repeated in this game session (will be set to the same value for all trials in a single game).
- `constellationSize`: The size of constellation used for this game - either 'Small' or 'Large'.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void Start()

// If there is no summary data yet, or the last session has ended,
// create a new session
if (lastSession is null || lastSession.endTime != "")
if (lastSession is null || lastSession.endTime is not null)
{
SessionData newSession = new SessionData();
newSession.sessionNumber = sessionData.GetNextSessionNumber();
Expand All @@ -32,7 +32,7 @@ private void OnApplicationQuit()
SaveData<SessionData> sessionData = new(saveFilename);
SessionData lastSession = sessionData.GetLast();

if (lastSession.endTime == "")
if (lastSession.endTime is null)
{
lastSession.LogEndTime();
TimeSpan sessionDuration = DateTime
Expand All @@ -52,6 +52,11 @@ public static void MarkGameAsComplete(string gameColumn)
SaveData<SessionData> sessionData = new(saveFilename);
SessionData lastSession = sessionData.GetLast();

if (lastSession is null)
{
return;
}

FieldInfo nGamesField = lastSession.GetType().GetField(gameColumn);
int nGames = (int)nGamesField.GetValue(lastSession);

Expand Down
41 changes: 40 additions & 1 deletion projects/AstroBalance/Assets/Scripts/SaveData/SaveData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ public void Save(T data)
}
}

/// <summary>
/// Add multiple data items to the save file.
/// They will be added in order - the last item in the list will be the last line in the file.
/// </summary>
/// <param name="data">Data from this session</param>
public void Save(List<T> data)
{
using (StreamWriter sw = new StreamWriter(dataPath, true))
{
if (!saveFileExists)
{
sw.WriteLine(DataToCsv(data.ElementAt(0), true));
saveFileExists = true;
}

foreach (T dataItem in data)
{
sw.WriteLine(DataToCsv(dataItem, false));
}
}
}

/// <summary>
/// Overwrite the last (most recent) item in the save file.
/// </summary>
Expand Down Expand Up @@ -148,7 +170,24 @@ protected T CsvToData(string csvHeader, string csvRow)
for (int i = 0; i < headerNames.Length; i++)
{
FieldInfo field = typeof(T).GetField(headerNames[i]);
field.SetValue(data, Convert.ChangeType(values[i], field.FieldType));
Type fieldType = field.FieldType;

if (
fieldType.IsGenericType
&& fieldType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))
)
{
fieldType = Nullable.GetUnderlyingType(fieldType);
}

if (values[i] != "")
{
field.SetValue(data, Convert.ChangeType(values[i], fieldType));
}
else
{
field.SetValue(data, null);
}
}

return data;
Expand Down
52 changes: 23 additions & 29 deletions projects/AstroBalance/Assets/Scripts/SaveData/SaveGameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,51 @@ public SaveGameData(string filename)
: base(filename) { }

/// <summary>
/// Get data from the last complete played game session.
/// </summary>
public T GetLastComplete()
{
if (!saveFileExists)
{
return null;
}

IEnumerable<T> lastGameData = GetLastNComplete(1);
if (lastGameData.Count() != 1)
{
return null;
}
else
{
return lastGameData.ElementAt(0);
}
}

/// <summary>
/// Get a list of data from the last n complete played games (or as many as have been completed). Game data is stored in chronological order, from earliest to latest (most recent game in final position).
/// Get a list of data from the last n complete played games (or as many as have been completed so far).
///
/// Game data is stored in chronological order, from earliest to latest (most recent game in final position).
/// Note: for most mini-games, one data item will be returned per game - but some (like StarMap) return
/// multiple items per game.
/// </summary>
/// <param name="nGames">Maximum number of games to retrieve</param>
public IEnumerable<T> GetLastNComplete(int nGames)
{
List<T> lastNComplete = new List<T>();
int nGamesDataRetrieved = 0;
int currentGameNumber = -1;

if (!saveFileExists)
{
return lastNComplete;
}

IEnumerable<string> csvLines = File.ReadLines(dataPath);
string header = csvLines.First();
int lineNo = csvLines.Count() - 1;
int maxLineNo = csvLines.Count() - 1;

// Start from end of file, and find n complete games
while (lineNo > 0 && lastNComplete.Count() < nGames)
// Start from end of file, and find n complete played games
for (int i = maxLineNo; i > 0; i--)
{
string line = csvLines.ElementAt(lineNo);

string line = csvLines.ElementAt(i);
T gameData = CsvToData(header, line);

if (gameData.gameCompleted)
{
if (gameData.gameNumber != currentGameNumber)
{
nGamesDataRetrieved++;
}
if (nGamesDataRetrieved > nGames)
{
break;
}

lastNComplete.Add(gameData);
currentGameNumber = gameData.gameNumber;
}
lineNo--;
}

lastNComplete.Reverse();

return lastNComplete;
}

Expand Down
26 changes: 24 additions & 2 deletions projects/AstroBalance/Assets/Scripts/StarMap/Constellation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class Constellation : MonoBehaviour
private int incorrectSequences = 0; // Incorrect sequences at current length
private bool hasBeenDowngraded = false; // Whether the sequence length has been downgraded due to incorrect guesses
private RepeatOrder order = RepeatOrder.Same;
private float starSelectionStartTime = 0; // Time when star selection was enabled (i.e. when the player started guessing)
private float starSelectionDuration = 0; // The number of seconds star selection was enabled for the last guess

private void Awake()
{
Expand Down Expand Up @@ -82,6 +84,11 @@ public int GetNumberOfStars()
return stars.Count();
}

public int GetCurrentSequenceLength()
{
return currentSequenceLength;
}

/// <summary>
/// Choose a new random sequence of stars, and display it to the player.
/// Once display completes, stars are enabled for selection.
Expand Down Expand Up @@ -130,6 +137,8 @@ private void DisableStarSelection()
{
star.DisableSelection();
}

starSelectionDuration = Time.time - starSelectionStartTime;
}

private void EnableStarSelection()
Expand All @@ -138,6 +147,8 @@ private void EnableStarSelection()
{
star.EnableSelection();
}

starSelectionStartTime = Time.time;
}

private IEnumerator CompleteSequence(bool correctGuess)
Expand Down Expand Up @@ -190,7 +201,12 @@ private IEnumerator HandleCorrectGuess()

// whole sequence has been guessed correctly
yield return StartCoroutine(CompleteSequence(true));
gameManager.UpdateScore(currentSequenceLength, hasBeenDowngraded);
gameManager.UpdateScore(
true,
currentSequenceLength,
hasBeenDowngraded,
starSelectionDuration
);

if (gameManager.IsGameActive() && currentSequenceLength < GetNumberOfStars())
{
Expand All @@ -207,6 +223,13 @@ private IEnumerator HandleCorrectGuess()
private IEnumerator HandleIncorrectGuess()
{
incorrectSequences += 1;
yield return StartCoroutine(CompleteSequence(false));
gameManager.UpdateScore(
false,
currentSequenceLength,
hasBeenDowngraded,
starSelectionDuration
);

// reduce length of next sequence, if the player
// has had n incorrect guesses in a row
Expand All @@ -220,7 +243,6 @@ private IEnumerator HandleIncorrectGuess()
incorrectSequences = 0;
}

yield return StartCoroutine(CompleteSequence(false));
ShowNewSequence(order);
}

Expand Down
10 changes: 7 additions & 3 deletions projects/AstroBalance/Assets/Scripts/StarMap/StarMapData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
[System.Serializable]
public class StarMapData : GameData
{
public int nSequencesRepeated;
public int maxSequenceLength;
public string repeatOrder; // string representation of StarMapManager.RepeatOrder enum
public int trialNumber;
public string sequenceType;
public int sequenceLength;
public bool? responseCorrect; // ? makes the field nullable. This will be null for an un-finished trial.
public float? responseTimeSeconds; // ? makes the field nullable. This will be null for an un-finished trial.
public int totalNumberTrials;
public int maxSpan;
public string constellationSize; // string representation of StarMapManager.ConstellationSize enum
}
Loading