Keseimbangan dalam desain game desktop: membuat grafik dengan Google App Script dan Gephi





Halo semuanya! Nama saya Nikita, dan saya ingin berbagi dengan Anda beberapa aspek praktis dalam mengembangkan permainan papan Surat Hantu saya (yang akan dirilis bulan ini oleh Economics). Kami mencoba mendekati proses pengembangan sesistematis mungkin, sehingga pengalaman kami mungkin menarik bagi seseorang.





Ghost Letters adalah permainan papan detektif dengan peran rahasia untuk pemikiran deduksi, gertakan, dan asosiatif. Jika Anda suka bermain "Mafia" atau "Imaginarium" - saya yakin Anda akan menyukainya juga. Dari permainan papan modern bergenre ini paling dekat dengan "Mysterium" dan "Criminalist".





Tugas yang ditetapkan

Mekanika dasar Ghost Letters didasarkan pada asosiasi antara kartu dengan gambar berbagai objek (kartu bukti). Dan pada salah satu tahap awal pengembangan, kami mengajukan pertanyaan: "Apakah mungkin menghitung dan membangun keseimbangan dalam permainan asosiasi?" Sebenarnya kenapa tidak mencobanya.





Tugas menyeimbangkan asosiasi adalah seperti ini:





  • Minimalkan jumlah asosiasi yang "tidak ambigu". Setiap kartu idealnya harus dikaitkan dengan beberapa lainnya dengan kekuatan yang kira-kira sama.





  • “ ”. , .





  • .





, , . 150 , – . , .





Google Docs

- Google , . - :





  • Google App Script. JS , -.





  • , . , .





  • , . - . .





Gephi

. .





:





. Google Sheets, , .





4 :





0 –

1 – ,

2 –

3 –





, – , .





, 150 150 ( , “”). , . , , , .





, , – , . , .





:





. id , . , id.





//     
function RefreshPictures() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  //  
  var sheet_a = ss.getSheetByName("");
  var range_a = sheet_a.getDataRange();
  //   
  var sheet_p = ss.getSheetByName("");
  var range_p = sheet_p.getDataRange();
  
  //    
  var row = sheet_a.getActiveCell().getRow();
  var col = sheet_a.getActiveCell().getColumn();
  
  //  id 
  var id1 = range_a.getCell(row, 1).getDisplayValue().toString();
  var id2 = range_a.getCell(1, col).getDisplayValue().toString();
  
  //        id
  var pos_pic1 = RowOfId(id1, range_p);
  var pos_pic2 = RowOfId(id2, range_p);
  
  // ,       id
  if (pos_pic1 != -1) {
    //       ,
    //      
    var pic1_f = range_p.getCell(pos_pic1, 2).getFormula();
    range_a.getCell(2, 1).setFormula(pic1_f);
  }
  else
  {
    range_a.getCell(2, 1).setValue("X");
  }
  
  if (pos_pic2 != -1) {
    var pic2_f = range_p.getCell(pos_pic2, 2).getFormula();
    range_a.getCell(2, 2).setFormula(pic2_f);
  }
  else
  {
    range_a.getCell(2, 2).setValue("X");
  }
}

//        id
function RowOfId(id, rng) {  
  var height = rng.getHeight();
  var data = rng.getValues();
  
  for (var i = 1; i < height; i++) {    
    if (data[i][0].toString() == id) {
      return i + 1;
    }
  }
  
  return -1;
}
      
      



. 150 , Google Sheets ( ). -, Google App Script .





//        Google Drive
function LoadPicturesFromDrive() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet_p = ss.getSheetByName("");
  var range_p = sheet_p.getDataRange();
  
  var art_folder = DriveApp.getRootFolder().getFoldersByName("  ").next()
  var files = art_folder.getFiles();
  
  //     
  var i = 1;
  while (files.hasNext()) {
    var file = files.next();
    
    var file_name = file.getName();
    //     id 
    var id = file_name.slice(0, file_name.indexOf("."));
    
    //  id  
    sheet_p.getRange(i + 1, 1).setValue(id);
    
    //     
    file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
    var file_id = file.getId();
    
    //        IMAGE
    sheet_p.getRange(i + 1, 2).setFormula("=IMAGE(\"" + "https://drive.google.com/uc?export=download&id=" + file_id + "\")");
    
    i = i + 1;
  }
}
      
      



, Google Sheets Google Drive, - 10% . , , , . API Dropbox, . Dropbox , , .





//        Dropbox
function LoadPicturesFromDropbox() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet_p = ss.getSheetByName("");
  var range_p = sheet_p.getDataRange();
  
  //    POST-
  var data = {
    "path": "",
    "recursive": false,
    "include_media_info": false,
    "include_deleted": false,
    "include_has_explicit_shared_members": false,
    "include_mounted_folders": true,
    "include_non_downloadable_files": true
  };
  var payload = JSON.stringify(data);
  
  var options = {
    "method" : "POST",
    "contentType" : "application/json",
    "headers" : {
       "Authorization" : "Bearer [ ]"
    },
    "payload" : payload,
    muteHttpExceptions : true
  };
  
  //  POST-      
  var url = "https://api.dropboxapi.com/2/files/list_folder";
  var response = UrlFetchApp.fetch(url, options);
  var json = JSON.parse(response.getContentText());
  
  //    
  for (var i = 0; i < json.entries.length; i++) {
    var name = json.entries[i].name;
    //     
    CreateSharedLink(name);
    var sh_link = GetSharedLink(name);
    
    //     id 
    id = name.slice(0, name.indexOf("."))
  
    //        IMAGE
    sheet_p.getRange(i + 2, 1).setValue(id);
    sheet_p.getRange(i + 2, 2).setFormula("=IMAGE(\"" + sh_link+"\")");
  }
}

//      
function CreateSharedLink(name) {
  //    POST-
  var data = {
    "path": ("/" + name),
    "settings": {
        "requested_visibility": "public",
        "audience": "public",
        "access": "viewer"
    }
  };
  var payload = JSON.stringify(data);
  
  var options = {
    "method" : "POST",
    "contentType" : "application/json",
    "headers" : {
       "Authorization" : "Bearer [ ]"
    },
    "payload" : payload,
    muteHttpExceptions : true
  };
  
  //  POST-      
  var url = "https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings";
  var response = UrlFetchApp.fetch(url, options);
}

//     
function GetSharedLink(name) {
  //    POST-
  var data = {
    "path": ("/" + name)
  };
  var payload = JSON.stringify(data);
  
  var options = {
    "method" : "POST",
    "contentType" : "application/json",
    "headers" : {
       "Authorization" : "Bearer [ ]"
    },
    "payload" : payload,
    muteHttpExceptions : true
  };
  
  //  POST-      
  var url = "https://api.dropboxapi.com/2/sharing/list_shared_links";
  var response = UrlFetchApp.fetch(url, options);
  var json = JSON.parse(response.getContentText());
  
  //       
  var urlForDownload = json.links[0].url.slice(0, -1) + '1';
  
  return urlForDownload;
}
      
      



Gephi ( ) CSV. : (: id, label) (: source, target, weight).





//         
function CreateGraph() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet_a = ss.getSheetByName("");
  var range_a = sheet_a.getDataRange();
  var data = range_a.getValues();
  var height = range_a.getHeight();
  
  //   
  var sheet_lbl = ss.getSheetByName("Graph Labels");
  //    
  var sheet_edg = ss.getSheetByName("Graph Edges");
  
  //     
  var weights = new Array("1", "2", "3");
  var edg_num = 0;
  
  //    
  var lbl_header = ["Id", "Label"];
  //     
  var edg_header = ["Source", "Target", "Weight"];
  
  //  
  sheet_lbl.clear();
  sheet_edg.clear();
  
  //    
  sheet_lbl.appendRow(lbl_header);
  sheet_edg.appendRow(edg_header);
  
  // ,        
  var tmp_arr = [];
  var tmp_arr_len = 0;
  
  //     (  )
  for (var i = 2; i < height; i++) {
    var id1 = data[i][0];
    var name1 = data[i][1];
    
    //      
    var lbl_row = [id1, name1];
    sheet_lbl.appendRow(lbl_row);
    
    for (var j = i + 1; j < height; j++) {
      var wt = data[i][j].toString();
      
      if (weights.includes(wt)) {
        var id2 = data[0][j];
        edg_num += 1;
        
        var edg_row = [id1, id2, wt];
        
        tmp_arr.push(edg_row);
        tmp_arr_len += 1;
        
        //      100 ,     .
        //        ,   
        //     Google App Script
        if (tmp_arr_len >= 100) {
          sheet_edg.getRange(sheet_edg.getLastRow() + 1, 1, tmp_arr_len, 3).setValues(tmp_arr);
          tmp_arr = [];
          tmp_arr_len = 0;
        }
      }
    }
  }
  
  //        
  if (tmp_arr_len > 0) {
    sheet_edg.getRange(sheet_edg.getLastRow() + 1, 1, tmp_arr_len, 3).setValues(tmp_arr);
    tmp_arr = [];
    tmp_arr_len = 0;
  }
}
      
      



Gephi ( ). , , , . .





, , . , “1” , . “2” “3”. .





, , , - . “”, . “” “” Gephi. , 100 :





, , “” . , . “”. , .





Tentu saja, dalam hal visualisasi grafik dan metode analisisnya, masih ada pekerjaan yang harus dilakukan, tetapi pendekatan ini telah menunjukkan dirinya dengan baik. Jika Anda juga menggunakan grafik dalam pengembangan game Anda, akan sangat menarik untuk mengetahui pengalaman Anda.






Jika Anda tertarik mengikuti perkembangan proyek, berlangganan grup game VKontakte dan Instagram . Di sinilah saya memposting catatan pengembangan, cuplikan plot, dan banyak lagi.








All Articles