Turnierklammer erstellen

Programmierkenntnisse: Anfänger 
Dauer: 5 Minuten 
Projekttyp: Automatisierung mit einem benutzerdefinierten Menü

Ziele

  • Verstehen, was die Lösung bewirkt.
  • Informationen zur Funktionsweise der Apps Script-Dienste in der Lösung.
  • Richten Sie das Skript ein.
  • Führen Sie das Skript aus.

Informationen zu dieser Lösung

Erstellen Sie ein Turnierbaumdiagramm für bis zu 64 Personen oder Teams. Mit dieser Lösung wird ein Baumdiagramm erstellt, das ein K.-o.-Turnier darstellt.

Screenshot eines Turnierbaums

Funktionsweise

Das Skript durchläuft die Liste der Spieler und ermittelt, wie viele Runden im Bracket erforderlich sind. Das Skript formatiert das Tabellenblatt Bracket, um das Baumdiagramm zu erstellen, und fügt die Namen der Spieler in der ersten Runde hinzu.

Apps Script-Dienste

Für diese Lösung wird der folgende Dienst verwendet:

Tabellendienst: Ruft den Bereich der Spieler ab und erstellt das Baumdiagramm für das Turnier.

Vorbereitung

Für dieses Beispiel müssen die folgenden Voraussetzungen erfüllt sein:

  • Ein Google-Konto (für Google Workspace-Konten ist möglicherweise die Genehmigung durch den Administrator erforderlich).
  • Ein Webbrowser mit Internetzugriff.

Skript einrichten

Klicken Sie auf die folgende Schaltfläche, um eine Kopie der Beispieltabellenkalkulation Turnierbaum erstellen zu erstellen.
Kopie erstellen

Skript ausführen

  1. Klicken Sie in der kopierten Tabelle auf Bracket Maker > Bracket erstellen. Möglicherweise müssen Sie die Seite aktualisieren, damit dieses benutzerdefinierte Menü angezeigt wird.
  2. Autorisieren Sie das Skript, wenn Sie dazu aufgefordert werden. Wenn auf dem OAuth-Zustimmungsbildschirm die Warnung Diese App ist nicht verifiziert angezeigt wird, wählen Sie Erweitert > Zu {Projektname} (unsicher) aus.

  3. Klicken Sie noch einmal auf Bracket-Generator > Bracket erstellen.

  4. Wechseln Sie zum Tab Bracket, um das Turnier-Bracket aufzurufen.

Code ansehen

Wenn Sie den Apps Script-Code für diese Lösung ansehen möchten, klicken Sie unten auf Quellcode ansehen:

Quellcode ansehen

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');
}

Beitragende

Dieses Beispiel wird von Google mit Unterstützung von Google Developer Experts verwaltet.

Nächste Schritte