private long ApplyAdvantage(RollData data, DiceAST root, int depth) { Value = Expression.Value; ValueType = Expression.ValueType; _values = Expression.Values.ToList(); var rolls = Expression.Reroll(data, root, depth + 1); if ((KeepType == KeepType.Advantage && Expression.Value > Value) || (KeepType == KeepType.Disadvantage && Expression.Value < Value)) { for (int i = 0; i < _values.Count; i++) { _values[i] = _values[i].Drop(); } Value = Expression.Value; _values.Add(new DieResult(SpecialDie.Add)); _values.AddRange(Expression.Values); } else { _values.Add(new DieResult(SpecialDie.Add)); _values.AddRange(Expression.Values.Select(d => d.Drop())); } return(rolls); }
public async Task BeSufficientlyRandom_WhenUsingDefaultRNG() { await Task.Run(() => { Dictionary <int, int> rollCounts = new Dictionary <int, int>(); for (int i = 1; i <= 20; i++) { rollCounts[i] = 0; } DieResult die; RollData data = new RollData() { Config = new RollerConfig() }; var numTrials = 10000000; var perRoll = numTrials / 20; var tolerance = perRoll * 0.005; for (int i = 0; i < numTrials; i++) { die = RollNode.DoRoll(data, RollType.Normal, 20); rollCounts[(int)die.Value]++; } for (int i = 1; i <= 20; i++) { int off = Math.Abs(rollCounts[i] - perRoll); if (off > tolerance) { Assert.Inconclusive("Default RNG fell outside of allowed tolerance of 0.5% ({0}/{1})", off, tolerance); } } }); }
public void FirstGame() { Debug.Log("FirstGame"); LeftRoll = LeftRoll; if (LeftRoll == 0 || LeftRoll == 3) { LeftRoll = 3; RollData[] datas = new RollData[10]; for (int i = 0; i < datas.Length; i++) { datas[i] = GetRandom(ROLL_TYPE.SKILL); } RollData thunder = new RollData(); thunder.type = ROLL_TYPE.SKILL; thunder.id = 0; SetShowCase(thunder, datas); } else { OnLeftRollFirstGame(); } SetRollPnl(true); Roll(); SetOnFadeOut(GameStart); SetOnPnlClose(delegate() { IsFirstRoll = false; GameManager.instance.IsFirstGame = false; }); SetOnLeftRoll(OnLeftRollFirstGame); }
protected static void EvaluateRoll(string diceExpr, RollerConfig conf, RollData data, int expectedRolls, string expectedResult) { var result = Roller.Roll(diceExpr, conf, data); Assert.AreEqual(expectedRolls, result.NumRolls); Assert.AreEqual(expectedResult, result.ToString()); }
///// <summary> ///// SkillUI를 가리키면 호출 ///// </summary> ///// <param name="position"></param> //public void SelectSkill(int position) //{ // if (isClickable && selected != -1 && datas[selected].type == ROLL_TYPE.SKILL) // { // //Debug.Log("Skill Added,position:" + position + " id:" + datas[selected].id); // target = position; // } //} public Sprite GetSprite(RollData data) { { Sprite result = null; try { switch (data.type) { case ROLL_TYPE.SKILL: result = GameDatabase.instance.skills[data.id].spr; break; case ROLL_TYPE.STAT: result = GameDatabase.instance.statSprite; break; case ROLL_TYPE.ITEM: result = GameDatabase.instance.itemSprites[Item.instance.sprIds[data.id]].spr; break; //case ROLL_TYPE.PASSIVE: // result = null;//수정 필요 // break; } return(result); } catch { return(null); } } }
/// <summary> /// Evaluates the node and asserts that the number of rolls and result match what is expected. /// </summary> /// <param name="node"></param> /// <param name="conf"></param> /// <param name="expectedRolls"></param> /// <param name="expectedResult"></param> protected static void EvaluateNode(DiceAST node, RollData data, int expectedRolls, string expectedResult) { var result = Roller.Roll(node, data); Assert.AreEqual(expectedRolls, result.NumRolls); Assert.AreEqual(expectedResult, result.ToString()); }
public RollData GetRandom(params ROLL_TYPE[] modes) { RollData result = new RollData(); int rnd = Random.Range(0, modes.Length); result.type = modes[rnd]; switch (modes[rnd]) { case ROLL_TYPE.ALL: int rndMode = Random.Range(1, (int)ROLL_TYPE.ITEM + 1); return(GetRandom((ROLL_TYPE)rndMode)); case ROLL_TYPE.SKILL: do { result.id = Random.Range(0, GameDatabase.instance.skills.Length); } while (!SkillData.IsBought(result.id) && !GameDatabase.instance.skills[result.id].isBasic); break; case ROLL_TYPE.STAT: result.id = Random.Range(0, 3); break; case ROLL_TYPE.ITEM: result.id = Random.Range(0, GameDatabase.instance.items.Length); break; //case ROLL_TYPE.PASSIVE: // result = GetRandom(); // //result.id = Random.Range(0, GameDatabase.instance.skills.Length);//패시브의 길이로 수정 // break; } return(result); }
public void SetShowCase(RollData selected, params RollData[] datas) { Init(); if (!LoadDatas()) { this.datas = datas; for (int i = datas.Length; i < 10; i++) { this.datas[i] = datas[Random.Range(0, datas.Length)]; Debug.Log("RANDOM"); } this.stopped = -1; for (int i = 0; i < 10; i++) { if (this.datas[i].type == selected.type && this.datas[i].id == selected.id) { this.stopped = i; } //showCases[i].enabled = true; //SetSprite(i, GetSprite(this.datas[i])); Debug.Log("Set:" + datas[i].id); } if (this.stopped == -1) { int rnd = Random.Range(0, 10); this.datas[rnd] = selected; //showCases[rnd].enabled = true; //SetSprite(rnd, GetSprite(this.datas[rnd])); this.stopped = rnd; Debug.Log("No Stopped"); } if (--stopped < 0) { stopped = 9; } string datasJson = JsonHelper.ToJson <RollData>(this.datas); PlayerPrefs.SetString("rollDatas", datasJson); PlayerPrefs.SetInt("stopped", stopped); } else { Debug.Log("RollData, params RollData[] : ShowCase Loaded"); //for (int i = 0; i < showCases.Length; i++) //{ // showCases[i].enabled = true; // SetSprite(i, GetSprite(this.datas[i])); //} } //SetStatTxt(true); this.InitScroll(); }
protected override long RerollInternal(RollData data, DiceAST root, int depth) { var rolls = Expression.Reroll(data, root, depth + 1); DoSort(); return(rolls); }
protected override long RerollInternal(RollData data, DiceAST root, int depth) { long rolls = Expression.Reroll(data, root, depth + 1); MarkCrits(); return(rolls); }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { long rolls = NumTimes?.Evaluate(data, root, depth + 1) ?? 0; rolls += Roll(data, root, depth); return(rolls); }
void OnRoll(ClickScript cs, RollData data) { var nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("trap")==0 || nume.Current.CompareTo("ambush")==0) data.bonus.Add(new KeyValuePair<List<string>, int>(new List<string>(), 4)); } }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { long rolls = Comparison?.Evaluate(data, root, depth + 1) ?? 0; rolls += Expression.Evaluate(data, root, depth + 1); rolls += DoExplode(data); return(rolls); }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { var rolls = Amount?.Evaluate(data, root, depth + 1) ?? 0; rolls += Expression.Evaluate(data, root, depth + 1); rolls += ApplyKeep(data, root, depth); return(rolls); }
/// <summary> /// 결정되었을 때 호출 /// </summary> public void Ok() { RollData rollData = datas[stopped]; switch (rollData.type) { case ROLL_TYPE.SKILL: if (SkillGUI.pointedSkill == -1) { break; } SkillData selectedSkill = GameDatabase.instance.skills[rollData.id]; //선택된 스킬 데이터 Skill slotSkill = SkillManager.instance.skills[SkillGUI.pointedSkill].skill; //해당 슬롯에 장착된 스킬 if (slotSkill == null || slotSkill.data.id == -1) //슬롯이 비었으면 { SkillManager.instance.SetSkill(selectedSkill, SkillGUI.pointedSkill); SetRollPnl(false); } else if (slotSkill.data.id == selectedSkill.id) //같은 스킬이면 { SkillManager.instance.SetSkill(selectedSkill, SkillGUI.pointedSkill); SetRollPnl(false); } else //다른 스킬이면 { if (slotSkill.data.level == 1) { SkillManager.instance.SetSkill(selectedSkill, SkillGUI.pointedSkill); SetRollPnl(false); } else { SkillChangeManager.instance.OpenChangePnl(selectedSkill, SkillGUI.pointedSkill); //스킬 교체 패널 오픈 } } //SetRollPnl(false, isStageUp); break; case ROLL_TYPE.STAT: StatManager.instance.SetStatPnl(true, rollData.id + 1); break; case ROLL_TYPE.ITEM: if (Item.isPointed) { Item.instance.EquipItem(rollData.id); SetRollPnl(false); } break; //case ROLL_TYPE.PASSIVE: // //selectedImg.sprite = GetSprite(data); // typeTxt.text = "Passive"; // nameTxt.text = "패시브"; // descTxt.text = "패시브"; // break; } }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { var rolls = MaxRerollsExpr?.Evaluate(data, root, depth + 1) ?? 0; rolls += Comparison.Evaluate(data, root, depth + 1); rolls += Expression.Evaluate(data, root, depth + 1); rolls += MaybeReroll(data, root, depth); return(rolls); }
internal MacroNode(string param, RollData data) { if (String.IsNullOrWhiteSpace(param)) { throw new DiceException(DiceErrorCode.InvalidMacro, new ArgumentException("Macro param cannot consist of only whitespace", nameof(param))); } Context = new MacroContext(param.Trim(), data); _values = new List <DieResult>(); }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { long rolls = Expression.Evaluate(data, root, depth + 1); rolls += Critical?.Evaluate(data, root, depth + 1) ?? 0; rolls += Fumble?.Evaluate(data, root, depth + 1) ?? 0; MarkCrits(); return(rolls); }
protected override long RerollInternal(RollData data, DiceAST root, int depth) { long rolls = 0; foreach (var c in Comparisons) { rolls += c.expr.Reroll(data, root, depth); } return(rolls); }
protected override long RerollInternal(RollData data, DiceAST root, int depth) { long rolls = Context.Expression?.Reroll(data, root, depth + 1) ?? 0; foreach (var arg in Context.Arguments) { rolls += arg.Reroll(data, root, depth + 1); } CallFunction(); return(rolls); }
protected override long RerollInternal(RollData data, DiceAST root, int depth) { if (Success == null) { throw new DiceException(DiceErrorCode.InvalidSuccess); } long rolls = Expression.Reroll(data, root, depth + 1); CountSuccesses(); return(rolls); }
public RollData(RollData other) { source = other.source; target = other.target; type = new List<string>(other.type); bonus = new List<KeyValuePair<List<string>, int>>(); roll = new List<int>(); this.other = other; other.other = this; }
public void Successfully_RegisterGlobalMacro_Data() { var registry = new MacroRegistry(); registry.RegisterType(new MacroContainer(3)); registry.RegisterGlobalMacro(MacroContainer.A); var data = new RollData() { MacroRegistry = registry }; EvaluateRoll("[b]", null, data, 0, "[b] => 3 => 3"); EvaluateRoll("[bb]", null, data, 0, "[bb] => 1 => 1"); }
/// <summary> /// Evaluates the node and asserts that a DiceException was thrown with the specified error code. /// </summary> /// <param name="node"></param> /// <param name="conf"></param> /// <param name="error"></param> protected static void EvaluateNode(DiceAST node, RollData data, DiceErrorCode error) { try { Roller.Roll(node, data); Assert.Fail("Expected DiceException with error code {0}, but did not receive an exception.", error.ToString()); } catch (DiceException e) { if (e.ErrorCode != error) { Assert.Fail("Expected DiceException with error code {0}, but got error code {1}.", error.ToString(), e.ErrorCode.ToString()); } } }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { // this doesn't increase depth as there is no actual logic that a ComparisonNode itself performs // (in other words, the Expression can be viewed as the ComparisonNode's evaluation) long rolls = 0; Value = 0; foreach (var c in Comparisons) { rolls += c.expr.Evaluate(data, root, depth); } return(rolls); }
void OnRoll(ClickScript cs, RollData data) { for (int i=0;i<data.bonus.Count;++i) { var nume = data.bonus[i].Key.GetEnumerator(); bool is_darkness_penalty = false; while (nume.MoveNext()) { if (nume.Current.CompareTo("darkness") == 0) is_darkness_penalty = true; } if (is_darkness_penalty) data.bonus[i] = new KeyValuePair<List<string>, int>(data.bonus[i].Key, data.bonus[i].Value + 4); } }
public void Successfully_ToString() { RollData data = new RollData() { Config = new RollerConfig() }; data.Config.FunctionRegistry.RegisterFunction("foo", Foo, FunctionScope.Roll, FunctionTiming.BeforeCrit); var partial = new RollPartialNode(new RollNode(RollType.Normal, One, Twenty)); partial.AddCritical(new CritNode(equal20, equal1)); partial.AddFunction(new FunctionNode(FunctionScope.Basic, "foo", new List <DiceAST>(), data)); partial.AddReroll(new RerollNode(0, equal1)); Assert.AreEqual("RPARTIAL<<1d20.reroll(=1).critical(=20).fumble(=1).foo()>>", partial.ToString()); }
RollData GetRollData(ulong userID, string rollname) { Dictionary <string, RollData> rollDatas; if (!rollsData.TryGetValue(userID, out rollDatas)) { rollsData[userID] = rollDatas = new Dictionary <string, RollData>(); } RollData rollData; if (!rollDatas.TryGetValue(rollname, out rollData)) { rollDatas[rollname] = rollData = new RollData(); } return(rollData); }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { if (Success == null) { throw new DiceException(DiceErrorCode.InvalidSuccess); } long rolls = Expression.Evaluate(data, root, depth + 1); rolls += Success.Evaluate(data, root, depth + 1); rolls += Failure?.Evaluate(data, root, depth + 1) ?? 0; CountSuccesses(); return(rolls); }
public void Successfully_ToAST() { RollData data = new RollData() { Config = new RollerConfig() }; data.Config.FunctionRegistry.RegisterFunction("foo", Foo, FunctionScope.Roll, FunctionTiming.BeforeCrit); data.Config.GetRandomBytes = GetRNG(0, 1); var partial = new RollPartialNode(new RollNode(RollType.Normal, One, Twenty)); partial.AddCritical(new CritNode(equal20, equal1)); partial.AddFunction(new FunctionNode(FunctionScope.Basic, "foo", new List <DiceAST>(), data)); partial.AddReroll(new RerollNode(0, equal1)); EvaluateNode(partial.CreateRollNode(), data, 2, "1d20.reroll(=1).foo().critical(=20).fumble(=1) => 1!* + 2 => 2"); }
private long Roll(RollData data) { long numDice = (long)NumDice.Value; long numSides = (long)(NumSides?.Value ?? 1); if (numDice < 0) { throw new DiceException(DiceErrorCode.NegativeDice); } if (numDice > data.Config.MaxDice) { throw new DiceException(DiceErrorCode.TooManyDice); } _values.Clear(); ValueType = ResultType.Total; if (numDice == 0) { Value = 0; _values.Add(new DieResult() { DieType = DieType.Literal, NumSides = 0, Value = 0, Flags = DieFlags.Extra }); return(0); } for (int i = 0; i < numDice; i++) { var result = DoRoll(data, RollType, (int)numSides); _values.MaybeAddPlus(); _values.Add(result); } Value = _values.Sum(d => d.Value); data.InternalContext.AddRollExpression(this); return(numDice); }
void OnRoll(ClickScript cs, RollData data) { bool ispray = false; bool isholy = false; var nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("pray")==0) ispray = true; } nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("holy")==0) isholy = true; } if (ispray && isholy) data.bonus.Add (new KeyValuePair<List<string>, int> (new List<string> (), 2)); }
void OnRoll(ClickScript cs, RollData data) { bool use = false; bool iseldritch = false; var nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("use")==0) use = true; } nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("eldritch")==0) iseldritch = true; } if (use && iseldritch) data.bonus.Add (new KeyValuePair<List<string>, int> (new List<string> (), 4)); }
public void OnLeftRollFirstGame() { Debug.Log("OnLeftRollFirstGame:" + LeftRoll); switch (LeftRoll) { case 2: { RollData[] datas = new RollData[10]; for (int i = 0; i < datas.Length; i++) { datas[i] = GetRandom(ROLL_TYPE.SKILL); } Debug.Log("Ice"); RollData ice = new RollData(); ice.type = ROLL_TYPE.SKILL; ice.id = 1; SetShowCase(ice, datas); Roll(); break; } case 1: { RollData[] datas = new RollData[10]; for (int i = 0; i < datas.Length; i++) { datas[i] = GetRandom(ROLL_TYPE.SKILL); } Debug.Log("DashShoes"); RollData dashshoes = new RollData(); dashshoes.type = ROLL_TYPE.SKILL; dashshoes.id = 6; SetShowCase(dashshoes, datas); SetOnLeftRoll(null); Roll(); break; } } }
protected override long EvaluateInternal(RollData data, DiceAST root, int depth) { if (data.MacroRegistry.Contains(Context.Name)) { data.MacroRegistry.Get(Context.Name).callback(Context); } else if (data.Config.MacroRegistry.Contains(Context.Name)) { data.Config.MacroRegistry.Get(Context.Name).callback(Context); } data.MacroRegistry.GlobalCallbacks?.Invoke(Context); data.Config.MacroRegistry.GlobalCallbacks?.Invoke(Context); Value = Context.Value; ValueType = Context.ValueType; data.InternalContext.AllMacros.Add(Value); if (Context.Value == Decimal.MinValue) { throw new DiceException(DiceErrorCode.InvalidMacro); } _values.Clear(); if (Context.Values != null) { _values.AddRange(Context.Values); } if (_values.Count == 0) { _values.Add(new DieResult() { DieType = DieType.Literal, NumSides = 0, Value = Context.Value, Flags = DieFlags.Macro }); } return(0); }
void OnRoll(ClickScript cs, RollData data) { bool use = false; bool identify = false; bool iseldritch = false; var nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("use")==0) use = true; } nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("eldritch")==0) iseldritch = true; } nume = data.type.GetEnumerator (); while (nume.MoveNext()) { if (nume.Current.CompareTo("identify")==0) identify = true; } if (use && iseldritch || identify) { if (data.roll.Count > 0) { int smallest_id = 0; for (int i = 1; i < data.roll.Count; ++i) { if (data.roll[i] < data.roll[smallest_id]) smallest_id = i; } data.roll[smallest_id] = Math.Max(data.roll[smallest_id], RandomManager.d6()); } } }
void OnRoll(ClickScript cs, RollData data) { data.bonus.Add (new KeyValuePair<List<string>, int> (new List<string> (), bonus)); }
void OnRoll(ClickScript cs, RollData data) { List<string> list = new List<string>(); list.Add("starvation"); data.bonus.Add(new KeyValuePair<List<string>, int>(list, -4)); }