특성 스카우트 최근 30회 모으기 프로젝트

최근 편집: 2021년 8월 30일 (월) 17:47
빠른 링크 최근 30회 모으기 폼: 고급 오디션
모은 결과: 고급 오디션

특성 스카우트 최근 30회 모으기 프로젝트는 앙상블스타즈 for kakao특성 스카우트 조합에 관한 여러가지 추리를 해 보기 위하여 스카우트 참고에서 볼 수 있는 '최근 30회 스카우트' 시도들을 각 참가자들이 옮겨 적도록 하여 이를 스프레드시트로 정리하는 프로젝트입니다.

제한 사항

  • 이 프로젝트는 스카우트된 카드의 정확한 종류와 희귀도는 수집하지 않습니다.
  • 이 프로젝트는 이벤트 스카우트 기록은 수집하고 있지 않습니다.
  • 이 프로젝트에 수집된 결과들은 아이돌마다 수가 다를 수 있습니다.
  • 현재 결과에서는 특성치를 최대한 사용한 경우(오디션의 경우 1500, 고급의 경우 3000)만이 표시되고 있습니다.

프로젝트가 기록을 모으는 방법

이 프로젝트는 다음 방법으로 기록을 모읍니다.

  • 각 참가자들이 스카우트 참고에서 볼 수 있는 최근 30회 스카우트구글 폼(오디션/고급)을 통해 입력합니다.
  • 관리자가 폼 응답 시트에 모인 데이터를 주기적으로 구급 앱 스크립트를 통해 결과 표로 변환합니다.

모인 결과 보기

구글 스프레드시트에서 전체 보기

구글 스프레드시트에서 전체 보기

참가하기

  1. 앙상블스타즈 for kakao에서 [스카우트] > [고급 or 오디션 스카우트] > [특성 스카우트] > [스카우트 참고]로 이동합니다.
  2. 아이돌을 선택합니다. 가능하면 수집 수가 적은 아이돌을 선택해 주세요.
  3. 구글 폼(고급/오디션)을 방문하여 선택한 아이돌을 입력합니다.
  4. 각 특성치를 쭉 받아 적습니다.
  5. 제출합니다.

부록

스프레드시트 시트 설명

각 시트 설명
순서 이름 설명 참고
1 결과 수집된 결과들을 조합과 아이돌에 따라 모은 표입니다. 필요에 따라 정렬하여 볼 수 있습니다.
2 폼 응답 시트 폼 응답이 그대로 모이는 시트입니다. 관리자만 수정할 수 있습니다.
3 변환된 데이터 최대 30개까지 모아져 있는 폼 응답 시트의 데이터들을 한 줄당 시도 하나로 변환합니다.
4 아이돌 수집 수 모여있는 기록들에 아이돌이 몇 있는지 갯수를 센 표로, 붉은 강조가 수가 적은 아이돌입니다.

정리 스크립트

다음 스크립트를 실행하면 도구 모음에 "특성 스카우트" 및 "설문지 데이터 변환"과 "데이터 표 갱신"이 추가됩니다. 각 용도가 다르지만 그냥 차례로 실행하면 결과는 나옵니다.

이 글을 보려면 오른쪽 '펼치기' 버튼 클릭
/**
 * A special function that runs when the spreadsheet is open.
 */
function onOpen() {
  var spreadsheet = SpreadsheetApp.getActive();
  var menuItems = [
    {name: '설문지 데이터 변환', functionName: 'convertData_'}, 
    {name: '데이터 표 갱신', functionName: 'refreshTable_'}
  ];
  spreadsheet.addMenu('특성 스카우트', menuItems);
  convertData_();
}
function convertData_() {
  var spreadsheet = SpreadsheetApp.getActive();
  
  var dataSheet = spreadsheet.getSheets()[1], convertedDataSheet = spreadsheet.getSheets()[2];
  
  var lastDataTimestamp = dataSheet.getRange(dataSheet.getLastRow(), 1).getValue();
  var lastConvertedDataTimestamp = convertedDataSheet.getLastRow() == 0 ? 0 : convertedDataSheet.getRange(convertedDataSheet.getLastRow(), 1).getValue();
  
  if( lastConvertedDataTimestamp instanceof Date && lastDataTimestamp.getTime() == lastConvertedDataTimestamp.getTime() ) return;
  
  var firstNewDataRow = 0;
  
  if ( lastConvertedDataTimestamp instanceof Date ) {
    for( firstNewDataRow = dataSheet.getLastRow(); dataSheet.getRange(firstNewDataRow, 1).getValue() > lastConvertedDataTimestamp; firstNewDataRow-- )
      continue;
    firstNewDataRow++;
  } else 
    firstNewDataRow = 2;
  
  Logger.log( firstNewDataRow+'행부터 기록 시작' );
  var newConvertedData = [ ];
  var toStandard = function(num) {
    if ( num % 100 == 0)
      num /= 100
      return num;
  };
  
  for ( var row = firstNewDataRow; row <= dataSheet.getLastRow(); row++ ) {
    Logger.log( row+'행 기록 시작' );
    values = dataSheet.getRange( row, 1, 1, 2 + 3*30 ).getValues()[0];
    var timestamp = values[0];
    var name = values[1];
    
    for ( var c = 2; c < 2 + 3*30 && values[c] !== '' && values[c+1] !== '' && values[c+2] !== '' ; c += 3 )
      newConvertedData.push( [ timestamp, name, toStandard(values[c]), toStandard(values[c+1]), toStandard(values[c+2]) ] );
  }
  Logger.log(newConvertedData.length);
  if ( newConvertedData.length != 0 ) {
    if ( convertedDataSheet.getLastRow() == 0 )
      convertedDataSheet.insertRows( 1, newConvertedData.length );
    else
      convertedDataSheet.insertRowsAfter( convertedDataSheet.getLastRow(), newConvertedData.length );
    convertedDataSheet.getRange( convertedDataSheet.getLastRow()+1, 1, newConvertedData.length, 5).setValues( newConvertedData );
  }
  spreadsheet.getSheets()[3].sort(2);
}
function refreshTable_() {
  var spreadsheet = SpreadsheetApp.getActive();
  var idols = [
    '테토라', '하지메', '토모야', '히나타', '미도리', '토리', '시노부', '유우타', '미츠루', '츠카사',
    '스바루', '호쿠토', '마코토', '소마', '아도니스', '코가', '리츠', '마오', '유즈루', '아라시',
    '케이토', '에이치', '카오루', '이즈미', '치아키', '쿠로', '와타루', '카나타', '레이', '나즈나'
  ];
  
  Logger.log(idols[0]);
  
  var tableSheet = spreadsheet.getSheets()[0], dataSheet = spreadsheet.getSheets()[2];
  var data = dataSheet.getRange(2,2,dataSheet.getLastRow()-1,4).getValues();
  var recipes = [ ];
  
  var ct = 0;
  for ( var i=0; i< data.length; i++)  {
    var key = ("0" + (data[i][1]+0)).substr(-2,2)+("0" + (data[i][2]+0)).substr(-2,2)+("0" + (data[i][3]+0)).substr(-2,2);
    //Logger.log(key);
    
    if ( recipes[key] == undefined ) {
      recipes[key] = [ ];
      recipes[key]['F'] = data[i][1];
      recipes[key]['C'] = data[i][2];
      recipes[key]['A'] = data[i][3];
      ct++;
    }
    
    if ( recipes[key][data[i][0]] == undefined ) {
      recipes[key][data[i][0]] = 1;
    }
    else
      recipes[key][data[i][0]]++;
  }
  
  range = tableSheet.getRange(2,2,tableSheet.getLastRow()-1,3+idols.length);
  values = range.getValues();
  
  for ( var i = 0; i < values.length; i++) {
    var key = ("0" + (values[i][0]+0)).substr(-2,2)+("0" + (values[i][1]+0)).substr(-2,2)+("0" + (values[i][2]+0)).substr(-2,2);
//    Logger.log(i + ' ' + values[i][0]);
    
    var j = 3;
    for ( var k = 0; k < idols.length ; k++ ) {
      if ( recipes[key] == undefined ) continue;
      
      if ( recipes[key][idols[k]] == undefined )
        values[i][j++] = 0;
      else
        values[i][j++] = recipes[key][idols[k]];
    }
  }
  
  range.setValues(values);
  
  tableSheet.sort( 35, false );
  spreadsheet.getSheets()[3].sort(2);
}