192 lines
5.5 KiB
TypeScript
Raw Normal View History

2022-08-26 16:48:17 +08:00
import { CoroutineV2 } from "../../CatanEngine/CoroutineV2/CoroutineV2";
import { RandomEx } from "./RandomEx";
export module NumberEx {
/**
*
* @param startNum
* @param endNum
* @param callbackfn
* @param chabgeRate
*/
export function* ChangeScore(startNum: number, endNum: number, callbackfn: (num: number) => void, sec: number) {
let fps = 30;
let waitTime = 0.03;
let changeRate = sec * fps; // -1為了讓changeRate數字能混亂點
changeRate = changeRate - 1 <= 0 ? changeRate : changeRate - 1;
changeRate = 1 / changeRate;
let diff = endNum - startNum;
let isIncrease = endNum >= startNum;
let tempScore = startNum;
let counter = 0;
//let randomRate = 0;
while (true) {
if (endNum != tempScore) {
/*if (counter % 2 == 0) {
if (isIncrease) {
randomRate = RandomEx.GetFloat(0, diff * changeRate).ExToNumFloorDecimal(2);
} else {
randomRate = RandomEx.GetFloat(0, -diff * changeRate).ExToNumFloorDecimal(2);
}
} else {
randomRate = -randomRate;
}*/
tempScore += diff * changeRate //+ randomRate;
// 遞增
if (isIncrease && tempScore > endNum) {
tempScore = endNum;
}
// 遞減
if (!isIncrease && tempScore < endNum) {
tempScore = endNum;
}
callbackfn(tempScore.ExToInt());
// yield null;
counter++;
yield CoroutineV2.WaitTime(waitTime);
}
else {
callbackfn(endNum);
break;
}
}
}
/**
*
* @param minNum
* @param maxNum
* @param callbackfn callbackfn
* @param sec
*/
export function* BeatScore(minNum: number, maxNum: number, endNum: number, callbackfn: (num: number) => void, sec: number): IterableIterator<any> {
let fps: number = 13;
let waitTime: number = 0.07;
let changeRate: number = sec * fps; // -1為了讓changeRate數字能混亂點
changeRate = changeRate - 1 <= 0 ? changeRate : changeRate - 1;
changeRate = 1 / changeRate;
let diff: number = maxNum - minNum;
let isIncrease: boolean = maxNum >= minNum;
let tempScore: number = minNum;
let counter: number = 0;
let randomRate: number = 0;
let lastNum: number = minNum;
let nowNum: number = minNum;
while (true) {
if (maxNum !== tempScore) {
if (counter % 2 === 0) {
if (isIncrease) {
randomRate = RandomEx.GetFloat(0, diff * changeRate).ExToNumFloorDecimal(2);
} else {
randomRate = RandomEx.GetFloat(0, -diff * changeRate).ExToNumFloorDecimal(2);
}
} else {
randomRate = -randomRate;
}
tempScore += diff * changeRate + randomRate;
// 遞增
if (isIncrease && tempScore > maxNum) {
tempScore = maxNum;
}
// 遞減
if (!isIncrease && tempScore < maxNum) {
tempScore = maxNum;
}
while (nowNum === lastNum) {
nowNum = RandomEx.GetInt(minNum, maxNum + 1);
}
lastNum = nowNum;
callbackfn(nowNum);
// yield null;
counter++;
yield CoroutineV2.WaitTime(waitTime);
} else {
callbackfn(endNum);
break;
}
}
}
/**
*
* @param {*number} num
*/
function checkBoundary(num: number) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(`${num} is beyond boundary when transfer to integer, the results may not be accurate`);
}
}
}
/**
*
*/
export function times(num1: number, num2: number, ...others: number[]): number {
if (others.length > 0) {
return times(times(num1, num2), others[0], ...others.slice(1));
}
const num1Changed = num1.Float2Fixed();
const num2Changed = num2.Float2Fixed();
const baseNum = num1.DigitLength() + num2.DigitLength();
const leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
}
/**
*
*/
export function plus(num1: number, num2: number, ...others: number[]): number {
if (others.length > 0) {
return plus(plus(num1, num2), others[0], ...others.slice(1));
}
const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength()));
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
}
/**
*
*/
export function minus(num1: number, num2: number, ...others: number[]): number {
if (others.length > 0) {
return minus(minus(num1, num2), others[0], ...others.slice(1));
}
const baseNum = Math.pow(10, Math.max(num1.DigitLength(), num2.DigitLength()));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
}
/**
*
*/
export function divide(num1: number, num2: number, ...others: number[]): number {
if (others.length > 0) {
return divide(divide(num1, num2), others[0], ...others.slice(1));
}
const num1Changed = num1.Float2Fixed();
const num2Changed = num2.Float2Fixed();
checkBoundary(num1Changed);
checkBoundary(num2Changed);
return times((num1Changed / num2Changed), Math.pow(10, num2.DigitLength() - num1.DigitLength()));
}
/**
*
*/
export function round(num: number, ratio: number): number {
const base = Math.pow(10, ratio);
return divide(Math.round(times(num, base)), base);
}
let _boundaryCheckingState = false;
/**
*
* @param flag true false
*/
function enableBoundaryChecking(flag = true) {
_boundaryCheckingState = flag;
}
}