Skip to content

Commit

Permalink
Merge pull request #146 from canopas/Mayank/store-user-stats
Browse files Browse the repository at this point in the history
Manage user stats in score board
  • Loading branch information
cp-mayank authored Nov 27, 2024
2 parents d7069f1 + 5ae4c1b commit 1bf099e
Show file tree
Hide file tree
Showing 22 changed files with 1,827 additions and 1,831 deletions.
2 changes: 1 addition & 1 deletion data/.flutter-plugins-dependencies

Large diffs are not rendered by default.

192 changes: 65 additions & 127 deletions data/lib/api/ball_score/ball_score_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,68 +134,6 @@ class FieldingPosition {
});
}

@freezed
class UserStat with _$UserStat {
const factory UserStat({
BattingStat? battingStat,
BowlingStat? bowlingStat,
FieldingStat? fieldingStat,
}) = _UserStat;

factory UserStat.fromJson(Map<String, dynamic> json) =>
_$UserStatFromJson(json);
}

@freezed
class BattingStat with _$BattingStat {
const factory BattingStat({
@Default(0) int innings,
@Default(0) int runScored,
@Default(0.0) double average,
@Default(0.0) double strikeRate,
@Default(0) int ballFaced,
@Default(0) int fours,
@Default(0) int sixes,
@Default(0) int fifties,
@Default(0) int hundreds,
@Default(0) int ducks,
}) = _BattingStat;

factory BattingStat.fromJson(Map<String, dynamic> json) =>
_$BattingStatFromJson(json);
}

@freezed
class BowlingStat with _$BowlingStat {
const factory BowlingStat({
@Default(0) int innings,
@Default(0) int wicketTaken,
@Default(0) int balls,
@Default(0) int runsConceded,
@Default(0) int maiden,
@Default(0) int noBalls,
@Default(0) int wideBalls,
@Default(0.0) double average,
@Default(0.0) double strikeRate,
@Default(0.0) double economyRate,
}) = _BowlingStat;

factory BowlingStat.fromJson(Map<String, dynamic> json) =>
_$BowlingStatFromJson(json);
}

@freezed
class FieldingStat with _$FieldingStat {
const factory FieldingStat({
@Default(0) int catches,
@Default(0) int runOut,
@Default(0) int stumping,
}) = _FieldingStat;

factory FieldingStat.fromJson(Map<String, dynamic> json) =>
_$FieldingStatFromJson(json);
}

@freezed
class OverStatModel with _$OverStatModel {
const factory OverStatModel({
Expand Down Expand Up @@ -698,23 +636,28 @@ extension ExtraSummaryMetaData on ExtraSummary {
}

extension BallScoreList on List<BallScoreModel> {
UserStat calculateUserStats(String currentUserId) {
final battingStat = calculateBattingStats(currentUserId: currentUserId);

final bowlingStat = calculateBowlingStats(currentUserId);

final fieldingStat = calculateFieldingStats(currentUserId);

return UserStat(
battingStat: battingStat,
bowlingStat: bowlingStat,
fieldingStat: fieldingStat,
UserStat calculateUserStats(
String currentUserId, {
UserStat? oldUserStats,
UserStatType? type,
bool isMatchComplete = false,
}) {
final newBattingStat = calculateBattingStats(currentUserId);
final newBowlingStat = calculateBowlingStats(currentUserId);
final newFieldingStat = calculateFieldingStats(currentUserId);

final newUserStats = UserStat(
matches: isMatchComplete ? 1 : 0,
type: type,
batting: newBattingStat,
bowling: newBowlingStat,
fielding: newFieldingStat,
);

return oldUserStats?.updateStat(newUserStats) ?? newUserStats;
}

BattingStat calculateBattingStats({
required String currentUserId,
}) {
Batting calculateBattingStats(String currentUserId) {
int runScored = 0;
int dismissal = 0;
int ballFaced = 0;
Expand All @@ -724,43 +667,36 @@ extension BallScoreList on List<BallScoreModel> {
final Map<String, List<BallScoreModel>> inningGroup = {};

for (final element in this) {
// Runs scored
if (element.batsman_id == currentUserId) {
runScored += element.runs_scored;

// Track boundaries
if (element.is_four && element.runs_scored == 4) {
fours++;
} else if (element.is_six && element.runs_scored == 6) {
sixes++;
}

// Count valid balls faced (excluding no balls, wides, etc.)
if (element.extras_type == null ||
element.extras_type == ExtrasType.legBye ||
element.extras_type == ExtrasType.bye) {
ballFaced++;
}
}

// Dismissals
if (element.player_out_id == currentUserId) {
dismissal++;
}

// Group by innings
if (element.batsman_id == currentUserId ||
element.non_striker_id == currentUserId ||
element.player_out_id == currentUserId) {
inningGroup.putIfAbsent(element.inning_id, () => []).add(element);
}
}

// Calculate averages and strike rate
final average = dismissal == 0 ? 0.0 : runScored / dismissal;
final strikeRate = ballFaced == 0 ? 0.0 : (runScored / ballFaced) * 100.0;

// Calculate ducks, fifties, and hundreds
int ducks = 0;
int fifties = 0;
int hundreds = 0;
Expand Down Expand Up @@ -797,21 +733,22 @@ extension BallScoreList on List<BallScoreModel> {
}
});

return BattingStat(
return Batting(
innings: inningGroup.length,
average: average,
strikeRate: strikeRate,
ballFaced: ballFaced,
runScored: runScored,
strike_rate: strikeRate,
ball_faced: ballFaced,
run_scored: runScored,
fours: fours,
sixes: sixes,
ducks: ducks,
fifties: fifties,
hundreds: hundreds,
dismissal: dismissal,
);
}

BowlingStat calculateBowlingStats(String currentUserId) {
Bowling calculateBowlingStats(String currentUserId) {
final deliveries = where((element) => element.bowler_id == currentUserId);

final wicketTaken = deliveries
Expand All @@ -827,10 +764,10 @@ extension BallScoreList on List<BallScoreModel> {
final bowledBallCount = deliveries
.where(
(element) =>
element.extras_type != ExtrasType.penaltyRun &&
element.wicket_type != WicketType.retired &&
element.wicket_type != WicketType.retiredHurt &&
element.wicket_type != WicketType.timedOut &&
element.extras_type != ExtrasType.penaltyRun,
element.wicket_type != WicketType.timedOut,
)
.length;

Expand All @@ -856,9 +793,7 @@ extension BallScoreList on List<BallScoreModel> {
);

final average = wicketTaken == 0 ? 0.0 : runsConceded / wicketTaken;

final strikeRate = wicketTaken == 0 ? 0.0 : bowledBallCount / wicketTaken;

final economyRate = bowledBallCountForEconomyRate == 0
? 0.0
: (runsConceded / bowledBallCountForEconomyRate) * 6;
Expand All @@ -869,46 +804,49 @@ extension BallScoreList on List<BallScoreModel> {
final noBallCount = deliveries
.where((element) => element.extras_type == ExtrasType.noBall)
.length;

final inningGroup = groupBy(deliveries, (ball) => ball.inning_id);
int maiden = 0;
final maidenOvers = _calculateMaidenOvers(deliveries);

inningGroup.forEach((inningId, balls) {
final overGroup = groupBy(balls, (ball) => ball.over_number);
return Bowling(
innings: inningGroup.length,
average: average,
strike_rate: strikeRate,
wicket_taken: wicketTaken,
economy_rate: economyRate,
balls: bowledBallCount,
wide_balls: wideBallCount,
runs_conceded: runsConceded,
no_balls: noBallCount,
maiden: maidenOvers,
);
}

overGroup.forEach((overNumber, balls) {
int runsConcededInOver = 0;
bool hasExtras = false;
int _calculateMaidenOvers(Iterable<BallScoreModel> deliveries) {
final overGroups = groupBy(deliveries, (ball) => ball.over_number);

for (final ball in balls) {
runsConcededInOver += ball.runs_scored + (ball.extras_awarded ?? 0);
if (ball.extras_type != null) {
hasExtras = true;
break;
}
}
int maiden = 0;

overGroups.forEach((overNumber, balls) {
int runsConceded = 0;
bool hasExtras = false;

if (runsConcededInOver == 0 && !hasExtras && balls.length == 6) {
maiden++;
for (final ball in balls) {
runsConceded += ball.runs_scored + (ball.extras_awarded ?? 0);
if (ball.extras_type != null) {
hasExtras = true;
break;
}
});
}

if (runsConceded == 0 && !hasExtras && balls.length == 6) {
maiden++;
}
});

return BowlingStat(
innings: inningGroup.length,
average: average,
strikeRate: strikeRate,
wicketTaken: wicketTaken,
economyRate: economyRate,
balls: bowledBallCount,
wideBalls: wideBallCount,
runsConceded: runsConceded,
noBalls: noBallCount,
maiden: maiden,
);
return maiden;
}

FieldingStat calculateFieldingStats(String currentUserId) {
Fielding calculateFieldingStats(String currentUserId) {
final catches = where(
(element) =>
element.wicket_taker_id == currentUserId &&
Expand All @@ -917,22 +855,22 @@ extension BallScoreList on List<BallScoreModel> {
element.wicket_type == WicketType.caughtAndBowled),
).length;

final runOut = where(
final runOuts = where(
(element) =>
element.wicket_taker_id == currentUserId &&
element.wicket_type == WicketType.runOut,
).length;

final stumping = where(
final stumpings = where(
(element) =>
element.wicket_taker_id == currentUserId &&
element.wicket_type == WicketType.stumped,
).length;

return FieldingStat(
return Fielding(
catches: catches,
runOut: runOut,
stumping: stumping,
runOut: runOuts,
stumping: stumpings,
);
}
}
Loading

0 comments on commit 1bf099e

Please sign in to comment.