« Previous : 1 : ... 140 : 141 : 142 : 143 : 144 : 145 : 146 : 147 : 148 : ... 221 : Next »

* 게일 리플링거(Gail Riplinger). 1947년생.

사용자 삽입 이미지

세벌식 글자판 운동에다 비유하자면, 거의 킹 제임스계의 송 현 선생님 같은 분.
여성이지만 변개된 역본들을 까는 전투력은 타의 추종을 불허하는 만렙이다. 변개된 성경 옹호자 내지 원어· 원문를 빠는 사람들의 천적, 나이트메어이며, 킬러요 저격수이다. 나 같은 사람은 감히 범접할 수조차 없는 세계적인 전문가이다. 다만, 그 덕분에 주변에 적도 엄청 많다.

구글에서 사진을 검색해 보면 일반 사진보다는, TV에 노출된 장면이 캡처된 게 더 많이 걸려 나온다. 예쁘장한 전형적인 미국 아줌마 인상이라나? 단, 그런 것들은 대개 최소한 20세기 시절의 굉장한 옛날 사진이다.

이분은 New Age Bible Version(국내엔 <뉴에이지 성경 역본>이라고 소개됨), In Awe of Thy Word, Hazardous Materials 같은 전설적인 책들을 썼는데, 다들 수백~천몇백 페이지에 달하는 어마어마한 거작이다.
그냥 성경간의 차이를 대조하는 수준이 아니라, KJV를 공격하는 데 쓰이는 알량한 히브리/그리스어 원어 사전이나 원문부터가 완전히 헛점투성이이고 싸그리 잘못된 이유를 다 밝혀 낸다. 그리고 그 바닥 학계가 얼마나 허접하고 더러운지를 까발린다. 종교적이 아니라 학술적으로 말이다.

그렇게 적을 상대로는 디버프를 시켜 놓고, KJV에 대해서는 버프 그 자체다. 언어 차원에서 성경의 영어 번역은 KJV 말고는 선택의 여지가 있을 수 없음을 논증하고, KJV의 영어는 매 단어 하나 하나가 거의 뜻글자나 마찬가지라는 수준으로 의미 부여를 시켜 준다. 가령, do의 3인칭 단수가 왜 굳이 doth(더쓰)와 doeth(두이쓰)로 달리 존재하는지 같은 것까지 다 아무렇게나 번역된 게 아니라는 거다.

과장 좀 보태면, 400여 년 전의 KJV 번역자들보다 KJV를 더 잘 알 것 같기도 한 사람이다.

본인은 이분의 저서 Hazardous Materials의 일부를 번역하는 일에 투입된 적이 있었다. 그런데 chapter 1만 봐도 이건 뭐..
다음과 같은 기상천외한 비유가 들어간 문장들을 생각해 낼 수 있는 사람은 역시 이분밖에 없다. ㅋㅋㅋㅋㅋㅋ 번역하면서 내가 다 놀랐다.
나부터가 글을 좀 호전· 도발· 공격적으로 쓰는 걸 좋아하는 스타일이다 보니, 그런 스타일의 글을 번역할 때도 동질감이 느껴진다.

1. 신학교 교수가 강의실에서 포르노를 보여주고는 이렇게 말한다고 생각해 보라. “이브의 ‘원판’(original)은 원래 이렇게 생겼지요. 그러니 여러분의 와이프라는 ‘판본’(version)은 원본보다 열등합니다.” 원어 어휘집은 우리의 신앙에 이와 동일한 맥락의 악영향을 끼치니, 정말 기독교계의 포르노라고 해도 과언이 아니다.

2. 이런 체계 하에서 성경학도들은 끝없이 배우지만 진리의 지식에 결코 도달하지 못할 것이다. 그럼에도 불구하고 그들은 계속해서 소프트웨어와 서적들을 모으면서 “지혜로워지고” 하나님께서 말씀해 주신 것보다 더 많은 것을 아는 “신들처럼 되려고” 노력할 것이다. 그들은 전쟁터에서 이미 뱀의 편이 되고 말았다. “참으로 하나님께서 그렇게 말씀하시더냐?” (Yea, hath God said?)

3. 에이즈(AIDS)라는 질병은 원래는 GRID(게이와 관련된 면역 체계 이상증세)라고 불렸다. 그런데 오늘날은 또 다른 GRID(그리스어와 관련된 면역 체계 이상증세)가 학생들을 물들이고 있다. 영적 면역력을 파괴하여 이단으로 빠지게 하는 것이다.

4. 하다못해 주변에 마약이나 포르노에 대한 유혹이 있다면, 성령의 검인 성경이 신자를 지켜서 그런 것들이 얼씬도 못 하게 할 수 있다. 그러나 마귀가 그 검을 빼앗아 버리면, 검을 빼앗긴 사람은 앞으로 어떤 공격도 막을 수 없는 무방비 상태가 된다.

5. 필자는 자라나는 대학생들로 인한 마음의 부담 때문에 매일 이렇게 기도한다. 그들에게 거짓을 가르치는 자들은 어서 회개하고, 만약 회개를 거부한다면 그들의 거짓말이 강제로라도 잠잠해지기를 말이다. 거짓말을 잘하는 사람이라면 합법적으로 거짓말을 해도 되고 거짓말이 최소한 ‘영적인’ 해악을 끼치지는 않는 직업을 선택하면 얼마나 좋을까? 중고차 판매 영업사원이 적절할 것 같다. 주님은 여러 위험한 교수들과 성경 의심쟁이들을 본업에서 끌어내셨으며, 일부를 진짜로 중고차 판매업계로 보내 버리신 적이 있다.


사실, 영어로 the original이라고 하면 원어도 되고 원문도 된다. 성경 번역의 품질은 얼마나 정확한 원문을 바탕으로 얼마나 정확한 언어 지식을 동원하여 번역하였느냐에 따라 결정된다.
킹 제임스 진영에서 기존 성경들이 다 변개되었다고 주장하는 건 대부분이 '원문' 문제이고 <뉴에이지 성경 역본> 같은 책도 다루는 분야가 이쪽이다. 오리겐 같은 사람이 변개한 부패한 원문을 웨스트코트와 호르트 같은 학자가 본문 비평이라는 정신승리 궤변을 들고서 다시 끄집어내어, 성경의 주류로 끌어올려 놓은 것이다. 이것은 참으로 거대하고 치밀한 음모이다.

그런데 세월이 흐르면서 리플링거 박사의 관심사는 원문을 넘어서서 이제 '원어'로 넘어갔다.
변개된 성경에 대해서는 경각심이 생긴 사람들의 마음을 도저히 고칠 수가 없으니, 악의 무리들은 이제는 본문은 KJV 그대로 놔 두더라도 단어의 뜻이 이게 아니고 원어로는 이렇다는 식으로 사기를 치는 것이다.
예를 들어, 영어로는 아가페 사랑과 에로스 사랑을 구분해서 표현할 수 없다거나, 하나님의 이름은 히브리어 사자음어 때문에 음가를 영원히 알 수 없다는 식의 괴담 말이다.

그래서 새로 나온 책은 변개된 역본이나 본문에 이어 원어 어휘집, 사전을 신랄하게 까고 있다.
요즘은 사전을 만들 때 편찬자의 주관이 아니라 다량의 말뭉치 분석을 통해서, 거기에 드러난 어휘의 용례를 바탕으로 뜻풀이를 추출하는 게 대세이다.
그런데 문제는 그런 원어 어휘집들의 밑천은 이집트나 그리스 이교도들이 남긴 전혀 기독교적이지 않은 문헌이라는 점이다.

그런 엉뚱한 걸 갖다대고는 단어의 의미가 서로 일치하지 않으면 KJV의 오역이라고 트집 잡고 넘기고, 심하면 KJV의 단어의 의미를 세속· 인본주의적인 뜻으로 완전히 왜곡해 버린다. 특히 지옥, 대속, 기도, 은혜 같은 단어가 그런 식으로 왜곡되면 이건 뭐 기독교의 근간이 다 무너지지 않겠는가?

단적인 예로 virgin이 사실 원어에 따르면 굳이 처녀가 아니라 '젊은 여성'도 된다. 이런 식으로 원어드립을 치면 예수님의 동정녀 탄생도 얼마든지 공격하고 부정할 수 있게 된다는 뜻이다.

이 주제로는 할 말이 무척 많지만, 오늘은 이쯤에서 글을 맺겠다. 요컨대 킹 제임스 성경에 대해서는

1. 변개되지 않은 바른 본문에서 번역되었으며,
2. 모든 바른 필사본들을 온전히 집대성했다.
3. 원문을 그 누구보다도 탁월한 실력으로 번역했고,
4. 원문을 교리적으로 바른 사상으로 번역했다.


이렇게 알면 정확할 것이다.
1은 무슨 뜻인지 설명이 더 필요하지 않겠지만, 2는 세상의 그 어떤 성경 필사본도 단일 필사본에 성경 66권 전서가 다 담겨 있지는 않기 때문에 짚고 넘어갈 필요가 있는 문제이다.
2가 불안하면 마가복음 16장의 마지막 열두 구절이라든가 요한일서 5:7 삼위일체 문제에서 걸려 넘어지게 된다.
1과 2는 원문 계층이고 3과 4는 원어 계층이다. 3은 KJV의 이스터(행 12:4) 같은 우수한 번역을 뒷받침하며,
4는 KJV가 동성애· 여자 목사 옹호, 지옥 부정 같은 불온사상에 물들지 않았음을 보여 준다.

성경 역본 논쟁은 확실히 창조-진화 논쟁 바닥과 비슷한 양상이다. 원숭이와 사람 사이의 중간 화석이 없는 것만큼이나 원어· 원문의 막연한 환상도 허상일 뿐 그 실체가 존재하지 않는다.
또한, 창조에 대한 믿음이 무너지면 그 뒤의 예수님의 동정녀 탄생이나 부활, 재림 같은 것도 결코 믿을 수 없게 되듯, 성경에 대한 믿음이 무너지면 성경에 기록된 그 어떤 말씀도 믿을 수 없게 된다.

KJV 신자의 믿음은 이런 성경 구절 패러디로도 요약될 것 같다. 매우 적절한 비유이다.

“나를 본 자는 아버지를 보았거늘 어찌 네가 말하기를, 우리에게 아버지를 보여 주소서, 하느냐?” (요 14:9)
킹 제임스 성경을 본 자는 이미 original(원어+원문)을 보았거늘, 어찌 네가 말하기를 우리에게 original을 보여 주소서, 하느냐?


한글-한자 논쟁으로 비유하자면, 리플링거 박사는 수천 년 전의 한중일 한문 고전을 죄다 술술 읽고 해석해 내는 한문 전문가뻘 된다. 그럼에도 불구하고 국민 계몽을 위한 한글 전용을 적극 지지하고 한자 기득권 속에 숨은 위선자 헛똑똑이들의 정체를 폭로하는 의로운 일을 하는 셈이다.

기독교의 하나님은 언어 가지고 말장난을 하시지 않는다. 언어 장벽은 인간의 동반 타락을 막기 위해 허락하신 것일 뿐, 이것이 성경 말씀에 대한 접근성 제약을 의도한 것은 결코 아니라는 뜻이다. 아무쪼록 리플링거의 책의 번역문이 어서 출판되어 나와서 국내의 많은 크리스천들에게 성경에 대한 바른 믿음을 세우는 데 도움이 되면 좋겠다.

Posted by 사무엘

2013/10/02 08:37 2013/10/02 08:37
, , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/883

제헌 국회 기도문

대한민국이 기도로 시작한 나라라는 걸 정치적으로 좀 우파 성향인 크리스천이라면 어렴풋이 들어서 알 것이다.
본인은 수 년 전, 우리나라 초대 겸 건국 대통령인 이 승만 박사의 옛 저서 Japan Inside Out의 번역판인 <일본 그 가면의 실체>가 국내에 출간됐을 때, 그 책을 통해서 저 기도문을 처음으로 접했다.

잠시 역사 배경을 설명하자면 이렇다.
대한민국의 제1대 국회인 대한민국 제헌국회는 대한민국 헌법을 첫 제정한 국회이며 1948년 5월 31일 구성되고 1950년 5월 30일까지 활동하였다. 대한민국에서 국민의 직접 투표로 선출된 국회의원을 구성원으로 한 최초의 국회이다. (한국어 위키백과 설명)

그 당시는 우리나라에 국회 의사당 건물이 따로 있는 게 아니었기 때문에, 서울 광화문 근처의 옛 중앙청 홀--김 영삼 정권 때 헐린 그 튼튼한 건물--에서 국회의원들이 모였다.
국회의원들은 정확히 세 주 전에 열린 5· 10 총선거 때 선출된 사람들이다. 남한만 단독으로 총선거를 해 버려서 남북 분단이 고착화되었다는 우려도 받았으나, 북한은 어차피 그 전에 이미 조선로동당 대회를 자체적으로 치렀으니 통일은 애초에 물 건너간 상황이었다.

자, 그래서 1948년 5월 31일 아침 10시경이 되었다.

* 임시 의장 이 승만

대한민국 독립 민주국 제 1차 회의를 여기서 열게 된 것을 우리가 하나님에게 감사해야 할 것입니다. 종교· 사상 무엇을 가지고 있든지 누구나 오늘을 당해 가지고 사람의 힘으로만 된 것이라고 우리가 자랑할 수 없을 것입니다. 그러므로 하나님에게 감사를 드리지 않을 수 없습니다. 나는 먼저 우리가 다 성심으로 일어서서 하나님에게 감사를 드릴 터인데 이 윤영 의원 나오셔서 간단한 말씀으로 하나님에게 기도를 올려 주시기를 바랍니다.

* 이 윤영 의원 기도 (일동 기립)

이 우주와 만물을 창조하시고 인간의 역사를 섭리하시는 하나님이시여, 이 민족을 돌아보시고 이 땅에 축복하셔서 감사에 넘치는 오늘이 있게 하심을 주님께 저희들은 성심으로 감사하나이다. 오랜 시일 동안 이 민족의 고통과 호소를 들으시사 정의의 칼을 빼서 일제의 폭력을 굽히시사 하나님은 이제 세계만방의 양심을 움직이시고 또한 우리 민족의 염원을 들으심으로 이 기쁜 역사적 환희의 날을 이 시간에 우리에게 오게 하심은 하나님의 섭리가 세계만방에 성시하신 것으로 저희들은 믿나이다.

하나님이시여, 이로부터 남북이 둘로 갈리어진 이 민족의 어려운 고통과 수치를 풀어 주시고 우리 민족 우리 동포가 손을 같이 잡고 웃으며 노래 부르는 날이 우리 앞에 속히 오기를 기도하나이다. 하나님이시여 원치 아니한 민생의 도탄은 길면 길수록 이 땅에 악마의 권세가 확대되나, 하나님의 거룩하신 영광은 이 땅에 오지 않을 수밖에 없을 줄 저희들은 생각하나이다.

원컨대 우리 조선 독립과 함께 남북통일을 주시옵고 또한 우리 민생의 복락과 아울러 세계평화를 허락하여 주시옵소서. 거룩하신 하나님의 뜻에 의지하여 저희들은 성스럽게 택함을 입어가지고 글자 그대로 민족의 대표가 되었습니다. 그러하오나 우리들의 책임이 중차대한 것을 저희들은 느끼고 우리 자신이 진실로 무력한 것을 생각할 때 지와 인과 용과 모든 덕의 근원이 되시는 하나님 앞에 이러한 요소를 저희들이 간구하나이다.

이제 이로부터 국회가 성립이 되어서, 우리 민족의 염원이 되는, 모든 세계만방이 주시하고 기다리는 우리의 모든 문제가 원만히 해결되며 또한 이로부터 우리의 완전 자주독립이 이 땅에 오며 자손만대에 빛나고 푸르른 역사를, 저희들이 정하는 이 사업을 완수하게 하여 주시옵소서. 하나님, 이 회의를 사회하시는 의장으로부터 모든 우리 의원 일동에게 건강을 주시옵고 또한 이겨서 양심의 정의와 위신을 가지고 이 업무를 완수하게 도와 주시옵기를 기도하나이다.

역사의 첫걸음을 걷는 오늘의 환희와 감격에 넘치는 이 민족적 기쁨을 다 하나님에게 영광과 감사를 올리나이다. 이 모든 말씀을 주 예수 그리스도의 이름을 받들어 기도하나이다. 아멘.

이 기도문은 이 윤영 목사가 원고를 미리 써 와서 읽은 게 아니라는 걸 유의하자.
이 승만 의장이 현장에서 갑작스럽게 즉흥으로 요청을 해서 기도가 시작된 것이다. 즉, 이건 애드립이다. 텍스트는 속기사가 받아 적어서 만들어졌다.
이런 건 좀 공신력 있는 사이트에 문헌으로 좀 기재되어 있어야 할 텐데 국회 홈페이지나 위키문헌엔 없나?
<날개셋> 타자연습에는 저 글이 연습글로 수록되어 있다.

뭔가, 아폴로 8호 승무원의 창세기 낭독 사건 같은 걸 보는 느낌이지 않은가.
이런 거 읽을 때만큼은 제발 후천년주의니 정교일치니 그딴 삐딱한 시선은 잠시 집어치우고, 일단 감격하고 감사할 줄 좀 알자.
누군 뭐 국가나 정치와 관련된 성경적 입장을 모르는 줄 아나..?

한쪽에서는 “정의의 칼을 빼서 일제의 폭력을 굽히시사 ... 오늘 같은 날을 있게 하신 주님께 저희들은 성심으로 감사하나이다. 우리 민족 우리 동포가 손을 같이 잡고 웃으며 노래 부르는 날이 속히 오기를 축원하나이다. 이 모든 말씀을 주 예수 그리스도의 이름을 받들어 기도하나이다” 이러면서 나라를 세웠다.

이 국회를 통해 1948년 7월 17일에 대한민국의 첫 헌법이 공표되었다. 그래서 지금은 공휴일에서 빠진 국경일 제헌절이 이 날로 제정된 것이다.

그 반면, 반대편에서 비슷한 시기에 벌인 북조선 로동당 2차 대회(1948년 3월 27일~30일)는 분위기가 아마 어땠을까? -_-;;
그때는 워낙 초창기이기 때문에 북한도 내부에 여러 파당이 있었으며 노골적인 김씨 우상화는 지금보다 덜했었다.
하지만 이미 인간성 말살이 시작되고 반대파 '반동'들을 비판하고 숙청하고, “동무들, 인민 해방을 위한 과업을 어서 완수하시오” “소련으로부터 지원 받아서 미 제국주의 남조선 원쑤들 다 쓸어버립시다” 이런 권모술수와 추악한 음모가 진행 중이었을 것이다.

덧붙이자면 북한이 태극기 대신 자체적인 인공기를 제정해서 쓴 게 1948년 초쯤부터이고, 애국가도 자기네 애국가를 1947년 하반기부터 채택했으니, 이미 남북 영구 분단 고착은 그 무렵부터 예고된 귀결이었다. 쟤들은 소련의 군사· 경제력을 등에 업고 시민들은 공산주의 지상락원으로 선동하고, 서로 비판하고 감시하고 못 믿게 만들고 팀웍을 해체시키는 방법으로 권력을 꽉 장악해 갔을 것이다.

난 이걸 생각하면 소름이 확 돋는다.
어디 누가 누굴 보고 대한민국이 처음부터 더럽게 시작되고 태어나지 말았어야 할 나라라고 정체성을 부정하고 앉았는가? 괘씸한 놈들!

난 우리나라가 건국 이래로 예수 믿고 교회 댕기고 예배드리고 심지어 거리설교까지 하는 데 아무 지장이 없었던 것 하나만으로도.. 우리나라의 자유는 정말 넘치도록 잘 보장되어 있었고, 극소수 있었던 부조리와 제약은 종북 불순분자 빨갱이들 빼고는 하나도 걸릴 게 없었다는 생각이 변함없다.

이 승만 전대통령은 대한민국의 초대 대통령으로, 건국 대통령으로 충분히 예우받고 존경받아야 한다. 그가 대통령으로서 잘못한 것들은 잘한 것에 비하면 정말 사소하고 불가피하고 최소한 악의는 없었던 것들이다. 특히 말도 안 되는 허무맹랑한 친일파 드립은 내 눈에 띄면 절대로 그냥 넘어가지 않을 것이다. 다 조직적으로 반박해 줄 것이며, 앞으로 기회가 되면 이 주제만으로 또 블로그에다 글을 쓸 기회가 있을 것이다.

아무에게나 정말 양심에, 가슴에 손을 얹고 솔직하게 물어 보고 싶다. 종북 빨갱이들조차 적으로 안 보이고 혁명가 투사로 보일 정도로 우리나라가 아직까지 그렇게도 엿같고 개판이고 다 갈아엎어야 하고, 국민들에게 해 준 게 없는 나라인가?

Posted by 사무엘

2013/09/29 08:36 2013/09/29 08:36
, , , , ,
Response
No Trackback , 6 Comments
RSS :
http://moogi.new21.org/tc/rss/response/882

지뢰찾기 연구

요즘 팔자에도 없던 지뢰찾기에 살짝 재미가 붙었다.
본인은 비슷한 학력· 경력으로 IT 업계에 종사하는 여느 사람들과는 달리, 머리 싸움을 즐기는 스타일이 전혀 아니었으며 복잡한 퍼즐 게임 따위와도 담을 쌓고 지내는 편이었다. 이런 점에서 본인은 완전 퍼즐 게임 매니아인 T모 님과는 성향이 다르다.

그래도 지뢰찾기 정도면 요령을 알고 나니까 은근히 재미있다. 초보 레벨로는(9*9, 지뢰 10개) 40초~1분 남짓한 시간 동안 대략 60~70%대의 승률로 깨겠다. 처음엔 초보 레벨조차도 5분이 넘게 끙끙대기도 했으나, 마치 경부선 서울-부산 열차의 운행 시간이 17시간에서 6시간대~4시간대로 줄어들듯이 시간이 단축되었다.

사용자 삽입 이미지
지뢰찾기는 소련에서 개발된 테트리스와 더불어 시간 죽이기용으로 상당히 적절한 컴퓨터용 퍼즐인 거 같다. 여느 보드 게임과는 달리, 물건이 먼저 존재하다가 컴퓨터로 옮겨진 게 아니라 처음부터 컴퓨터용으로 만들어진 게임이라는 차이가 있다.

맥북의 터치패드 격인 트랙패드로는 도저히 게임을 할 수 없는 듯했다.
두 손가락을 동시에 누르거나 패드 우측 하단을 지그시 누르면 우클릭이 되긴 하는데, 이게 생각보다 정확하게 인식되지가 않는 듯하기 때문이었다.

지뢰가 있다는 깃발만 꽂으려고 우클릭을 했는데, 그게 좌클릭으로 인식되어 지뢰를 밟고 장렬히 죽는 참사가 한두 번 발생하는 게 아니어서 말이다. 단, Windows Vista 이후부터 새로 개발된 지뢰찾기는 Shift+클릭으로 우클릭, 더블클릭으로 좌우 클릭도 돼서 조작이 훨씬 더 편해졌다.

키보드로는 Space는 셀 개봉(좌클릭)이고, Shift+Space가 깃발(우클릭)이다.
그런데 이번엔 깃발이 꽂힌 것을 제외한 모든 인접 셀들을 한꺼번에 개봉하는 건 키보드로 어떻게 하는지 모르겠다. 게임에 익숙해지고 나면 셀 개봉은 하나씩 클릭하는 것보다 저렇게 개봉을 훨씬 더 즐겨 하게 되는데 말이다.

지뢰찾기라는 게임은 풀이 순서를 논리적으로 명확하게 유추 가능한 상황이 대부분이지만, 가끔은 주어진 정보만으로는 정확한 지뢰 배치를 알 수 없어서 찍기(guessing)를 해야 하는 경우도 있다. 지뢰가 정확하게 어떤 조건으로 배치되어 있을 때 그런 상황이 생기는지는 잘 모르겠다.

숫자 정보로부터 유추 가능한 지뢰 배치 가짓수는 기본적으로 폭발적으로 증가할 수 있으며, 어떻게 될 수 있는지 백트래킹으로 일일이 하나하나 때려박아 넣으며 추적을 하는 수밖에 없다. 뭔가 네모네모 로직을 푸는 것 같은 느낌이 들기도 한다. 이 때문인지 이 문제는 전산학적으로 봤을 때 NP 완전 문제라는 것까지 증명되었다.

그리고 찍기가 필요 없는 명확한 상황일 때 사람이 지뢰를 찾는 절차는 의외로 아주 명료하고 기계적이다.
딱 이 정도 영역이 개봉되고 인접 셀의 지뢰 정보가 이렇게 주어졌을 때, '명백한 해법' 하나만 동원해서라도 컴퓨터가 게임 진행을 충분히 도와 줄 수 있겠다는 생각이 들었다.

그래서, 막간을 이용해 지뢰찾기를 푸는 프로그램을 짜 봤다.
초-중급 수준의 간단한 클래스 설계와 알고리즘 구현이 동원되니 심심풀이 땅콩 코딩용으로 꽤 적절한 거 같다!
'명백한 해법'을 적용할 수 없어서 '찍기'를 해야 할 때, 지뢰가 있을 만한 위치를 가장 유력하게 유추하는 것 정도까지 구현해야 비로소 중급-고급 사이를 넘볼 수 있지 싶다.

대략의 코딩 내역은 이러하다.
지뢰 답을 알고 있는 MineSource 클래스(각 칸마다 지뢰 여부를 실제로 담고 있는 2차원 배열),
그리고 그 MineSource에다가 쿼리를 해 가며 1~8 숫자와 자기가 찾아낸 지뢰 위치 정보만을 알고 있는 MineSolver 클래스를 만들었다.
이들은 다 2차원 배열과 배열의 크기는 공통 정보로 갖고 있으므로 MapData라는 동일 기반 클래스를 설정했다.

MineSource는 특정 위치 x,y에 대한 쿼리가 온 경우, MineSolver에다가 인접 셀들의 지뢰 개수를 써 준다. 인접 셀에 지뢰가 하나도 없다면 여느 지뢰찾기 프로그램이 그러는 것처럼 인접 셀 8개도 한꺼번에 개봉하면서 flood fill을 한다.
곧바로 지뢰를 찍었다면 당연히 곧바로 게임 오버라고 알려 준다. 그리고 요즘 지뢰찾기 게임 구현체들이 그런 것처럼, 첫 턴에서는 절대로 지뢰를 찍는 일이 없게 내부 보정을 하는 것도 이 클래스에서 하는 일이다.

지뢰찾기의 '명백한 해법'은 딱 두 가지이다.

  1. 열리지 않은(지뢰 마크가 있는 놈 포함) 인접 셀의 개수와 자기 숫자가 '같은' 셀은 주변 미개봉 셀이 다 지뢰임이 100% 확실하므로 그것들을 전부 지뢰 마크(깃발)로 표시한다.
  2. 깃발이 꽂힌 주변 셀의 개수와 자기 숫자가 같은 셀의 경우, 지뢰 마크가 없는 나머지 열리지 않은 인접 셀은 지뢰가 아닌 게 100% 확실하다. 따라서 전부 개봉한다.
  3. (위의 명백한 해법만으로 개봉할 만한 셀이 존재하지 않는 건 운이 나쁜 케이스다. 패턴을 기반으로 랜덤 추측을 해야 하는데, 이건 일단 보류.)

텍스트 모드에서 자기 스스로 무작위하게 지뢰밭을 만들고 지뢰찾기를 풀기도 하는 자문자답 프로그램을 만드니, 200줄이 좀 안 되는 코드가 완성되었다.
이 프로그램은 인접 셀에 대해서 뭔가 조건을 만족하는 셀의 개수를 세거나, (getCount) 일괄적으로 동일한 조치를 취하는(doAction) 패턴이 많다.

이걸 그냥 for(j=y-1; j<=y+1; j++) for(i=x-1; i<=x+1; i++)이라는 2중 for문만으로 돌리기에는 i나 j가 boundary 밖인 경우도 고려해야 하고, (i,j)가 (x,y)와 같은 위치인 경우도 피해 가야 하기 때문에 loop 자체가 생각보다 복잡하다.
그러니, 그 loop 자체만 하나만 짜 놓고 loop 안에서 하는 일을 그때 그때 달리 지정하는 것은 템플릿-람다로 깔끔하게 설계했다.

다음은 프로그램의 간단한 실행 결과이다.

after the first turn:
+ + 1 . . . . . .
+ + 1 . 1 1 1 . .
+ + 1 . 1 + 2 1 .
+ + 1 . 1 2 + 1 .
1 1 1 . . 1 + 2 1
. . . . 1 1 + + +
. . . . 1 + + + +
. 1 1 2 2 + + + +
. 1 + + + + + + +

(중간 과정 생략)

picking 7 9
@ @ 1 . . . . . .
2 2 1 . 1 1 1 . .
1 1 1 . 1 @ 2 1 .
1 @ 1 . 1 2 @ 1 .
1 1 1 . . 1 2 2 1
. . . . 1 1 3 @ 2
. . . . 1 @ 3 @ 2
. 1 1 2 2 2 2 1 1
. 1 @ 2 @ 1 . . .
You Won!


이 정도 초보적인 지뢰 찾기 풀이 프로그램은 이미 다 개발되고도 남았으니,
유튜브를 뒤지면 신의 경지 수준의 속도를 자랑하는 지뢰찾기 TAS (매크로 프로그램 내지 역공학을 동원한 게임 스피드런) 동영상들이 나돌고 있다.

여담이다만, 지뢰찾기를 하다가 지뢰를 밟아서 게임 오버가 될 때 본인은 깜짝 깜짝 잘 놀란다. =_= 마치 옛날에 페르시아의 왕자를 하는데 타이밍을 잘못 잡아서 왕자가 쇠톱날(chopper)에 두 동강 나서 죽는 것 같은 그런 느낌이다.

Posted by 사무엘

2013/09/26 08:32 2013/09/26 08:32
, , , ,
Response
No Trackback , 4 Comments
RSS :
http://moogi.new21.org/tc/rss/response/881

세계의 국가(national anthem)들

한 나라의 상징으로는 깃발(국기), 꽃(국화) 등과 더불어 노래(국가)가 있다.
난 우리나라의 여러 상징들이 전반적으로 개성 있고 잘 만들어졌다고 생각한다. 고유 문자인 한글은 두 말할 나위도 없고, 소나무, 태권도, 무궁화 다 좋다. 국기인 태극기도 적당한 상징성과 복잡도로 잘 만들었다.

다만, 그런 것들에 비해 상대적으로 '덜' 좋아하는 상징은 국가인 애국가이다. 다소 밋밋한 가사, 그리고 시작 부분의 너무 어색한 박자 때문이다(갖춘마디에다가 못갖춘마디 스타일의 박자를 얹음). 뭐, 덜 좋아한다는 거지, 아주 싫다는 뜻은 아니지만.

1. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라 만세
2. 남산 위의 저 소나무 철갑을 두른 듯 바람 서리 불변함은 우리 기상일세
3. 가을 하늘 공활한데 높고 구름 없이 밝은 달은 우리 가슴 일편단심일세
4. 이 기상과 이 맘으로 충성을 다하여 괴로우나 즐거우나 나라 사랑하세

후렴) 무궁화 삼천리 화려강산 대한 사람 대한으로 길이 보전하세


난 개인적으로 1절과 4절은 모두 외우고 있고, 2절과 3절은 첫 단의 가사만 기억하고 있었다. 군대 훈련소에 있던 동안은 각 절을 매일 돌아가면서라도 훈련병들에게 애국가 가사를 4절까지 다 외우게 했던 것 같다.

그럼, 대한민국 말고 다른 나라들의 국가는 어떨까?
내가 멜로디를 완전히 알고 있는 외국 국가로는 미국, 중국, 영국, 독일, 그리고 북한이 있다.
교회 다니시는 분들은 영국과 독일의 국가 멜로디는 이미 자동으로 숙지하고 계실 것이다. 찬송가에 동일 멜로디의 찬양이 수록돼 있기 때문이다. <피난처 있으니>와 <시온 성과 같은 교회>.
하긴, 우리나라에서도 한때는 <천부여 의지 없어서>(혹은 작별의 노래) 멜로디에다가 애국가 가사를 끼워서 부른 적이 있었다.

중국의 국가는 영락없는 행진곡 군가 스타일이어서 호전적이고 씩씩한 느낌이다.
중국 국가는 '칠라이'(일어나라), '치안찐'(전진) 같은 단어가 반복해서 들린다. "앞으로 용진 또 용진" 이러는 우리나라 <육군가>와 비슷한 느낌을 준다. 가사의 주제는 "자, 노예로 살기 원치 않는 인민들이여, 함께 일어나 적들을 무찌르고 새 세상을 건설하자. 빠샤!" 정도?

노래를 부를 때는 성조를 전혀 표현할 수가 없어진다. 그럼 중국어를 알아듣는 데 어려움이 생기지는 않나 모르겠는데, 하지만 의외로 문맥으로 별다른 어려움 없이 식별이 된다고 한다. 그런 식으로 따지자면 사실 한국어도 완전 말도 안 되는 모호성이 적지 않기도 하고 말이다(소년/소녀, 그년/그녀, 내/네 등).

미국의 국가는 가사가 전투 장면을 묘사하고 있지만 멜로디는 군가풍이 아니며 오히려 3박자 계통이다. 그리고 가사 중에 국기인 성조기에 대한 묘사가 있는 게 특징이다. "그 치열한 전장에서도 우리의 성조기는 당당히 펄럭이고 있었노라."
가사 끝부분에 나오는 "자유의 땅, 용사의 고향"이라는 표현은 아메리카 대륙에 대한 미국인들의 자부심을 짐작케 한다.

독일의 국가는 "도이칠란트 도이칠란트, 위버 알레스 위버 알레스 인 데르 벨트"(우리 독일이 세계 킹왕짱)라고 시작하는 첫부분이 인상적이다. 가사의 나머지 부분도 전투적인 요소는 별로 없이 그냥 자기 나라 찬가이다.

영국의 국가 <God Save the Queen>은 군주인 (여)왕에 대한 축복송이라고 생각하면 되겠다. 찬송가뿐만 아니라 Noteworthy Composer 악보 프로그램에도 예제 데이터로 곡이 통째로 실려 있다.

다음으로, 북한의 국가는 제목이 남한과 동일한 <애국가>이다. 김씨 부자에 대한 우상화가 지금처럼 극심해지기 전에 미리 만들어져서 그런지 노래 자체는 의외로 전투적이거나 위수김동을 전파하는 내용이 없다. 그냥 평범한 조국 찬가 스타일이고, 어찌 보면 남한의 애국가보다 퀄리티가 더 좋게 느껴질 수도 있다.
하지만 실질적으로 북한 내부에서 주요 행사 때는 애국가보다 별도의 장군님 찬가를 더 즐겨 부른다고 하니 '역시나'이다. 북한 애국가에 대한 자세한 묘사는 국가보안법에 걸릴 수 있으니 더는 하지 않겠다.

이스라엘의 국가는 역시 이스라엘 아니랄까봐, 국가가 웬 단조라는 것 정도만 기억한다. (찬송가 중에 <여호와 하나님>이 이스라엘 민요풍의 단조)

끝으로, 일본의 국가는 <기미가요>인데.. 지극히 일본스럽다. 일본 사람이 자기 내면을 잘 표현하지 않고 말을 모호하게 하는 걸 즐기고, 헌법조차 덴노의 정체성에 대해서 아주 모호한 문장으로 시작하듯...
국가도 마찬가지다. "임의 대(代)는 1000대까지.. 8000대째에 작은 조약돌이 바위가 되어 이끼가 낄 때까지.."라는 너무나 짧고 의미도 밍숭생숭하기 그지없는 가사이다. 세계에서 가장 짧은 국가라나? 멜로디의 음계 또한 전통적인 서양 음악 스타일을 떠올렸다가는 놀라게 된다.

모든 일본인들이 이런 기미가요를 국가로서 좋아하는 것 역시 아니라고 한다. 똑같은 군주 찬가여도 대놓고 신을 거론하며 마음껏 복을 비는 영국 국가하고는 스타일이 너무 다르다.
가사 내용에 대해 또 딴지를 걸자면, 돌멩이는 무슨 눈덩이나 흙덩이도 아닌데, 긴 세월이 흐르면 커지기보다는 닳고 쪼개지지 않나 싶기도 하다.

기미가요는 가사 자체는 너무 추상적이다 보니 별로 문제될 게 없으나, 역시 일제 군국주의와 함께 강제로 보급되고 퍼진 이력이 있다 보니, 한국처럼 일제의 피식민지 경험이 있는 국가에서는 좋은 평판을 못 받고 있는 노래이다.

다른 나라들은 그렇다 치고 한중일 CJK만 살펴보더라도, 국가가 삼국이 서로 극과 극으로 다름을 알 수 있다.
세계의 국가들을 군가/전투형, 군주 찬가형, 국가 찬가형 등으로 분류할 수도 있을 것 같다.

Posted by 사무엘

2013/09/23 08:25 2013/09/23 08:25
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/880

간단한 인트린직 이야기

요즘 컴파일러에는 인트린직(intrinsic)이라고 정의된 내장 함수들의 집합이 있다. 그래서 그런 함수를 호출한 것은 실제 함수 호출이 아니라 특정 기계어 코드로 곧장 치환된다. 함수의 몸체가 직접 삽입된다는 점에서는 함수 인라이닝과 비슷하지만, 인트린직은 그 몸체가 컴파일러에 의해 내장되어 있으니 개념과 용도가 그것과는 살짝 다르다.

인트린직은 굳이 인라인 어셈블리 같은 거창한 문법 없이 간단한 C 함수 호출 스타일로 특정 기계어 인스트럭션을 곧장 집어넣거나 컴파일러의 확장 기능을 사용하기 위한 목적이 강하다. #pragma가 특수한 의미를 지닌 지시를 내리기만 하는 전처리기로 비실행문이라면, 인트린직은 실행문이다.

또한, 기존의 표준 C 함수가 인트린직 형태로 몰래 처리되기도 한다. memset, strcpy처럼 간단한 메모리 조작은 컴파일러가 아예 직통 대입 코드를 집어넣는 식으로 최적화를 하기도 하며, 각종 수학 함수들도 FPU 명령 하나로 곧장 치환되는 게 보통이다. 가령 제곱근을 구하는 sqrt함수는 곧바로 fsqrt 인스트럭션으로 말이다.

C 라이브러리 DLL인 msvcr*.dll은 여전히 수학 함수 심벌들을 제공한다. 그러나 요즘 컴파일러가 수학 연산을 인트린직 대신 일일이 그런 함수 호출 형태로 곧이곧대로 사용하는 경우란, 수학 함수들을 함수 포인터 형태로 접근해야 할 때밖에 없다.

비주얼 C++이 제공하는 여러 인트린직 함수 중에는 '일을 하지 않음'(no operation)을 의미하는 __noop이라는 함수가 있다. x86의 nop 인스트럭션(코드 바이트 0x90)과 비슷한 발상인데, nop를 생성하기라도 하는 것도 아니다. 컴파일러는 파싱만 해 주지 코드 생성은 안 하고 넘긴다. 파이썬으로 치면 pass와 비슷한 물건이다.

파이썬은 세미콜론 같은 구분자도 없고 공백 들여쓰기가 유효한 의미를 갖기 때문에 empty statement를 표현하려면 pass 같은 별도의 문법이 반드시 필요하다. 그러나 C/C++은 ; 하나만 찍어 줌으로써 empty statement쯤이야 얼마든지 만들 수 있는데 굳이 저런 잉여로운 인트린직은 왜 필요한 걸까?

__noop의 주 용도는, 가변 인자를 받는 디버그 로그를 찍는 함수의 컴파일 여부를 제어하는 것이다.

#ifdef _DEBUG
    #define WRITE_LOG   WriteLog
#else
    #define WRITE_LOG   __noop
#endif

WRITE_LOG("Start operation");
WRITE_LOG("Operation ended with code %d", nErrorCode);

함수가 가변 인자가 아니라면, WRITE_LOG 자체를 매크로 상수가 아닌 매크로 함수로 선언하면 된다.

#ifdef _DEBUG
    #define WRITE_LOG1(msg,a1)  WriteLog(msg,a1)
#else
    #define WRITE_LOG1(msg,a1)  0
#endif

이렇게 해 주면 디버그가 아닌 릴리즈 빌드에서는 WriteLog가 호출되지 않을 뿐더러, 매개변수들의 값 평가도 전혀 발생하지 않게 된다.
그러나 매크로 함수는 가변 인자를 받을 수 없기 때문에 임의의 개수의 인자를 모두 커버하려면 결국 함수 이름 자체만 치환하는 매크로 상수를 써야 한다. 매크로 상수는 함수의 호출만 없앨 수 있지 함수로 전달되는 매개변수들의 값 평가를 없앨 수는 없다. 뭐, 상수들의 나열이야 컴파일러의 최적화 과정에서 제거되겠지만 side effect가 남는 함수 호출은 어떡하고 말이다.

이런 이유로 인해 가변인자를 받는 디버그 함수를 제어하는 매크로는 범용적인 버전뿐만 아니라 매개변수 고정 버전도 같이 딸려 나오는 게 관행이었다. 대표적인 게 MFC의 TRACE 매크로이다. TRACE0~TRACE3도 있다. 한번 함수를 호출할 때 전달되는 매개변수의 개수가 런타임 때 매번 바뀌는 것도 아니니, 가능하면 고정 버전을 쓰는 게 프로그래밍 언어의 관점에서 더 안전했기 때문이다.

그런데 비주얼 C++의 __noop은, 하는 일은 없으면서 0개부터 n개까지 아무 개수로 그 어떤 type의 인자를 넘겨줘도 되는 훌륭한 페이크 함수이다. 그래서 매크로 상수를 이용해서 그 어떤 함수도 __noop로 치환하면 그 함수의 호출은 깔끔하게 무시되고 코드가 생성되지 않는다.

게다가 코드는 생성되지 않지만 컴파일러가 각 토큰에 대한 구문 분석은 해 준다는 점에서 __noop은 매크로 상수뿐만 아니라 매크로 함수보다도 더 우월하다.
WRITE_LOG1에다가 아예 얼토당토 않은 선언되지 않은 변수를 집어넣을 경우, 이것을 그냥 0으로만 치환해 버리는 코드는 디버그 버전에서만 에러가 발생하고 릴리즈 버전은 그냥 넘어간다.

그러나 __noop으로 치환하면 효과는 0 치환과 동일하면서 릴리즈 버전에서도 컴파일 에러가 뜬다. 그러니 더욱 좋다.
이 인트린직은 #pragma once만큼이나, 그야말로 기존 C/C++ 문법만으로는 뭔가 2% 부족한 면모가 있는 걸 채워 준 물건이 아닐 수 없다. 컴파일러 개발사들이 괜히 비표준 꼼수를 집어넣는 게 아니다. 그 꼼수가 정말 타당하다고 여겨지면 다음 표준 때 정식으로 반영까지 될 테고.

아무 일도 안 하는 null instruction은 코드 바이트도 0으로 하는 게 직관적이지 않나 싶은데..
아까도 얘기했듯이 x86은 의도적으로 쉽게 떠오르지 않는 값에다 그 명령을 할당했다.
크기 최적화를 하지 않고 프로그램을 빌드하는 경우(디버그 또는 속도 최적화), 비주얼 C++은 machine word align을 맞추거나 edit and continue용 공간을 확보해 두기 위해 코드 바이트를 약간 듬성듬성하게 배치하는데, 과거의 6.0은 그 빈 틈에 nop(0x90)를 집어넣었다.

그러나 언제부턴가 닷넷부터는 그 버퍼 코드가 int 3(0xCC)으로 바뀌었다.
정상적인 경우라면 거기는 도달해서는 안 되는 곳인데, 그냥 아무 일 없이 nop로 넘어가는 게 아니라 breakpoint가 걸리게 보안을 강화한 게 아닌가 싶다.

말이 나왔으니 말인데, int 3을 집어넣어 주는 인트린직도 응당 존재한다. 바로 __debugbreak 함수이다. 이건 사실 Windows API에도 DebugBreak()로 있기도 하고 말이다.
이걸 쓰면 비주얼 C++ IDE에서 F9를 누른 것과 동일한 효과를 낼 수 있다. 디버거를 붙여서 실행할 경우, 그 지점에서 프로그램의 실행이 멈춘다.

Posted by 사무엘

2013/09/20 08:30 2013/09/20 08:30
, , , ,
Response
No Trackback , 2 Comments
RSS :
http://moogi.new21.org/tc/rss/response/879

지금으로부터 수십 년 전에는 동네마다 컴퓨터 학원이 있었고, 꼬꼬마가 프로그래밍을 공부하겠다고 하면 으레 GWBASIC부터 시작하곤 했다. 베이직은 16비트 MS-DOS뿐만 아니라 각종 가정용 8비트 컴퓨터에도 특유의 인터프리터 환경이 내장되어 있기도 해서 접하기가 한결 쉬웠다.

그때와는 달리 오늘날의 컴퓨터 교육은 이미 만들어진 소프트웨어들을 활용만 하는 실무에만 치우친 편이다.
지금 컴퓨터 프로그래밍을 처음부터 공부하고 싶다면 무엇부터 시작하는 게 좋을까?
이 질문에 대한 답변은 그 사람이 무슨 프로그램을 작성하고 컴퓨터로 무엇을 하고 싶은지 목적에 따라 크게 달라진다.
이 글은 나의 지극히 좁은 편견만을 반영하고 있으므로, 당연히 프로그래머마다 생각이나 견해가 다를 수 있다.

1. 비전문가/비전공자로서 그냥 최소한의 시간 투자로 개인적인 컴퓨터 활용도만 높이고 싶다면(고급 계산기 + 기초 알고리즘 실습 + 파일 자동 조작 + 매크로/자동화 도구 등)

개인적으로 파이썬을 추천한다. 복잡한 자료형을 다루기가 쉬워서 여타 언어들에 비해 짧은 코드만으로 복잡한 일을 한번에 끝낼 수 있다. 방대한 크기의 파일을 읽어서 내가 원하는 처리를 한 뒤 출력을 뱉어내는 수십 줄 남짓한 프로그램만 짤 줄 알아도 인생이 굉장히 편해질 수 있다.
좀 수학 덕후 기질이 있다면, 함수형 프로그래밍 언어를 건드려 봐도 될 듯.

2. 1보다는 좀 더 나아가서 가성비가 뛰어난 개발 환경에서 최소한의 GUI까지라도 만들어 보고 싶으면

Windows 플랫폼 한정으로 C#급 언어가 가장 좋겠다.

3. 웹브라우저에서 어지간한 애니메이션이나 프레젠테이션을 다 띄우고, 글이나 그림을 계산 결과로서 출력하고 싶으면

HTML + 자바스크립트.
요즘은 HTML이 단순히 화면에 뿌려지는 글과 그림, 하이퍼텍스트 문서일 뿐이라고 생각하는 건 큰 오산이다.
문서에다 서식을 주는 건 이제 CSS라는 방대한 별도의 규격으로 독립해 나가고, HTML은 문서 반 코드 반이다. 실시간으로 내용이 업데이트되고 화면 끝까지 스크롤됐을 때 추가로 컨텐츠를 로딩하고.. 사용자의 조작에 반응하여 그림을 뿌려 주는 등, 예전에는 ActiveX나 하다못해 플래시라도 써야 했을 컨텐츠들이 지금은 저것만으로 다 된다.

웹브라우저가 거의 플랫폼 독립적인 프로그램 구동 플랫폼처럼 바뀌었으니, 이를 활용할 줄 알면 역시 컴퓨터 활용 능력이 크게 향상될 수 있다. 웹 프로그램은 다른 언어나 런타임, IDE 같은 걸 설치할 필요조차 없이, 그냥 메모장에서 코딩 후 웹브라우저에서 곧바로 돌려보면 된다.

4. 맥 OS용 응용 프로그램이나 아이폰 앱을 개발하고 싶다면

Objective C + xcode + COCOA API 등등으로 고고씽이다. 일단 맥북을 장만해야 할 것이고 Windows와는 너무 이질적인 개발 환경 때문에 처음에 고생 많이 할 것이다.

5. 안드로이드 스마트폰용 앱을 개발하고 싶다면

자바 + 이클립스 IDE에 익숙해져야 할 것이다. Java는 요즘 스마트폰 앱 개발용 언어로 입지가 확 되살아난 듯하다. 이게 완전한 웹용 언어도 아니고(자바스크립트는 자바와 전혀 다른 언어임), 자바 애플릿이 플래시/ActiveX를 완전히 대체하는 RIA (rich internet application) 프레임워크로 자리잡은 것도 아니고, 로컬에서는 느리고 성능이 안 좋다 보니 전통적인 기계어 프로그램들에 밀려서.. 예전까지는 위상이 좀 어정쩡했기 때문이다. 로컬에서는 일부 크로스플랫폼 소프트웨어의 GUI(프런트 엔드)를 돌릴 때나 좀 쓰이곤 했다.

6. 끝으로, PC + Windows 환경에서 네이티브 코드 + standalone으로 실행되는 프로그램을 개발하고 싶다면

아래아한글이나 <날개셋> 한글 입력기나 어지간한 온라인 게임과 같은 급의 기계어 실행 파일을 만들고 싶다면..
역시나 재래식 Visual C++이나 최소한 델파이 같은 툴로 가야 한다.
개발 환경, 언어 문법과 기본 라이브러리, Windows API, 그 뒤 개발 분야에 따라 추가적인 라이브러리 공부까지 산 넘어 산이다.

오늘날 프로그램 개발 환경이 결국 로컬 + 웹 + 앱이라는 세 양상으로 구분된다고 예전에 글을 쓴 적이 있는데.. 그것과도 관계가 있다.
프로그래밍, 더 나아가 소프트웨어 개발에 관심이 있는 분이라면 이런 아이템들을 참고하면 되겠다.
그런데 정작 이런 글을 쓴 본인은 6만 빼고 나머지 분야는 여전히 너무 모른다는 게 함정..ㅎㅎ

Posted by 사무엘

2013/09/17 08:37 2013/09/17 08:37
,
Response
No Trackback , 13 Comments
RSS :
http://moogi.new21.org/tc/rss/response/878

올림픽 잡설

* 스포츠는 내가 극도로 관심이 없는 분야 중 하나이다만..

1. 잘 알다시피.. 2020년 하계 올림픽의 개최지로 일본 도쿄가 선정되었다.
전쟁 범죄를 전혀 반성하지 않은 나라, 더구나 방사선 유출 사고까지 친 나라가 어째 올림픽을 또 유치해 냈는지에 대해 의아해하는 분이 적지 않다만, 아무튼 이로써 일본은 1964년 이래로 거의 반세기 만에 올림픽을 동일 도시에서 또 하게 됐다.
일본은 1988년 올림픽에서 나고야에서 올림픽을 유치하려 했으나, 잘 알다시피 52:27의 표로 우리나라 서울에 패했던 적이 있다. 이른바 바덴바덴의 기적이다.

2. 그 전까지 역사상 올림픽을 두 번 개최한 동일 도시는 그리스 아테네(1896/2004)와 프랑스 파리(1900/1924)가 있고, 세 번은 런던(1908/1948/2012)뿐이었다.
미국은 올림픽을 네 번이나 개최한 유일한 국가이지만, 전부 다 다른 지역이다(1904/1932/1984/1996).
독일은 두 번 개최하긴 했으나, 나치 독일-베를린(1936), 그리고 서독-뮌헨(1972)이어서 둘의 위상이 서로 미묘하게 다르다.
그리고 오스트레일리아도 다른 지역에서 두 번 개최한 나라이다(1956/2000).

3. 사실, 일본은 2차 세계대전이 아니었으면 20년 전인 아예 1944년에 올림픽 개최가 예정되었을 선진국이었다. 그로부터 20년 뒤, 일본은 1964년 도쿄 올림픽의 개최에 맞춰 세계 최초로 상용 최대 속도가 시속 200km를 넘는 신칸센 철도를 개통했었다. 신칸센은 표준궤일 뿐만 아니라 같은 표준궤 철도 중에서도 열차의 폭이 한국이나 유럽의 철도 차량보다 수십cm가량 더 넓게 설계되었다. 그래서 한 줄에 2-2뿐만 아니라 2-3 좌석 배치도 있다. 협궤 철도의 한계에 이골이 난 걸까.

전쟁은 일본의 올림픽 개통뿐만 아니라 지하철의 개통까지도 늦췄다.
일본은 아시아에서 최초로 긴자 선이라 불리는 도쿄 지하철을 1927년에 개통했었다.
그러나 그 다음 노선인 마루노우치 선은 그로부터 또 무려 27년이나 지난 1954년에야 개통할 수 있었다.
전쟁 때문에 물자가 부족하니, 신규 철도 건설은 고사하고 이미 있는 철도 선로도 뜯어가야 할 판이었기 때문이다.

4. 2020년 이전에 일단 요 몇 년간은 남아메리카 브라질이 꽤 주목을 받을 것 같다.
2014년 FIFA 월드컵도 브라질, 2016년 올림픽도 브라질(리우데자네이루)이기 때문이다. 특히 올림픽의 경우 역사상 최초의 남아메리카 개최이다.
월드컵은 매 경기가 서로 다른 지역의 다양한 경기장에서 개최되기 때문에, 올림픽과는 달리 개최국만 지정하지 도시 이름까지 하나로 콕 지명되지는 않는다.

5. 끝으로, 축구 얘기를 좀 한 후 글을 맺겠다.
지금이야 우리나라는 홈그라운드에서 무려 4강에까지 진출한 적이 있고 얼마 전엔 원정 16강까지도 진출한 축구 강국이다. 그러나, 대한민국 축구의 시작은 심히 미약했다는 걸 알 만한 분들은 다 알 것이다.

광복 후 최초 참가였던 1948년 런던 올림픽에서는 1라운드에서 멕시코를 5:3으로 이겼으나, 2라운드에서 우리나라는 스웨덴에게는 무려 12:0으로 패해서 올림픽 역사상 최다 실점이라는 기록을 갖고 있다.
1954년에 첫 참가한 FIFA 월드컵도 마찬가지다. 그 당시 월드컵은 스위스에서 열렸는데, 헝가리에게 9:0, 터키에게 7:0으로 졌다. 월드컵에서 9점차라는 실점 규모는 역사상 공동 1위이다.

물론 이건 부끄러워할 기록이 전혀 될 수 없다. 해방 직후에, 또 전쟁으로 전국토가 폐허가 된 직후에, 국제 스포츠 경기 참가를 위해 나라가 해 줄 수 있는 게 없다시피하던 시절이었다. 1948년 런던 올림픽 참가의 경우, 선수들은 먼저 부산까지 열차를 타고 간 뒤 일본을 거쳐서 각종 배와 경비행기를 갈아타면서 런던까지 가는 데만 무려 3주가 걸렸었다! 배 타고 갑판 위에서 축구 연습을 했다면 믿으시겠는가?

의류비(단복, 운동복 등)나 숙소 체류 비용조차 제대로 못 내서 완전 추레한 촌티를 팍팍 낸 채, 이들은 도착 직후에 시차 적응도 못 한 채 경기를 뛰어야 했다. 사정없이 쏟아지는 공격에 골키퍼는 상처투성이가 되는 투혼을 발휘하면서 온몸으로 공을 막아 냈다. 오히려 12:0으로, 9:0으로밖에 지지 않은 게 대단하다고 외신들이 골키퍼를 칭찬할 정도였으니... 눈물젖은 빵+헝그리 정신의 결정체가 아닐 수 없다.
스포츠도 나라가 부강하고 잘 살아야 제대로 육성이 가능하다는 걸 느낀다.

Posted by 사무엘

2013/09/15 08:30 2013/09/15 08:30
, ,
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/877

1. 클립보드 개론

과거에 Windows 3.x 시절에는 '클립보드 표시기'(clipbrd.exe)라는 프로그램이 있었다. 95/98 시절에도 있다가(16비트 바이너리 형태 그대로) 운영체제가 NT 계열로 바뀌면서 완전히 역사 속으로 사라진 듯하다.
그러나 지금도 그런 부류의 액세서리 프로그램이 있으면 좋겠다는 생각을 개인적으로 가끔은 한다. 번거롭게 여타 프로그램을 띄워서 '붙이기' 명령을 내리지 않고도 클립보드에 지금 무엇이 들어있는지를 확인할 수 있기 때문이다.

사실, 제3자가 개발한 클립보드 표시/관리 유틸리티는 당연히 존재한다. 이런 프로그램은 단순히 클립보드 표시 기능뿐만 아니라 클립보드 내용을 파일로 저장하거나 불러올 수도 있고, 지금 MS Office 프로그램들이 그러는 것처럼 여러 개의 클립보드 데이터를 관리하는 기능도 있어서 잘만 활용하면 대단히 편리하다.

기술적으로 봤을 때 클립보드는 여러 프로그램들이 한데 공유할 수 있는 메모리 핸들의 집합이다.
0과 1의 나열일 뿐인 데이터가 텍스트인지 이미지인지 포맷을 식별하는 정수값이 있고, 그 포맷 식별자와 메모리 핸들이 한데 대응하여 튜플을 이룬다.

클립보드에는 여러 종류의 데이터가 동시에 공존할 수 있다. 그래서 워드 프로세서라면 자신만의 고유한 포맷을 등록해서 자신이 만든 모든 정보가 완전히 보존되어 있는 데이터를 놔 둬야겠지만(예를 들어, 이 데이터가 일반 블록이 아니라 칼럼 블록이라는 표시도..), 같은 데이터에 대해서 메모장 같은 프로그램에서도 최소한 텍스트라도 붙여 넣을 수 있게 표준 텍스트 포맷으로도 데이터를 보관해 줘야 한다.

클립보드로부터 데이터를 가져오거나, 거기에다 내 데이터를 저장하려면 먼저 OpenClipbaord 함수를 호출해서 클립보드를 열면 된다. 이 함수가 왜 윈도우 핸들(HWND)을 인자로 받는지는 잘 모르겠다. 클립보드의 사용이 끝난 뒤엔 CloseClipboard를 하면 된다.

클립보드 API는 한 순간에 시스템 전체를 통틀어 단 한 프로그램/스레드만 클립보드에 접근하는 걸 가정하고 만들어졌다. 그래서 딱히 OpenClipboard 함수가 무슨 다른 핸들 같은 걸 되돌리지는 않는다.

2. 클립보드를 위한 메모리 할당 함수

클립보드에다 데이터를 지정하거나 가져오는 건 Set/GetClipboardData 함수로 하면 된다. 이때 주고받는 핸들은 GlobalAlloc 함수를 이용하여 특수하게 할당된 메모리이다.
클립보드 API는 구시대 16비트 Windows 시절의 디자인을 그대로 답습하고 있는 게 많다. 클립보드는 지금 같은 memory mapped file이나 가상 메모리 같은 게 없던 시절부터 존재했다. 그때는 운영체제에 global heap과 local heap이라는 두 종류의 메모리가 존재했고, 클립보드는 응당 global heap의 영역에 존재했다.

운영체제의 heap 함수는 고정된 메모리 주소에다 공간을 바로 할당시킬 수도 있고, 할당은 하되 당장 그 메모리를 사용하지 않을 경우 실제 위치를 운영체제가 재량껏 재배치도 하다가 응용 프로그램이 실제로 잠깐 사용을 할 때만 메모리를 고정시키는 '유동적인' 방식으로 할당할 수도 있다.

메모리를 사용하는 프로그래머의 입장에서는 무척 번거로운 일이지만, 당장 사용하지 않는 메모리를 운영체제가 필요에 따라 재배치 가능하게 할당해 놓으면, 아무래도 PC의 절대적인 메모리 공간이 충분치 않을 때 메모리의 단편화를 예방할 수 있어서 효율적이다. API 자체가 그렇게 헝그리 정신과 상호 협력 이념을 염두에 두고 설계돼 있다는 뜻이다.

GlobalAlloc 함수에는 메모리를 할당할 때 클립보드/OLE 공유가 가능하게 하는 GMEM_DDESHARE 같은 여러 플래그를 줄 수 있다. 이게 어찌 보면 16비트 시절의 VirtualAlloc 함수 같기도 하다. 하지만 32비트로 오면서 GlobalAlloc 함수의 잡다한 플래그들은 다 legacy 잉여로 전락했고, 메모리를 유동적으로 할당할지/고정적으로 할당할지, 그리고 할당된 메모리를 0으로 초기화도 할지를 설정하는 플래그만이 현재 유효하다.

이 함수는 이제 클립보드 복사나 OLE drag & drop 기능을 구현할 때밖에 쓸 일이 없다. 아니면 아주 특수한 상황에서 프로세스의 기본 heap에 의존하지 않고 메모리를 할당할 일이 있을 때나 쓰든가.
32비트 이후부터는 global heap과 local heap의 구분도 없고, 또 이 함수로 개당 몇십 바이트짜리 연결 리스트의 노드를 일일이 저장한다거나 하는 건 바보짓이다.

3. 클립보드 표시기 만들기

일반적으로는 클립보드에 접근해서 데이터를 읽고 쓰고, 클립보드를 비우는 것만 알면 된다.
그것보다 조금 더 고급으로 나가면 나만의 클립보드 포맷을 등록하고 다양한 클립보드 포맷을 조회하는 조작까지 필요해진다.
그 다음으로 클립보드와 관련된 가장 복잡한 조작은 바로, 클립보드 내용이 바뀌었을 때 통지를 실시간으로 받겠다고 운영체제에다 요청하고 실제로 그런 일이 일어났을 때 각종 뒷처리를 하는 일이다.

이렇게 클립보드의 변경 내역을 통지받는 프로그램을 개념적으로 '클립보드 표시기(viewer)'라고 부른다. 모든 프로그램들이 사용자가 누르는 Ctrl+C/X에 관심이 있는 게 아니니, 클립보드 변경 내역은 특별히 요청을 한 프로그램에게만 알려 주는 것이다. 통지가 오는 형태는 메시지이기 때문에, 클립보드 표시기는 응당 윈도우를 생성하고 메시지 loop을 돌고 있어야 한다.

자신(윈도우)을 클립보드 표시기로 등록하려면, WM_CREATE나 WM_INITDIALOG 같은 초기화 메시지에서 SetClipboardViewer 함수를 호출하여 자신의 핸들값을 전달하면 된다.
그러면 그 뒤부터는 어떤 프로그램에서든 클립보드의 내용을 건드린 뒤 CloseClipboard 함수를 호출해 주면, 내 창으로 WM_DRAWCLIPBOARD 메시지가 날아온다. 그럼 내 프로그램은 그때 클립보드 내용을 들여다보면서 적절한 출력을 해 주면 된다.

그런데 문제는 이게 전부가 아니라는 것이다.
클립보드 표시기 API는 엄청난 구시대 스타일로 굉장히 구리게 설계되어 있다. Windows API를 통틀어서 이 정도로 지저분한 물건은 흔치 않을 것 같다.

클립보드 변경 통지 요청을 한 윈도우는 우리 프로그램뿐만이 아니라 여러 개가 동시에 있을 수 있다. 그러니 운영체제는 그 윈도우들의 목록을 내부적으로 관리해야겠지만, 각각의 윈도우의 입장에서야 나 말고 다른 윈도우가 무엇이 있든 말든, 나만 통지를 곱게 받고 끝이어야 정상일 것이다.
그런데 클립보드 표시기 관련 API들은 그렇지 않다. 클립보드 표시기로 등록된 창들은 일종의 단방향 연결 리스트의 형태로 관리되는데, 운영체제는 그 리스트의 head 노드만을 갖고 있다. 그 뒤 나의 다음으로는 무슨 창이 있는지 관리를 해당 응용 프로그램이 직접 해야만 한다.. -_-;;;

SetClipboardViewer 함수는 인자로 받은 윈도우를 연결 리스트의 맨 앞 head 노드로 등록한 뒤, 예전에 head였던 윈도우 핸들을 되돌린다. 우리는 그 값을 반드시 따로 보관해 둬야 한다.

hwndNextCBViewer = SetClipboardViewer(hMyWindow);

그리고 내가 WM_DRAWCLIPBOARD 메시지를 받았다면, 우리는 자체 처리를 마친 뒤에 그 메시지를 저 창에다가 수동으로 전해 줘야 한다.

if(hwndNextCBViewer) SendMessage(hwndNextCBViewer, uMsg, wParam, lParam);
(uMsg는 어차피 WM_DRAWCLIPBOARD이고, wParam과 lParam은 쓰이지 않기 때문에 값이 모두 0임)

메시지를 DefWindowProc로 넘긴다 해도 이 일을 운영체제가 알아서 해 주지 않는다. 우리가 저렇게 메시지를 안 보내 주면 다음 클립보드 표시기들은 클립보드의 변경 내역을 전달받지 못하게 되어 동작이 죄다 꼬이고 만다!

내가 제어를 운영체제로 신속하게 돌려 주지 않으면 운영체제 전체를 다운시킬 수 있던 협력형 멀티태스킹의 암울한 냄새가 물씬 풍긴다.
훅 프로시저는 CallNextHookEx를 반드시 호출해 줘야 하는 것과 같은 스타일이기도 하고 말이다.

내 윈도우가 없어질 때(WM_DESTROY) 클립보드 표시기 지정 해제도 당연히 수동으로 해야 하는데, 이때 사용하는 함수는 ChangeClipboardChain이다. 얘에다가 내 윈도우뿐만 아니라 처음에 SetClipboardViewer의 리턴값으로 받았던 나의 다음 노드 윈도우도 같이 전해 줘야 한다. 마치 옛날에 C++에서 소멸자 함수가 존재하는 객체들의 동적 배열을 delete []연산자로 해제할 때, 배열 원소의 개수를 수동으로 전해 줘야 했던 것만큼이나 번거롭다.

ChangeClipboardChain(hMyWindow, hwndNextCBViewer);

그러면 운영체제는 자신이 내부적으로 갖고 있는 연결 리스트의 head 노드에 속하는 윈도우에다 WM_CHANGECBCHAIN 메시지를 보낸다. wParam에는 해제되는 윈도우, lParam에는 그 해제되는 윈도우의 다음 노드 윈도우가 들어있다.

클립보드 표시기 윈도우는 이 메시지도 살펴봐서 만약 내가 갖고 있는 '다음 노드' 값이 등록 해제되는 윈도우(wParam - hwRemove)라면, 나의 '다음 노드' 값을 등록 해제되는 윈도우의 다음 윈도우(lParam - hwNext)로 업데이트하면 된다. 물론, 나 자신이 등록 해제되고 있다면 저런 메시지 따위는 오지 않고 말이다. 아래의 소스 코드를 참고하라.

void On_WM_CHANGECBCHAIN(HWND hwRemove, HWND hwNext)
{
    if(hwndNextCBViewer==hwRemove) hwndNextCBViewer=hwNext;
    else if(hwndNextCBViewer) SendMessage(hwndNextCBViewer, uMsg, wParam, lParam);
}

hwRemove가 나의 다음 윈도우에 해당한다면 다음 윈도우를 그 다음 것으로 업데이트하고 처리를 종결한다.
그렇지 않으면 아까 WM_DRAWCLIPBOARD를 포워딩했던 것처럼 동일 메시지를 다음 윈도우로 전달해 준다.

연결 리스트에서 어떤 노드를 삭제하기 위해서는 그 노드의 이전 노드가 가리키는 다음 노드를 고쳐 줘야 한다. 그러나 클립보드 표시기 chain은 이전 노드 정보가 존재하는 이중 연결 리스트가 아니라, 오로지 '다음' 노드 정보만이 존재하는 단일 연결 리스트이다.
그렇기 때문에 임의의 노드를 삭제하려면 이전 노드를 파악하기 위해 리스트를 처음부터 다 조회해야 하고, 결과적으로 시간 복잡도 O(n)에 해당하는 절차가 필요해진 것이다. 그것도 운영체제가 알아서 처리해 주는 게 아니라 응용 프로그램들이 다 협조해 줘야 하는 번거로운 형태이고 말이다.

요컨대 클립보드의 내용을 실시간으로 업데이트하여 표시하는 프로그램이라면 최소한 나의 다음 윈도우 정보는 보관해야 하며, WM_DRAWCLIPBOARD와 WM_CHANGECBCHAIN 메시지를 정석대로 처리해 줘야 한다. 내가 프로그램을 잘못 짜면 다른 프로그램의 동작까지 망칠 수가 있으니 이건 운영체제의 보안 관점에서도 굉장히 안 좋은 디자인이다..

운영체제가 달랑 갖고 있는 클립보드 표시기 chain의 head 노드 윈도우를 되돌리는 GetClipboardViewer라는 함수도 있다. 얘는 가장 마지막으로 SetClipboardViewer함수를 호출한 윈도우의 핸들을 되돌리는 셈인데, 이 윈도우로부터 다음 윈도우를 알 수 있는 것도 아니고(다음 윈도우 핸들은 각 창마다 고유한 방식으로 저장하고 있을 테니), 이 함수는 사실상 아무짝에도 쓸모가 없다.

나 같으면, 표시기 윈도우 리스트의 관리를 운영체제가 전적으로 알아서 해 주고 WM_CHANGECBCHAIN 처리를 할 필요가 없는 새로운 SetClipboardViewerEx 함수라도 만들 것 같다. 새로운 응용 프로그램은 더 깔끔한 새로운 API를 쓰라고 말이다. 서브클래싱만 해도 더 깔끔하게 하라고 Windows XP부터는 종전의 SetWindowLongPtr을 대체할 SetWindowSubclass 같은 함수가 새로 추가되지 않았던가.

(* 2017. 7. 14 추가)
그렇게 생각했는데, 최신 MSDN을 우연히 뒤져 보니 역시나 AddClipboardFormatListener라고 내가 생각하는 것과 개념상 정확히 동일한 함수가 Windows Vista에서부터 추가됐구나. 저건 클립보드 내용이 변경될 때마다 내 윈도우로 통지 메시지가 오게 하는 함수로, 예전 같은 번거로운 chain 관리가 필요하지 않다. 등록이 아닌 제거는 Add 대신 Remove로 시작한다. 게다가 실제로 변경된 포맷이 무엇인지도 GetUpdatedClipboardFormats라는 함수로 알아올 수 있다.

이 새로운 listener에 등록되고 나면 클립보드가 변경되었을 때 WM_CLIPBOARDUPDATE라는 메시지가 날아온다. 안 그래도 1024개밖에 안 되는 시스템 메시지 영역은 부족해서 난리일 텐데.. WPARAM, LPARAM 아무 용도가 없는 새로운 메시지를 굳이 추가할 필요가 있나 싶은 생각이 든다. 기존의 WM_DRAWCLIPBOARD도 인자가 전혀 쓰이지 않으며, 메시지를 받는 클라이언트의 입장에서는 용도가 정확하게 동일할 텐데 말이다. 뭐 확실한 구분을 위해서 메시지도 따로 만든 것이지 싶다.
아울러, GetClipboardSequenceNumber라는 함수도 있다. 얘는 클립보드 내용이 변경될 때마다 1씩 증가하는 시퀀스 번호를 되돌리며, Vista가 아니라 2000 시절부터 존재해 온 물건이다.

이걸로도 모자라서 나만의 클립보드 포맷을 등록하여 그 내용을 화면에다 어떻게 표시할지까지 시시콜콜하게 다 지정하는 규격도 Windows API에 있긴 하다. 거기까지 가면 실생활에서 쓰이는 일은 정말 거의 없다시피한 잉여이다.

Posted by 사무엘

2013/09/12 08:29 2013/09/12 08:29
,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/876

우리나라의 전방 지역에 있는 PC방, 식당, 여관 같은 업소들이 군인들을만을 상대로 굉장한 바가지 요금을 받는 게 공공연한 관행이라니, 굉장히 충격이다.
이건 휴가철 때 해수욕장이나 유원지 민박들이 바가지 요금을 받는 것보다 죄질이 훨씬 더 나쁘다.

첫째는 민간인이 휴가를 떠나는 건 전적으로 당사자의 자발적인 선택과 의지인 반면 군복무는 그렇지 않기 때문이요,
둘째는 간부들은 그나마 위수지역이 넓은 편이고 승용차라도 있지, 병들은 꼼짝없이 그 지역에서 호구로 당할 수밖에 없기 때문이다.

정말 그 지역 상인들이 도저히 먹고 살기 힘들다면, 모든 고객을 대상으로 요금을 올리면 된다.
국가에 자기 인생을 희생하여 충성하는 군인에게 할인을 해 줘도 모자랄 판에(철도 같은 일부 공공요금은 실제로 그러함) 바가지라니, 이건 정말 군납비리만큼이나 국방부나 정부 차원에서 나서서 저런 부조리를 단호하게 근절해야 하지 않나 싶다.

수 년 전에 강원도 모 지역 모 부대에서 실제로 있었던 일이라고 한다.
바가지가 해도 해도 너무한 지경에 이르자, 사단장이 특단의 조치를 취했다. 휘하의 모든 병과 간부들에게 그 지역의 상점과 숙박시설을 절대로 이용하지 말고, 휴가와 복귀 시엔 간부들 차를 타고 군부대와 시외버스 터미널 사이를 직통으로 이동하도록 명령을 내렸다. 지역 상점들에 대한 보이콧을 선언한 것이다. 헌병들은 그 지역을 순찰하면서 다른 군기 위반자가 아니라 상점을 무단으로 이용하는 군인들을 적발했다.

이 일이 있고 나자 지역 경제가 다 망하게 된 상인들이 항복(?)해서 요금을 여타 지역 수준으로 내렸다나 어쨌다나.
씁쓸한 일이 아닐 수 없다.

돈과 관련된 사항만이 전부가 아니다.
다른 사례로는, 외박 나갔던 군인들이 위수지역에 있는 불량배 고등학생 패거리한테 심하게 맞고 다쳐서 돌아온 적이 있었다. (군인들은 민간인과 얽히면 법적으로 굉장히 골치아파지기 때문에 이런 일이 생기면 그냥 피하거나 순순히 당하는 수밖에 없다.)

그러자 이 꼴을 목격한 대대장이던가 사단장이 격분했다. “어떤 놈이 감히 내 부하들을 이 모양으로 만들었나? 당장 이실직고하지 못해?”라고 다그쳐서 진상을 파악하고, 5분 대기조까지 편성해서 결국 가해자들을 잡아내고 합의 내지 처벌시켰다.

시스템 클럽에 가 보면 지 만원 박사의 회고록에도 월남전 참전 중에 겪은 비슷한 일화가 수록돼 있으니 참고하시라.

“앞으로 C-레이션(미군 전투 식량)이 필요하면 내게 전화하라. 하지만 만일 내 병사에게 손을 또 한번 대면 그 때엔 주먹과 무력으로 다스릴 것이다.” 전쟁터에서 존중돼야 할 전투병들이 옷이나 깨끗히 다려 입고 지내는 헌병 따위에게 뺨을 맞고 다닌다는 건 참을 수 없는 일이었다. 까불던 헌병들이 그날 전투병들의 맛을 톡톡히 본 것이다. 그후 그 초소를 지나는 내 부대 차량들은 언제나 기분좋게 프리패스됐다.


자, 이런 것들이 바로 윗사람이 아랫사람을 챙겨 주고, 사기를 진작시키는 방법이다.
저런 지도자 밑에서라면 내 목숨 바쳐서 국가를 위해 싸울 수 있겠다고 병사들의 마음을 사는 방법이다!

훈련할 때, 굴릴 때는 정말 가혹하게 빡세게 굴리더라도 상벌을 확실하고 공정하게 주고, 진짜 위급한 전쟁터에서야말로 진정한 전투력과 전우애가 나오게 하고..
초병은 직속상사의 명령 외에 누구의 지시도 받지 않는다는 걸 윗사람들이 솔선수범해서 실천하고..

나라가 예산이 모자라서 병사들에게 월급을 알바 최저임금 수준만치도 못 준다면, 돈 안 드는 저런 리더십이라도 발휘할 수 있지 않겠는가?
최소한 “간부, 고참들부터 죽인 뒤에 북한군 쏘겠다” 이러는 병사는 국군내에 없어야 하지 않겠나 말이다.

Posted by 사무엘

2013/09/09 08:23 2013/09/09 08:23
Response
No Trackback , No Comment
RSS :
http://moogi.new21.org/tc/rss/response/875

1. 장폐단· 단폐단

한국 철도에서 운행 중인 특대형 디젤 기관차(정확히는 디젤 전기 기관차)는 앞부분이 잘 알다시피 이렇게 생겼다. (사진들의 출처: 위키미디어)

사용자 삽입 이미지

그런데 가끔은 앞부분이 이렇게 생긴 열차가 다니기도 한다.

사용자 삽입 이미지

이미 눈치 챈 독자도 계시겠지만, 이것은 새로운 다른 기관차가 아니라, 똑같은 기관차를 방향만 달리하여 배치한 것이다.
기관차의 뒷부분이 전방을 향하게 하고, 기관차의 원래의 앞부분을 후방으로 배치하여 객차를 연결한 뒤 기관차를 전진이 아닌 후진시킴으로써 앞으로 나아간다. 본인이 예전에 몇 번이나 언급한 적이 있듯, 모든 철도 동력차들은 전진과 후진을 완전히 동일한 성능으로 자유자재로 할 수 있기 때문이다. 자동차나 비행기와는 다르다.

기관차의 운전석은 통상 앞부분과 가까이 배치되어 있으며, 전방의 시야도 넓게 확보되어 있다. 이런 직관적인 앞부분으로 기관차를 자연스럽게 운전하는 것을 '단폐단 운전'이라고 한다. 운전석과 차체의 진행 방향 끝부분이 가까이 있다는 뜻이다.
그러나 기관차의 양방향 중 운전석 방향과 먼 반대쪽으로 열차를 운전하는 것을 '장폐단 운전'이라고 한다.

철도는 신호 시스템이 아주 발달해 있고 방향 전환이 필요 없는 교통수단이긴 하지만, 그래도 장폐단 운전이 단폐단 운전보다 더 위험하고 기관사의 심신에 부담을 많이 끼치는 근무인 것은 두 말할 나위가 없다.
운전석에서 차량의 말단이 멀리 떨어져 있다 보니 그렇잖아도 눈에 안 띄는 사각지대가 많아지는데, 그나마도 양 끝의 작고 좁은 창문만을 통해서 앞을 오랫동안 내다보느라 기관사의 자세도 구부정해지기 때문이다.

이런 장폐단 편성은 왜 생기는 걸까? 기관차의 방향을 돌려 주는 전차대나 루프선이 없는 노선을 운행했다가 되돌아올 때가 있기 때문이다.

대표적인 예는 바로 경인선이다.
경인선에서는 전동차뿐만이 아니라 인천항을 왕래하는 화물 열차도 비정기적으로 운행된다.
그러나 경인선의 종점인 인천 역은 인상선도, 루프선도, 전차대도 없이 열차가 있는 그대로 들어갔다가 도로 나올 수만 있는 매우 열악한 종착역이다. 그래서 인천 방면을 향하고 있던 기관차는 도로 서울 방면으로 돌아갈 때도 뒤쪽인 인천을 향한 채 주행하게 된다.

철도 차량은 아무래도 앞뒤 주행에 모두 유동적으로 대응 가능한 형태로 만드는 게 유리함을 알 수 있다. 앞으로 도입될 예정인 7600호대 디젤 전기 기관차는 앞뒤에 동일하게 운전석과 큰 창문이 달린 전후 대칭형으로 만들어질 예정이라고 한다. 이 경우 마치 동차처럼 장폐단· 단폐단이라는 구분 자체가 무의미해질 것이다.

물론, 전기 기관차는 진작부터 운전실이 앞뒤에 둘 달린 전후 대칭형으로 만들어져 있긴 했다. 기계 부품을 배치하는 데 다른 동력원 기관차보다 자유도가 더 높기 때문일 것이다.
전기나 디젤과는 달리 과거의 증기 기관차는 보일러와 탄수차, 차륜의 배치 같은 여러 문제 때문에 태생적으로 전후 대칭형으로 만들기가 사실상 불가능하다. 얘는 길쭉한 보일러가 앞으로 불쑥 돌출돼 있으니, 장폐단 형태만이 가능하다.

사용자 삽입 이미지

드물게, 중형 기관차인 4400호대 디젤 기관차는 설계상의 정방향이 장폐단 형태이다. 증기 기관차처럼 말이다.

사용자 삽입 이미지

그리고 일명 봉고 기관차라고도 불린 7000호대 디젤 기관차는 반대로 후진(=장폐단 주행)을 아예 고려하지 않은 극단적인 설계 때문에 사실상 단폐단 전진 운전밖에 못 한다. 운전석 안에서 후방 시야를 확보할 수 없기 때문이다. 얘는 작년 말에 다 퇴역했기 때문에 지금은 볼 수 없다.

사용자 삽입 이미지

2. 차륜 배치

자동차에는 엔진이 자동차의 어느 쪽에 적재되고 구동축이 어느 쪽 바퀴에 연결되는지를 나타내는 FF(전륜구동), FR(후륜구동), RR, 4WD 같은 용어가 있다. 이와 비슷한 개념이 철도 차량에도 응당 존재한다.

먼저, 동력 분산식 차량의 경우, 연결된 차량 자체가 동력차인지 아니면 단순히 끌려다니는 객차인지를 나타내는 표기가 있다. Tc(한쪽 말단에 운전실이 달린 객차), M(동력차), M'(전동차 한정. 동력차이면서 팬터그래프도 달린 차), T(단순 객차)가 그것.

그리고 다음으로 한 차량을 이루는 대차의 차륜 구성을 나타내는 표기가 있다. 연속으로 이어져 있는 바퀴의 수를 나열하는데, 동력이 연결된 바퀴는 A, B, C로 시작하는 알파벳으로 적고, 그렇지 않은 바퀴는 아라비아 숫자로 적는다.

예를 들어, 아래의 8200호대 전기 기관차의 차륜을 표기하면 Bo-Bo이다. (보다시피 전후 대칭인 것도 맞지?)

사용자 삽입 이미지

B라고 적힌 걸 보니, 한 대차당 바퀴가 두 개 있고 각 바퀴에 모두 동력이 전달된다는 뜻이다. 이 기관차 하나만을 자동차 같은 차량에다 비유한다면 진짜 4WD급인 셈이다.
B 다음에 붙은 o는 그 구동축이 동력원이 내연 기관 같은 다른 엔진이 아니라 전기 모터임을 뜻한다. 순수 전기 기관차뿐만이 아니라 디젤 전기 기관차의 구동축도 결국 전기 모터와 연결되어 있기 때문에 o가 붙는다.

사실, 8200호대 전기 기관차는 차륜이 한 레일당 총 4개로 적은 편이다. 가볍고 접지력이 낮은 것에 비해서 출력만 너무 강하다 보니, 이 기관차는 오르막에서 바퀴가 헛도는 공전 현상이 종종 발생했다고 한다.
8000호대 전기 기관차는 Bo-Bo-Bo이며, 특대형 디젤 기관차는 Co-Co로 6개이다. 최근에 도입되고 있는 8500호대 신규 전기 기관차 역시 이 추세게 맞추어 Co-Co로 돌아갔다.

오늘날의 디젤이나 전기 기관차는 차륜이 비교적 규칙적이고 배치 방식이 그렇게까지 다양하지는 않기 때문에 조합이 기껏 저 정도밖에 안 된다. 다양한 차륜의 종결자는 역시 증기 기관차였다.
얘는 엔진 내부에서 전문적인 동력비 조절 장치를 갖추고 있지 않은 원시적인 구조이기 때문에 바퀴의 개수와 크기가 기관차의 출력과 직접적으로 연결되었다. 그래서 여객용 기관차는 구동축이 걸리는 바퀴를 크게 하여 좀 더 빨리 달릴 수 있게 했고, 반대로 화물용 기관차는 작은 바퀴를 여러 개 달아서 속도 대신 토크(견인력)를 크게 했다.

19세기에 앞바퀴가 엄청 큼직한 자전거가 잠시 등장했던 것을 떠올려 보면 이해가 될 것이다. 그때는 체인이라는 개념이 도입되지 않아서 두발자전거도 세발자전거처럼 페달이 앞바퀴에 곧장 연결되어 있었으며 앞바퀴가 구동축이었다.
그리고 바퀴를 크게 하는 게 오늘날로 치면 고단 기어를 써서 페달을 조금만 밟아도 접지면의 바퀴는 더 많이 돌게 하기 때문에, 속도를 향상시킬 수 있다. 물론 그만큼 페달을 밟는 데 힘은 많이 들겠지만 말이다.

이렇듯, 철도에는 장폐단· 단폐단 같은 미처 생각도 못 했던 특성 구분이 존재한다는 걸 우리는 알 수 있었다.
비행기의 랜딩 기어 바퀴의 배치도 이런 표기법으로 기술해 보고 싶은 생각이 들지 않는지?

다만, 랜딩 기어 바퀴에는 구동축 같은 건 전혀 존재하지 않으며, 반대로 철도 차량은 비행기나 트럭의 바퀴처럼 바퀴가 안쪽으로 두 겹이 배치되는 경우는 존재하지 않는다는 게 고려할 점이다. 궤도를 구성하는 한 쌍의 레일의 안쪽에 또 차륜을 얹을 레일이 있는 건 아니기 때문이다. 무슨 복수의 궤간을 지원하도록 특수하게 설계된 선로가 아닌 이상 말이다.

Posted by 사무엘

2013/09/06 08:34 2013/09/06 08:34
, , , ,
Response
No Trackback , 3 Comments
RSS :
http://moogi.new21.org/tc/rss/response/874

« Previous : 1 : ... 140 : 141 : 142 : 143 : 144 : 145 : 146 : 147 : 148 : ... 221 : Next »

블로그 이미지

그런즉 이제 애호박, 단호박, 늙은호박 이 셋은 항상 있으나, 그 중에 제일은 늙은호박이니라.

- 사무엘

Archives

Authors

  1. 사무엘

Calendar

«   2025/01   »
      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  

Site Stats

Total hits:
3079727
Today:
1309
Yesterday:
1636