퇴근5분전

 

 그리드 헤더를 병합하는데, Custom 하기 위해서는 소스코딩이 많이 들어간다.  일일이 쳐야되니까.

 

그래서 알고리즘을 하나 만들어봐야겠다고 생각해서... 만들었는데 6시간이나 타이핑쳐서 만들었넹.

 

이런 그리드일때 이걸 병합하려면 일일이 코드를...

 

 Z

Y

 

그럼 같은 값을 가진 Cell들을 그룹지어 묶어주면 되겠지?

음... 처음엔 for .. for 를 이용해서 무작정 돌려봤는데 .. 쉽게 안묶인다. 

 

그래서 고안해 낸 방법은 자세한 내용은 담에 적고

 

 간략히  XXX를 먼저 그룹으로 묶고

 X를 구하고

 W를 구하고

 U를 구하고

 Y

 Y를 구한다.

 

곧 col > 증가시키면서 그룹을 먼저 묶은 후 하위 엘리먼트의 col 비교값을 제한한다.

row를 증가시키고 증가할수 없으면 col시작 값을 증가시키면서 그룹을 묶어 가면 된다.

 

( 소스 숨김 )

 

 

## 추가!!

 

1. x 값을 버퍼에 저장

2. row 0에서 x값과 같은 cell[ row, col ]값을 찾아 탐색. Y를 만나면 break 하면서 row0번의 colmax를 3으로 지정

3. row 1에서 x값과 같은 cell[ row, col ]값을 찾아 탐색. Z를 만나면 break 하면서 row1번의 colmax를 0으로 지정

4. 탐색 탈출.

 

4-1. 모여진 집합으로 CellRange 셋팅!

4.2. row별로 모인 카운트 정보가 다르면 가장 윗 row 컬렉션 정보만을 병합대상으로 관리하고 나머지는 버림.

 

5. row를 증가시킬수 있는지 체크 > yes : 증가 , 아니면 row별 colmax값과 현재 col시작값을 비교하여 적으면 col을 증가

6. 현재 row의 이하 row별 colmax를 초기값(colcount)으로 재지정

7. 다시 탐색. ( 마지막 cell까지 탐색을 마치면 그룹별로 CellRange 목록이 만들어짐 )

 

 

 

ㅡ.,ㅡ;; 젠장...  테스트를 할수록 버그가 텨나오넹...

쩝...

 

# 추가 수정. 버그 잡았다!! 우쒸!!

 

 이런 소스를 아래처럼 해당 위치 좌표를 구해온다.

 

몇줄이 되었든 이제야 제대로 좌표를 수집해온다.

 

이걸 이용하면 그리드 Merge된 소스를 쉽게 만들어낼 수 있게 된다.

 

## 추가 수정

  - 업로드되어 있던 소스에 대한 업데이트!! ( 약간 오류가 있는 버전으로 업데이트가 안되어있어 수정 )

  - 표 그리기 처리하면서 다시 수정된 버젼 올림.

 

## 추가 수정

 

 

   이번에 새로 단순 병합모드를 지원하는 소스를 만듬.

   - 단방향으로 쭉 훑어가므로 간단하지만,  동일한 내용이 흩어져있으면 원하는 결과가 나타나지 않음.

       ex) 'Z'가 'I' 라면 처음위에 만든 소스는 구분해서 병합함.

            이건 구분하지 못함.

       용도 - 이번 플젝에서 ultragrid 동적으로 컬럼 구성하고 병합해야 하는데 뭔가 부실해...

                회사에서 6시간 가까이 하던게 안되서 그냥 집에서 10분만에 만들어 ... 가져가서 쓰려고 기록함.

                내용상 단방향으로 훑었을때 데이타가 같은게 흩어져있지 않음.

'# 1) 프로그래밍' 카테고리의 다른 글

연말정산 프로그램? API... ( 이게 아니란다. )  (0) 2016.01.20
다음 맵 API 관련.  (0) 2016.01.11
Xaml 정리기  (0) 2015.09.04
Visual studio Community 2013 설치!  (0) 2014.12.07
app.config Section 작성 변환기...  (0) 2014.11.05

 

 현재의 프로젝트 중에 xaml이 개발표준에 맞지 않게 되있어서 화면을 열때마다 조금씩 틀어지거나 흔들려보이는 부분들을

 

깔끔하게 정리하여 맞춰주는 프로그램을 잠깐 만들어서 사용한다.

 

 탭 인덱스도 위에서 아래로 그리드 레이어일 경우 내부의 컨트롤들은 Grid.RowIndex와 Grid.ColIndex 순서대로 자동으로 부여하도록 만들어져있다.

 

쓸데없이 Margin준거라든가 높이값을 주어 흐트러지는 틀을 모두 제거하거나 위치에 맞게 값을 다시 셋팅한다.

 

각 컨테이너에 맞춤 스타일 정보를 셋팅하고, 컨테이너 하위에 있는 컨트롤 스타일도 없는 것들 채워넣거나 다시 셋팅하여

 

깔끔하게 줄맞춘 xaml을 얻을 수 있다.

 

 이 프로그램 덕에 일일이 탭 인덱스 찾아 넣을필요도 없고,... 그리드 레이어 안에 컨트롤들 찾아다니는 수고도 덜고...

 

일이 간편해진 만큼 다른 것들을 신경 쓸수 있어서 좋다... 이번 프로젝트도 힘내서 !!! 아자 아자..

 

 

 Visual Studio 2013 Community를 드디어 설치했다.

 

설치가 참 힘들었다 계속 오류가 떨어져서... 왜 안될까 .... 찾다 찾다...

 

마지막 포멧을 앞두고.

 

http://blogs.msdn.com/b/astebner/archive/2008/08/28/8904493.aspx

 

닷넷 삭제 툴. dotnetfx_cleanup_tool.zip

 

이걸로 삭제하고 설치했더니 오류없이 넘어가서 ... 설치가 완료되었다.

 

JSFW 프로젝트를 로드했더니 좋당!!!

 

게다가 설치 후 닷넷(.net)프로그래머 모임게시글을 보고 흥미가 더 생기는데...

 

과연 C#으로 아이폰, 안드로이드폰 개발이 가능해지니까... C#하길 잘했다 봐야겠지?

 

'# 1) 프로그래밍' 카테고리의 다른 글

Cell Merge를 구현할 알고리즘!  (0) 2015.10.17
Xaml 정리기  (0) 2015.09.04
app.config Section 작성 변환기...  (0) 2014.11.05
비동기 처리] IAsyncResult 를 이용함.  (0) 2014.10.30
before, do, after를 묶어보자!!  (0) 2014.10.28

 

 이번 일하면서 프로그램내 설정을 app.config에 담을 일생겼는데 이게 settings 같은걸로 분리해서 담아서 쓰면 데이타에 대한 분류가 안되고 섞일 것  같아서 데이타를 나누어 관리하기 위해 사용자정의 형태로 만들었다. 이번에 만들면서도 또 구글링하며 번거롭게 했다. 전에도 했었는데...

 

 그래서 이번엔 아예 코드를 작성해주는 프로그램을 만들었다.

만들기전에 혹시나 하고 프로그램을 찾아봤더니... 비슷해보이는데 다운로드 해볼수가 없어서... 그림을 보고 소스를 살짝 봤더니 원하는 모양이 아닌듯 해서 그냥 넘겼다.

 

 이 로직으론 저장할 xml만 만들면 된다. xml을 넘겨주면 .cs 코드를 받을수 있고  이 코드를 저장하면 쉽게 app.config( or web.config) 에서 설정관련

데이타를 관리할 수 있다.

 

요렇게 생긴 대상 데이타를 xml로 만든다.

  <SectionName Att="1111">
    <EEL Att1="222" >
      <Add Key="VV" Value="TT" />
    </EEL>
    <PPL>
      <AS Value="a"/>
      <AS Value="b"/>
    </PPL>
    <MySection>
      <MySettings MyKey="John" MyValue1="Developer" MyValue2="Expert"/>
      <MySettings MyKey="Tomas" MyValue1="Developer" MyValue2="Junior"/>
      <MySettings MyKey="Robert" MyValue1="Developer" MyValue2="Senior"/>
      <MySettings MyKey="Kurt" MyValue1="IT" MyValue2="Expert"/>
      <MySettings MyKey="Anna" MyValue1="HR" MyValue2="Senior"/>
    </MySection>
  </SectionName>

 

그리고

 

 

요렇게 xml을 담아 변환 시키면..

 

 

요렇게 소스로 준다... ( 길어서 짤림 )

 

 

테스트 모양이다. 각 변수에 담긴 값을 확인할 수 있다.

'# 1) 프로그래밍' 카테고리의 다른 글

Xaml 정리기  (0) 2015.09.04
Visual studio Community 2013 설치!  (0) 2014.12.07
비동기 처리] IAsyncResult 를 이용함.  (0) 2014.10.30
before, do, after를 묶어보자!!  (0) 2014.10.28
ExtJs > ExtNet 변환 툴!!!  (0) 2014.07.10

 

 최근에 나온 task나 await 는 못써봤다. 가끔 문서는 봤는데 어렵더랑...

간단하게 비동기 처리를 할 수 있는 옛날 버젼으로다가.

정리해본다. ( 전에 해둔것 같은데 못찾겠다... )

 

 delegate void Async<T>(T ctrl, Action begin, Action complite) where T : Control;
        Async<Control> async = (ctrl, begin, complite) =>
        {
            if (begin != null)
            {

               // 비동기 처리 시작!
                begin.BeginInvoke((ir) => {
                    begin.EndInvoke(ir);

               // 종료...
                    ctrl.DoInvoke(c =>
                    {
                        complite();
                    });
                }, begin);
            }
        };

 

// 컨트롤의 크로스 스레드 작업이 잘못되었습니다. 의 메세지를 회피할 수 있는 확장 메서드다.

 public static class Ex
    {
        public static void DoInvoke<T>(this T ctrl, Action<T> callMethod) where T : Control
        {
            if (ctrl.InvokeRequired)
            {
                ctrl.Invoke(new Action<T, Action<T>>(DoInvoke), ctrl, callMethod);
            }
            else
            {
                callMethod(ctrl);
            }
        }
    }

 

 

대리자 하나를 선언한다.

   : begin~~~~처리 ~~~~~complite

 

테스트!!!

폼에 버튼 하나를 둔다. ( : 추후에 프로그래스 바를 움직을 것임. )

 

 

 

테스트에 실행될 메서드

        bool isRun = false;
        void DemoAsyncMethod()
        {
            while (isRun)
            {
                System.Threading.Thread.Sleep(10000);// 10sec
                isRun = false;
            }
        }

 

 

아무런 처리를 하지 않았을때...

 private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            isRun = true;
            DemoAsyncMethod();
            button1.Enabled = true;
        }

 실행하면 비동기 버튼은 비활성화 되면서 DemoAyncMethod가 실행되면서 10초간 꼼짝도 하지 않는다.

이렇게 되면 사용자는 ...

그래서 비동기 처리를 해봤다.

private void button1_Click(object sender, EventArgs e)
        {
            // button1.Enabled = false;
            async(this, () => // begin Invoke ~ endInvoke
            {
                button1.Enabled = false;  // 크로스 쓰레드 error가 발생한다. 
                // button1.DoInvoke(b => b.Enabled = false); 주석을 해제하고 위 라인을 삭제하면 Invoke 처리로 정상 동작을 할 수 있다. 
                isRun = true;
                DemoAsyncMethod();
            }, () =>  // async complite
            {
                button1.Enabled = true;
            });
        }

 

 실행을 하면 버튼이 비활성화 된채 폼을 이리저리 움직여도 아까와 다르게 움직여진다...

 

좀더 시각적 효과를 주기위해 프로그래스를 기능을 포함한다.

bool isRun = false;
        void DemoAsyncMethod()
        {
            int progressValue = 0;
            while (isRun)
            {
                progressBar1.DoInvoke(p => p.Value = (++progressValue) * 10);
                System.Threading.Thread.Sleep(1000);// 10sec
                if (progressValue >= 10) isRun = false;
            }
        }

 

 

 

 

 

'# 1) 프로그래밍' 카테고리의 다른 글

Visual studio Community 2013 설치!  (0) 2014.12.07
app.config Section 작성 변환기...  (0) 2014.11.05
before, do, after를 묶어보자!!  (0) 2014.10.28
ExtJs > ExtNet 변환 툴!!!  (0) 2014.07.10
Directory.Create 관련...  (0) 2014.06.09

 

 오늘 조회, 수정, 삭제 관련 폼 작업을 하며 코드를 정리하다가...

 

조회를 할때 동작전, 동작, 동작 후 세단계를 계속 거치는데, 이걸 코드에 표현해서 메서드로 나열하자니

놓치는게 있는 듯 하고 해서 이걸 묶어서 코딩하면 좀더 앞으로의 코딩이 줄것 같고 놓칠게 줄어들듯 하여

바꿔봤다!

 

public delegate void DoAction(Func<bool?> beforeaction, Action doaction, Action afteraction);

 

대리자로 이렇게 동작을 연결짓는 매개체로 삼고

 

        protected DoAction SearchAction = (beforeaction, doaction, afteraction) =>
        {
            if (beforeaction == null || (beforeaction() ?? true))
            {
                // progress
                if (doaction != null) doaction();
                if (afteraction != null) afteraction();
            }
        };

 

이렇게 SearchAction을 만들었다.

우선은 별게 없다!

 

조회버튼이 클릭했을 때...

 

            if (SearchAction != null)
            {
                SearchAction(
                beforeaction: () =>
                {
                    // todo : 조회 조건 체크
                    return true;
                },
                doaction: () =>
                {
                    // todo : 조회 동작 처리

                },
                afteraction: () =>
                {
                    // todo : 조회 후 동작 처리
                });
            }

이렇게 연쇄적으로 호출할 수 있다면 어떨까 해서 ... 만들었다.

 

특정 동작에 대한 전 후 동작을 같은 곳에 표현할 수 있게 된다.

 

 

이건 저장 동작에 대한 틀이다.

 

        protected DoAction SaveAction = (beforeaction, doaction, afteraction) =>
        {
            if (beforeaction == null || (beforeaction() ?? true))
            {
                DialogResult confirmDialogResult = MessageBox.Show("저장하시겠습니까?", "Save", MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                if (confirmDialogResult == DialogResult.OK)
                {
                    // progress
                    if (doaction != null) doaction();
                    if (afteraction != null) afteraction();
                }
            }
        };

 

저장 버튼이 클릭했을때!

 

            if (SaveAction != null)
            {
                SaveAction(
                beforeaction: () =>
                {
                    // todo : 저장전 유효성 체크
                    return true;
                },
                doaction: () =>
                {
                    // todo : 저장 동작 처리
                },
                afteraction: () =>
                {
                    // todo : 저장 이후 동작 처리.
                });
            }

 

우선 beforeaction에서 넘어오는 반환값에 따라 이후 동작들이 연쇄 호출이 되는 셈!

적용해보니 괜찮은데... 이번 프로젝트는 이걸로 가볼까!!!

 

 

 

 

 

 이번 프로젝트에서 ExtJs 디자이너로 화면을 만들어 놓은것을

Ext.Net에 맞춰 변환 하는 프로그램을 만들면서 살짝 이력을 남겨본다.

 

# 정보수집..

1. 자바스크립 Object 구성으로 만들어진다. composite!

2. 그렇다면 트리 구조로 데이타를 추적할수 있다.

3. 문자열 > Object 변환이 필요하다. json으로 되는지 보자.

4. 각 프로퍼티에 대응하는 object 프로퍼티 맵을 어떻게 구성해야 하는지.. 고민해봐야 한다.

5. 기간! 주어진 시간이 짧기에 [ 변환 소스 만드는 시간 = 손으로 바꿔야 하는 시간 ] 이 쌤쌤이어야 한다.

 

! 정보수집 된 내용을 기반으로 머리속에서 프로그램이 동작하는 부분들을 미리 이미지화 한다.

 

# 제작..

   쿵짝 쿵짝.. 만드는데 3시간, 테스트 3시간!!

# 결과

   OK! 소스 변환까지는 금방 완성이 되었는데... 다른 일들이 껴들어와서 누적시간이 더 걸렸음.

         테스트 할때는 실제 변환해서 화면에 뿌려보니 디자이너로 제작한 내용과 다른 부분들이 존재하여

         추적하여 디버깅하였음.

         리플렉션 + 대리자를 이용! 소스가 엄청 짧고 간단한다.

 

# Hint!

  소스 라인은 833 라인!으로 ExtJs의 필요한 부분들을 최대한 필요한 만큼 수용한 변환 툴 완성!

 

 - 사용된 디자인 패턴 : Visitor [ 역시 타입별로 대응해서 뭔가 처리 하고자 할때 ... 좋음. ]

 

# 변환기 호출 처리 로직

1.

string                                                    // 변환된 문자열

ToConvert (

            EXTNETBASE ex,                         // 변환 대상

            int depth,                                            // 현재 깊이

               Func<EXTNETBASE, int, string> Fn // 변환기

2.

Func<EXTNETBASE, int, string>                     // 타입에 맞는 변환메서드

GetConvert(

           string xType                                // 타입

)

3.

string                                                   // 타입에 맞는 변환 결과

ToContainer(

           EXTNETBASE ex,                         // 변환 대상

           int depth                                    // 깊이

)

 

기본 흐름은 위처럼 변환대상에 대해 시작하면(ToConvert) 해당 타입을 변환 할 수 있는 메서드를 꺼내서(GetConvert)

변환(ToContainer)

 

 

    public interface IVisitor
    {
        string Visit(IAcceptor act);
    }
    public interface IAcceptor
    {
        EXTNETBASE GetInstance();
        string Acceptor(IVisitor visit);
    }

 

  이번에 개발하면서 대리자+ 리플렉션 이용해서 소스를 줄이고 시간을 벌었다. 

 

// extjs 의 문자열들을 object 트리 구조로 변환 시켜줌 ( Json이용 )

EXTNETBASE m = JsonConvert.DeserializeObject<EXTNETBASE>("    extjs design source  ");

 

// 트리구조의 object를 비지터로 모두 순회 하면서 각 타입별로 변환 시킴.

ExtNetConverter vis = new ExtNetConverter();
string s = m.Acceptor(vis);

 

// Object

public class EXTNETBASE : IAcceptor
{

        public Collection<EXTNETBASE> items { get; set; }

        public string Id { get; set; }
        public string name { get; set; }
        public string xtype { get; set; }

   
        . . .

          
        public string Acceptor(IVisitor visit)
        {
            return visit.Visit(this);
        }

        public EXTNETBASE GetInstance()
        {
            return this;
        }
}

 

public class ExtNetConverter : IVisitor
{
        public string Visit(IAcceptor act)
        {
            EXTNETBASE cont = act.GetInstance();
            return ToConvert(cont, 0, GetConvert(cont.xtype));
        }

       

        // 탭의 깊이만큼 생성 반환!

        static Func<int, string> Tab = (depth) => { return new string('\t', depth); };

 

        // 구조의 깊이를 추적할수 있는 대리자.

        static Func<EXTNETBASE, string, int, int> CalcMaxDepth = (ext, collectionPropertyName, depth) => {

            // todo : 트리구조이므로 깊이를 추적함.

            PropertyInfo collectionProperty = ext.GetType().GetProperty(collectionPropertyName, BindingFlags.Public | BindingFlags.Instance);
            if (collectionProperty != null)
            {
                Collection<EXTNETBASE> coll = collectionProperty.GetValue(ext, null) as Collection<EXTNETBASE>;
                if (coll != null)
                {
                    int maxChildDepth = 0;
                    int temp = 0;
                    foreach (var item in coll)
                    {
                        temp += CalcMaxDepth(item, collectionPropertyName, depth);
                        if (temp > maxChildDepth) temp = maxChildDepth;
                    }
                    depth += maxChildDepth;
                }
            }
            return depth;
        };

 

       string ToConvert(EXTNETBASE ex, int depth, Func<EXTNETBASE, int, string> Fn) {

 

            // todo : 객체별 변환메서드를 호출하며, 탭으로 서식 유지 시켜 보기 편하게 만듬.
            string result = Tab(depth) + (Fn != null ? Fn(ex, depth) : "@*## Convert미지원 " + ex.xtype + " ##*@");
            if (ex.items != null && ex.items.Count > 0)
            {
                result += ".Items(" + Environment.NewLine + string.Join(","+Environment.NewLine, ex.items.Select(s =>

                                           ToConvert(s, depth+1, GetConvert(s.xtype))).ToArray());
                int itemDepth = CalcMaxDepth(ex, "items", depth);
                result += Environment.NewLine + Environment.NewLine + Tab( itemDepth ) + ")";
            }

            if (ex.dockedItems != null && ex.dockedItems.Count > 0)
            {
                result += ".DockedItems(" + Environment.NewLine + string.Join("," + Environment.NewLine, ex.dockedItems.Select(s =>

                                          ToConvert(s, depth+1, GetConvert(s.xtype))).ToArray());
                int dockedItemsDepth = CalcMaxDepth(ex, "dockedItems", depth);
                result += Environment.NewLine + Environment.NewLine + Tab(dockedItemsDepth) + ")";
            }

            if (ex.gridcolumns != null && ex.gridcolumns.Count > 0)
            {
                result += ".ColumnModel(" + Environment.NewLine + string.Join("," + Environment.NewLine, ex.gridcolumns.Select(s =>

                                          ToConvert(s, depth+1, GetConvert(s.xtype))).ToArray());
                int columnModelDepth = CalcMaxDepth(ex, "gridcolumns", depth );
                result += Environment.NewLine + Environment.NewLine + Tab(columnModelDepth) + ")";
            }
            return result;
        }

 

        Func<EXTNETBASE, int, string> GetConvert(string xType)
        {

            // todo : 각 타입별 변환 메서드 반환

            switch (("" + xType).ToLower())
            {
                default:
                    return new Func<EXTNETBASE, int, string>((e, i) => { return @"@*"+xType+"*@"; });
                case "container":
                    return ToContainer;

                case "textfield":
                    return ToTextfield;

                case "textareafield":
                    return ToTextareafield;

              

                ... 각 타입별 변환 메서드!

           }

       }

 

        string ToContainer(EXTNETBASE ex, int depth)
        {
            string content = "X.Container()";
            content += GetCommonConvert(ex);
            return content;
        }

 

        string GetCommonConvert(EXTNETBASE ex, string opt = "")
        {

               // todo : 객체들 공통프로퍼티 변환목록을 묶어서 진행.

         }

 

         private static string GetPropertyConvert(EXTNETBASE ex, string propertyName, string opt = "")
        {

                // todo : Js변환 대상 프로퍼티 -> Net 변환

        }
        // 이후로는

        // 20여개의 변환 메서드

        // 15개 정도의 프로퍼티 변환처리.

}

 

 

LCD 숫자 표기.

 

사진 처럼 각 숫자의 digit table을 만들어서  ...

 

전에 FND 그려본적이 있어서 그리는건 문제가 안되는데...

 

다만. 동적으로 늘고 줄고 하는 것처럼 책에 있다.

 

 S + 2열, 2S + 3행

예제는 S = 2일때 3일때를 표시하고 있는데...

내가 푼방법에는 안맞는것 같넹...

 

풀이를 살펴봐야겠다.

 

 

'# 1) 프로그래밍 > 프로그래밍챌린지' 카테고리의 다른 글

Chapter 01. Q3. 여행... ㅡ.,ㅡ?  (0) 2014.07.04
Chapter 01. Q2. 지뢰찾기  (0) 2014.07.02
Chapter 01. Q1. 3n+1  (0) 2014.07.01
시작하며...  (0) 2014.07.01

 

 문제도 이해가 안되고 풀이봐도 이해가 안되네...

 

검색해봤더니 푼사람이 있다..

 

헉... ㅡ.,ㅡ;;???

 

나누기 2는 대체 왜 하는거지???

소스 코드를 훑어보고 코드를 쳐봤따 .

 

 

static void Main(string[] args)
        {
           /*문제가 이해가 안되!!*/

           /*
                 여행을 가는 사람들이 지출비용을 관리함.
           *  전달될 돈이 똑같게 하기 위한... ( 어렵다... 뭐라는지... )
           */
            
            List<double> moneys = new List<double>();
            moneys.Add(10d);
            moneys.Add(20d);
            moneys.Add(30d);
            Draw(moneys);
            Calc(moneys);
            moneys.Clear();
            moneys.Add(15d);
            moneys.Add(15.1d);
            moneys.Add(3d);
            moneys.Add(3.1d);
            Draw(moneys);
            Calc(moneys);
            Console.ReadLine();
        }

        private static void Calc(List<double> moneys)
        {
            double avg = moneys.Average();
            double result = 0d;
            moneys.ForEach(m =>
            {
                result += Math.Abs((int)((m - avg) * 100d) / 100.0d);//소수점 자리 버림.
            });
            Console.WriteLine( "Result: "+ ( result / 2d ).ToString("N2")); // 대체 왜 /2를 하는걸까? 주고 받고?
        }

        private static void Draw(List<double> moneys)
        {
            Console.WriteLine(moneys.Count);
            moneys.ForEach(m => Console.WriteLine(m.ToString("N2")));
        }

'# 1) 프로그래밍 > 프로그래밍챌린지' 카테고리의 다른 글

Chapter 01. Q4. LCD 숫자 표시  (0) 2014.07.04
Chapter 01. Q2. 지뢰찾기  (0) 2014.07.02
Chapter 01. Q1. 3n+1  (0) 2014.07.01
시작하며...  (0) 2014.07.01

 

한시간 반정도 걸렸넹..

드라마 보기 시작해서 시작! 종료... 11시 반.

문제는 지뢰 매설 > 지뢰게임처럼 cell 주변에 지뢰가 몇개 있는지 숫자를 붙이는 것임.

 

맵을 만들고, 지뢰갯수를 지정

CreateMap( row : 10, col : 10 , 10 지뢰갯수 );

 

맵의 각 cell을 돌며 Cell주변의 지뢰갯수를 업데이트.

MapNavi( map )

 

cell 의 8방향으로 체크해서 지뢰가 있으면 업데이트 + 1

Search( cell번호, row갯수, col갯수, 지뢰맵, 업데이트맵 );

 

 

 

 좀 보기 좋게 꾸미려고 간격조정과 특수문자로 지뢰 표시.

 

'# 1) 프로그래밍 > 프로그래밍챌린지' 카테고리의 다른 글

Chapter 01. Q4. LCD 숫자 표시  (0) 2014.07.04
Chapter 01. Q3. 여행... ㅡ.,ㅡ?  (0) 2014.07.04
Chapter 01. Q1. 3n+1  (0) 2014.07.01
시작하며...  (0) 2014.07.01