Bots de conversa de Telegram amb Google Apps Script

Bots de conversa Exemples Dades pràctiques   Recursos CITCEA
Google Apps Script Projectes Interacció   Inici

Joc de Mastermind

El Mastermind original és un joc de taula en el que s'amaga una combinació de quatre fitxes triades entre sis colors (que es poden repetir) i el jugador ha d'encertar la combinació. Cada cop que el jugador proposa una combinació, se li indica quantes fitxes ha encertat i de quantes n'ha encertat el color però no estan al seu lloc.

En el nostre cas, no és gaire factible treballar amb colors i convé que el jugador pugui introduir fàcilment el codi que proposa, per tant la combinació consisteix en quatre xifres entre 1 i 6. S'ha dissenyat, però, de manera que sigui fàcil fer servir lletres o símbols en lloc de xifres i també que la combinació pugui ser d'un nombre d'elements diferent de quatre.

La combinació amagada i el nombre de tirades que porta l'usuari es guarden a la memòria cau per tal de tenir-les disponibles cada cop que s'executa l'script. La clau és l'identificador de l'usuari. Atès que la memòria cau no treballa bé amb vectors, les dades es guarden en format de text; concretament en una seqüència de caràcters en la que els quatre primers són la combinació desada, el cinquè és el símbol ^ (que fa de separador) i després el número de tirada que està guardat.

En començar la partida es crea la combinació secreta, s'inicialitza el comptador i es faciliten les instruccions. A cada tirada es comprova que l'usuari ha introduït una combinació acceptable i se l'informa dels encerts i les aproximacions de la seva proposta. La funció que mira els encerts va canviant els digits comptats per símbols ($ i %) per evitar que el mateix dígit sigui comptat més d'un cop. Això vol dir que si es decideix fer servir símbols en la combinació caldria evitar aquests dos o modificar la funció de comprovació per tal que faci servir altres caràcters.

El programa de l'script és el següent:

var token = "^^34328844:AAFIpk-e7j3UZtYQYQaTduf4hEhnDqIcNXI"; // API Token de Telegram 
var telegramUrl = "https://api.telegram.org/bot" + token;  // URL que comunica el bot de conversa amb Telegram 
// Vector que conté les diferents opcions de fitxes
// Atès que tot es basa en aquest vector, modificant-lo podem fer que 
//   el joc es basi en lletres o en símbols en lloc de xifres
// Els símbols % i $ es fan servir en el programa
// També es pot modificar el nombre d'opcions
var opcions = ["1", "2", "3", "4", "5", "6"];
var numPos = 4;  // Nombre d'elements a encertar
function doPost(e){
  var data = JSON.parse(e.postData.contents);  // Llegeix les dades rebudes per JSON i les guarda
  var text = data.message.text;  // Comanda enviada
  var id = data.message.chat.id;  // Identificador de la finestra d'on prové el missatge 
  var realitzat = false;
  if (text == '/help'){
    realitzat = true;
    var resposta = "Comandes disponibles:\n";
    resposta = resposta + "/help  -  Llista de comandes\n";
    resposta = resposta + "/mastermind  -  Comença una partida\n";
    resposta = resposta + "/final  -  Finalitza i esborra la partida actual\n";
    resposta = resposta + "/t XXXX  -  Fa un nou intent per encertar el codi amagat\n";
    sendText(id,resposta);
  }
  if(text == "/mastermind"){
    realitzat = true;
    inici(id);
  }
  if(text == "/final"){
    realitzat = true;
    final(id);
  }
  if(text.indexOf("/t") == 0){
    realitzat = true;
    tirada(id, text);
  }
  if (!realitzat){
    var resposta = "Comanda desconeguda";
    sendText(id,resposta);
  }
}
function inici(chatId){
  var combi = "";
  for(var i=0; i<numPos; i++){
    var pnt = Math.floor(Math.random() * opcions.length);
    combi = combi + opcions[pnt];
  }
  //sendText(chatId,"La combinació triada és " + combi);  // Línia només per fer proves
  combi = combi + "^0";  // Hi afegim un comptador per saber quantes tirades porta l'usuari
  var cache = CacheService.getScriptCache();
  cache.put(chatId, combi);  // Guardem la tirada a la memòria cau
  var resposta = "Comença la partida\n";
  resposta = resposta + "Pots fer servir les opcions  ";
  for(var i=0; i<opcions.length; i++){
    resposta = resposta + " " + opcions[i];
  }
  combi = "";
  resposta = resposta + "\nPer exemple, una tirada podria ser:\n";
  for(var i=0; i<numPos; i++){
    var pnt = Math.floor(Math.random() * opcions.length);
    combi = combi + opcions[pnt];
  }
  resposta = resposta + "/t " + combi + "\n\n";
  resposta = resposta + "Jo et contestaré coses com  1e 2a  ";
  resposta = resposta + "on e són els encerts i a els valors que són a la ";
  resposta = resposta + "combinació però en una posició diferent de la indicada\n\n";
  resposta = resposta + "Sort!";
  sendText(chatId,resposta);
}
function final(chatId){
  var cache = CacheService.getScriptCache();
  cache.remove(chatId);  // Esborrem les dades de la memòria cau
  var resposta = "S'ha esborrat la partida\n";
  sendText(chatId,resposta);
}
function tirada(chatId, txt){
  var cache = CacheService.getScriptCache();
  var anterior = cache.get(chatId);  // Llegim les dades de la memòria cau
  if (!anterior){
    var resposta = "No tens cap partida començada (o ha caducat)";
    sendText(chatId,resposta);
  } else {
    var text = anterior.split("^");
    var combi = text[0];
    var numTir = +text[1] + 1;
    var tirada = txt.substring(2,txt.length);  // Agafa el valor introduït per l'usuari
    tirada = tirada.replace(" ","");  // Suprimeix possibles espais
    if(correcte(tirada)){
      var result = comprova(combi, tirada);
      if(result == "fi"){
        var resposta = "El codi amagat era " + combi + "\n";
        resposta = resposta + "Ho has encertat en " + numTir + " tirades\n";
        resposta = resposta + "Enhorabona!";
        sendText(chatId,resposta);
        var cache = CacheService.getScriptCache();
        cache.remove(chatId);  // Esborrem les dades de la memòria cau
      } else {
        combi = combi + "^" + numTir;  // Hi afegim un comptador per saber quantes tirades porta l'usuari
        var cache = CacheService.getScriptCache();
        cache.put(chatId, combi);  // Guardem la tirada a la memòria cau
        var resposta = numTir + "  >>  " + tirada + "  >>  " + result + "\n";
        sendText(chatId,resposta);
      }
    } else {
      var resposta = "La teva tirada no és correcta";
      sendText(chatId,resposta);
    }
  }
}
function comprova(comb, tir){
  var combi = comb.split("");  // Converteix en vector
  var tirad = tir.split("");
  var ne = 0;
  var na = 0;
  for(var i=0; i<tirad.length; i++){
    if(tirad[i] == combi[i]){
      tirad[i] = "$";
      combi[i] = "%";
      ne++;
    }
  }
  if(ne == numPos){
    return "fi";
  }
  for(var i=0; i<tirad.length; i++){
    for(var j=0; j<combi.length; j++){
      if(tirad[i] == combi[j]){
        tirad[i] = "$";
        combi[j] = "%";
        na++;
      }
    }
  }
  return ne + "e " + na + "a";
}
function correcte(tir){
  var corr = false;
  if(tir.length == numPos){
    var cpt = 0;
    for(var i=0; i<numPos; i++){
      var char = tir.substring(i,i+1);
      for(var j=0; j<opcions.length; j++){
        if(char == opcions[j]){
          cpt++;
        }
      }
    }
    if(cpt == numPos){
      corr = true;
    }
  }
  return corr;
}
function sendText(chatId,text_env,keyBoard){  // Funció que prepara per enviar un text o un teclat a Telegram 
  keyBoard = keyBoard || 0;
  if(keyBoard.inline_keyboard || keyBoard.keyboard){
    var data = {
      method: "post",
      payload: {
        method: "sendMessage",
        chat_id: String(chatId),
        text: text_env,
        parse_mode: "HTML",
        reply_markup: JSON.stringify(keyBoard)
      }
    }
  } else {
    var data = {
      method: "post",
      payload: {
        method: "sendMessage",
        chat_id: String(chatId),
        text: text_env,
        parse_mode: "HTML"
      }
    }
  }
  UrlFetchApp.fetch( telegramUrl + '/', data);
}

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.