} //END (CalcStats) /// <summary> /// Add game data to Top if needed (by preset - max 5 player records and by 3BV - max 10 player records) /// </summary> /// <param name="index">Index of the current preset</param> /// <param name="now">CUrrent date and time</param> /// <param name="gameTime">Current game time</param> /// <param name="level3BV">Difficulty level by 3BV</param> /// <param name="askPN">Handler to the method that asks for a player name</param> /// <returns>Fastest game time from the Top table</returns> private uint AddToTop(int index, DateTime now, uint gameTime, uint level3BV, AskPlayerName askPN) { //first of all we'll check whether we have to add to StatsBy3BV int topLength = (StatsBy3BV == null) ? //if statsby3bv is not created by now 0 : //set toplenght to zero StatsBy3BV.Length; //otherwise set toplength to the length of statsby3bv bool HaveToAdd = false; //flag that is true when we have to add to top string playerName = null; //playerName is not specified yet if (topLength >= 10) //if topLength is 10 records or more (we will limit top by 10 records) { if (StatsBy3BV[topLength - 1].Level3BV < level3BV) //if current difficulty level is more than the minimal one in top { HaveToAdd = true; //we have to add it } else if (StatsBy3BV[topLength - 1].Level3BV > level3BV) //if current difficulty level is less than the minimal one in top { HaveToAdd = false; //we mustn't add it } else if (StatsBy3BV[topLength - 1].GameTime > gameTime) //if they are equal and current game time is less than added to the top { HaveToAdd = true; //we have to add it } } //ENDIF (top is 10 or more records) else //if top has less than 10 records { HaveToAdd = true; //we have to add current game to the top } if (HaveToAdd) //if we have to add to the top { playerName = askPN(); //ask for player name Array.Resize(ref StatsBy3BV, ++topLength); //get memory for the new record in the top //add a new record to the top StatsBy3BV[topLength - 1].GameTime = gameTime; //game duration StatsBy3BV[topLength - 1].Name = playerName; //player name StatsBy3BV[topLength - 1].WinTime = now; //win date and time StatsBy3BV[topLength - 1].Level3BV = level3BV; //difficulty level switch (index) //switch between presets using the specified index { case 0: //Newbie StatsBy3BV[topLength - 1].Preset = MinesSettings.Preset.Newbie; //records preset is Newbie break; case 1: //Advanced StatsBy3BV[topLength - 1].Preset = MinesSettings.Preset.Advanced; //records preset is Advanced break; case 2: //Professional StatsBy3BV[topLength - 1].Preset = MinesSettings.Preset.Professional; //records preset is Professional break; default: //any other undex value will become a Custom StatsBy3BV[topLength - 1].Preset = MinesSettings.Preset.Custom; //record preset is Custom break; } //ENDSWITCH (preset) Array.Sort(StatsBy3BV, new WinnerInfo().CompareByLevel3BV); //sort top descending by 3bv and then ascending by game duration Array.Resize(ref StatsBy3BV, (topLength > 10 ? 10 : topLength)); //if top length is more than 10 records cut its length to 10 // this will cut records that are last in the top } //ENDIF (have to add to top) if (index < 0 || index > 2) //if preset is not newbie, advanced or professional { return(StatsBy3BV[0].GameTime); //return game duration from the first record of the top } //now we'll check whether we have to add to StatsByPreset topLength = (StatsByPreset[index].Top == null) ? //if stats by preset top has records 0 : //set topLength to zero StatsByPreset[index].Top.Length; //otherwise set it to length of the top HaveToAdd = false; //set have-to-add flag to false if (topLength >= 5) //if top length is 5 or more (we'll limit its length by 5) { if (StatsByPreset[index].Top[topLength - 1].GameTime > gameTime) //if current game duration is less than the last record in the top { HaveToAdd = true; //we have to add a new record } } //ENDIF (top length is 5 or more) else //if top length is less than 5 { HaveToAdd = true; //we have to add a new record } if (HaveToAdd) //if we have to add a new record to top { Array.Resize(ref StatsByPreset[index].Top, ++topLength); //get memory for the new record StatsByPreset[index].Top[topLength - 1].GameTime = gameTime; //save game duration StatsByPreset[index].Top[topLength - 1].Name = (playerName == null) ? //if player name is not specified yet askPN() : //ask for player name playerName; //otherwise use already specified name StatsByPreset[index].Top[topLength - 1].WinTime = now; //save date and time of win StatsByPreset[index].Top[topLength - 1].Level3BV = level3BV; //save difficulty level switch (index) //switch between presets { case 0: //Newbie StatsByPreset[0].Top[topLength - 1].Preset = MinesSettings.Preset.Newbie; //save preset as Newbie break; case 1: //Advanced StatsByPreset[1].Top[topLength - 1].Preset = MinesSettings.Preset.Advanced; //save preset as Advanced break; case 2: //Professional StatsByPreset[2].Top[topLength - 1].Preset = MinesSettings.Preset.Professional; //save preset as Professional break; } //ENDSWITCH (preset) Array.Sort(StatsByPreset[index].Top, new WinnerInfo().CompareByGameTime); //sort top list acsending by game duration Array.Resize(ref StatsByPreset[index].Top, (topLength > 5 ? 5 : topLength)); //if top length is more than 5 records cut its length to 5 records // this will cut records that are last in the top } //ENDIF (have to add to top) return(StatsByPreset[index].Top[0].GameTime); //return game duration from the first record of the top } //END (AddToTop)
} //END (getInstance) /// <summary> /// Calculate stats for the current game /// </summary> /// <param name="me">Engine of the current game</param> /// <param name="ms">Settings of the current game</param> /// <param name="askPN">Handler of the method that asks for a player name</param> public void CalcStats(MinesEngine me, MinesSettings ms, uint gameTime, AskPlayerName askPN) { DateTime curTime = DateTime.Now; //current date and time int index = -1; //index of the current preset in the stats array if (me.CurrentGameState.State != MinesEngine.GameState.Loose && //if game is not lost me.CurrentGameState.State != MinesEngine.GameState.Win) //AND game is not won { return; //do nothing and just return } uint level3BV = me.Level3BV; //get difficulty level of the game from the engine switch (ms.CurrentPreset) //switch between game presets { case MinesSettings.Preset.Newbie: index = 0; break; //for Newbie index is zero case MinesSettings.Preset.Advanced: index = 1; break; //for Advanced index is 1 case MinesSettings.Preset.Professional: index = 2; break; //for Professional index is 2 case MinesSettings.Preset.Custom: //for Custom we will not add stats by preset // but we will try to add a record to the top by difficulty level if (me.CurrentGameState.State == MinesEngine.GameState.Win) //if game is won { AddToTop(3, curTime, gameTime, level3BV, askPN); //try to add record to top list } return; //return default: return; //if somehow preset in game settings is invalid do nothing and return } //ENDSWITCH (preset) StatsByPreset[index].TotalGames++; //increase total games played for the current preset if (me.CurrentGameState.State == MinesEngine.GameState.Win) //if game is won { if (gameTime > StatsByPreset[index].LongestGameTime) //if current game duration is more than the saved in stats one { StatsByPreset[index].LongestGameTime = gameTime; //save current game duration } StatsByPreset[index].WinGames++; //increase won games counter StatsByPreset[index].WinPercent = StatsByPreset[index].WinGames / (double)StatsByPreset[index].TotalGames * 100.0; //calculate the new win-percentage StatsByPreset[index].WinStreak++; //increase win streak counter if (StatsByPreset[index].LooseStreak > StatsByPreset[index].MaxLooseStreak) //if current loose streak is longer than the saved one { StatsByPreset[index].MaxLooseStreak = StatsByPreset[index].LooseStreak; //save the current loose streak as the maximal } StatsByPreset[index].LooseStreak = 0; //reset current loose streak StatsByPreset[index].FastestGameTime = AddToTop(index, curTime, gameTime, level3BV, askPN); //try to add current game to top } //ENDIF (game is won) else //if game is LOST { if (StatsByPreset[index].WinStreak > StatsByPreset[index].MaxWinStreak) //if current win streak is longer than the saved one { StatsByPreset[index].MaxWinStreak = StatsByPreset[index].WinStreak; //save current win streak as the maximal } StatsByPreset[index].WinStreak = 0; //reset current win streak StatsByPreset[index].LooseStreak++; //increase the loose streak counter } //ENDELSE (game is lost) } //END (CalcStats)