[대항해시대 온라인][글섭] 아이템 정리글

영어로 된 이름의 아이템과 약자들, 혹은 글섭에만 있는 아이템들을 좀 더 쉽게 확인하기 위해 작성해 둡니다. (계속 업데이트 예정)   - Emergency Shipbuilding Request / ESBR : 긴급조선의뢰서(긴조) - Master's Ship Material Purchase Order (No.1) : 주간 보너스 퀘스트 5회 달성 시 주는 아이템. - WTS : 삽니다 (Want to sell) - WTB : 팝니다 (Want to buy) - WTT : 교환합니다 (Want to trade) - WTH : 고용합니다 (Want to hire) - PC {물품이름}: 가격이 얼마인가요? (Price)

[STL] vector 의 정렬 - object pointer 정렬

이미지
[STL] vector 의 정렬 - object pointer 정렬 이 주제는 C++ STL 의 기본에 가까운 듯 한데, 평소에 C++ 로 프로젝트가 진행되는 경우가 없어서 익숙하지가 않아, 쓸때마다 헷갈려서 ( 특히 object pointer 타입을 다룰 때… ) 정리차원에서 한 번 포스팅해 좀. 1. Primitive 타입 먼저 가장 기본 형태. primitive type 의 vector 를 보자. vector<int> v; for (int i = 0; i < 20; i++) v.push_back(i); random_shuffle(v.begin(), v.end()); for (int i = 0; i < 20; i++) cout << v[i] << " "; cout << endl; sort(v.begin(), v.end()); for (int i = 0; i < 20; i++) cout << v[i] << " "; cout << endl; (실행결과) 1 11 15 0 14 7 16 13 8 10 17 5 2 19 18 9 4 3 6 12 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 위와 같이 오름차순으로 정렬이 된다. 기본적으로 std::sort 함수는 elements 비교에 ‘<’ 연산자를 사용하기 때문이다. 그럼 내림차순으로 정렬을 하려면 어떻게 해야 하는가? 바로 compare 하는 함수를 지정해 주거나, compare object 를 지정해 주는 것이다. 이때 함수는 bool comp(int a, int b) 형태로 표현하면 된다. 중요한 점은 comp 함수의 return value 가 true 라면 a 가 b 보다 앞으로 간다는 것이다. 위의 코드에

[Unit Test] Robolectric 4.4 와 Shadow 그리고 Mocking

이미지
[Unit Test] Robolectric 4.4 와 Shadow 그리고 Mocking 안드로이드 어플리케이션의 유닛 테스트를 작성하다 보면,비즈니스 로직을 완전 순수하게 자바로 독립해서 작성하기에는 너무 코드가 많아지고 복잡해지고 솔직히 너무 오버 아키텍처가 되는게 아닐까 고민하게 되는 것 같습니다. 결국 안드로이드 프레임워크 API 를 이용하게 되는데, 이 안드로이드 API 들을 mocking 하기 위해서 그래도 가볍우면서 샘플코드나 자료를 쉽게 찾을 수 있는 mocking framework인 Mockito 를 사용하게 됩니다. 그런데 또 이걸 이용해서 유닛 테스트를 만들며 mock object들을 만들다보면 내가 테스트 코드를 작성하는 건지, 안드로이드 프레임워크 코드를 작성하는 건지 하는 생각이 듭니다. 결국 안드로이드 프레임워크 코드를 내가 작성해야 하는 상황이 싫어, Robolectric을 사용하는 것을 고민하게 됩니다. Robolectric의 원래 목적을 생각해보면 실제 디바이스나 에뮬레이터 상에서 UI를 수행하는 대신, 빌드 타임에 UI테스트를 수행할 수 있게 해 줍니다. 하지만 이 글에서는 여기까지는 고려하지 않고, 직접 Mock 객체를 만들지 않아도 안드로이드 프레임워크 API를 이용할 수 있다는 것에 집중하려합니다. 그리고 Mock 객체를 직접 만들지 않고 Shadow를 사용하는 것은 부족한 점이 있지만, 이 부분을 어떻게 채워가는지 이야기 하고자 합니다. Mocking 할 필요가 없다. 먼저 JUnit으로 안드로이드 어플리케이션의 유닛 테스트를 작성하는 상황을 보겠습니다. 테스트를 작성할 때, 코드에서 안드로이드 프레임워크의 API를 이용하면 IDE 상으로는 에러를 보여주지 않지만, 실제 테스트를 수행해 보면 에러가 발생합니다. (테스트 대상 클래스) public class MyClass { public boolean verifyName(String name) { r

[책] 소프트웨어 세계화

이미지
소프트웨어 세계화 박미라 저 에어비앤비, 페이스북, 트위터는 해외에서 50% 이상의 수익을 번다. 그런데 우리나라에는 왜 그러한 소프트웨어가 없을까? 문제는 세계화다. 마이크로소프트, 구글, 에어비앤비, 페이스북, 트위터, 넷플릭스, 링크트인, 인튜이트는 기획 단계부터 세계화를 고려한다. 일단 국내에서 통하고 보자고? 그럼 영원히 해외로 나갈 수 없게 될 것이다. 이 책은 MS 미국 본사 국제화 부서에서 10년 이상 근무한 저자가 세계화를 체계적으로 정리한 국내 최초의 소프트웨어 세계화 지침서다. 세계화, 국제화, 현지화의 개념을 잡는 것... 소프트웨어의 세계화, 국제화, 현지화에 대한 책. 책의 전체적인 내용은 단순히 코딩에 대한 내용은 아니고, 소프트웨어 개발 전반에 걸쳐(기획부터 품질관리까지) 세계화를 어떻게 할 것인가에 대해서 설명하고 있다. 회사에서 세계화 담당팀이 별도로 없고, 자신이 담당하고 있는 소프트웨어 프로덕트가 세계화를 해야할 필요가 있다면 읽어보면 좋을 듯. 개인적으로 나는 이러한 내용들을, 검증으로부터 문제를 전달 받으면서 주먹구구식으로 익힌 느낌인데, 이런 책이 있으면 좀 더 개념잡기에 좋을 것 같다. 전 세계에 배포하는 소프트웨어를 담당하는 팀이라면 신입사원들에게도 한 번 읽어보도록 하면 좋을 것 같다.

[TensorFlow] 대항해시대 온라인 시세 공유 도우미 (2)

이 글에서는 학습된 데이터를 어떻게 저장하고 어떻게 읽어와서 사용할 지에 중점을 두고 설명하겠습니다. 지난 번 글에서 언급한 도시이름, 시세, 화살표의 Learing Model 코드는 이곳 에서 확인하실 수 있습니다. 이 코드는 교역품의 러닝 모델과 거의 비슷하기에 뒤에 학습된 모델을 읽어오기 위해 필요한 부분만 설명하겠습니다. 텐서플로우 공식 사이트에는 Save and Restore 항목이 있고, 여기에 보면 tf.saved_model.simple_save 를 이용하면 제일 쉽다고 되어 있습니다. 그래서 저는 이 함수를 사용하기로 결정하였습니다. 처음에는 단순히 아래와 같이 simple_save 코드를 이용하였습니다. ---------- simple_save(session, export_dir) ---------- 그리고 저장된 모델은 아래와 같이 로드하였습니다. ---------- def estimate(model_dir, raw_bytes):     tf.reset_default_graph()     graph = tf.Graph()     with graph.as_default():         with tf.Session(graph=graph) as sess:             tf.saved_model.loader.load(sess, [tag_constants.SERVING], model_dir, )             x_data = [[float(x) for x in raw_bytes]]             logits = tf.argmax(model, 1)         return sess.run(logits, feed_dict={X: x_data, keep_prob: 1.0})[0] ---------- 이러면 에러가 발생합니다. X, keep_prob, model 이라는 것이 무엇인지 모르기 때문이지요. 그렇다고 로드하는 곳에서 다시 X, keep_prob, model 을 정의한다고 이용할 수 있는 것은 아닙니다. 새로 정

[파이썬] 패키지 재사용을 위한 패키징과 배포

너무나 사심이 가득하고 개인적인 대항해시대 온라인 시세 공유 프로젝트를 진행하면서 파이썬에 대해서도 많이 공부하게 되는 것 같습니다. 단순 언어도 공부가 되었지만, 실제 deploy 하는 측면에서도 고민을 하고 해결 방법을 찾아보곤 합니다. 대항해시대 시세 공유 도우미 프로그램는 크게 2개의 프로젝트로 구성되어 있습니다. 그리고 이 두개의 프로젝트는 물리적으로 분리된 프로젝트로 만들려고 합니다.   - Machine Learning 을 수행하는 부분   - GUI 클라이언트 부분   이 두개의 프로젝트는 공통으로 사용하는 utils 패키지가 있는데, 이 코드를 두 프로젝트에서 소스로 가지고 있으면 관리의 어려움이 있기에 utils 패키지를 패키징해서 pip install 을 이용해 사용하는 방법을 알아보았습니다. 구글에서 검색한 내용을 참고로 저는 아래와 같이 프로젝트 디렉토리를 구성하였습니다 --------------------------------------------- uwo_ps_utils/     LICENSE     MANIFEST.in     README.md     setup.py     .gitignore     docs/     uwo_ps_utils/         __init__.py         market_rates_cropper.py ---------------------------------------------         (docs 디렉토리에는 어떤 포맷으로 작성해야 하는 지 몰라서, 제가 마음대로 작성한 텍스트 파일이 하나 들어있습니다) MANIFEST.in 이나 setup.py 작성 방법에 대해서는 제일 아래에 있는 사이트를 참고하세요. .gitignore 나 LICENSE 부분은 github 에서 기본으로 제공하는 파일을 이용했습니다. 이 프로젝트를 빌드하기 위해서는 setuptools와 wheel이 필요하기 때문에, pip install setuptools wheel 명령으로

[TensorFlow] 대항해시대 온라인 시세 공유 도우미 (1)

이미지
국내에서 서비스하는 대항해시대 온라인의 최악의 시스템은 랜덤 그레이드 옵션이 아닐까 생각합니다. 그런데 어쩌다 보니 글로벌판에서 경험치,스킬숙련도,명성 최대 4배 이벤트를 하는 것을 보고, 글로벌판으로 갈아탔지요. 그리고 foxytrixy 를 이용해 오픈 채팅방에서 시세 공유하는 것을 보고 스크린샷에서 바로 정보를 가져올 수 있으면 좋겠다는 생각에 시작했습니다. 때마침 머신러닝 교육을 갔다와서 어디 적용할 만한 것이 없을까 고민하고 있었고요. 처음에는 게임의 해상도마다 이미지 크기가 조금씩 다를테니 이걸 같은 크기로 리사이즈 하고 이런 데이터들을 모아서 학습을 시키면 모든 해상도에서 정보를 인식할 수 있을꺼라 생각했습니다. 그런데 이 옛날 게임은 해상도가 달라도 "Market Rates" 보는 창의 크기는 동일한 사이즈였습니다. 머신러닝을 적용하는 것이 큰 의미가 없어지긴 했지만, 그래도 반투명한 부분 때문에 충분히 도움이 되지 않을까 생각하면서 진행해 봤습니다. 여기서는 Python + Tensorflow 를 이용해서 제가 데이터를 모으고, 신경망을 구성한 것을 보여드리고자 합니다. 일단 대항해시대 온라인의 Market Rates 화면입니다. 창의 왼쪽에는 교역품 시세, 오른쪽에는 인근 도시의 시세입니다. 일단 왼쪽 교역품 항목에 집중해 봅시다. 화면에서 교역품 정보를 알기 위해서는 그림을 보거나 이름을 보거나 둘 중 하나가 될 텐데요, 저는 이미지를 택했습니다. 웬지 이름 보다는 더 식별을 잘 할 것 같아서 말이죠. 스크린샷에서 교역품 이미지를 확인해 보니, 이 이미지는 배경화면의 영향을 받지 않습니다. 그래도 머신러닝 시작한 김에 계속 진행합니다. 대항해시대 온라인의 교역품 종류는 https://ssjoy.org/ 사이트 기준으로 대략 600 가지가 넘는 것으로 보입니다. 처음에는 이 모든 교역품의 이미지를 스크린샷으로 부터 가져와서 데이터를 만들기는 어려워 사람들이 시세를 많이 확인하는 품목 몇 종류만