perpet

http://robot114.com/cafe/club/club_show.asp?c_idx=11

자주가던 로봇커뮤니티게시판에 로봇대회 홍보글이 올라와서 대회에 참가하게 됬습니다.
예전에 하던 msrds 개발 방법과 비슷하고 단지 c++ 로 프로그램을 짜면 되는 수준이였죠
주로 혼자 대회를 참가하는걸 좋아하는데 대회 룰상 그룹으로만 참여가 가능하더군요.
그래서 회사 직원들을 꼬셨습니다.
처음에는 멘토를 하던 직원들을 꼬셨지만 그들만 믿고 진행하기는 힘들어
주위 여러명을 우선 꼬셨습니다. 그중에 지쳐 떨어져나가도 프로젝트가 진행될수있는 인원으로요.
그리고 마지막에 나를 포함 4명이 남고 프로젝트를 진행했죠.
대회룰상 3명이상만 되기때문에 팀이 진행하는데는 문제가 없었습니다.
하지만 한팀보다는 여러팀으로 나가는게 좋겠다 싶어 2명을 더꼬셔 2팀 3명씩 본선대회에 출전했습니다.
팀원을 나눌때 상금 문제가 걸리더군요. 누가 더열심히 하고 누가 덜한 문제가 발생하여 형평성 문제로
고민하다 상금은 무조건 한팀만 타도 6명이 나누기로 했습니다.

대회 진행을 제가 시작했기때문에 이결정을 제가 했는데.. 결론적으로 무지 잘한판단이 였습니다.
결론적으로 저희팀은 본선 16강에서 실수로 테스트코드가 들어가서 바로 탈락을 하고 저희 다른팀은
훌륭하게 1등을 했거든요..ㅋㅋㅋㅋ 아쉽게 이력서에 올릴건 없지만 상금은 서로 나눠먹었네요...

그나저나 대회를 준비하면서
회사에서 같이 일하는 거나 별반 다른게 없는것 같습니다. 서로 목적의식?이 다르다보니
얼만큼 그들 각자에게 이대회가 어떠한 만족감이 있는지 인식시켜주며 진행하는것은 회사에서 프로젝트 진행하는거랑 같은 이슈?상황이라 보여집니다.

하여간 대회상금으로 회식도 하고 돈도 챙겨.. 나름 고생한 보람이 있었네요.


지금은 딱히 나갈대회가 없어 개인적으로 하고싶던 개인프로젝트를 위해 인공지능을 공부하고 있네요.

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

Comment +2

예전에 조립정도만 하고 말았던 레고로봇
이제야 비젼도 넣어보고 해서 로봇을 만들어 컨트롤 해보는 것을 해본다.

 

 

 

 

 

 

 

 

Comment +2

 작업하다보면 foreach 안에서 remove 를 할때가 꼭있다.

속도무시하고 편하게 사용하고 싶을때 사용하면 좋을듯하다.

어떤식으로 구현하는지 의도만 파악하고 자신의 입맛대로 바꾸길 바란다.

 

lib 코드

  1.  
  2. using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Text;
  3. /// 버전 0.1
    /// perpet@hitel.net 구본수
    /// 소스 수정해서 사용하는건 문제 없으나 수정을 하면 반드시 원 제작자에게 수정된 소스를 메일로 보내야합니다. 버그나 개선된것을 꼭알려달라는 뜻입니다.
    ///
    /// 초기 버전이라 버그가 많을수있습니다..
  4.  
  5. namespace Foreach_safe_list
    {
  6.     class SafeCollection<TKey, TValue> //: Dictionary<TKey, TValue>
        {
            //원본리스트
            Dictionary<TKey, TValue> _List = new Dictionary<TKey,TValue>();
  7.         // 임시 add list
            Dictionary<TKey, TValue> _AddList = new Dictionary<TKey, TValue>();
  8.         // 임시 remove list
            List<TKey> _RemoveList = new List<TKey>();
  9.         public Dictionary<TKey, TValue>.KeyCollection Keys
            {
                get { return _List.Keys; }
           
  10.        }
  11.  
  12.         public void Clear()
            {
                if (bForeachCount == 0)
                {
                    _List.Clear();
                }
                else
                {
  13.                 _AddList.Clear();
                    _RemoveList.Clear();
  14.                 foreach(TKey key in _List.Keys)
                        _RemoveList.Add(key);
  15.             }
  16.         }
  17.        public Dictionary<TKey, TValue>.ValueCollection Values {
               get{return _List.Values;}
            }

  18.         public bool ContainsKey(TKey key)
            {
                // 제일 먼저 add list 에서 찾아봐야한다
                bool ret = _AddList.ContainsKey(key);
                if (ret == true)
                    return true;
                // 그다음 remove list 에서 찾아봐야한다.
                if (_RemoveList.Contains(key))
                {
                    return false;
                }
  19.             return _List.ContainsKey(key);
            }
  20.         public bool TryGetValue(TKey key, out TValue value)
            {
                if (bForeachCount == 0)
                {
                    return _List.TryGetValue(key, out value);
                }
                else
                {
                    // 제일 먼저 add list 에서 찾아봐야한다
  21.                 bool ret = _AddList.TryGetValue(key, out value);
                    if (ret == true)
                        return true;
  22.                 // 그다음 remove list 에서 찾아봐야한다.
                    if (_RemoveList.Contains(key))
                    {
                        return false;
                    }

  23.                 return _List.TryGetValue(key, out value);
                }
  24.             //return false;
            }

  25.   public void Add(TKey key ,TValue value)
      {
                if (bForeachCount == 0)
                {
                    _List.Add(key, value);
                }
                else
                {
                    _AddList.Add(key,value);
                }
  26.   }

  27.         public void Remove(TKey key)
            {
                if (bForeachCount == 0)
                {
                    _List.Remove(key);
                }
                else
                {
                    if (_AddList.ContainsKey(key))
                    {
                        _AddList.Remove(key);
                    }
                    else
                    {
                        if (!_List.ContainsKey(key) || _RemoveList.Contains(key))
                        {
                            throw new Exception("dosen't have key");
                        }
  28.                     _RemoveList.Add(key);
                    }
                   
                }
            }
           
            public void StartForeach()
            {
                bForeachCount++;
            }
  29.         public void EndForeach()
            {
                bForeachCount--;
                if (bForeachCount == 0)
                {
  30.                 // remove 먼저해야함
  31.                 foreach (TKey item in _RemoveList)
                    {
                        _List.Remove(item);
                    }
  32.                 _RemoveList.Clear();
  33.                 foreach (KeyValuePair<TKey, TValue> item in _AddList)
                    {
                        _List.Add(item.Key, item.Value);
                    }
                    _AddList.Clear();
                }
            }

  34.   public uint bForeachCount = 0;
  35.         public Dictionary<TKey, TValue>.Enumerator BaseGetEnumerator()
      {
                return _List.GetEnumerator();
      }
  36.   public IEnumerator GetEnumerator()
      {
       return new SafeEnumerator(this);
      }

  37.         class SafeEnumerator : IEnumerator, IDisposable
            {
                SafeCollection<TKey, TValue> _list;
                Dictionary<TKey, TValue>.Enumerator enumerator;
  38.             public object Current { get { return enumerator.Current; } }
                public bool MoveNext() {
  39.                 while (enumerator.MoveNext())
                    {
                        if (_list._RemoveList.Contains(enumerator.Current.Key))
                            continue;
                        return true;
                    }
  40.                 return false;
               
                }
                public void Reset() {
                    //enumerator...Reset();
                }
  41.             public SafeEnumerator(SafeCollection<TKey, TValue> list)
                {
                    _list = list;
                    enumerator = _list.BaseGetEnumerator();
  42.                 _list.StartForeach();
  43.             }
  44.             public void Dispose()
                {
                    _list.EndForeach();
                }
            }

  45.  }
    }

 

test code

 

  1.  sdsd
  2. using System;
    using System.Collections.Generic;
    using System.Text;
  3. namespace Foreach_safe_list
    {
  4.     class buff
        {
            public bool _flag;
            public buff(bool flag)
            {
                _flag = flag;
            }
          
            public void update(){}
          
           
        }
  5.  class Program
     {
  6.  
  7.   static void Main(string[] args)
      {
                SafeCollection<int, buff> a = new SafeCollection<int, buff>();
  8.             a.Add(1,new buff(true));
                a.Add(2,new buff(true));
                a.Add(3,new buff(false));
                a.Add(4,new buff(true));

  9.             foreach (KeyValuePair<int, buff> aaa in a)
       {
                    if( a.ContainsKey(2))
                        a.Remove(2);
  10.                 foreach (KeyValuePair<int, buff> bbb in a)
                    {
                        bbb.Value.update();
                        if (bbb.Value._flag == false)
                            a.Remove(bbb.Key);
                    }
                }
  11.             foreach (KeyValuePair<int, buff> aaa in a)
                {
                    if (a.ContainsKey(2))
                        a.Remove(2);
  12.                 foreach (KeyValuePair<int, buff> bbb in a)
                    {
                        if (!a.ContainsKey(2))
                            a.Add(2, new buff(true));
  13.                 }
  14.             }
  15.             foreach (KeyValuePair<int, buff> aaa in a)
                {
                    Console.WriteLine("{0}", aaa.ToString());
                }
  16.  
  17.   }
     }
    }
  18.  

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

Comment +1

튜링봇

개인 프로젝트2009. 9. 27. 06:09
튜링테스트 라고 들어보셨을겁니다. 컴퓨터로 채팅을 하는데 채팅하는대상이 사람인지 봇인지 대화를 통해 알아맞추는것이죠. 저는 이걸 확장해서 게임상에 만난 캐릭과 같이 미션을 수행하는데 그 캐릭이 사람인지 봇인지 판단할수 없도록 하는 시스템을 만들고 싶었습니다. 앞으로 이걸 "튜링봇" "튜링시스템" 이라 할 생각입니다.


게임에서의 튜링봇을 의미하기위해
튜링 NPC 가 어떨까 하기도 하고.

Comment +2

2.퀘스트

스터디/C++,CLI,C#2009. 9. 14. 20:11

 

그렇다면 이것으로 간단한 퀘스트를 짜보고 간단한 핵심 코드 리뷰를 해보자

Demo2

일반적으로 기획자가 상상하는 단순한 퀘스트를 상상해보자.

1.유저가 npc 를 클릭한다.

2.유저에게 A 를 만나달라고 대화박스를 보인다

3.승낙을 하면 아이템을 준다.

4.A를 클릭하면 고맙다고 한다.

아주일반적인 퀘스트 내용이다.

 

이것을 정말 저런순서대로 코딩을 할수없을까?

 

밑에 코드를 보자

 

quest1 버튼을 누르면 밑에 코드가 돌아간다.

 

우선 퀘스트 코드를 보자

 [소스1]


  1.         public IEnumerator GetEnumerator()
            {

    // 이미 퀘스트를 받았나?

                if (_Owner._QuestInfo.Contains(1))
                {

  2.        

            yield return new NCondition.WaitMessage("여기서 뭐하나", 2);

                    yield break;
                }

  3.            // 부탁을 한다.

                NCondition.WaitMessage msg = new NCondition.WaitMessage("반갑군. 내부탁을 들어줄수있나?", 0);

                yield return msg;

  4.            
  5.             if (msg.Ret() == "OK")
                {

                // ok 이면 퀘스트를 준다

                    _Owner._QuestInfo.Add(1);

                    yield return new NCondition.WaitMessage("고맙군 어서 친구를 찾아주게 ", 2);
                }
                else
                {

  6.                //

        yield return new NCondition.WaitMessage("실망일세 꺼지라우", 2);

                    yield break;
                }

  7.             // A를 클릭하면

                yield return new NCondition.WaitClickEvent(1);

  8.          
  9.             // 보상을 해주던지 다른이벤트를 하던지 하여간 여기서 끝냄

                yield return new NCondition.WaitMessage("반갑군 자네가 그친구인가? 너무늦었네... ", 5);


                yield break;
            }

     

     


 

한마디로 yield 로 표현된 코드는 우리가 일일히 스테이트관리를 해야하는작업을 코드가 알아서 만들어준다고 보면된다.

우리는 귀찮은 스테이트 관리와 데이타 관리를 컴파일러에게 넘겨주고 우리가 필요한 컨텐츠 코드작성만 하면되는것이다.

 [소스2]

  1.  
            public void Update()
            {
  2.             // 등록된 enumerable 오브젝트를 가지고 있다.
                // for 문중 ProcessList 에 있는 아이템을 지울수있는 구조를 위에 뒤에서 앞으로 for 문을 돈다.(성능은 좋지않다)
               
                for (int index = ProcessList.Count - 1; index >= 0; index--)
                {
                    JobInfo pProcess = ProcessList[index];
  3.                 // 현재 스크립트용 함수에서 yield return new icondition 류가 있는지 본다.
                    if (pProcess.m_Condition != null)
                    {
                        // yield return new icondition 이 있으면 완료가 될때까지 스킵한다.
                        if (pProcess.m_Condition.IsComplete() == false)
                        {// 선행작업이 완료되지 않았다.
                            continue;
                        }
                    }
  4.                 // yield 나 yield return 이 올때까지 프로세스가 진행된다.
                    if (pProcess.m_ProcessEnum.MoveNext() == true)
                    {
                        // 유저가 요정한 yield return new icondition 을 저장한다.
  5.                     pProcess.m_Condition = (ICondition)pProcess.m_ProcessEnum.Current;
                        continue;
                    }
                    else
                    {
                        // enumerable 문을 다 완료하였다면 지운다.
                        ProcessList.Remove(pProcess);
                    }
                }
  6.         }

위[소스2] 코드는 [소스1] 의 코드를 어떻게 제어할수있는지 보여주는 코드이다.

이샘풀소스에 위코드 두가지를 이해한다면 핵심적인 내용은  다이해한거라 볼수있다.


다음에는 이 yield 프로그래밍을 가지고 분산프로그램을 쉡게 구현할수있는 방법을 소개해 보겠다.

이 글은 스프링노트에서 작성되었습니다.

Comment +1

YIELD 키워드(lua coroutine)

이글은 c# 을 스크립트나 병렬처리를 하기위한 기초지식을 위한 글이다..

 c# 을쓰면서 yield 키워드를 쓰는일이 거의 없을수도 있다. 그것은 필요가 없는것이 아니라 그용도와 사용방식을 잘 모르기때문인것 같다.

특히나 이 yield  키워드는 c++ 에 없는 키워드이기에 c++ 프로그래머 들에게는 너무 생소하다.

(c++ 에서  Fiber 라는 것이 있다고 한다.나는 써보지를 않아서....)

 

나또한 이 개념을 알게 된 계기도 서버에서 스크립트로 lua 에서 coroutine 개념을 처음 써보고 후에 c# 에서 이 개념을 써보고 싶어서 자료를 찾던중 yield  라는 키워드로 제공되는것을 알았다.

우선

 

http://asyncsample.googlecode.com/files/AsyncSample.zip

 

에서 소스를 다운받는다.

다음 Enumerable 솔루션 파일을 열고

(ms visual c# 2008 express  http://www.microsoft.com/express/download/ )

 
Demo0 프로젝트를 본다.


우선 이 yield 키워드가 어떠한 일을 하는지 보고 이것을 가지고 어떠한 곳에서 사용할수있는지 보자.

우선 핵심적인 내용은 TestCode1() 함수안에 있는 코드의 진행을 IEnumerator.MoveNext() 라는 함수로 제어를 할수있다는것이다.


루아를 써보신분은 쉽게 접근을 할수있겠지만 코루틴을 처음 보시는분은 아직도 감이 오지않을것이다.

c++ 프로그래머 이라면 과연 저것이 내부적으로 어떻게 움직이는지 궁금할것이다.

 

http://www.lutzroeder.com/dotnet/

 

여기 사이트에 들어가서 reflector/ 프로그램을 다운받고 위에 샘풀코드 실행파일을 역어셈해보자

역어셈코드를 보면 코드가 어떻게 움직이는지 바로 느낄수있을거다.

 

원래 코드이다

 

  1.  
            public static IEnumerable TestCode1()
            {
  2.             int x = 3;
  3.             yield return x;
                x++;
                yield return x;
                x++;
                yield return x;
                x++;
                yield return x;
                x++;
  4.             yield break;
  5.         }

 

 .net Reflector 를 사용하여 위코드가 어떻게 변환되였는지 보자

 

  1.  

    private bool MoveNext() 
    {
  2. switch (this.<>1__state)
    {
    case 0:
    this.<>1__state = -1;
    this.<x>5__1 = 3;
    this.<>2__current = this.<x>5__1;
    this.<>1__state = 1;
    return true;
    case 1:
    this.<>1__state = -1;
    this.<x>5__1++;
    this.<>2__current = this.<x>5__1;
    this.<>1__state = 2;
    return true;
    case 2:
    this.<>1__state = -1;
    this.<x>5__1++;
    this.<>2__current = this.<x>5__1;
    this.<>1__state = 3;
    return true;
    case 3:
    this.<>1__state = -1;
    this.<x>5__1++;
    this.<>2__current = this.<x>5__1;
    this.<>1__state = 4;
    return true;
    case 4:
    this.<>1__state = -1;
    this.<x>5__1++;
    break;
    }
    return false;
    }

위코드가 변화되는것이 흥미롭다면  Demo01 도 한번 컴파일 하고 Reflector 로 보기 바란다.

 

그런데 과연 이것이 어떠한 코드표현에 유용한지 이해가 안간다면

우선  gpg 5권을 10.4 단락을 읽어보기 바란다 거기서 표현하고자 하는 의도와 여기서 말하는것은 다른것이 없다.

 

핵심적인 내용은 순차적인 어떠한 서술내용을 프로그램밍으로 직관적으로 표현할수있다라는것이다.

이것이 앞으로 이해할 핵심적내용이다 이 서술적 프로그래밍은 앞으로 이해할 프로그래밍을 설명하는 핵심적 문구라 볼수있다.

 

 

 

 

이 글은 스프링노트에서 작성되었습니다.

Comment +1

이기적 유전자 한글판 146 쪽 매와 비둘기 샘풀
예전에 이기적 유전자를 읽으면서 꼭한번 프로그램으로 만들고 싶다고 생각한것을 이번기회에 해봤다 여러 테스트를 거쳐 도킨스이론의 코드를 만들었다



동영상을 보면 처음에 비둘기만 사는곳에 돌연변이로 매의성격을 가진놈을 만들어냈다 점점 매가 강세를 펼치지만 어느지점에 가서 매가 많아지면 매의 전술은 손해를 보는 전술이 되서 다시 비둘기가 강세를 이룬다 그러다 보면 ess 에 도달한다. 내가 궁극적으로 단순한 현상을 보고 싶었던것이 아니다 나는 여기서 매끼리 싸울때 손해보는 점수를 적게 주었다 다음동영상을 보면 둘다 어느지점에 머무르긴하지만 매의 평균 수가 높아진것을 볼수있다.

결록적으로 매끼리 서로 알아볼수있는 능력이나 표시를 가져서 서로 인식하고 손해를 보는것을 줄일수있따면 위와같은 동영상이 될것이다. 우리사회는 분명 첫번째 동영상의 위치던 두번째 동영상의 위치던 어느곳에 머물러있을것이다 내가 말하고싶은건 어릴때 서로 사랑하고 도와가는 비둘기 처럼 살아야한다고 강요한다. 우리들은 항상 어릴때 부터 악한자는 언젠가는 벌을 받는다고 교육받는다 하지만 이기적 유전자 이론을 기초로한다면 절대로 악한자는 벌을 받지않는다 오히려 더 교활할수록 더 잘살아갈 확률이 높아진다. 그렇다고 해서 그들만 살아서는 생존할수없다는것도 안다. 그들에게는 적당한 비둘기들이 필요하다. 그래서 새로태어난 어린이들에게 항상 비둘기처럼 살라고 한다.

Comment +4


만들어봐야겠다..
GA

Comment +1

이기적 유전자 2 라고 해야할까
처음에 이기적 유전자를 읽고

도킨스가 다음에 쓴책이 "확장된 표현형" http://www.yes24.com/24/goods/1402331 이란걸알고
들뜬마음으로 도서관에 가서 읽어보았다 하지만 예상과다르게 너무어렵고 깊이 들어가버려서 나를 지치게 만들었다
그후 그가 쓴다른책 눈먼 시계공을 알게 되였다 몇가지 더 있지만 다른건 그닥 흥미가 안끌려서
안읽어봤는데

"쉽게 배우는 유전 알고리즘" 을 읽다가 문장 중간에 이기적 유전자와 눈먼시계공책을 언급한다.
그때 느낌이 눈먼시계공이란책이 흥미로울것 같았다.
찾아보니 역시나 이기적유전자 2부 라고 해야할까 확장된 표현형 책에서 기대했던 그런내용이
여기에 있었다.

http://www.yes24.com/24/goods/1405744

전에 블로그에 내가 이기적 유전자에서 설명한 예시를 프로그램하고싶다고 쓴기억이 난다.
이제 슬슬 만들어봐야할듯하다.



Comment +1

인식률이 좋지않지만 기본적인 hmm 을 이해하는 도움이 되였다..
다음은 제스쳐를 인식할까해본다..
제스쳐중에 어떤 팩터를 특징데이타로 뽑아야할지 고민이다.
HMM

Comment +6