레이블이 C#인 게시물을 표시합니다. 모든 게시물 표시
레이블이 C#인 게시물을 표시합니다. 모든 게시물 표시

2015년 6월 21일 일요일

C#_Naver Search API 활용 소스


AnalysisEngine.
class AnalysisEngine
{
    public enum Step
    {
        WEB,
        IN,
        CAFE,
        BLOG
    }

    const string NAVER_OPENAPI_KEY = "InputYourNaverAPIKey";
    const string NAVER_OPENAPI_URL = "http://openapi.naver.com/search?";
    const int NAVER_SEARCH_COUNT = 100;

    string keyword;
    string url;
    string blog;
    string cafe;

    public AnalysisEngine(string keyword, string url, string blog, string cafe)
    {
        this.keyword = keyword;
        this.url = url;
        this.blog = blog;
        this.cafe = cafe;
    }

    public void Analysis()
    {
        AnalysisResult result = new AnalysisResult();
        

        result.webRank = AnalysisProccess(Step.WEB, url);
        result.blogRank = AnalysisProccess(Step.BLOG, blog);
        result.cafeRank = AnalysisProccess(Step.CAFE, cafe);

        Console.WriteLine("0 = 100위안에 없음.");
        Console.WriteLine("네이버 웹문서 분석 결과 : " + result.webRank);
        Console.WriteLine("네이버 블로그 분석 결과 : " + result.blogRank);
        Console.WriteLine("네이버 카페 분석 결과 : " + result.cafeRank);

        Console.ReadLine();
    }

    int AnalysisProccess(Step step, string target)
    {
        string html = AnalysisTools.GetHTML(CreateURL(step));

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(html);

        int rank = 0;

        foreach (XmlNode node in doc.SelectNodes("rss/channel/item/link"))
        {
            string realURL = GetRealURL(node.InnerText);

            if (realURL.Length > target.Length)
                realURL = realURL.Substring(0, target.Length);

            Console.WriteLine(realURL);

            ++rank;
            if (target == realURL)
            {
                return rank;
            }
        }

        return 0;
    }

    string CreateURL(Step step)
    {
        string target = "";
        switch (step)
        {
            case Step.WEB: target = "webkr";
                break;
            case Step.IN: target = "in";
                break;
            case Step.CAFE: target = "cafearticle";
                break;
            case Step.BLOG: target = "blog";
                break;
            default:
                break;
        }

        return string.Format("{0}key={1}&query={2}&display={4}&start=1&target={3}", NAVER_OPENAPI_URL, NAVER_OPENAPI_KEY, keyword, target, NAVER_SEARCH_COUNT);

    }

    /*
    Naver API를 활용하여 url주소를 획득 할 시
    실주소가 아닌 API 로 맵핑된 가상주소를 제공 해주기 때문에
    직접 리다이렉트 주소를 획득하여 반영 하기위한 함수.
    */

    string GetRealURL(string url) 
    {
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        webRequest.AllowAutoRedirect = false;

        webRequest.Timeout = 10000;           
        webRequest.Method = "HEAD";

        HttpWebResponse webResponse;
        string uriString = string.Empty;

        using (webResponse = (HttpWebResponse)webRequest.GetResponse())
        {
            if ((int)webResponse.StatusCode >= 300 && (int)webResponse.StatusCode <= 399)
            {
                uriString = webResponse.Headers["Location"];
                webResponse.Close();
            }
        }

        return uriString;
    }
}

AnalysisResult
class AnalysisResult
{
    public int webRank;
    public int cafeRank;
    public int blogRank;
}

AnalysisTool
class AnalysisTools
{
    public static string GetHTML(string url)
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();

        if (response.StatusCode == HttpStatusCode.OK)
        {
            Stream receiveStream = response.GetResponseStream();
            StreamReader readStream = null;

            if (response.CharacterSet == null)
            {
                readStream = new StreamReader(receiveStream);
            }
            else
            {
                readStream = new StreamReader(receiveStream, Encoding.UTF8);
            }

            string data = readStream.ReadToEnd();

            response.Close();
            readStream.Close();

            return data;
        }

        return string.Empty;
    }
    
}

Main
class Program
{
    static string keyword = ""; //키워드
    static string homepage = ""; //홈페이지 주소
    static string blog = ""; //블로그 주소
    static string cafe = ""; //카페 주소


    static void Main(string[] args)
    {

        AnalysisEngine engine = new AnalysisEngine(
            keyword , 
            homepage, 
            blog,
            cafe);

        engine.Analysis();

        
    }
}

2015년 6월 2일 화요일

Unity_코루틴 함수를 활용한 Lerp함수 활용 using IEnumerator with Lerp

Explain.

Unity Coroutine 함수를 활용한 Object의 Lerp(선형보간)운동 구현구현
가장 심플하게 구현한 예제.
C#의 Generic , Reflection을 활용하여 기능 확장 가능.

Code.
IEnumerator moveCoroutine(float duration, Vector3 end)
{
 WaitEndOfFrame wait = new WaitEndOfFrame();

 Vector3 start = transform.position;
 float elapsed = 0.0f;

 while(elapsed < duration){
  elapsed += Time.deltatime;
  transform.position = Vector3.Lerp(start,end elapsed / duration);
  yield return wait;
 }

 transform.position = end;
}

IEnumerator colorCoroutine(float duration, Color start, Color end)
{
 WaitEndOfFrame wait += new WaitEndOfFrame();

 float elapsed = 0.0f;

 while(elapsed < duration){
  elapsed = Time.deltaTime;
  renderer.material.color  = Color.Lerp(start,end elapsed / duration);
  yield return wait;
 }

 renderer.material.color = end;
}

2015년 5월 14일 목요일

Game Open Source_3-Match Puzzle 형식의 게임 소스



예전에 만들어둔 3-Match형식(애니팡) 소스를 Github에 올려둔게 있어서 포스팅.


References.
Github.
PlayStore.

C#_Naver Search API 활용 예제


Explain.
C#환경 에서 네이버 오픈 검색 API 를 활용하는 예제.

Input - 키워드(검색값), 페이지(URL)
Output - 네이버 노출 순위

Environment.
Visual Studio 2015 Comunity.
Naver Search API KEY


Logic flow.
1. Input / Keyword, Home Page URL
2. WebRequest를 활용하여 네이버 오픈 API에 request 요청 후 respawn 데이터 저장.
3. 2.의 respawn 데이터 네이버 노출 순위 검색.

소스 코드

Result.














소스 코드

2015년 4월 15일 수요일

Finite State Machine for CSharp_Step2. 활용 예제

Explain.
게임 제작시 MainFrame(MainManager, GameManager 등)에서 FSM을 구현하는 방법 정리


MainFrame.cs
class MainFrame
{
    public enum State
    {
        Game,
        Lobby
    }

    FiniteStateMachine<MainFrame, State> FSM;
    
    LobbyState stateLobby = new LobbyState();
    GameState stateGame = new GameState();

    void Awake()
    {
        FSM = new FiniteStateMachine<MainFrame, State>(this);
        FSM.AddState(stateLobby);
        FSM.AddState(stateGame);

        FSM.ChangeState(stateLobby); // 시작시 stateLobby State
    }
}
LobbyState.cs
class LobbyState : FiniteState<MainFrame, MainFrame.State>
{
    public override void SetEntity(MainFrame entity)
    {
        base.SetEntity(entity);
    }
    public override void Enter()
    {
        base.Enter();
        //게임 입장시 이벤트 구현부
    }
    public override void Excute()
    {
        base.Excute();
        //게임 실행시 이벤트 구현부
    }
    public override void Exit()
    {
        base.Exit();
        //게임 퇴장시 이벤트 구현부
    }

    public override MainFrame.State _StateID
    {
        get
        {
            return MainFrame.State.Game;
        }
    }
}
GameState.cs
class GameState : FiniteState<MainFrame, MainFrame.State>
{
    public override void SetEntity(MainFrame entity)
    {
        base.SetEntity(entity);
    }
    public override void Enter()
    {
        base.Enter();
        //게임 입장시 이벤트 구현부
    }
    public override void Excute()
    {
        base.Excute();
        //게임 실행시 이벤트 구현부
    }
    public override void Exit()
    {
        base.Exit();
        //게임 퇴장시 이벤트 구현부
    }

    public override MainFrame.State _StateID
    {
        get
        {
            return MainFrame.State.Game;
        }
    }
}

Finite State Machine for CSharp_Step1. FSM 구현

Explain. 
유한 상태 기계라고 하며, 특정한 Input(event) 에 따라 해당하는 state(output)으로 변화하는 방법론. 다양한 분야(특히 게임)에 사용되어 지고있으며 상태에 변화에 따른 이벤트를 발생시킬수있으므로 좀더 유연한 로직을 구성할수있다. 이전에 게임 제작시 사용했던 현재도 사용하고있는 FSM에 대해 정리. 스크립트 설명의경우 주석으로 진행.

Step. 
1. FiniteStateMachine 구현
2. 간단한 사용법

FSM 구현

Summary.
 IState ( FiniteState의 명세를 담은 Interface )
 FiniteState ( State 클래스 )
 FiniteStateMachine ( FSM 클래스 )

IState.cs

interface IState<T>
{
    
    void Enter();
    void Excute();
    void Exit();

    T _StateID
    {
        get;
    }
}

FiniteState.cs
class FiniteState<T, U> : IState<U>
{
    protected T entity;

    public virtual void SetEntity(T entity)
    {
        this.entity = entity;
    }

    public virtual void Enter()
    {
        Console.WriteLine(typeof(T).ToString() + "Enter");
    }

    public virtual void Excute()
    {
        Console.WriteLine(typeof(T).ToString() + "Excute");
    }

    public virtual void Exit()
    {
        Console.WriteLine(typeof(T).ToString() + "Exite");
    }

    public virtual U _StateID
    {
        get
        {
            throw new ArgumentException("Exception");
        }
    }

}

FiniteStateMachine.cs
class FiniteStateMachine<T, U>
{
    private T entity; // State의 주체가 되는 class

    private Dictionary<U, FiniteState<T, U>> stateDic; // 전체 State

    private FiniteState<T, U> currentState; // 현재 상태
    private FiniteState<T, U> previousState; // 이전 상태

    /// <summary>
    /// 생성자
    /// </summary>
    /// <param name="entity">주체 class</param>
    public FiniteStateMachine(T entity)
    {
        this.entity = entity;
        stateDic = new Dictionary<U, FiniteState<T, U>>();
    }

    public void ExcuteState()
    {
        if (currentState != null) currentState.Excute();
    }

    public void ChangeState(FiniteState<T, U> nextState)
    {
        if (currentState == nextState) return;

        if(currentState != null)
        {
            currentState.Exit();
            previousState = currentState;
        }

        currentState = nextState;

        currentState.Enter();
    }

    public void ChangeState(U stateID)
    {
        try
        {
            FiniteState<T, U> state = stateDic[stateID];
            ChangeState(state);
        }
        catch(KeyNotFoundException)
        {
            // exception 처리
        }
    }

    //이전 state로 상태 되돌리기
    public void RevertState()
    {
        if (previousState != null)
            ChangeState(previousState);
    }

    public void AddState(FiniteState<T, U> state)
    {
        if (state == null) return;
        state.SetEntity(entity);
        stateDic.Add(state._StateID, state);
    }

    public void RemoveState(FiniteState<T, U> state)
    {
        stateDic.Remove(state._StateID);
    }
}

2015년 1월 29일 목요일

C#.HtmlLoader_HtmlAgilityPack을활용하여 Web에서 Html 데이터 받아오는법.

Summary.
  -C#환경(.net)에서 사용할수있는 HtmlAgilityPack을 활용하여 Web에서 Html데이터 받아오는 코드.

Requirements.
 -HtmlAgilityPack Library
   : VS 내의 NuGet Pakage Manager를 통해 설치할수 있다.


Code.
class HtmlLoader
{
    public enum State
    {
        Working,
        End
    }

    string mURL;
    HtmlDocument mDocument;
    State mState;
    Action mCallback;
    Encoding mEncoding;

    public HtmlLoader(string url, Encoding enc , Action callback)
    {
        this.mURL = url;
        this.mState = State.End;
        this.mCallback = callback;
        this.mEncoding = enc;
    }

    //새로운 스레드를 생성하여 실행.
    public void LoadWithThread()
    {
        if (mState == State.Working) return;

        Thread thraed = new Thread(new ThreadStart(LoadHtml));
        thraed.Start();

    }
    
    //호출한 스레드상에서 바로 실행.
    public void Load()
    {
        if (mState == State.Working) return;
        LoadHtml();
        
    }

    void LoadHtml()
    {
        mState = State.Working;

        mDocument = new HtmlDocument();
        HtmlWeb website = new HtmlWeb();
        StreamReader reader = new StreamReader(WebRequest.Create(mURL).GetResponse().GetResponseStream(), mEncoding);   

        mDocument.Load(reader);

        mCallback();
        mState = State.End;
    }
    
    public HtmlDocument _Document
    {
        get { return mDocument; }
    }
}
Use.
string url = textBox1.Text;

loader = new HtmlLoader(url,
    Encoding.GetEncoding("euc-kr"),
    new Action(() => 
        System.IO.File.WriteAllText("web.txt", loader._Document.DocumentNode.InnerText)
));
loader.LoadWithThread();
이후 생성되는 web.txt파일을 확인할수있다.

2014년 7월 9일 수요일

Unity C#_Array Refernce & Copy


Explain.
자주있는 일은 아니지만, 종종
System.Array type의 값, 즉 C#에서 배열로 선언한 값들을 사용할때
orgArr[원본]
destArr[복사본]
즉 Array 에 대한 Reference가 아닌 Copy가 필요한경우

무의식중에 destArr = orgArr;
이런식으로 코딩하고 넘어가는경우(즉, 아직 저처럼 실력이 부족한경우겠지만..)
가 발생할수도 있지만 이경우 destArr가 orgArr의 data를 Copy한것이아닌
reference(참조)하고 있는것이므로
orgArr의 데이터값 변화가 생기면 자동으로 destArr의값또한 변화가 생긴다.

이러한특징은 C#의 System.Array type(int [] , string[] , float [] 등등)
으로 선언된 데이터는 모두 reference형식으로 선언되는점때문에 일어나는 현상이다.

이럴때 copy가 필요한경우
System.Array.Copy 메소드를 사용해서 array자체를 복사해주는것으로 해결하면된다.

자세한내용의 MSDN에 잘명시되어있다. 링크


Code.

System.Array.Copy(orgArray, destArray, orgArray.Length); // prams (원본 배열 , 복사본 배열, 원본배열의 길이)