Steem.js API로 게시물 주사위게임 만들기 (1)

in #kr-arduino7 years ago (edited)

Steem.js API로 게시물 주사위게임 만들기 (1)






잠시 아두이노 포스팅을 중단 하고 최근 Steem API가 재밌어 보여서 입문을 해 보았습니다. 사용할 수 있는 함수들과 그 예제를 찾기가 진짜 힘이 들더군요. 함수에서 받는 인자값이 정확히 어떤 것을 지칭하는지 머리속에서 잘 컴파일이 안되어서 이해하는데 좀 애 먹었네요. @tradingideas의 steem.api.getActiveVotes()함수 예제가 있어서 꽤 재밌는 정보를 담고 있어서 event 태그에서 주로 하는 주사위 게임이 떠오르더군요. 그래서 한번 이 정보를 기반으로 주사위를 만들어 볼까 하고 도전해 봤네요. 뭔가 흥미를 가질만한 소재로 Steem API를 다뤄야 공부가 더 잘되니깐요. 암튼 html도 기억 잘 안나고 자바스크립트 문법도 사실 따로 공부한 적도 없고 그냥 C언어 코딩 머리로 대충 때려 맞췄으니깐 코딩이 유치해도 이해해 주세요. 원하는 기능의 표현을 할때가 사실 좀 애먹었네요. 그 기능을 담당하는 함수를 구글 검색으로 통해서 찾는데 시간 좀 많이 소비했네요.

1. Steem API를 자바스크립트로 사용해보기


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
          <title>Steem.js</title>
    </head>
    <body>
        <script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
        <script>    
                명령어 수행!
        </script>
    </body>
<hteml>

대충 메모장에서 편집해도 되고 온라인 html문서 편집기나 자바스크립트 문서 편집기로도 동작하네요. 이게 기본 골격이고 Steem.js API 함수들을 명령어 수행 라인에 표현해서 사용하시면 결과를 얻을 수 있습니다.

기본예제)
출처 : https://steemit.github.io/steemit-docs/#steemjs-1 의 한 대목

<script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
<script>
    steem.api.getAccounts(['ned', 'dan'], function(err, response){
            console.log(err, response);
    });
</script>

한명 이상의 유저의 정보를 가져올 수 있습니다. respons에 그 정보가 저장되는데 테스트 할때는 콘솔창으로 그 결과를 출력해볼 수 있습니다.

steem.api.getAccounts(['codingman'], function(err, response){
            console.log(err, response);
    });

이렇게 자신의 아디를 입력하시고 정보를 추출하시면 해당 아디의 모든 정보가 출력됩니다.

좀 데이터 정보가 복잡해 보이시죠, 아래 표를 보시면 이해가 되실거에[요.

대충 response라는 공간에 id, name등 각각의 'codingman' 이란 사람의 정보가 들어있게 됩니다. 그러면 우리가 사용할려면 각각의 정보중에서 원하는 정보를 추출해야 겠죠. 접근하는 법은 표에서 한것처럼 'response[0].name'하면 'codingman'의 이름을 가져오게 됩니다. 'steemd.com' 에서 자신의 개인정보를 보신적 있을꺼에요. 그 정보들이라고 생각하시면 됩니다. 원하는 정보를 일일히 불러와서 html 출력하면 원하는 자신만의 개인 정보창을 만들 수 있겠죠.

참고로, 왜! response[0]으로 했냐면 배열변수 입니다. 그래서 배열변수의 첫번째 저장공간위치를 가리킵니다.

기본 베이스가 끝났고 이제는 주사위게임을 만들기로 들어가도록 하겠습니다.

2. steem.api.getActiveVotes()란 무엇인가?


해당 게시물의 대해 보팅한 사람들의 정보를 가져오는 함수입니다. 아래 기본표현을 참고하세요. 여기서 저장하는 변수이름을 'response'이라 했다가 'result'라 하고 햇갈릴 수 있지만 저장 변수 네임을 이렇게 자기의 원하는 이름으로 바꿀 수 있다는 점을 보여주기 위해서 표현한 것임으로 나중에 예제에서 보겠지만 'getactivevotes'라고 함수네임을 그냥 소문자형태로 변수명을 지정했네요. 표현은 자기 마음입니다.

steem.api.getActiveVotes(author, permlink, function(err, result) {
  console.log(err, result);
});
  • author : 아이디('codingman')
  • permlink : 게시물주소('steemit')

이 함수는 뭔지는 모르지만 보팅에 관련 정보를 가져온다라는 것을 함수명으로 알 수 있습니다. 그러면 어떤 정보가 들어 있을까요. 한번 살펴보도록 하죠. 본인의 게시물로 실험을 꼭 해주세요. 챙피하니깐요.

예제) 제 첫 게시물의 풀 주소 : 'https://steemit.com/kr/@codingman/steemit'

  • author : 'codingman'
  • permlink : 'steemit'

[ 코딩을 하면]

<script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>
<script>
        var author = 'codingman';
        var permlink = 'steemit';
        steem.api.getActiveVotes(author, permlink, function(err, result) {
            console.log(err, result);
        });
</script>

[결과]

여기서 매번 author, permlink를 입력해야 하냐고 귀찮아 하실분이 있습니다.

다음과 같이 코딩을 하면 게시물 풀 주소로 쉽게 해결 할 수 있습니다.

게시물 풀 주소로 author, permlink 얻기


  • 사용함수 : split(), replace()


위 그림을 살펴보시면 Post Link 정보에 author, permlink의 정보가 들어 있는 것을 보실꺼에요. 그러면 해당 게시물의 풀 주소를 알고 있다면 그 주소를 기반으로 author, permlink를 추출하면 되겠죠. 구지 author, permlink를 따로 입력할 필요는 없어집니다. 추출하기 위해서 사용된 함수는 split(), replace() 라는 두개의 함수를 사용해서 표현해 보겠습니다.

이 함수가 처음에 생소해서 찾는데 애먹었네요. 문자열 쪼개기랑 특정문자 제거하는 키워드로 구글 검색을 열심히 해서 두 함수를 발견했습니다.

  • 문자열변수.split('/') : '/' 기준으로 문자를 쪼개는 함수입니다.
    예) var a = b.split('/') : '/' 기준으로 a[0], a[1], a[2],..... 쪼개진것들이 이곳에 순차적으로 저장됩니다.
  • 문자열변수.replace('@','') : '@'문자를 찾아서 공백으로 바꾸는 함수인데 쉽게 말해 제거한다고 생각하시면 됩니다.
    예) var a= b.split('@','') : '@codingman'이란 문자열이 있으면 a에 'codingman'만 저장됩니다.

게시물 링크주소는 '/' 구분되잖아요. split('/')쪼개서 마지막 배열위치에 값은 permlink 값이 됩니다. 마지막에서 두번째는 author 값이 됩니다. "왜!" 저 두 함수를 사용한지 아시겠죠. post 풀 주소만 있으면 author와 permlink를 추출할 수 있기 때문에 사용된 것이죠. 그리고 마지막의 두번째 값은 '@codingman'이란 값이여서 '@'를 제거하기 위해서 replace()함수를 사용하였습니다. 물론 다른 방식으로 split('@')로 쪼개고 마지막에 저장된 'codingman' 값을 가져오셔서 됩니다.

  var src = 'https://steemit.com/kr/@codingman/steemit'
  var arrsrc = src.split('/');
  var idsrc = arrsrc[arrsrc.length-2].replace('@','');

  var author = idsrc;
  var permlink =  arrsrc[arrsrc.length-1];

3. Voters 정보로 주사위를 굴려 볼까요?


1) Voters들의 정보 추출

위 표처럼 result 안에는 현재 게시물에 보팅한 내역이 전부 다 들어 있습니다. 여기서, 살펴보면은 result[] 배열로 result[0]은 첫번째 보팅한 유저정보가 들어 있고, result[1]은 두번째 보팅한 유저정보가 들어있습니다. 이런식으로 게시물에 보팅한 사람들의 모든 기록이 들어 있습니다.

        steem.api.getActiveVotes(author, permlink, function(err, result) {
            console.log(result[0].voter);
        });         

이렇게 출력을 하면은 첫번째 보팅한 유저의 이름이 출력됩니다. 그리고 보팅한 사람의 수는 'result.length'로 통해서 얻을 수 있습니다. 그러면 아래 코딩으로 보팅한 숫자와 첫번째 voter를 출력해 볼까요.

        steem.api.getActiveVotes(author, permlink, function(err, result) {
            console.log(result.length);
            console.log(result[0].voter);
        }); 
    

결과는 다음과 같습니다.

'result.length'은 result[]안에 의 들어있는 데이터의 개수를 반환됩니다. 즉, result[] 배열이 총 몇개 만들어졌는지 확인할 수 있는 코드이지요. 보팅한 사람만큼 result[]배열이 만들어졌으니 배열의 개수는 보팅한 총 수를 의미하게 되겠죠. 결과에 15라는 숫자가 출력되는 걸 봐서는 15명이 보팅 했군요. 그리고 두번째 줄은 보팅한 사람들 중에 첫번째에 저장된 voter의 이름이 출력 되었네요.

여기서, 우리는 뭘 알 수 있을까요. 보팅한사람이 누구이면 이 게시물에 보팅한 총 인원을 알 수 있게 되었습니다.

그러면, 주사위 게임을 한다고 했으니깐 보팅한 사람과 보팅한 사람에 대한 주사위를 굴리는 작업이 필요하겠죠. 주사위는 어떻게 만들까요. 난수를 이용해서 만들면 됩니다. 주사위 100을 하면 난수 1~100사이의 값을 생성하면 됩니다.

2) 주사위 난수만들기


  • 사용함수 : Math.random(), Math.floor()

  • Math.random() : 0~1사이의 난수를 발생 시킴.
  • Math.floor() : 소숫점 이하는 버림
  • Number() : 문자값을 숫자화

어느 게시물에 보면 난수를 생성할 때 이 함수보다는 다른 랜덤함수를 사용하라고 하는데 그냥 이방식으로 표현 했습니다. 의미 전달에 초점을 뒀으니깐요.

[ 공식 ] 난수(최소값~최대값) 사이의 수를 출력

식 : (난수추출값 * 난수최대값)+난수최소값

var diceValue = Number(Math.floor(Math.random() *100)+1);
console.log(diceValue);

결과가 난수 1~100사이에서 77이라는 수가 출력 되었네요.

3) 보팅한 사람과 주사위 난수를 같이 출력하기


이제 보팅한사람 수 만큼 주사위를 돌려야 합니다. 어떻게 해야할까요. 바로 보팅수 만큼 for문을 돌리면 되겠죠.

steem.api.getActiveVotes(author, permlink, function(err, result) {      
        for(var i=0;i<result.length;i++){
        
          주사위 굴리기;
        }
}); 
        

위 코딩처럼 보팅 정보를 가져온 함수내에서 result.length은 보팅수라고 했으니깐 그 보팅수 만큼 for문을 반복하면 됩니다. 아주 간단한 표현이죠. 이제 주사위를 보팅한 사람과 매칭해서 굴려볼까요.

steem.api.getActiveVotes(author, permlink, function(err, result) {
    var voter='';
    var diceValue=0;
    
        for(var i=0;i<result.length;i++){
          voter=result[i].voter;
          diceValue=Number(Math.floor(Math.random() *100)+1);
          console.log(voter+' : '+ diceValue);
        }
}); 

편의상 voter, diceValue 변수로 따로 빼냈습니다. 보팅한 유저 이름을 추출할 수 있고, 그다음 난수를 만들어보는 것 까지 위해서 했습니다. 그 과정을 보팅한 숫자만큼 for문을 통해서 15번을 반복한 결과가 아래의 그림처럼 출력됩니다.

보팅한 아디와 주사위 100의 결과가 순차적으로 출력 되었네요. 주사위 게임이 간단 하지요.

4. 오늘 공부한 내용을 종합한 결과


[ 전체 소스 ] : 메모장에다가 복사 하셔서 test.html 저장해서 웹브라우저로 열어보세요.
(주의 : 인코딩 선택 UTF-8)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Steem.js</title>
</head>
<body>

<script src="https://cdn.steemjs.com/lib/latest/steem.min.js"></script>

<script>
  var src = 'https://steemit.com/kr/@codingman/steemit';
  var arrsrc = src.split('/');
  var idsrc = arrsrc[arrsrc.length-2].replace('@','');

  var author = idsrc;
  var permlink =  arrsrc[arrsrc.length-1];   

  steem.api.getActiveVotes(author, permlink, function(err, result) {
      var voter='';
      var diceValue=0;
      var DiceData='';
      console.log(result.length);
      
      for(var i=0;i<result.length;i++){
          voter=result[i].voter;
          diceValue=Number(Math.floor(Math.random() *100)+1);
          //console.log(voter+' : '+ diceValue);
          DiceData+=voter+' : '+ diceValue + '</br>';
      }
      
      document.getElementById("demo").innerHTML=DiceData;
  });     
  
</script>
  <p id='demo'></p>
</body>
</html>

여기서, DiceData로 주사위 굴린 voter랑 주사위 값들을 저장했습니다. 저장하는 변수로 설정했네요.

DiceData+=voter+' : '+ diceValue + '</br>'; 

이 명령문 원리는

A = A+1; 

A 값이 1씩 계속 증가하는 명령문과 같이 처음 보팅한 사람과 주사위 숫자에다가 계속 주사위를 굴림 다음 사람의 정보를 더해서 A에 기록한다고 생각하시면 됩니다. 문자열 더하기는 다음과 같습니다.

'문자1 ' + '문자2' => '문자1문자2'

이렇게 나오게 됩니다. '</br>' 태크는 다음 정보는 새로운 줄에 표시하기 현재라인에서 'Enter'를 누른 것처럼 새로운 라인으로 이동하라는 표시입니다. 그래서 현재 주사위 돌린 사람의 정보가 출력되고 다음 새로운 라인에 두번째 주사위를 돌린 사람이 출력되는 표현이라고 생각하시면 됩니다.

document.getElementById("demo").innerHTML=DiceData;

이 부분은 그냥 통으로 html구문에서 id가 'demo'인 위치를 가리키는 문장이라고 생각하시면 됩니다. 그러면 해당 태그(id)의 위치로 가서 DiceData 값들이 출력되게 됩니다.

<body>
<p id='demo'> 출력되는 위치 </p>
<body>

대충 아래 표현을 잘 보시고 이렇게 출력되는구나 하고 이해하시면 됩니다.

그리고 위 소스를 다음과 같이 메모장에 복사한 뒤에 저장해 주세요.


'test.html'로 표현했지만 아무 이름이나 하나 만드시고요. 파일형식은 모든파일로 변경해주세요. 그래야 html 확장자로 저장하면 html 확장자로 파일이 저장됩니다. 그리고 그냥 저장을 누르면 일부 글자가 깨집니다. 인코딩 형식을 소스에서 선언하긴 했지만 저장하실때 여기서 UTF-8로 저장하셔야 글자가 안깨집니다.

그리고 저장하시고 그 파일을 실행하려고 더블 클릭하면 뭘로 여실건가요. 질문창이 나옵니다. 크롬, 엣지 오페라에서 바로 열립니다. 익스나 스윙 같은 곳에서는 컨텐츠가 차단되었다는 문구와 함께 실행이 되지 않습니다. 따로 푸는 작업을 해야하니깐 그냥 크롬, 엣지, 오페라 정도에서 편하게 실행하세요. 파폭이나 다른 브라우저는 테스트를 안해봤네요.

[ 결과 ]
정상적으로 'test.html' 파일이 생성이 되었고 실행을 시키니 그 결과는 아래와 같이 voter와 주사위 값이 정상적으로 출력 되었습니다.

위 소스에다가 post link 주소만 갱신하면 언제든지 자신의 게시물에 대한 보팅한 분들의 주사위를 돌릴 수 있겠죠.
수정은 문서편집기가 있으면 좋지만 없으셔도 메모장에서 해당 파일을 여시면 됩니다. 그리고 게시물 주소를 복사해서 여기에 붙여 넣기만 하고 저장하시면 끝납니다.

편하게 자신의 게시물의 보팅 주사위를 돌릴 수 있습니다.

마무리


getActiveVotes()함수의 정보를 통해서 얻은 voter들의 정보를 기준으로 주사위 100을 굴렸습니다. 여기서 끝은 아닙니다. 글을 쓰다보니깐 너무 길어져서 더 길게 쓰면은 안좋을 것 같아서 어쩔 수 없이 다음편으로 내일 포스팅을 하게 될 예정입니다. 내일은 순위를 정하는 코딩이 들어가겠습니다. 15명만 주사위를 굴렸기 때문에 쉽게 누가 일등 인지를 알 수 있습니다. 하지만 100명이상을 상대로 주사위를 굴린다면 과연 누가 1일등인지 확인하는 작업이 쉽지 않습니다. 그리고 주사위를 굴리면 같은 숫자가 나올 확률은 높아집니다. 그럼 같은 숫자를 가진 1등이 2명이라면 누구를 1등으로 할 것인지에 대한 규칙도 없습니다.

이런 몇가지의 문제에 대해서 다음 포스팅에서 해결할 수 있는 방법을 제시하겠습니다.

아! 아두이노를 포스팅 해야 하는데 삼천포로 빠져서 약간 맛배기로 몇일 전 입문해서 공부한 함수하나를 포스팅으로 써먹네요. 딱 주사위 까지만 포스팅을 하고 다시 아두이노 세계로 돌아가겠습니다.

Sort:  

오... 스팀이 여러개발 툴이라고 해야하나 그 부분이 오픈이 되어 있나 보네요.... 으음 전 프로그래밍에 젬병이라.... 잘 모르겠지만... 먼가 개발하고자 맘먹으면 그 자료가 오픈은 되어 있나 보네요

Steem API 를 통해서 스팀블록에 기록된 정보들을 쉽게 읽고 쓸 수 있게 되어 있다는게 신기하더군요.
함수를 알아야 할 것이 많은데 조금만 가공하면 재밌는 표현을 많이 할 수 있겠더군요.
물론 먼저 함수를 알아야 겠지만요.
어짜피 공개된 스팀의 빅데이터를 누구나 쉽게 접근할 수 있고 그 정보를 가공해서 새로운 형태로 결과물로 출력할 수 있다는데 큰 의미가 있는 것 같아요.

정성 담긴 글 감사합니다.

읽어주셔서 감사합니다.

짱짱맨 부활!
Kr-gazua태그에서는 반몰로만대화한대요^^ 재미있는 태그라서 추천드려요

짱짱맨 화이팅!
재밌는 태그네요. 그런데 약간 위험성이 있어 보이네요.
말을 놓는다는 것은 경우에 따라서 상대에게 불쾌한 단어가 들어 갈 여지가 있어서 신중해야할 듯요.
어느정도 친한 사이가 아닌이상은 이런 표현으로 상대방에게 오해를 살 가능성도 있어보이네요
재밌는 태그이긴 한데 선을 넘으면 오히려 문제가 발생 될 가능성이 있는 태그인 것 같아요.

코딩맨 형님. 저도 추천해요. 그거 은근 재밌습니다. ㅎㅎㅎ 친한 사이가 되면 되는 거죠 뭐. ㅋㅋㅋ