public static Address GetPrevWeekAddress(long thisWeekBlockIndex) { var gameConfigState = States.Instance.GameConfigState; var index = Math.Max((int)thisWeekBlockIndex / gameConfigState.WeeklyArenaInterval, 0); return(WeeklyArenaState.DeriveAddress(index)); }
public static Address GetNextWeekAddress(long blockIndex) { var gameConfigState = States.Instance.GameConfigState; var index = (int)blockIndex / gameConfigState.WeeklyArenaInterval; index++; return(WeeklyArenaState.DeriveAddress(index)); }
public static bool TryGetThisWeekAddress(long blockIndex, out Address weeklyArenaAddress) { var gameConfigState = States.Instance.GameConfigState; var index = (int)blockIndex / gameConfigState.WeeklyArenaInterval; if (index < 0) { return(false); } weeklyArenaAddress = WeeklyArenaState.DeriveAddress(index); return(true); }
private Transaction <PolymorphicAction <ActionBase> > RankingReward() { // private 테스트용 임시 로직 변경 var index = (int)_chain.Tip.Index / GameConfig.WeeklyArenaInterval; var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(index); var weeklyArenaState = new WeeklyArenaState(_chain.GetState(weeklyArenaAddress)); var actions = new List <PolymorphicAction <ActionBase> > { new RankingReward { gold1 = 50, gold2 = 30, gold3 = 10, agentAddresses = weeklyArenaState.GetAgentAddresses(3), } }; return(_chain.MakeTransaction(_privateKey, actions.ToImmutableHashSet())); }
public async Task Query(bool ended) { const string query = @" { address ended orderedArenaInfos { agentAddress avatarAddress arenaRecord { win lose draw } level combatPoint armorId active dailyChallengeCount score } }"; var weeklyArenaState = new WeeklyArenaState(WeeklyArenaState.DeriveAddress(0)); if (ended) { weeklyArenaState.End(); } var queryResult = await ExecuteQueryAsync <WeeklyArenaStateType>(query, source : weeklyArenaState); Assert.Equal( new Dictionary <string, object> { ["address"] = WeeklyArenaState.DeriveAddress(0).ToString(), ["ended"] = ended, ["orderedArenaInfos"] = new List <object>(), }, queryResult.Data ); }
public IAccountStateDelta ResetChallengeCount(IActionContext ctx, IAccountStateDelta states) { var gameConfigState = states.GetGameConfigState(); var index = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0); var weeklyAddress = WeeklyArenaState.DeriveAddress(index); var rawWeekly = (Dictionary)states.GetState(weeklyAddress); var resetIndex = rawWeekly["resetIndex"].ToLong(); if (ctx.BlockIndex - resetIndex >= gameConfigState.DailyArenaInterval) { var weekly = new WeeklyArenaState(rawWeekly); if (resetIndex >= RankingBattle.UpdateTargetBlockIndex) { // Reset count each ArenaInfo. weekly.ResetIndex = ctx.BlockIndex; var listAddress = weeklyAddress.Derive("address_list"); if (states.TryGetState(listAddress, out List rawList)) { var addressList = rawList.ToList(StateExtensions.ToAddress); foreach (var address in addressList) { var infoAddress = weeklyAddress.Derive(address.ToByteArray()); if (states.TryGetState(infoAddress, out Dictionary rawInfo)) { var info = new ArenaInfo(rawInfo); info.ResetCount(); states = states.SetState(infoAddress, info.Serialize()); } } } } else { // Run legacy ResetCount. weekly.ResetCount(ctx.BlockIndex); } states = states.SetState(weeklyAddress, weekly.Serialize()); } return(states); }
public IAccountStateDelta WeeklyArenaRankingBoard2(IActionContext ctx, IAccountStateDelta states) { var gameConfigState = states.GetGameConfigState(); var index = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0); var weeklyAddress = WeeklyArenaState.DeriveAddress(index); var rawWeekly = (Dictionary)states.GetState(weeklyAddress); var nextIndex = index + 1; var nextWeekly = states.GetWeeklyArenaState(nextIndex); if (nextWeekly is null) { nextWeekly = new WeeklyArenaState(nextIndex); states = states.SetState(nextWeekly.address, nextWeekly.Serialize()); } var resetIndex = rawWeekly["resetIndex"].ToLong(); // Beginning block of a new weekly arena. if (ctx.BlockIndex % gameConfigState.WeeklyArenaInterval == 0 && index > 0) { var prevWeeklyAddress = WeeklyArenaState.DeriveAddress(index - 1); var rawPrevWeekly = (Dictionary)states.GetState(prevWeeklyAddress); if (!rawPrevWeekly["ended"].ToBoolean()) { rawPrevWeekly = rawPrevWeekly.SetItem("ended", true.Serialize()); var weekly = new WeeklyArenaState(rawWeekly); var prevWeekly = new WeeklyArenaState(rawPrevWeekly); weekly.Update(prevWeekly, ctx.BlockIndex); states = states.SetState(prevWeeklyAddress, rawPrevWeekly); states = states.SetState(weeklyAddress, weekly.Serialize()); } } else if (ctx.BlockIndex - resetIndex >= gameConfigState.DailyArenaInterval) { var weekly = new WeeklyArenaState(rawWeekly); weekly.ResetCount(ctx.BlockIndex); states = states.SetState(weeklyAddress, weekly.Serialize()); } return(states); }
private void UpdateWeeklyArenaState() { _blockRenderer.EveryBlock() .ObserveOnMainThread() .Subscribe(_ => { var doNothing = true; var agent = Game.Game.instance.Agent; var gameConfigState = States.Instance.GameConfigState; var challengeCountResetBlockIndex = States.Instance.WeeklyArenaState.ResetIndex; var currentBlockIndex = agent.BlockIndex; if (currentBlockIndex % gameConfigState.WeeklyArenaInterval == 0 && currentBlockIndex >= gameConfigState.WeeklyArenaInterval) { doNothing = false; } if (currentBlockIndex - challengeCountResetBlockIndex >= gameConfigState.DailyArenaInterval) { doNothing = false; } if (doNothing) { return; } var weeklyArenaIndex = (int)currentBlockIndex / gameConfigState.WeeklyArenaInterval; var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(weeklyArenaIndex); var weeklyArenaState = new WeeklyArenaState( (Bencodex.Types.Dictionary)agent.GetState(weeklyArenaAddress)); States.Instance.SetWeeklyArenaState(weeklyArenaState); }) .AddTo(_disposables); }
public void Execute() { var previousWeeklyState = _initialState.GetWeeklyArenaState(ArenaIndex); var previousAvatar1State = _initialState.GetAvatarState(_avatar1Address); previousAvatar1State.level = 10; var prevScore = previousWeeklyState[_avatar1Address].Score; var previousState = _initialState.SetState( _avatar1Address, previousAvatar1State.Serialize()); var itemIds = _tableSheets.WeeklyArenaRewardSheet.Values .Select(r => r.Reward.ItemId) .ToList(); Assert.All(itemIds, id => Assert.False(previousAvatar1State.inventory.HasItem(id))); var row = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.ATK); var costume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row.CostumeId], new TestRandom()); costume.equipped = true; previousAvatar1State.inventory.AddItem(costume); var row2 = _tableSheets.CostumeStatSheet.Values.First(r => r.StatType == StatType.DEF); var enemyCostume = (Costume)ItemFactory.CreateItem( _tableSheets.ItemSheet[row2.CostumeId], new TestRandom()); enemyCostume.equipped = true; var enemyAvatarState = _initialState.GetAvatarState(_avatar2Address); enemyAvatarState.inventory.AddItem(enemyCostume); Address worldInformationAddress = _avatar1Address.Derive(LegacyWorldInformationKey); var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(RankingBattle.UpdateTargetWeeklyArenaIndex); previousState = previousState .SetState( _avatar1Address.Derive(LegacyInventoryKey), previousAvatar1State.inventory.Serialize()) .SetState( worldInformationAddress, previousAvatar1State.worldInformation.Serialize()) .SetState( _avatar1Address.Derive(LegacyQuestListKey), previousAvatar1State.questList.Serialize()) .SetState(_avatar1Address, previousAvatar1State.SerializeV2()) .SetState( _avatar2Address.Derive(LegacyInventoryKey), enemyAvatarState.inventory.Serialize()) .SetState( _avatar2Address.Derive(LegacyWorldInformationKey), enemyAvatarState.worldInformation.Serialize()) .SetState( _avatar2Address.Derive(LegacyQuestListKey), enemyAvatarState.questList.Serialize()) .SetState(_avatar2Address, enemyAvatarState.SerializeV2()) .SetState( weeklyArenaAddress, new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex).Serialize()); var action = new RankingBattle { avatarAddress = _avatar1Address, enemyAddress = _avatar2Address, weeklyArenaAddress = weeklyArenaAddress, costumeIds = new List <Guid> { costume.ItemId }, equipmentIds = new List <Guid>(), }; var nextState = action.Execute(new ActionContext { PreviousStates = previousState, Signer = _agent1Address, Random = new TestRandom(), Rehearsal = false, BlockIndex = RankingBattle.UpdateTargetBlockIndex, }); Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive(_avatar1Address.ToByteArray()), out Dictionary rawArenaInfo)); Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive(_avatar2Address.ToByteArray()), out Dictionary rawEnemyInfo)); Assert.True(nextState.TryGetState(weeklyArenaAddress.Derive("address_list"), out List rawAddressList)); var nextWeekly = nextState.GetWeeklyArenaState(weeklyArenaAddress); Assert.Empty(nextWeekly.Map); var nextAvatar1State = nextState.GetAvatarStateV2(_avatar1Address); var nextArenaInfo = new ArenaInfo(rawArenaInfo); var addressList = rawAddressList.ToList(StateExtensions.ToAddress); Assert.Contains(_avatar1Address, addressList); Assert.Contains(_avatar2Address, addressList); Assert.Contains(nextAvatar1State.inventory.Materials, i => itemIds.Contains(i.Id)); Assert.NotNull(action.ArenaInfo); Assert.NotNull(action.EnemyArenaInfo); Assert.True(nextArenaInfo.Score > prevScore); // Check simulation result equal. var player = new Player( previousAvatar1State, _tableSheets.CharacterSheet, _tableSheets.CharacterLevelSheet, _tableSheets.EquipmentItemSetEffectSheet); var simulator = new RankingSimulator( new TestRandom(), player, action.EnemyPlayerDigest, new List <Guid>(), _tableSheets.GetRankingSimulatorSheets(), RankingBattle.StageId, action.ArenaInfo, action.EnemyArenaInfo, _tableSheets.CostumeStatSheet); simulator.Simulate(); Assert.Equal(nextArenaInfo.Score, simulator.Log.score); Assert.Equal(previousAvatar1State.SerializeV2(), nextAvatar1State.SerializeV2()); Assert.Equal(previousAvatar1State.worldInformation.Serialize(), nextAvatar1State.worldInformation.Serialize()); }
public WeeklyArenaStateUpdateScenarioTest() { _initialState = new Tests.Action.State(); var sheets = TableSheetsImporter.ImportSheets(); foreach (var(key, value) in sheets) { _initialState = _initialState.SetState( Addresses.TableSheet.Derive(key), value.Serialize()); } var tableSheets = new TableSheets(sheets); var rankingMapAddress = new PrivateKey().ToAddress(); _agent1Address = new PrivateKey().ToAddress(); _avatar1Address = new PrivateKey().ToAddress(); var agentState = new AgentState(_agent1Address); var avatarState = new AvatarState( _avatar1Address, _agent1Address, 0, tableSheets.GetAvatarSheets(), new GameConfigState(sheets[nameof(GameConfigSheet)]), rankingMapAddress ) { worldInformation = new WorldInformation( 0, tableSheets.WorldSheet, Math.Max( tableSheets.StageSheet.First?.Id ?? 1, GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)), level = 100, }; agentState.avatarAddresses.Add(0, _avatar1Address); var agent2Address = new PrivateKey().ToAddress(); _avatar2Address = new PrivateKey().ToAddress(); var agent2State = new AgentState(agent2Address); var avatar2State = new AvatarState( _avatar2Address, agent2Address, 0, tableSheets.GetAvatarSheets(), new GameConfigState(sheets[nameof(GameConfigSheet)]), rankingMapAddress ) { worldInformation = new WorldInformation( 0, tableSheets.WorldSheet, Math.Max( tableSheets.StageSheet.First?.Id ?? 1, GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)), level = 100, }; agent2State.avatarAddresses.Add(0, _avatar2Address); var agent3Address = new PrivateKey().ToAddress(); _avatar3Address = new PrivateKey().ToAddress(); var agent3State = new AgentState(agent3Address); var avatar3State = new AvatarState( _avatar3Address, agent2Address, 0, tableSheets.GetAvatarSheets(), new GameConfigState(sheets[nameof(GameConfigSheet)]), rankingMapAddress ) { worldInformation = new WorldInformation( 0, tableSheets.WorldSheet, Math.Max( tableSheets.StageSheet.First?.Id ?? 1, GameConfig.RequireClearedStageLevel.ActionsInRankingBoard)), level = 100, }; agent3State.avatarAddresses.Add(0, _avatar3Address); var prevWeeklyArenaState = new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex - 2); var weeklyArenaState = new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex - 1); weeklyArenaState.SetV2(avatarState, tableSheets.CharacterSheet, tableSheets.CostumeStatSheet); weeklyArenaState[_avatar1Address].Activate(); weeklyArenaState.SetV2(avatar2State, tableSheets.CharacterSheet, tableSheets.CostumeStatSheet); weeklyArenaState[_avatar2Address].Activate(); _weeklyArenaAddress = WeeklyArenaState.DeriveAddress(RankingBattle.UpdateTargetWeeklyArenaIndex); var gold = new GoldCurrencyState(new Currency("NCG", 2, minter: null)); _initialState = _initialState .SetState(_agent1Address, agentState.Serialize()) .SetState(_avatar1Address, avatarState.Serialize()) .SetState(agent2Address, agent2State.Serialize()) .SetState(_avatar2Address, avatar2State.Serialize()) .SetState(agent3Address, agent2State.Serialize()) .SetState(_avatar3Address, avatar2State.Serialize()) .SetState(Addresses.GameConfig, new GameConfigState(sheets[nameof(GameConfigSheet)]).Serialize()) .SetState(prevWeeklyArenaState.address, prevWeeklyArenaState.Serialize()) .SetState(weeklyArenaState.address, weeklyArenaState.Serialize()) .SetState(_weeklyArenaAddress, new WeeklyArenaState(RankingBattle.UpdateTargetWeeklyArenaIndex).Serialize()) .SetState(GoldCurrencyState.Address, gold.Serialize()) .SetState(Addresses.GoldDistribution, GoldDistributionTest.Fixture.Select(v => v.Serialize()).Serialize()) .MintAsset(GoldCurrencyState.Address, gold.Currency * 100000000000); }
public static WeeklyArenaState GetWeeklyArenaState(this IAccountStateDelta states, int index) { var address = WeeklyArenaState.DeriveAddress(index); return(GetWeeklyArenaState(states, address)); }
public static MakeInitialStateResult MakeInitialState() { var goldCurrencyState = new GoldCurrencyState(new Currency("NCG", 2, minter: null)); var ranking = new RankingState1(); for (var i = 0; i < RankingState1.RankingMapCapacity; i++) { ranking.RankingMap[RankingState1.Derive(i)] = new HashSet <Address>().ToImmutableHashSet(); } var sheets = TableSheetsImporter.ImportSheets(); var weeklyArenaAddress = WeeklyArenaState.DeriveAddress(0); var initialState = new Tests.Action.State() .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize()) .SetState( Addresses.GoldDistribution, GoldDistributionTest.Fixture.Select(v => v.Serialize()).Serialize() ) .SetState( Addresses.GameConfig, new GameConfigState(sheets[nameof(GameConfigSheet)]).Serialize() ) .SetState(Addresses.Ranking, ranking.Serialize()) .SetState(weeklyArenaAddress, new WeeklyArenaState(0).Serialize()); foreach (var(key, value) in sheets) { initialState = initialState.SetState(Addresses.TableSheet.Derive(key), value.Serialize()); } var tableSheets = new TableSheets(sheets); var rankingMapAddress = new PrivateKey().ToAddress(); var agentAddress = new PrivateKey().ToAddress(); var agentState = new AgentState(agentAddress); var avatarAddress = new PrivateKey().ToAddress(); var avatarState = new AvatarState( avatarAddress, agentAddress, 0, tableSheets.GetAvatarSheets(), new GameConfigState(), rankingMapAddress) { worldInformation = new WorldInformation( 0, tableSheets.WorldSheet, GameConfig.RequireClearedStageLevel.ActionsInShop), }; agentState.avatarAddresses[0] = avatarAddress; var initCurrencyGold = goldCurrencyState.Currency * 100000000000; var agentCurrencyGold = goldCurrencyState.Currency * 1000; var remainCurrencyGold = initCurrencyGold - agentCurrencyGold; initialState = initialState .SetState(GoldCurrencyState.Address, goldCurrencyState.Serialize()) .SetState(agentAddress, agentState.Serialize()) .SetState(avatarAddress, avatarState.Serialize()) .SetState(Addresses.Shop, new ShopState().Serialize()) .MintAsset(GoldCurrencyState.Address, initCurrencyGold) .TransferAsset(Addresses.GoldCurrency, agentAddress, agentCurrencyGold); var action = new CreateTestbed { weeklyArenaAddress = weeklyArenaAddress, }; var nextState = action.Execute(new ActionContext() { BlockIndex = 0, PreviousStates = initialState, Random = new TestRandom(), Rehearsal = false, }); return(new MakeInitialStateResult( nextState, action, agentState, avatarState, goldCurrencyState, rankingMapAddress, tableSheets, remainCurrencyGold, agentCurrencyGold)); }
public IAccountStateDelta PrepareNextArena(IActionContext ctx, IAccountStateDelta states) { var gameConfigState = states.GetGameConfigState(); var index = Math.Max((int)ctx.BlockIndex / gameConfigState.WeeklyArenaInterval, 0); var weeklyAddress = WeeklyArenaState.DeriveAddress(index); var rawWeekly = (Dictionary)states.GetState(weeklyAddress); var nextIndex = index + 1; var nextWeekly = states.GetWeeklyArenaState(nextIndex); if (nextWeekly is null) { nextWeekly = new WeeklyArenaState(nextIndex); states = states.SetState(nextWeekly.address, nextWeekly.Serialize()); } // Beginning block of a new weekly arena. if (ctx.BlockIndex % gameConfigState.WeeklyArenaInterval == 0 && index > 0) { var prevWeeklyAddress = WeeklyArenaState.DeriveAddress(index - 1); var rawPrevWeekly = (Dictionary)states.GetState(prevWeeklyAddress); if (!rawPrevWeekly["ended"].ToBoolean()) { rawPrevWeekly = rawPrevWeekly.SetItem("ended", true.Serialize()); var weekly = new WeeklyArenaState(rawWeekly); var prevWeekly = new WeeklyArenaState(rawPrevWeekly); var listAddress = weekly.address.Derive("address_list"); // Set ArenaInfo, address list for new RankingBattle. var addressList = states.TryGetState(listAddress, out List rawList) ? rawList.ToList(StateExtensions.ToAddress) : new List <Address>(); if (ctx.BlockIndex >= RankingBattle.UpdateTargetBlockIndex) { weekly.ResetIndex = ctx.BlockIndex; // Copy Map to address list. if (ctx.BlockIndex == RankingBattle.UpdateTargetBlockIndex) { foreach (var kv in prevWeekly.Map) { var address = kv.Key; var lazyInfo = kv.Value; var info = new ArenaInfo(lazyInfo.State); states = states.SetState( weeklyAddress.Derive(address.ToByteArray()), info.Serialize()); if (!addressList.Contains(address)) { addressList.Add(address); } } } else { // Copy addresses from prev weekly address list. var prevListAddress = prevWeekly.address.Derive("address_list"); if (states.TryGetState(prevListAddress, out List prevRawList)) { var prevList = prevRawList.ToList(StateExtensions.ToAddress); foreach (var address in prevList.Where(address => !addressList.Contains(address))) { addressList.Add(address); } } // Copy ArenaInfo from prev ArenaInfo. foreach (var address in addressList) { if (states.TryGetState( prevWeekly.address.Derive(address.ToByteArray()), out Dictionary rawInfo)) { var prevInfo = new ArenaInfo(rawInfo); var info = new ArenaInfo(prevInfo); states = states.SetState( weeklyAddress.Derive(address.ToByteArray()), info.Serialize()); } } } // Set address list. states = states.SetState(listAddress, addressList.Aggregate(List.Empty, (current, address) => current.Add(address.Serialize()))); } // Run legacy Update. else { weekly.Update(prevWeekly, ctx.BlockIndex); } states = states.SetState(prevWeeklyAddress, rawPrevWeekly); states = states.SetState(weeklyAddress, weekly.Serialize()); } } return(states); }