Skip to content

Commit

Permalink
player stats
Browse files Browse the repository at this point in the history
  • Loading branch information
notV4l committed May 29, 2024
1 parent 7631bf8 commit 27f970d
Show file tree
Hide file tree
Showing 10 changed files with 490 additions and 56 deletions.
Binary file removed .DS_Store
Binary file not shown.
Binary file modified assets/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions src/config/ryo.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait};
use rollyourown::{models::{season::{Season, SeasonImpl, SeasonTrait}}};

const TWO_MIN: u16 = 120;
const TWENTY_MIN: u16 = 1200;
// const TWENTY_MIN: u16 = 1200;
//
// const TWENTY_MIN: u32 = 1200;
const TWENTY_MIN: u32 = 1200;
const ONE_HOUR: u32 = 3600;
const SIX_HOUR: u32 = 21_600;
const ONE_DAY: u32 = 86_400;
Expand Down Expand Up @@ -38,8 +38,8 @@ impl RyoConfigImpl of RyoConfigTrait {
initialized: true,
paused: false,
season_version: 1,
season_duration: SIX_HOUR, // ONE_WEEK
season_time_limit: TWENTY_MIN, // ONE_HOUR
season_duration: TWENTY_MIN, // SIX_HOUR, // ONE_WEEK
season_time_limit: TWO_MIN, // TWENTY_MIN, // ONE_HOUR
paper_fee: 1000, // in ether
paper_reward_launderer: 100, // in ether
treasury_fee_pct: 5,
Expand Down
4 changes: 3 additions & 1 deletion src/systems/devtools.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ mod devtools {
randomizer.between::<u32>(0, 100_000)
};

let rand_hustler_id = randomizer.between::<u16>(0, 3);

let mut game = Game {
game_id,
player_id,
Expand All @@ -60,7 +62,7 @@ mod devtools {
game_mode: GameMode::Dealer,
//
player_name: Bytes16Impl::from('fake'),
hustler_id: 1,
hustler_id: rand_hustler_id,
//
game_over: true,
final_score: 0,
Expand Down
108 changes: 106 additions & 2 deletions web/src/dojo/hooks/useGamesByPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,51 @@ import {
SeasonSettings,
World__Entity,
World__EntityEdge,
World__Event,
World__EventEdge,
useAllGameConfigQuery,
useAllSeasonSettingsQuery,
useGamesByPlayerQuery,
useTravelEncounterByPlayerQuery,
useTravelEncounterResultsByPlayerQuery,
} from "@/generated/graphql";
import { useMemo } from "react";
import { GameClass } from "../class/Game";
import { useDojoContext } from "./useDojoContext";
import { Hustler, Hustlers } from "@/components/hustlers";
import { WorldEvents } from "../generated/contractEvents";

export type PlayerStats = {
totalGamesPlayed: number;
totalGamesPaid: number;
payRate: string;
totalPaperClaimed: number;
bestRanking: string;
gamesByHustler: {
[Hustlers.Dragon]: number;
[Hustlers.Monkey]: number;
[Hustlers.Rabbit]: number;
};
mostPlayedHustler: {
[Hustlers.Dragon]: boolean;
[Hustlers.Monkey]: boolean;
[Hustlers.Rabbit]: boolean;
};
totalCopsEncounter: number;
totalGangEncounter: number;
totalFight: number;
totalRun: number;
totalPay: number;
};

export interface GamesByPlayerInterface {
isFetched: boolean;
games: GameClass[];
onGoingGames: GameClass[];
endedGames: GameClass[];
isFetched: boolean;
playerStats?: PlayerStats;
}


// TODO : change to get games by player by Season
export const useGamesByPlayer = (playerId: string): GamesByPlayerInterface => {
const { data, isFetched } = useGamesByPlayerQuery({
Expand All @@ -32,6 +61,15 @@ export const useGamesByPlayer = (playerId: string): GamesByPlayerInterface => {
const { data: allSeasonSettings } = useAllSeasonSettingsQuery({});
const { data: allGameConfig } = useAllGameConfigQuery({});

const { data: allTravelEncounters } = useTravelEncounterByPlayerQuery({
travelEncounterSelector: WorldEvents.TravelEncounter,
playerId,
});
const { data: allTravelEncounterResults } = useTravelEncounterResultsByPlayerQuery({
travelEncounterResultSelector: WorldEvents.TravelEncounterResult,
playerId,
});

const { configStore } = useDojoContext();

const games = useMemo(() => {
Expand Down Expand Up @@ -69,10 +107,76 @@ export const useGamesByPlayer = (playerId: string): GamesByPlayerInterface => {
return games.filter((i: GameClass) => i.gameInfos.game_over);
}, [games]);

const playerStats = useMemo(() => {
if (!games || !allTravelEncounters || !allTravelEncounterResults) return undefined;

// return games.filter((i: GameClass) => i.gameInfos.game_over);
const paidGames = games.filter((i: GameClass) => i.gameInfos.claimable > 0);
const totalGamesPlayed = games.length;
const totalGamesPaid = paidGames.length;
const payRate = `${Number((totalGamesPaid / totalGamesPlayed) * 100).toFixed(2)}%`;
const totalPaperClaimed = paidGames.map((i: GameClass) => i.gameInfos.claimable || 0).reduce((p, c) => p + c, 0);
const orderedRanks = games
.flatMap((i: GameClass) => (i.gameInfos.position > 0 ? [i.gameInfos.position] : []))
.sort((a, b) => a - b);
const bestRanking = orderedRanks.length > 0 ? orderedRanks[0] : "Noob";

const dragonGames = games.filter((i: GameClass) => i.gameInfos.hustler_id === 0).length;
const monkeyGames = games.filter((i: GameClass) => i.gameInfos.hustler_id === 1).length;
const rabbitGames = games.filter((i: GameClass) => i.gameInfos.hustler_id === 2).length;

const maxPlayed = Math.max(dragonGames, monkeyGames, rabbitGames);

const totalCopsEncounter = (allTravelEncounters?.events?.edges || []).filter(
(i) => i?.node?.data![0] === "0x436f7073",
).length;

const totalGangEncounter = (allTravelEncounters?.events?.edges || []).filter(
(i) => i?.node?.data![0] === "0x47616e67",
).length;

const totalFight = (allTravelEncounterResults?.events?.edges || []).filter(
(i) => i?.node?.data![0] === "0x2",
).length;
const totalRun = (allTravelEncounterResults?.events?.edges || []).filter(
(i) => i?.node?.data![0] === "0x0",
).length;
const totalPay = (allTravelEncounterResults?.events?.edges || []).filter(
(i) => i?.node?.data![0] === "0x1",
).length;


const stats = {
totalGamesPlayed,
totalGamesPaid,
payRate,
totalPaperClaimed,
bestRanking,
gamesByHustler: {
[Hustlers.Dragon]: dragonGames,
[Hustlers.Monkey]: monkeyGames,
[Hustlers.Rabbit]: rabbitGames,
},
mostPlayedHustler: {
[Hustlers.Dragon]: dragonGames === maxPlayed,
[Hustlers.Monkey]: monkeyGames === maxPlayed,
[Hustlers.Rabbit]: rabbitGames === maxPlayed,
},
totalCopsEncounter,
totalGangEncounter,
totalFight,
totalRun,
totalPay,
};

return stats;
}, [games, allTravelEncounters, allTravelEncounterResults]);

return {
games: games || [],
onGoingGames: onGoingGames || [],
endedGames: endedGames || [],
playerStats: playerStats || undefined,
isFetched,
};
};
110 changes: 110 additions & 0 deletions web/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,22 @@ export type GameStorePackedSubscriptionSubscriptionVariables = Exact<{

export type GameStorePackedSubscriptionSubscription = { __typename?: 'World__Subscription', entityUpdated: { __typename?: 'World__Entity', id?: string | null, keys?: Array<string | null> | null, models?: Array<{ __typename: 'DrugConfig' } | { __typename: 'ERC20AllowanceModel' } | { __typename: 'ERC20BalanceModel' } | { __typename: 'ERC20MetadataModel' } | { __typename: 'EncounterStatsConfig' } | { __typename: 'Game' } | { __typename: 'GameConfig' } | { __typename: 'GameStorePacked', game_id?: any | null, player_id?: any | null, packed?: any | null } | { __typename: 'HustlerItemBaseConfig' } | { __typename: 'HustlerItemTiersConfig' } | { __typename: 'InitializableModel' } | { __typename: 'LocationConfig' } | { __typename: 'RyoAddress' } | { __typename: 'RyoConfig' } | { __typename: 'Season' } | { __typename: 'SeasonSettings' } | { __typename: 'SortedList' } | { __typename: 'SortedListItem' } | null> | null } };

export type TravelEncounterByPlayerQueryVariables = Exact<{
travelEncounterSelector?: InputMaybe<Scalars['String']>;
playerId?: InputMaybe<Scalars['String']>;
}>;


export type TravelEncounterByPlayerQuery = { __typename?: 'World__Query', events?: { __typename?: 'World__EventConnection', edges?: Array<{ __typename?: 'World__EventEdge', node?: { __typename?: 'World__Event', id?: string | null, keys?: Array<string | null> | null, data?: Array<string | null> | null } | null } | null> | null } | null };

export type TravelEncounterResultsByPlayerQueryVariables = Exact<{
travelEncounterResultSelector?: InputMaybe<Scalars['String']>;
playerId?: InputMaybe<Scalars['String']>;
}>;


export type TravelEncounterResultsByPlayerQuery = { __typename?: 'World__Query', events?: { __typename?: 'World__EventConnection', edges?: Array<{ __typename?: 'World__EventEdge', node?: { __typename?: 'World__Event', id?: string | null, keys?: Array<string | null> | null, data?: Array<string | null> | null } | null } | null> | null } | null };

export type SeasonByVersionQueryVariables = Exact<{
version?: InputMaybe<Scalars['u16']>;
listId?: InputMaybe<Scalars['felt252']>;
Expand Down Expand Up @@ -2991,6 +3007,100 @@ export const GameStorePackedSubscriptionDocument = `
}
}
`;
export const TravelEncounterByPlayerDocument = `
query TravelEncounterByPlayer($travelEncounterSelector: String, $playerId: String) {
events(limit: 99999, keys: [$travelEncounterSelector, "*", $playerId]) {
edges {
node {
id
keys
data
}
}
}
}
`;
export const useTravelEncounterByPlayerQuery = <
TData = TravelEncounterByPlayerQuery,
TError = unknown
>(
variables?: TravelEncounterByPlayerQueryVariables,
options?: UseQueryOptions<TravelEncounterByPlayerQuery, TError, TData>
) =>
useQuery<TravelEncounterByPlayerQuery, TError, TData>(
variables === undefined ? ['TravelEncounterByPlayer'] : ['TravelEncounterByPlayer', variables],
useFetchData<TravelEncounterByPlayerQuery, TravelEncounterByPlayerQueryVariables>(TravelEncounterByPlayerDocument).bind(null, variables),
options
);

useTravelEncounterByPlayerQuery.getKey = (variables?: TravelEncounterByPlayerQueryVariables) => variables === undefined ? ['TravelEncounterByPlayer'] : ['TravelEncounterByPlayer', variables];
;

export const useInfiniteTravelEncounterByPlayerQuery = <
TData = TravelEncounterByPlayerQuery,
TError = unknown
>(
variables?: TravelEncounterByPlayerQueryVariables,
options?: UseInfiniteQueryOptions<TravelEncounterByPlayerQuery, TError, TData>
) =>{
const query = useFetchData<TravelEncounterByPlayerQuery, TravelEncounterByPlayerQueryVariables>(TravelEncounterByPlayerDocument)
return useInfiniteQuery<TravelEncounterByPlayerQuery, TError, TData>(
variables === undefined ? ['TravelEncounterByPlayer.infinite'] : ['TravelEncounterByPlayer.infinite', variables],
(metaData) => query({...variables, ...(metaData.pageParam ?? {})}),
options
)};


useInfiniteTravelEncounterByPlayerQuery.getKey = (variables?: TravelEncounterByPlayerQueryVariables) => variables === undefined ? ['TravelEncounterByPlayer.infinite'] : ['TravelEncounterByPlayer.infinite', variables];
;

export const TravelEncounterResultsByPlayerDocument = `
query TravelEncounterResultsByPlayer($travelEncounterResultSelector: String, $playerId: String) {
events(limit: 99999, keys: [$travelEncounterResultSelector, "*", $playerId]) {
edges {
node {
id
keys
data
}
}
}
}
`;
export const useTravelEncounterResultsByPlayerQuery = <
TData = TravelEncounterResultsByPlayerQuery,
TError = unknown
>(
variables?: TravelEncounterResultsByPlayerQueryVariables,
options?: UseQueryOptions<TravelEncounterResultsByPlayerQuery, TError, TData>
) =>
useQuery<TravelEncounterResultsByPlayerQuery, TError, TData>(
variables === undefined ? ['TravelEncounterResultsByPlayer'] : ['TravelEncounterResultsByPlayer', variables],
useFetchData<TravelEncounterResultsByPlayerQuery, TravelEncounterResultsByPlayerQueryVariables>(TravelEncounterResultsByPlayerDocument).bind(null, variables),
options
);

useTravelEncounterResultsByPlayerQuery.getKey = (variables?: TravelEncounterResultsByPlayerQueryVariables) => variables === undefined ? ['TravelEncounterResultsByPlayer'] : ['TravelEncounterResultsByPlayer', variables];
;

export const useInfiniteTravelEncounterResultsByPlayerQuery = <
TData = TravelEncounterResultsByPlayerQuery,
TError = unknown
>(
variables?: TravelEncounterResultsByPlayerQueryVariables,
options?: UseInfiniteQueryOptions<TravelEncounterResultsByPlayerQuery, TError, TData>
) =>{
const query = useFetchData<TravelEncounterResultsByPlayerQuery, TravelEncounterResultsByPlayerQueryVariables>(TravelEncounterResultsByPlayerDocument)
return useInfiniteQuery<TravelEncounterResultsByPlayerQuery, TError, TData>(
variables === undefined ? ['TravelEncounterResultsByPlayer.infinite'] : ['TravelEncounterResultsByPlayer.infinite', variables],
(metaData) => query({...variables, ...(metaData.pageParam ?? {})}),
options
)};


useInfiniteTravelEncounterResultsByPlayerQuery.getKey = (variables?: TravelEncounterResultsByPlayerQueryVariables) => variables === undefined ? ['TravelEncounterResultsByPlayer.infinite'] : ['TravelEncounterResultsByPlayer.infinite', variables];
;

export const SeasonByVersionDocument = `
query SeasonByVersion($version: u16, $listId: felt252) {
seasonModels(where: {version: $version}) {
Expand Down
38 changes: 28 additions & 10 deletions web/src/graphql/game.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ query GameById($gameId: u32) {
}
}
}
}
}

query RegisteredGamesBySeason($version: u16) {
gameModels(
limit: 9001,
where: { season_version: $version, registered: true }
order: {field: FINAL_SCORE, direction: DESC}
limit: 9001
where: { season_version: $version, registered: true }
order: { field: FINAL_SCORE, direction: DESC }
) {
edges {
node {
Expand All @@ -42,7 +42,6 @@ query RegisteredGamesBySeason($version: u16) {
}
}


query GamesByPlayer($playerId: String) {
entities(limit: 9001, keys: ["*", $playerId]) {
edges {
Expand All @@ -69,18 +68,13 @@ query GamesByPlayer($playerId: String) {
game_id
player_id
packed

}
}
}
}
}
}





query GameStorePacked($gameId: String!, $playerId: String!) {
entities(keys: [$gameId, $playerId]) {
totalCount
Expand Down Expand Up @@ -114,3 +108,27 @@ subscription GameStorePackedSubscription($id: ID) {
}
}
}

query TravelEncounterByPlayer($travelEncounterSelector: String, $playerId: String) {
events(limit: 99999,keys: [$travelEncounterSelector, "*", $playerId]) {
edges {
node {
id
keys
data
}
}
}
}

query TravelEncounterResultsByPlayer($travelEncounterResultSelector: String, $playerId: String) {
events(limit: 99999, keys: [$travelEncounterResultSelector, "*", $playerId]) {
edges {
node {
id
keys
data
}
}
}
}
2 changes: 1 addition & 1 deletion web/src/manifests/dev/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@
],
"address": "0x45780a1a9786ee6bcd2e347d43d717a385dbd72e8282676d891835e0a278d14",
"transaction_hash": "0x23d8f0f19d1a0625a336efd3626d5e26ee37b44adfe33202dc79095e0b984d0",
"block_number": 4,
"block_number": 20,
"seed": "rollyourown",
"metadata": {
"profile_name": "dev",
Expand Down
Loading

0 comments on commit 27f970d

Please sign in to comment.