Criar uma chave do torneio

Nível de programação: iniciante
Duração: 5 minutos
Tipo de projeto: automação com um menu personalizado

Objetivos

  • Entenda o que a solução faz.
  • Entenda o que os serviços do Apps Script fazem no solução.
  • Configure o script.
  • Execute o script.

Sobre esta solução

Crie uma chave de torneio para até 64 pessoas ou equipes. Essa solução cria um diagrama de árvore que representa um torneio eliminatório.

Captura de tela de uma chave de torneio

Como funciona

O script percorre a lista de jogadores e determina quantas rodadas são necessárias necessário na chave. O script formata a planilha Bracket para criar o diagrama de árvore e adiciona os pontos para a primeira rodada.

Serviços do Apps Script

Esta solução usa o seguinte serviço:

Serviço de planilha: recebe o intervalo de jogadores e cria o diagrama de árvore do torneio.

Pré-requisitos

Para usar este exemplo, você precisa dos seguintes pré-requisitos:

  • Uma Conta do Google (as contas do Google Workspace podem precisam da aprovação do administrador).
  • Um navegador da Web com acesso à Internet.

Configurar o script

Clique no botão a seguir para copiar Criar uma chave de torneio. planilha de amostra.
Fazer uma cópia

Executar o script

  1. Na planilha copiada, clique em Fabricante de chaveiro > Criar colchete. Talvez seja necessário atualizar a página para que esse menu personalizado apareça.
  2. Quando solicitado, autorize o script. Se a tela de permissão OAuth exibir o aviso Este app não foi verificado, continue selecionando Avançado > Acesse {Project Name} (não seguro).

  3. Clique em Fabricante de broquetes. > Criar colchete novamente.

  4. Alterne para a guia Chave para ver a chave do torneio.

Revisar o código

Para revisar o código do Apps Script para esta solução, clique em Veja o código-fonte abaixo:

Acessar o código-fonte

Code.gs

solutions/automations/bracket-maker/Code.js
// To learn how to use this script, refer to the documentation:
// https://developers.google.com/apps-script/samples/automations/bracket-maker

/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

const RANGE_PLAYER1 = 'FirstPlayer';
const SHEET_PLAYERS = 'Players';
const SHEET_BRACKET = 'Bracket';
const CONNECTOR_WIDTH = 15;

/**
 * Adds a custom menu item to run the script.
 */
function onOpen() {
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  ss.addMenu('Bracket maker',
             [{name: 'Create bracket', functionName: 'createBracket'}]);
}

/**
 * Creates the brackets based on the data provided on the players.
 */
function createBracket() {
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let rangePlayers = ss.getRangeByName(RANGE_PLAYER1);
  let sheetControl = ss.getSheetByName(SHEET_PLAYERS);
  let sheetResults = ss.getSheetByName(SHEET_BRACKET);

  // Gets the players from column A.  Assumes the entire column is filled.
  rangePlayers = rangePlayers.offset(0, 0, sheetControl.getMaxRows() -
      rangePlayers.getRowIndex() + 1, 1);
  let players = rangePlayers.getValues();

  // Figures out how many players there are by skipping the empty cells.
  let numPlayers = 0;
  for (let i = 0; i < players.length; i++) {
    if (!players[i][0] || players[i][0].length == 0) {
      break;
    }
    numPlayers++;
  }
  players = players.slice(0, numPlayers);

  // Provides some error checking in case there are too many or too few players/teams.
  if (numPlayers > 64) {
    Browser.msgBox('Sorry, this script can only create brackets for 64 or fewer players.');
    return; // Early exit
  }

  if (numPlayers < 3) {
    Browser.msgBox('Sorry, you must have at least 3 players.');
    return; // Early exit
  }

  // Clears the 'Bracket' sheet and all formatting.
  sheetResults.clear();

  let upperPower = Math.ceil(Math.log(numPlayers) / Math.log(2));

  // Calculates the number that is a power of 2 and lower than numPlayers.
  let countNodesUpperBound = Math.pow(2, upperPower);

  // Calculates the number that is a power of 2 and higher than numPlayers.
  let countNodesLowerBound = countNodesUpperBound / 2;

  // Determines the number of nodes that will not show in the 1st level.
  let countNodesHidden = numPlayers - countNodesLowerBound;

  // Enters the players for the 1st round.
  let currentPlayer = 0;
  for (let i = 0; i < countNodesLowerBound; i++) {
    if (i < countNodesHidden) {
      // Must be on the first level
      let rng = sheetResults.getRange(i * 4 + 1, 1);
      setBracketItem_(rng, players);
      setBracketItem_(rng.offset(2, 0, 1, 1), players);
      setConnector_(sheetResults, rng.offset(0, 1, 3, 1));
      setBracketItem_(rng.offset(1, 2, 1, 1));
    } else {
      // This player gets a bye.
      setBracketItem_(sheetResults.getRange(i * 4 + 2, 3), players);
    }
  }

  // Fills in the rest of the bracket.
  upperPower--;
  for (let i = 0; i < upperPower; i++) {
    let pow1 = Math.pow(2, i + 1);
    let pow2 = Math.pow(2, i + 2);
    let pow3 = Math.pow(2, i + 3);
    for (let j = 0; j < Math.pow(2, upperPower - i - 1); j++) {
      setBracketItem_(sheetResults.getRange((j * pow3) + pow2, i * 2 + 5));
      setConnector_(sheetResults, sheetResults.getRange((j * pow3) + pow1, i * 2 + 4, pow2 + 1, 1));
    }
  }
}

/**
 * Sets the value of an item in the bracket and the color.
 * @param {Range} rng The Spreadsheet Range.
 * @param {string[]} players The list of players.
 */
function setBracketItem_(rng, players) {
  if (players) {
    let rand = Math.ceil(Math.random() * players.length);
    rng.setValue(players.splice(rand - 1, 1)[0][0]);
  }
  rng.setBackgroundColor('yellow');
}

/**
 * Sets the color and width for connector cells.
 * @param {Sheet} sheet The spreadsheet to setup.
 * @param {Range} rng The spreadsheet range.
 */
function setConnector_(sheet, rng) {
  sheet.setColumnWidth(rng.getColumnIndex(), CONNECTOR_WIDTH);
  rng.setBackgroundColor('green');
}

Colaboradores

Este exemplo é mantido pelo Google com a ajuda de especialistas do Google Developers.

Próximas etapas