//should include startFrame, include endframe public void HandleInputFramesInBackground(SWBytes initialInputFramesData, int startFrameNumber, int endFrameNumber) { lock (FRAME_SYNC_LOCK) { if (_game.gameState == FrameSyncGameState.Stopped) { return; } SWConsole.Info($"HandleInputFramesInBackground startFrameNumber={startFrameNumber} endFrameNumber={endFrameNumber}"); _startFrameNumber = startFrameNumber; _endFrameNumber = endFrameNumber; _initialInputFrameDeltas.Clear(); _initialInputFramesData = initialInputFramesData; for (int i = startFrameNumber; i < endFrameNumber; i++) { InputFrameDelta delta = new InputFrameDelta(); byte length = initialInputFramesData.PopByte(); initialInputFramesData.PopByteBuffer(delta.bytes, 0, length); _initialInputFrameDeltas.Add(delta); } int expected = endFrameNumber - startFrameNumber; int got = _initialInputFrameDeltas.Count; //reset read index, we will save the data to disk later _initialInputFramesData.SetReadIndex(0); if (expected != got) { SWConsole.Error($"HandleInputFramesInBackground got={got} expected={expected}"); } } }
int Simulate(int frameNumber) { SWConsole.Crit($"Engine: Simulate frameNumber={frameNumber}"); InputFrame lastInputFrame = inputFrames[frameNumber - 1]; InputFrameDelta lastInputFrameDelta = inputFrameDeltas[frameNumber - 1]; int playerFrameNumber = lastInputFrameDelta.playerFrameNumber; InputFrame inputFrame = inputFrames[frameNumber]; if (inputFrame == null) { inputFrame = new InputFrame(frameNumber); inputFrames[frameNumber] = inputFrame; } inputFrame.FrameNumber = frameNumber; inputFrame.ResetBytes(); if (lastInputFrame == null || _input == null || inputFrame == null || lastInputFrameDelta == null) { SWConsole.Error($"Engine: Simulate input data is nil {lastInputFrame} {_input} {inputFrame} {lastInputFrameDelta}"); } lastInputFrameDelta.Apply(_input, lastInputFrame, inputFrame); FrameSyncUpdateType updateType = FrameSyncUpdateType.Normal; DoSimulate(updateType, inputFrame, frameNumber); return(playerFrameNumber); }
public void SendInputFrameDeltas(SWBytes inputFrameDeltas, int count, byte inputSize) { for (int i = 0; i < count; i++) { int playerFrameNumber = inputFrameDeltas.PopInt(); int predictedFrameNumber = inputFrameDeltas.PopInt(); byte length = inputFrameDeltas.PopByte(); if (playerFrameNumber == _lastReceivedPlayerFrameNumber + 1) { int correctPredictedFrameNumber = 0; if (predictedFrameNumber != 0) { correctPredictedFrameNumber = _lastPredictedFrameNumber + 1; _predictedFrameNumber = predictedFrameNumber; _correctFrameNumber = correctPredictedFrameNumber; SWConsole.Info($"MOCK: SendInputFrameDeltas playerFrameNumber={playerFrameNumber} correctPredictedFrameNumber={correctPredictedFrameNumber} _predictedFrameNumber={_predictedFrameNumber}"); } InputFrameDelta delta = new InputFrameDelta(); delta.frameNumber = playerFrameNumber; inputFrameDeltas.PopByteBuffer(delta.bytes, 0, length); _receivedInputFrameDeltas.Enqueue(delta); _lastReceivedPlayerFrameNumber = playerFrameNumber; _lastPredictedFrameNumber = correctPredictedFrameNumber; } else { SWConsole.Info($"MOCK: SendInputFrameDeltas SKIP playerFrameNumber={playerFrameNumber}"); inputFrameDeltas.SkipRead(length); } } }
static void DoAdjustmentForPrediction() { //if client prediction is enabled, input is sampled in fixed updated //so we only adjust fixed update delta time //error = actual server frame number - predicted server frame number if (_avgPredictionError > 1) { //predicted is less than actual //local should run faster so local can predicter a larger frame numbers internalFixedDeltaTime = internalFixedDeltaTime * FrameSyncConstant.DYNAMIC_ADJUST_STEP; if (internalFixedDeltaTime < _minDeltaTime) { internalFixedDeltaTime = _minDeltaTime; } SWConsole.Warn($"Adjust FASTER internalFixedDeltaTime={internalFixedDeltaTime}"); } else if (_avgPredictionError < -1) { //predicted is greater than actual //local should run slower so local can predict smaller frame numbers internalFixedDeltaTime = internalFixedDeltaTime / FrameSyncConstant.DYNAMIC_ADJUST_STEP; if (internalFixedDeltaTime > _maxDeltaTime) { internalFixedDeltaTime = _maxDeltaTime; } SWConsole.Warn($"Adjust SLOWER internalFixedDeltaTime={internalFixedDeltaTime}"); } }
public static void InitDebugMode(string playerUID, int playerCount) { if (Instance != null) { return; } if (playerCount < 1 || playerCount > 8) { Debug.LogError($"{_debugName}: invalid player count. (Max=8)"); return; } _debugMode = true; _debugPlayerCount = playerCount; Instance = new FrameSyncClient(playerUID); UnityThread.initUnityThread(); SWConsole.SetLogger(new UnityLogger()); SWConsole.level = ConsoleLogLevel.error; if (UnityEngine.Application.isPlaying) { GameObject obj = new GameObject("_SWFrameSyncClientBehaviour"); //obj.hideFlags = HideFlags.HideAndDontSave; SWFrameSyncClientBehaviour cb = obj.AddComponent <SWFrameSyncClientBehaviour>(); cb.SetClient(Instance); } }
internal void Apply(FrameSyncInput input, InputFrame i1, InputFrame i2) { //copy i1 to i2 SWBytes.CopyFull(i1.bytes, i2.bytes); //let input reset //important to reset triggers input.InputJustCopied(i2.bytes); //apply delta for each player byte inputSize = input.Size; SWConsole.Crit($"ApplyDelta delta frameNumber={frameNumber} {bytes.FullString()}"); while (bytes.DataLength > 0) { byte playerID = bytes.PopByte(); FrameSyncPlayer player = input.GetPlayer(playerID); if (player == null) { SWConsole.Error($"InputFrameDelta Apply: player not found {playerID}"); } byte offset = player.InputOffset; SWBytes.Copy(bytes, i2.bytes, bytes.ReadIndex, offset, inputSize); bytes.SkipRead(inputSize); } //reset read index bytes.SetReadIndex(0); //prepare bitarray input.InputDeltaJustApplied(i2.bytes); }
public override int GetIntValue(BitArray bitArray) { int result = 0; for (int i = 0; i < _size; i++) { int index = _bitOffset + i; bool bit = bitArray[index]; if (bit) { result |= 1 << i; } } //-2, -1, 0, 1, 2 // 0, 1, 2, 3, 4 //if result is greater than the max value //the actual value = result - number of values //for example, for result 3, actual value = 3 - 5 = -2 //is result valid? if (result > _nvalues) { SWConsole.Error($"invalid result({result}): result={result} min={_min} max={_max} default={_defaultValue}"); result = _defaultValue; } else if (result > _max) { result = result - _nvalues; } return(result); }
void OnDestroy() { SWConsole.Verbose("FrameSyncDebugger OnDestroy"); _tcpConnection.OnConnectionEstablished -= _tcpConnection_OnConnectionEstablished; _tcpConnection.OnConnectionNewPacket += _tcpConnection_OnConnectionNewPacket; _tcpConnection.Stop(); _tcpConnection = null; }
public void DidStep(FrameSyncEngine engine, FrameSyncGame game) { if (_watchStarted && game.gameState == FrameSyncGameState.Running) { _watchStarted = false; float ms = _watch.Stop(); SWConsole.Verbose($"Debugger DidStep {game.frameNumber} ms={ms}"); //_watcStarted might be in wrong state if (game.frameNumber == 0) { return; } _debugFrame.frameNumber = game.frameNumber; _debugFrame.elapsedMS = ms; _debugFrame.playerFrameOnServer = engine.PlayerFrameCountOnServer; _debugFrame.localServerFrameCount = engine.LocalServerFrameCount; _debugFrame.inputSampleInterval = FrameSyncTime.internalInputSampleInterval * 1000; _debugFrame.localStepInterval = FrameSyncTime.internalFixedDeltaTime * 1000; SWSystemDataFrame systemDataFrame = engine.GetSystemDataFrame(game.frameNumber); _debugFrame.hash = systemDataFrame.bytes.Crc32(); SWConsole.Verbose($"Debugger DidStep frame hash={_debugFrame.hash}"); InputFrame inputFrame = engine.GetInputFrame(game.frameNumber); FrameSyncInput input = _agent.frameSyncInput; FrameSyncInputConfig inputConfig = input.inputConfig; _debugFrame.inputs.Clear(); foreach (FrameSyncPlayer player in input._Players()) { _debugFrame.inputs[player.PlayerID.ToString()] = player.ExportDictionary(inputConfig, inputFrame.bytes); } _debugFrame.staticBehaviours.Clear(); List <StaticFrameSyncBehaviour> staticFrameSyncBehaviours = new List <StaticFrameSyncBehaviour>(StaticFrameSyncBehaviourManager._behaviours.Values); foreach (StaticFrameSyncBehaviour behaviour in staticFrameSyncBehaviours) { _debugFrame.staticBehaviours[behaviour.FrameSyncBehaviourID.ToString()] = behaviour.ExportDictionary(); } string json = JSONWriter.ToJson(_debugFrame); SWConsole.Verbose(json); if (game.type == FrameSyncGameType.Offline) { SendData(json, 1); } else { SendData(json, game.localPlayer.PlayerID); } } }
public void Initialize(FrameSyncAgent agent) { _tcpConnection = new SWTCPConnection(); _tcpConnection.OnConnectionEstablished += _tcpConnection_OnConnectionEstablished; _tcpConnection.OnConnectionNewPacket += _tcpConnection_OnConnectionNewPacket; SWConsole.Verbose("FrameSyncDebugger Initialized"); _agent = agent; _tcpConnection.Connect(_host, _port); _initialzied = true; }
void Awake() { if (instance) { Destroy(this); } DontDestroyOnLoad(gameObject); instance = this; SWConsole.Info("SWClientBehaviour awake"); }
public bool OnUpdate(float deltaTime) { _stopwatch.Stop(); double elapsed = _stopwatch.Elapsed.TotalSeconds; _stopwatch.Restart(); if (_game.type == FrameSyncGameType.Online && _game.gameState == FrameSyncGameState.Running) { _inputSampleTimer += deltaTime; int serverPlayerFrameCount = PlayerFrameCountOnServer; int localServerFrameCount = LocalServerFrameCount; bool adjusted = false; if (_game.clientSidePrediction) { FrameSyncTime.DoFixedTickIfNecessary((float)elapsed, serverPlayerFrameCount, () => { if (_localCounter == 0) { _stopwatch1.Start(); } _localCounter++; SWConsole.Debug($"=====[OnUpdate] serverPlayerFrameCount={serverPlayerFrameCount} ====="); FlushInputOnlinePrediction(); RunningOnlineWithPrediction(); if (_localCounter == 900) { _stopwatch1.Stop(); double elapsed1 = _stopwatch1.Elapsed.TotalSeconds; //SWConsole.Error($"elapsed={elapsed1}"); } }); } else { adjusted = FrameSyncTime.Adjust(serverPlayerFrameCount, localServerFrameCount, deltaTime); if (_inputSampleTimer > FrameSyncTime.internalInputSampleInterval) { _inputSampleTimer = 0; FlushInputOnline(); } } return(adjusted); } return(false); }
void SetSaveHandler(int skipSaveIndex) { SWConsole.Warn($"SetSaveHandler skipSaveIndex={skipSaveIndex}"); if (_game.replayFileName != null) { if (_saveHandler != null) { inputFrameDeltas.SetSaveDataHandler(_saveHandler, InputFrameDelta.DataSize); inputFrameDeltas.SetSkipSaveIndex(skipSaveIndex); } } }
void RunningOnline() { SWConsole.Info($"Engine: ================RunningOnline {_currentInputFrameNumber + 1}================="); if (CanSimulateInputFrame(_currentInputFrameNumber + 1)) { SimulateInputFrame(_currentInputFrameNumber + 1); ExportSimulationResult(); } SWConsole.Info("Engine: ================end================="); }
internal CompressedIntInputDataController(byte bitOffset, int min, int max, byte size, int defaultValue = 0) : base(bitOffset) { _min = min; _max = max; _nvalues = _max - _min + 1; _size = size; _defaultValue = defaultValue; if (_defaultValue < _min || _defaultValue > _max) { SWConsole.Error($"Default value({_defaultValue}) should be between {_min} and {_max}. Using {_min} as the default value."); _defaultValue = _min; } }
void FlushInputOnlinePrediction() { InputFrameDelta previousInputDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber]; _currentLocalInputFrameDeltaNumber++; if (_nextPlayerFrameNumberToConfirm == 0) { _nextPlayerFrameNumberToConfirm = _currentLocalInputFrameDeltaNumber; } InputFrameDelta inputFrameDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber]; if (inputFrameDelta == null) { inputFrameDelta = new InputFrameDelta(_currentLocalInputFrameDeltaNumber); localInputFrameDeltas[_currentLocalInputFrameDeltaNumber] = inputFrameDelta; } inputFrameDelta.frameNumber = _currentLocalInputFrameDeltaNumber; inputFrameDelta.resend = FrameSyncConstant.LOCAL_INPUT_FRAME_RESEND_COUNT; inputFrameDelta.ResetBytes(); _input.ExportInput(inputFrameDelta.bytes); bool inputChanged = false; if (previousInputDelta == null) { inputChanged = true; } else { bool sameInput = previousInputDelta.IsSameInput(inputFrameDelta); inputChanged = !sameInput; } if (!inputChanged) { SWConsole.Crit($"Engine: FlushInputOnlinePrediction Input did NOT Change: localFN={_currentLocalInputFrameDeltaNumber}"); //_currentLocalInputFrameDeltaNumber--; //send an empty frame to keep the fixed delta time adjustment running inputFrameDelta.ResetBytes(); } else { SWConsole.Crit($"Engine: FlushInputOnlinePrediction Input changed: localFN={_currentLocalInputFrameDeltaNumber}"); } SendLocalInputs(); }
internal CompressedFloatInputDataController(byte bitOffset, Fix64 min, Fix64 max, Fix64 precision, byte size, Fix64 defaultValue, Func <Fix64, Fix64> predictionModifer) : base(bitOffset) { _min = min; _max = max; _precision = precision; _nvalues = (int)((_max - _min) / precision) + 1; _size = size; _defaultValue = defaultValue; _predictionModifier = predictionModifer; if (_defaultValue < _min || _defaultValue > _max) { SWConsole.Error($"Default value({_defaultValue}) should be between {_min} and {_max}. Using {_min} as the default value."); _defaultValue = _min; } }
public static bool AdjustPrediction(int serverPlayerFrameCount, int localServerFrameCount, float deltaTime) { _adjustTimer += deltaTime; if (_adjustTimer > _adjustInterval) { _adjustTimer = 0; UpdateLocalServerFrameCount(localServerFrameCount); UpdateServerPlayerFrameCount(serverPlayerFrameCount); SWConsole.Debug($"[internalInputSampleInterval]"); internalInputSampleInterval = Optimize( internalInputSampleInterval, _avgServerPlayerFrameCount, _previousAvgServerPlayerFrameCount, FrameSyncConstant.OPTIMIZED_SERVER_PREDICTION_PLAYER_FRAME_COUNT, _maxDeltaTime, _minDeltaTime, 0.05f, 0.2f, FrameSyncConstant.DYNAMIC_ADJUST_SMALL_STEP, FrameSyncConstant.DYNAMIC_ADJUST_STEP, true); _previousAvgServerPlayerFrameCount = _avgServerPlayerFrameCount; //SWConsole.Debug($"[internalFixedDeltaTime]"); //internalFixedDeltaTime = Optimize( // internalFixedDeltaTime, // _avgLocalServerFrameCount, // _previousAvgLocalServerFrameCount, // FrameSyncConstant.OPTIMIZED_LOCAL_PREDICTION_FRAME_COUNT, // _maxDeltaTime, // _minDeltaTime, // 0.1f, // 0.1f, // FrameSyncConstant.DYNAMIC_ADJUST_SMALL_STEP, // FrameSyncConstant.DYNAMIC_ADJUST_STEP, // false); //_previousAvgLocalServerFrameCount = _avgLocalServerFrameCount; return(false); } return(false); }
void WaitingForRoomFrame() { if (_firstFrameReceived > 0) { SWConsole.Crit($"WaitingForRoomFrame _firstFrameReceived={_firstFrameReceived}"); InputFrameDelta delta = inputFrameDeltas[_firstFrameReceived]; if (delta != null) { SWConsole.Crit($"WaitingForRoomFrame delta not null Delta.frameNumber = {delta.frameNumber}"); if (delta.frameNumber == _firstFrameReceived) { if (_firstFrameReceived > 1) { _game.gameState = FrameSyncGameState.WaitingForInitialSystemData; SWConsole.Crit($"WaitingForRoomFrame RequestInputFrames end={_firstFrameReceived}"); _io.RequestInputFrames(1, _firstFrameReceived); SWConsole.Crit($"WaitingForRoomFrame game WaitingForInitialSystemData now"); } else { //start from 1st frame _currentInputFrameNumber = 1; //create an empty input frame to start with inputFrames[_currentInputFrameNumber] = new InputFrame(_currentInputFrameNumber); _game.gameState = FrameSyncGameState.Running; SetSaveHandler(0); SWConsole.Crit($"WaitingForRoomFrame game running now"); } ResetTimeStamp(); return; } } } if (CheckInterval(FrameSyncConstant.SERVER_FRAME_INITIALIZATION_INTERVAL)) { SWBytes buffer = new SWBytes(32); buffer.Push(0); //frame number buffer.Push(0); //predict byte length = 0; buffer.Push(length); _io.SendInputFrameDeltas(buffer, 1, _input.Size); } }
void SaveInput(SWBytes data, int start, int end) { SWConsole.Info($"SaveItems start={start}, end={end}"); if (end > _lastEndIndex) { _lastEndIndex = end; } return; string partialName = _game.replayFileName + start.ToString("D6") + end.ToString("D6"); SaveReplayoperation operation = new SaveReplayoperation(data.Data(), partialName); operationQueue.AddOperation(operation); }
public FrameSyncPlayer CreateOfflineGamePlayer() { if (_gameState != FrameSyncGameState.Default) { SWConsole.Error("SWFrameSyncGame: not allow to add players after starting the game"); return(null); } FrameSyncPlayer player = _input.CreatePlayer(_offlineGamePlayerID); _offlineGamePlayerID++; OnNewPlayerCreated(player); return(player); }
void RestoreToConfirmedFrame() { //skip the first frame because there is no systemData to restore to if (_currentInputFrameNumber > 1) { SWConsole.Crit($"Engine: RestoreToConfirmedFrame {_currentInputFrameNumber}"); SWSystemDataFrame systemDataFrame = systemDataFrames[_currentInputFrameNumber]; IRestorable restorable = systemDataFrame.GetUserRestorable(); if (restorable != null) { restorable.Restore(); } ReloadSystemDataSnapshot(systemDataFrame.bytes); systemDataFrame.bytes.SetReadIndex(0); } }
public static bool Adjust(int predictionError, float deltaTime) { _adjustTimer += deltaTime; if (_adjustTimer > _adjustInterval) { _adjustTimer = 0; SWConsole.Warn($"======================Adjust======================="); //SWConsole.Warn($"Adjust serverPlayerFrameCount={serverPlayerFrameCount} localServerFrameCount={localServerFrameCount}"); UpdatePredictionError(predictionError); //SWConsole.Warn($"Adjust AVG _avgServerPlayerFrameCount={_avgServerPlayerFrameCount} _avgLocalServerFrameCount={_avgLocalServerFrameCount}"); DoAdjustmentForPrediction(); return(true); } return(false); }
void WaitingForInitialSystemData() { if (HasNewInitialInputFrameDeltas()) { //play all initial input frame SWConsole.Crit($"WaitingForInitialSystemData has initial input deltas startFrameNumber={_startFrameNumber}"); InputFrame inputFrame1 = new InputFrame(); InputFrame inputFrame2 = new InputFrame(); int frameNumber = _startFrameNumber + 1; //if start number is 1 delta, we need to simulate 2 because 2 = 1 input + 1 delta foreach (InputFrameDelta delta in _initialInputFrameDeltas) { inputFrame2.ResetBytes(); delta.Apply(_input, inputFrame1, inputFrame2); FrameSyncUpdateType updateType = FrameSyncUpdateType.Restore; SWConsole.Crit($"WaitingForInitialSystemData simulate {frameNumber}"); DoSimulate(updateType, inputFrame2, frameNumber); InputFrame temp = inputFrame1; inputFrame1 = inputFrame2; inputFrame2 = temp; frameNumber++; } //start from the last restored frame; frameNumber--; _currentInputFrameNumber = frameNumber; ExportSimulationResult(); //create an empty input frame to start with inputFrames[frameNumber] = inputFrame1; //export system data ExportSimulationResult(); SWConsole.Warn($"WaitingForInitialSystemData _initialInputFramesData={_initialInputFramesData.DataLength}"); _saveHandler(_initialInputFramesData, _startFrameNumber, _endFrameNumber); _game.gameState = FrameSyncGameState.Running; SetSaveHandler(_endFrameNumber - 1); //end frame was excluded from initial frames, so we want to save it SWConsole.Crit($"WaitingForInitialSystemData game is running now _currentInputFrameNumber={_currentInputFrameNumber}"); ResetTimeStamp(); return; } }
public static FrameSyncInputSetting CompressedIntInput(string name, int min, int max, int defaultValue) { if (min >= max) { SWConsole.Error(""); return(NullSetting); } FrameSyncInputSetting setting = new FrameSyncInputSetting(); setting._inputType = FrameSyncInputType.CompressedInt; setting._name = name; setting._bitSize = CompressedIntSize(min, max); setting._minInt = min; setting._maxInt = max; setting._defaultValueInt = defaultValue; return(setting); }
bool Predict(int localFrameDeltaNumber, int frameNumber) { SWConsole.Crit($"Engine: Predict localFrameDeltaNumber={localFrameDeltaNumber} frameNumber={frameNumber}"); InputFrameDelta inputFrameDelta = localInputFrameDeltas[localFrameDeltaNumber]; _inputFrameForPrediction.FrameNumber = frameNumber; _inputFrameForPrediction.ResetBytes(); inputFrameDelta.Apply(_input, _lastInputFrameForPrediction, _inputFrameForPrediction); _input.ApplyPredictionModifier(_inputFrameForPrediction.bytes); FrameSyncUpdateType updateType = FrameSyncUpdateType.Prediction; DoSimulate(updateType, _inputFrameForPrediction, frameNumber); return(true); }
public void FlushInputOnline() { InputFrameDelta previousInputDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber]; _currentLocalInputFrameDeltaNumber++; InputFrameDelta inputFrameDelta = localInputFrameDeltas[_currentLocalInputFrameDeltaNumber]; if (inputFrameDelta == null) { inputFrameDelta = new InputFrameDelta(_currentLocalInputFrameDeltaNumber); localInputFrameDeltas[_currentLocalInputFrameDeltaNumber] = inputFrameDelta; } inputFrameDelta.frameNumber = _currentLocalInputFrameDeltaNumber; inputFrameDelta.resend = FrameSyncConstant.LOCAL_INPUT_FRAME_RESEND_COUNT; inputFrameDelta.ResetBytes(); _input.ExportInput(inputFrameDelta.bytes); bool inputChanged = false; if (previousInputDelta == null) { inputChanged = true; } else { bool sameInput = previousInputDelta.IsSameInput(inputFrameDelta); inputChanged = !sameInput; } if (!inputChanged) { SWConsole.Crit("Engine: Input did NOT Change"); _currentLocalInputFrameDeltaNumber--; } else { SWConsole.Crit("Engine: Input Changed"); } SendLocalInputs(); }
public static FrameSyncInputSetting CompressedFloatInput(string name, Fix64 min, Fix64 max, Fix64 precision, Fix64 defaultValue, Func <Fix64, Fix64> predictionModifier) { if (min >= max) { SWConsole.Error(""); return(NullSetting); } FrameSyncInputSetting setting = new FrameSyncInputSetting(); setting._inputType = FrameSyncInputType.CompressedFloat; setting._name = name; setting._bitSize = CompressedFloatSize(min, max, precision); setting._minFloat = min; setting._maxFloat = max; setting._precisionFloat = precision; setting._defaultValueFloat = defaultValue; setting._predictionModifier = predictionModifier; return(setting); }
public static void RandromTest() { Dictionary <UInt32, int> dict = new Dictionary <uint, int>(); SortedList <UInt32, int> distribution = new SortedList <UInt32, int>(); _internal_seed(1); int count = 1000; uint groupSize = 5; for (int i = 0; i < count; i++) { UInt32 result = Next(100); SWConsole.Info($"PRandom = {result}"); if (dict.ContainsKey(result)) { dict[result]++; } else { dict[result] = 1; } UInt32 group = result / groupSize; if (distribution.ContainsKey(group)) { distribution[group]++; } else { distribution[group] = 1; } } foreach (var pair in distribution) { SWConsole.Info($"{pair.Key} = {pair.Value}"); } }
public override Fix64 GetFloatValue(BitArray bitArray) { int result = 0; for (int i = 0; i < _size; i++) { int index = _bitOffset + i; bool bit = bitArray[index]; if (bit) { result |= 1 << i; } } //min = -1.0 //max = 1.0 //precision = 0.5 //default = 0.0 //-1.0, -0.5, 0, 0.5, 1.0 // 0, 1, 2, 3, 4 //if result is greater than the max value //the actual value = (result - number of values) * precision //for example, for result 3, actual value = (3 - 5) * 0.5 = -2 * 0.5 = -1.0 Fix64 floatResult = (Fix64)result * _precision; //is result valid? if (result > _nvalues) { SWConsole.Error($"invalid result({result}): result={result} min={_min} max={_max} default={_defaultValue}"); floatResult = _defaultValue; } else if (floatResult > _max) { floatResult = (Fix64)(result - _nvalues) * _precision; } return(floatResult); }