반응형

위 그림을 보면 tex의 자료형이 float 로 되어있다 그덕분에 위처럼 나온다

아래처럼 float2로 만 해줘도 제대로 나올수 있다, hlsl은 이런 오타로 인한 버그를 조심해야 되는것 같다

 

반응형
반응형

윈도우 제목이 한글자만 로딩되는 버그다, 그림에서는 Project1 로딩되어야 하는데

한글자만 로딩되고 있다, 알고보니

세팅을 손보면서 Preprocessor Definitions 부분을 지워버렸다, 사실 이부분에

 

 아래와 같은

 

_UNICODE;UNICODE;

 

매크로가 들어가야 유니코드 함수를 온전히 사용할 있다, 매크로가 없을 경우 빌드에는 문제 없지만, 위와같은 버그가 발생한다.

반응형
반응형

마우스 위치가 맞지 않는다

정확히 가로 세로 10px 정도 비껴간 느낌이다, 따로 설정을 해놓은 적이 없는데

알고보니

 

 

윈도우창에 시스템 메뉴를 추가한뒤에, ClientSize로 전체적으로 초기화 해야되는데

ScreenSize로 초기화 해버려서 발생했던 것 

 

 

 

아래와 같이 클라이언트 사이즈 구한뒤 초기화 작업을 다시함

 

 

 

그결과 ImGUI가 마우스 위치를 제대로 인식하고, 폰트 깨짐 현상도 없어짐

 

 

반응형
반응형

아래 코드는 char 문자열을 wchar_t 문자열로 

wchar_t 문자열을 char 문자열로 바꿔주는 코드이다 

 

#include <stringapiset.h>

void char_to_wchar(const char* input_str, wchar_t* output_wstr)
{
	int strSize = MultiByteToWideChar(CP_UTF8, 0, input_str, -1, NULL, NULL);
	MultiByteToWideChar(CP_UTF8, 0, input_str, strlen(input_str) + 1, output_wstr, strSize);
}


void wchar_to_char(const wchar_t* input_wstr, char* output_str)
{
	int strSize = WideCharToMultiByte(CP_UTF8, 0, input_wstr, -1, NULL, 0, NULL, NULL);
	WideCharToMultiByte(CP_UTF8, 0, input_wstr, -1, output_str, strSize, 0, 0);
}
반응형
반응형

 

programmers.co.kr/learn/courses/30/lessons/42746

 

코딩테스트 연습 - 가장 큰 수

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요. 예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 ��

programmers.co.kr

위 문제를 c++로 풀면서 string을 썼는데

문득 Java 를 배울때 string 을 쓰기 보다는 stringbuilder 를 쓰는게 퍼포먼스 면에서 좋다고 배웠던 기억이 났다

그러나 해당 코드를 c++로 짜는 중이었기 때문에 c++ 에 stringbuilder는 없어서 쓸 수 없었고 대신 stringstream이 비슷한 역할을 하는 것 같아서, stringstream으로 코드를 작성한뒤 성능 측정을 비교해 봤는데

//A코드 : stringstream 사용
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>

using namespace std;

bool cmp(int a, int b)
{
    stringstream ss1;
    stringstream ss2;
    ss1 << a << b;
    ss2 << b << a;
    return ss1.str() > ss2.str();
}


string solution(vector<int> numbers) {

    stringstream ss;
    sort(numbers.begin(), numbers.end(), cmp);
    for (auto& i : numbers)
    {
        ss << i;
    }
    return ss.str()[0] == '0' ? "0" : ss.str();
}
//B코드 : string만 사용
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

bool cmp(int a, int b)
{
    string s1 = to_string(a) + to_string(b);
    string s2 = to_string(b) + to_string(a);
    return s1 > s2;
}

string solution(vector<int> numbers) {

    string answer = "";
    sort(numbers.begin(), numbers.end(), cmp);
    for (auto& i : numbers)
    {
        answer += to_string(i);
    }
    return answer[0] == '0' ? "0" : answer;
}

 

B코드, 즉 string을 사용한 쪽이 퍼포먼스가 A에 비해서 더 잘나오는것을 볼 수 있었다, 어떤 부분들은 2~3배 가까이 차이가 난다. 

c++ 의 stringstream 은 Java 의 stringbuilder와 달리 퍼포먼스를 위해 쓰는 용도는 아닌것 같다,

특히나 다른 c++ 사용자들도 stringstream을 사용했을때 느리더라 라는 글들도 몇몇개 보인다.

 

참고 :

cppjava.tistory.com/63

 

[퍼온글] 문자열 숫자로 바꾸기 stringstream

출처 : http://www.buggymind.com/83 요즘 C++로 Admission Control System을 개발중입니다. 근데 프로그램을 짜다 보면 으례 그렇겠지만 스트링을 숫자로, 숫자는 스트링으로 변환할 일이 많이 생기더군요. 종전

cppjava.tistory.com

stackoverrun.com/ko/q/1443219

 

반응형
반응형


double	g_timePerFrame;// 임의로 정해놓은 프레임 제한시간


int APIENTRY WinMain(
	HINSTANCE a_hInst, 
	HINSTANCE a_hPrevInst, 
	LPSTR a_lpszCmdParam, 
	int a_iCmdShow)
{	
	//윈도우 클래스 등록
	if (!InitWndClass(a_hInst))
	{
		return false;
	}

	//윈도우 생성 및 화면에 보여주기
	if (!InitInstance(a_hInst, a_iCmdShow))
	{
		return false;
	}

	
	MSG Message;

	std::chrono::system_clock::time_point worktime_old = std::chrono::system_clock::now();
	std::chrono::system_clock::time_point worktime_now;
	g_timePerFrame = 200.0; 
	while (1)
	{
		if (PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
		{
			if (Message.message == WM_QUIT || Message.message == WM_DESTROY)
			{
				break;
			}
			TranslateMessage(&Message);
			DispatchMessage(&Message);
		}
		else
		{
			worktime_now = std::chrono::system_clock::now();

			//루프가 끝나고, 다시 시작하는 시점 까지의 경과시간(공백시간)
			std::chrono::duration<double, std::milli> work_time = worktime_now - worktime_old; 
            
			if (work_time.count() < g_timePerFrame)
			{
				double d = g_timePerFrame - work_time.count(); //임의로 정해놓은 프레임 제한시간에서 실제 프레임당 걸리는 시간을 빼준다, 그렇게 남는시간은
				std::chrono::duration<double, std::milli> sleepTime(d);
				std::chrono::milliseconds sleepTime_ms_duration = std::chrono::duration_cast<std::chrono::milliseconds>(sleepTime);
				std::this_thread::sleep_for(sleepTime_ms_duration); // 해당 thread를 sleep 시키는 시간으로 쓴다
			}
			worktime_old = std::chrono::system_clock::now();
			
            
			//ToDo : GameLogic 처리 Update, Rendering
		}
	}
	return Message.wParam;

}
반응형
반응형

코드

template <typename T>
class SingleTonBase
{
private:
	static T* instance;

public:
	static T* GetInstance()
	{
		if (!instance)
		{
			instance = new T;
		}
		return instance;
	}
    
    	static void DeleteInstance()
	{
		if (instance)
		{
			delete instance;
            		instance = nullptr;
		}
	}

protected:
	SingleTonBase(){}
	virtual ~SingleTonBase(){}

public:
	SingleTonBase(const SingleTonBase&) = delete;
	SingleTonBase& operator = (const SingleTonBase&) = delete;
};

template<typename T>
T* SingleTonBase<T>::instance = nullptr;



//클래스에서 상속을 받고 friend 키워드를 통해 적용
class MyClass : public SingleTonBase<MyClass>
{
	friend class SingleTonBase<MyClass>;
private:
	MyClass() {};
	~MyClass() {};

public:
	void print(HDC a_hDC, int a_x, int a_y)
	{
		std::wstringstream wss;
		wss << L"MyClass : " << (int)GetInstance();
		TextOut(a_hDC, a_x, a_y, wss.str().c_str(), wss.str().length());
	}
};

 

테스트

같은 주소를 가리키고 있다, 즉 언제나 GetInstance() 통해서만 instance를 받을수 있고 그 주소는 오직 하나의 주소만 가리키는걸 볼 수 있다.

반응형
반응형

 

 

Mutable

Immutable

생성된후 변경 가능 여부

가능

불가능

예시

list, dict, set,

byte array

int, float, complex,
string, tuple, frozen set,
bytes

복사 대입 방식 a = b

shallow copy

deep copy

비용

Immutable 비해 싸다

mutable 비해 비싸다

 

반응형
반응형

Sprite Animation 구현 및 공에 중력 적용

 

공에 중력 적용및 튕기는 코드 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
float THROW_FORCE_Y = -10.f;
float THROW_FORCE_X = 10.f;
constexpr float Gravity = 0.4f; //중력
 
void Ball::Update(float a_deltaTime, RECT a_pikachuColliderRect)
{
    //화면경게선에 왔을때 튕기기(반대방향으로 전환)
    if (m_y <= 0)
    {
        THROW_FORCE_Y *= -1;
    }
    if (m_y >= GROUND)
    {
        THROW_FORCE_Y *= -1;
    }
    if (m_x <= 0)
    {
        THROW_FORCE_X *= -1;
    }
    if (m_x >= 800 - 42)
    {
        THROW_FORCE_X *= -1;
    }
 
    // 플레이어와 부딛혔을때
    if (a_pikachuColliderRect.left <= m_x && a_pikachuColliderRect.right >= m_x 
    && a_pikachuColliderRect.top <= m_y && a_pikachuColliderRect.bottom >= m_y)
    {
        THROW_FORCE_Y *= -1;
        THROW_FORCE_X *= -1;
    }
 
 
    //속도 줄어들기
    if (THROW_FORCE_X > 0)
    {
        THROW_FORCE_X -= 0.01f;
    }
    if (THROW_FORCE_Y > 0)
    {
        THROW_FORCE_Y -= 0.1f;
    }
    
 
    m_y += (int)(THROW_FORCE_Y * a_deltaTime);
    m_x += (int)(THROW_FORCE_X * a_deltaTime);
    THROW_FORCE_Y += Gravity;
    
    
    //애니메이션
    switch (m_AniState)
    {
    case Ball::Idle:
        m_Animations[Idle]->Update(a_deltaTime * (THROW_FORCE_X + THROW_FORCE_Y));
        break;
    case Ball::Spiked:
        m_Animations[Spiked]->Update(a_deltaTime);
        break;
    default:
        break;
    }
 
}
 
cs
반응형
반응형

https://leetcode.com/problems/validate-ip-address/

 

Validate IP Address - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

LeetCode 문제를 풀었는데 처음으로 Runtime이 100%만큼의 축적된 다른 답안들 보다 빠르다고 나옴 

 

 

신기해서 자세히 보니

총 73,968 명이 답을 했는데 그중에 C++ 만 대략 50~80명 낸듯;;

메모리는 92.27% 답안들 보다 덜 쓴다고 나옴

 

 

사실 내 답안이 제일 하위권에 속할 줄 알았는데 의외의 결과 였음

그래도 실력이 향상됐다는 기록이기도 해서 올려봄

코드

class Solution {
public:
    bool IsValidInteger(char *_str)
    {
        if (atoi(_str) > 255)
        {
            return false;
        }
        
        if (_str[0] == '0' && strlen(_str) > 1)
        {
            return false;
        }

        for (int i = 0; i < strlen(_str); i++)
        {
            char c = _str[i];
            if (c >= '0' && c <= '9')
            {
                continue;
            }
            else
            {
                return false;
            }
        }
        return true;
    }

    bool IsValidHexadecimal(char* _str)
    {
        if (_str[0] == '0' && strlen(_str) > 4 )
        {
            return false;
        }

        if (strlen(_str) > 4)
        {
            return false;
        }

        for (int i = 0; i < strlen(_str); i++)
        {
            char c = _str[i];
            bool InValidtest1 = c < '0' || c > '9';
            
            if (InValidtest1)
            {
                bool InValidtest2 = (c < 'a' || c > 'f'); // c가 'a' 보다 작거나, 'f' 보다 크다
                bool InValidtest3 = (c < 'A' || c > 'F'); // c가 'A' 보다 작거나, 'F' 보다 크다
                if (InValidtest2 && InValidtest3)
                {
                    return false;
                }
            }
        }
        return true;
    }

    string validIPAddress(string IP) {
        
        bool validIPv4 = true;
        bool validIPv6 = true;

      
        //1.IPv4 모양인지 아니면 IPv6 모양인지 검사
        //최대 갯수 넘어가는지 검사
        if (IP.length() > 15 || IP.length() < 7)
        {
            validIPv4 = false;
        }

        if (IP.length() > 39 || IP.length() < 15)
        {
            validIPv6 = false;
            if (!validIPv4)
            {
                return "Neither";
            }
        }

        // . 갯수 검사
        size_t tokenCount = 0;
        for (size_t i = 0; i < IP.length(); i++)
        {
            if (IP.c_str()[i] == '.')
            {
                tokenCount++;
            }
        }
        if (tokenCount != 3)
        {
            validIPv4 = false;
        }


        // : 갯수 검사
        tokenCount = 0;
        for (size_t i = 0; i < IP.length(); i++)
        {
            if (IP.c_str()[i] == ':')
            {
                tokenCount++;
            }
        }
        if (tokenCount != 7)
        {
            validIPv6 = false;
        }

        int chunkCount = 0;
        if (validIPv4)
        {
            char IPv4[16] = { 0 };
            strcpy(IPv4, IP.c_str());
            char* tok = strtok(IPv4, ".");
            chunkCount++;
            while (tok != nullptr)
            {
                if (IsValidInteger(tok) == false)
                {
                    validIPv4 = false;
                    break;
                }
                else
                {
                    tok = strtok(NULL, ".");
                    if (tok)
                    {
                        chunkCount++;
                    }
                }
            }
            if (chunkCount != 4)
            {
                validIPv4 = false;
            }
        }
        else if (validIPv6)
        {
            char IPv6[40] = { 0 };
            strcpy(IPv6, IP.c_str());
            int chunkCount = 0;
            char* tok = strtok(IPv6, ":");
            chunkCount++;
            while (tok != nullptr)
            {
                if (IsValidHexadecimal(tok) == false)
                {
                    validIPv6 = false;
                    break;
                }
                else
                {         
                    tok = strtok(NULL, ":");
                    if (tok)
                    {
                        chunkCount++;
                    }
                }
            }
            if (chunkCount != 8)
            {
                validIPv6 = false;
            }
        }

        if (validIPv4)
        {
            return "IPv4";
        }
        else if (validIPv6)
        {
            return "IPv6";
        }
        else
        {
            return "Neither";
        }
    }
};
반응형

+ Recent posts