검색결과 리스트
글
담당 프로젝트
2021. 11. 10. 12:29
펑키러쉬
2020년 6월 ~ 2022년 1월
사용 언어 및 라이브러리 : C#, OWIN Self hosting, Linq, Super socket
툴 : VS2019, IBM Cloud, MySQL, Unity 2020.3.14f1
5vs5 MOVA 게임 개발 및 출시
Jenkins와 각종 툴 연동
- 빌드, 테이블 및 코드 생성, 패치, 배포 등 자동화
TCP/IP 엔진 제작 및 각종 백앤드 구현
- 마스터, 런처, 로그인, 게임, 채팅, 매칭, 랭킹 서버 디자인 및 구현
- 디비 설계 및 구현
웹서버 제작
- 버전, 웹 스토어
디비 설계 및 구현
설정
트랙백
댓글
글
프로그래밍 일반
2019. 7. 9. 12:41
클리커 게임 표현식 구현하기
3년간 서버만 만들다가 오랜만에 클라이언트 작업을 시작하면서 재미있었던 내용이 있는데 공유해보도록 하겠습니다.
클리커 게임을 만들면서 재화 표현식은 어떻게 만드는게 좋을까? 엄청 큰 자료형에 정수를 무조건 담을까?
자릿수 표현은 어떻게 처리하지??
어비스리움의 표현식을 가져오면 아래와 같은데
1000 = 1A
1000A = 1B
double형 지수부를 이용하려고 생각했기 때문에 액셀을 이용해 패턴을 찾으려고 아래와 지수 표현식을 나눠
패턴을 분석
승수 (자릿수) | 나머지 | 몫 | 표현식 | |
1.00E+ | 0 | 0 | 0 | 1 |
1.00E+ | 1 | 1 | 0 | 10 |
1.00E+ | 2 | 2 | 0 | 100 |
E+ | 3 | 0 | 1 | 1000 = 1A |
E+ | 4 | 1 | 1 | 10A |
E+ | 5 | 2 | 1 | 100A |
E+ | 6 | 0 | 2 | 1000A = 1B |
E+ | 7 | 1 | 2 | 10B |
E+ | 8 | 2 | 2 | 100B |
패턴이 너무 간단 명료해서 코딩이 빠르게 끝남..
재화는 double형에 담으면 되고 출력을 위해 스트링형식으로 바꾸면 되기 때문에 아래와 같이 작업
/// <summary>
/// 확장 메서드 모음
/// </summary>
public static partial class ExtensionMethods
{
const string Zero = "0";
/// <summary>
/// 단위 표현 스타일
/// </summary>
public enum CurrencyType
{
Default,
SI,
}
/// <summary>
/// 표현 가능한 화폐 단위, double형 e+308까지 자릿수 표현 지원
/// </summary>
static readonly string[] CurrencyUnits = new string[]
{
"",
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z",
"AA",
"AB",
"AC",
"AD",
"AE",
"AF",
"AG",
"AH",
"AI",
"AJ",
"AK",
"AL",
"AM",
"AN",
"AO",
"AP",
"AQ",
"AR",
"AS",
"AT",
"AU",
"AV",
"AW",
"AX",
"AY",
"AZ",
"BA",
"BB",
"BC",
"BD",
"BE",
"BF",
"BG",
"BH",
"BI",
"BJ",
"BK",
"BL",
"BM",
"BN",
"BO",
"BP",
"BQ",
"BR",
"BS",
"BT",
"BU",
"BV",
"BW",
"BX",
"BY",
"BZ",
"CA",
"CB",
"CC",
"CD",
"CE",
"CF",
"CG",
"CH",
"CI",
"CJ",
"CK",
"CL",
"CM",
"CN",
"CO",
"CP",
"CQ",
"CR",
"CS",
"CT",
"CU",
"CV",
"CW",
"CX",
};
/// <summary>
/// SI 표기법 생략...
/// </summary>
static readonly string[] SI = new string[]
{
};
/// <summary>
/// double형 데이터를 클리커 화폐 단위로 표현한다.
/// 확장 메서드로 제공한다.
/// </summary>
/// <param name="number">double형 숫자</param>
/// <param name="currencyType">클리커 단위타입</param>
/// <returns>클리커 표현식</returns>
public static string ToCurrencyString(this double number, CurrencyType currencyType = CurrencyType.Default)
{
// 정수부가 0인경우 0으로 퉁친다.
if (-1d < number && number < 1d)
{
return Zero;
}
if (true == double.IsInfinity(number))
{
return "Infinity";
}
// 부호 출력 문자열
string significant = (number < 0) ? "-" : string.Empty;
// 보여줄 숫자
string showNumber = string.Empty;
// 단위 문자열
string unitString = string.Empty;
// 패턴을 단순화 시키기 위해 무조건 지수표현식으로 변경한 후 처리한다.
string[] partsSplit = number.ToString("E").Split('+');
// 예외 상황이다....
if (partsSplit.Length < 2)
{
UnityEngine.Debug.LogWarning(string.Format("Failed - ToCurrencyString({0})", number));
return Zero;
}
// 지수 (자릿수 표현)
if (false == int.TryParse(partsSplit[1], out int exponent))
{
UnityEngine.Debug.LogWarning(string.Format("Failed - ToCurrencyString({0}) : partsSplit[1] = {1}", number, partsSplit[1]));
return Zero;
}
// 몫은 문자열 인덱스
int quotient = exponent / 3;
// 나머지는 정수부 자릿수 계산에 사용 (10의 거듭제곱을 사용)
int remainder = exponent % 3;
// 1A 미만은 그냥 표현한다.
if (exponent < 3)
{
showNumber = Math.Truncate(number).ToString();
}
else
{
// 10의 거듭제곱을 구해서 자릿수 표현값을 만들어준다.
var temp = double.Parse(partsSplit[0].Replace("E", "")) * Math.Pow(10, remainder);
// 소수 둘째자리까지만 출력한다.
showNumber = temp.ToString("F").Replace(".00", "");
}
if (currencyType == CurrencyType.Default)
{
unitString = CurrencyUnits[quotient];
}
else
{
unitString = SI[quotient];
}
return string.Format("{0}{1}{2}", significant, showNumber, unitString);
}
/// <summary>
/// 문자열로 입력한 클리커 재화를 double형으로 표현한다.
/// </summary>
/// <param name="currencyString">재화</param>
/// <param name="stringType">문자열의 재화 표현 타입</param>
/// <returns>double형 재화</returns>
public static double ToCurrencyDouble(this string currencyString, CurrencyType stringType = CurrencyType.Default)
{
double result = 0;
bool isNumber = double.TryParse(currencyString, out result);
if (true == isNumber)
{
return result;
}
else
{
int length = currencyString.Length;
int lastNumberIndex = -1;
for (int i = length - 1; 0 <= i; --i)
{
if (true == char.IsNumber(currencyString, i))
{
lastNumberIndex = i;
break;
}
}
if (lastNumberIndex < 0)
{
throw new Exception("Failed currency string");
}
string number = currencyString.Substring(0, lastNumberIndex + 1);
string unit = currencyString.Substring(lastNumberIndex + 1);
int index = (CurrencyType.Default == stringType) ? Array.FindIndex(CurrencyUnits, p => p == unit) : Array.FindIndex(SI, p => p == unit);
if (-1 == index)
{
throw new Exception("Failed currency string");
}
string exponentNumber = string.Format("{0}E+{1}", number, index * 3);
return double.Parse(exponentNumber);
}
}
}
참 쉽다..끝
RECENT COMMENT