private Cell <Square> GetSquare(int target, Stream <int> sCheck, Stream <int> sFlag) { Cell <Square> square = sFlag.Filter(target.Equals).Snapshot(Flags[target], (_, value) => value ? new Flag().Square : new Tile().Square).Hold(new Tile().Square).SwitchC(); Stream <ISet <int> > sFlipMine = sCheck.Filter(t => Flags[t].Sample()).Filter(Mines.Contains).Map(_ => Mines); Stream <ISet <int> > sFlipVoid = sCheck.Filter(t => Flags[t].Sample()).Filter(Voids.Contains).Map(t => CollectConnectedVoid(t, Voids, Adjacent)); if (Mines.Contains(target)) { var sFlip = sFlipMine.Filter(targets => targets.Contains(target)).Map(_ => Unit.Value); var sTrigger = sCheck.Filter(target.Equals).Filter(_ => Flags[target].Sample()).Map(_ => Unit.Value).OrElse(sFlip); return(sTrigger.Map(_ => new Mine().Square).Hold(square).SwitchC()); } if (Voids.Contains(target)) { var sFlip = sFlipVoid.Filter(targets => targets.Contains(target)).Map(_ => Unit.Value); var sTrigger = sCheck.Filter(target.Equals).Filter(_ => Flags[target].Sample()).Map(_ => Unit.Value).OrElse(sFlip); return(sTrigger.Map(_ => new Void().Square).Hold(square).SwitchC()); } if (Hints.ContainsKey(target)) { var sFlip = sFlipVoid.Filter(voids => Adjacent[target].Any(voids.Contains)).Map(voids => Unit.Value); var sTrigger = sCheck.Filter(target.Equals).Filter(_ => Flags[target].Sample()).Map(_ => Unit.Value).OrElse(sFlip); return(sTrigger.Map(_ => new Hint(Hints[target]).Square).Hold(square).SwitchC()); } return(new Tile().Square); }
private string Sanitize(Variant value) { string final = null; if (value.GetVariantType() == Variant.VariantType.ByteString) { try { final = encoding.GetString((byte[])value); } catch (DecoderFallbackException) { throw new PeachException("Error, " + debugName + " value contains invalid " + stringType + " bytes."); } } if (value.GetVariantType() == Variant.VariantType.BitStream) { try { var rdr = new BitReader((BitwiseStream)value); rdr.BaseStream.Seek(0, System.IO.SeekOrigin.Begin); final = rdr.ReadString(encoding); } catch (DecoderFallbackException) { throw new PeachException("Error, " + debugName + " value contains invalid " + stringType + " bytes."); } } else { try { encoding.GetBytes((string)value); } catch { throw new PeachException("Error, " + debugName + " value contains invalid " + stringType + " characters."); } final = (string)value; } if (_hasLength) { var lenType = lengthType; var len = length; if (lenType == LengthType.Chars) { if (NeedsExpand(final.Length, len, nullTerminated, final)) { if (nullTerminated) { len -= 1; } final += MakePad((int)len - final.Length); } } else { if (lenType == LengthType.Bits) { if ((len % 8) != 0) { throw new PeachException("Error, " + debugName + " has invalid length of " + len + " bits."); } len = len / 8; lenType = LengthType.Bytes; } System.Diagnostics.Debug.Assert(lenType == LengthType.Bytes); int actual = encoding.GetByteCount(final); if (NeedsExpand(actual, len, nullTerminated, final)) { int nullLen = encoding.GetByteCount("\0"); int padLen = encoding.GetByteCount(new char[1] { padCharacter }); int grow = (int)len - actual; if (nullTerminated) { grow -= nullLen; } if (grow < 0 || (grow % padLen) != 0) { throw new PeachException(string.Format("Error, can not satisfy length requirement of {1} {2} when padding {3} {0}.", debugName, lengthType == LengthType.Bits ? len * 8 : len, lengthType.ToString().ToLower(), stringType)); } final += MakePad(grow / padLen); } } } int test; if (int.TryParse(final, out test)) { if (!Hints.ContainsKey("NumericalString")) { Hints.Add("NumericalString", new Hint("NumericalString", "true")); } } else { if (Hints.ContainsKey("NumericalString")) { Hints.Remove("NumericalString"); } } return(final); }