diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2025-05-26 15:55:29 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2025-05-26 15:55:29 +0200 |
| commit | 47cb23ce1f991c21ceb9273cf4bed717a09abd9a (patch) | |
| tree | 90f6e3299abf5ec632123513fc80959f3336e15e | |
Kickoff commit
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | augment.py | 194 | ||||
| -rw-r--r-- | csp.js | 181 | ||||
| -rw-r--r-- | data.json | 86 | ||||
| -rw-r--r-- | example-output.txt | 912 | ||||
| -rw-r--r-- | index.html | 13 | ||||
| -rw-r--r-- | requirements.txt | 1 | ||||
| -rw-r--r-- | style.css | 21 | ||||
| -rw-r--r-- | tabularasa.js | 284 |
9 files changed, 1698 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6d50316 --- /dev/null +++ b/Makefile | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | install: venv | ||
| 2 | venv/bin/pip install --upgrade pip | ||
| 3 | venv/bin/pip install -r requirements.txt | ||
| 4 | |||
| 5 | venv: | ||
| 6 | python3 -m venv ./venv | ||
diff --git a/augment.py b/augment.py new file mode 100644 index 0000000..d96d511 --- /dev/null +++ b/augment.py | |||
| @@ -0,0 +1,194 @@ | |||
| 1 | import json | ||
| 2 | from pprint import pprint | ||
| 3 | from random import randrange, randint | ||
| 4 | |||
| 5 | league_count = 4 | ||
| 6 | tabelle = [] | ||
| 7 | |||
| 8 | with open('data.json') as f: | ||
| 9 | data = json.load(f) | ||
| 10 | |||
| 11 | ident = 0 | ||
| 12 | for o in data["orte"]: | ||
| 13 | o["id"] = ident | ||
| 14 | o["raucher"] = not randrange(2) | ||
| 15 | o["teams"] = [] | ||
| 16 | ident += 1 | ||
| 17 | |||
| 18 | ident = 0 | ||
| 19 | for t in data["teams"]: | ||
| 20 | |||
| 21 | t["id"] = ident | ||
| 22 | t["tag"] = randrange(7) | ||
| 23 | t["liga"] = randrange(league_count) | ||
| 24 | t["nichtraucher"] = not randrange(4) | ||
| 25 | |||
| 26 | team_nr = t["nichtraucher"] | ||
| 27 | |||
| 28 | found = False | ||
| 29 | while not found: | ||
| 30 | heimort = randrange(len(data["orte"])) | ||
| 31 | ersatzort = randrange(len(data["orte"])) | ||
| 32 | |||
| 33 | if data["orte"][ersatzort]["raucher"]: | ||
| 34 | continue | ||
| 35 | |||
| 36 | ort_nr = not data["orte"][heimort]["raucher"] | ||
| 37 | |||
| 38 | if team_nr != ort_nr: | ||
| 39 | continue | ||
| 40 | |||
| 41 | if team_nr: | ||
| 42 | ersatzort = -1 | ||
| 43 | |||
| 44 | found = True | ||
| 45 | |||
| 46 | t["ersatzort"] = ersatzort | ||
| 47 | t["heimort"] = heimort | ||
| 48 | data["orte"][heimort]["teams"].append(ident) | ||
| 49 | |||
| 50 | ident += 1 | ||
| 51 | |||
| 52 | # Count necessary spieltage | ||
| 53 | max_spieltage = 0 | ||
| 54 | for league in range(league_count): | ||
| 55 | pairings_count = len([t for t in data["teams"] if t["liga"] == league]) | ||
| 56 | if pairings_count % 2: | ||
| 57 | pairings_count += 1 | ||
| 58 | max_spieltage = max(2 * (pairings_count - 1), max_spieltage); | ||
| 59 | |||
| 60 | print( "Max Spieltage: ", max_spieltage) | ||
| 61 | |||
| 62 | # Fill Tabelle with our demo data | ||
| 63 | ident = 0 | ||
| 64 | for league in range(league_count): | ||
| 65 | league_teams = [t for t in data["teams"] if t["liga"] == league] | ||
| 66 | |||
| 67 | for team_a in league_teams: | ||
| 68 | game_count = 0 | ||
| 69 | |||
| 70 | for team_b in league_teams: | ||
| 71 | if team_a["id"] == team_b["id"]: continue | ||
| 72 | |||
| 73 | # If Heimspiel-Team is smokers and the Gastteam is not, the alternative | ||
| 74 | # location needs to be chosen | ||
| 75 | ort = next((ort for ort in data["orte"] if ort["id"] == team_a["heimort"]), None) | ||
| 76 | if team_b["nichtraucher"] and ort["raucher"]: | ||
| 77 | ort = next((ort for ort in data["orte"] if ort["id"] == team_a["ersatzort"]), None) | ||
| 78 | |||
| 79 | tabelle.append({"team_a": team_a["id"], "team_b": team_b["id"], "liga": league, "ort": ort["id"], "tag": team_a["tag"], "id": ident}) | ||
| 80 | ident += 1 | ||
| 81 | game_count += 1 | ||
| 82 | |||
| 83 | while game_count < max_spieltage / 2: | ||
| 84 | tabelle.append({"team_a": team_a["id"], "team_b": -1, "liga": league, "ort": -1, "tag": -1, "id": ident}) | ||
| 85 | ident += 1 | ||
| 86 | tabelle.append({"team_a": -1, "team_b": team_a["id"], "liga": league, "ort": -1, "tag": -1, "id": ident}) | ||
| 87 | ident += 1 | ||
| 88 | game_count += 1 | ||
| 89 | |||
| 90 | rueckrundenstart = max_spieltage // 2 | ||
| 91 | |||
| 92 | from ortools.sat.python import cp_model | ||
| 93 | model = cp_model.CpModel() | ||
| 94 | |||
| 95 | variables = {game["id"]: model.new_int_var(0, max_spieltage - 1, f"game{game['id']}") for game in tabelle} | ||
| 96 | |||
| 97 | # Make sure each team only plays once each spieltag | ||
| 98 | for team in data["teams"]: | ||
| 99 | # team_games = [game["id"] for game in tabelle if game["team_a"] == team["id"] or game["team_b"] == team["id"]] | ||
| 100 | # print (len(team_games), team_games, team) | ||
| 101 | model.add_all_different([variables[game["id"]] for game in tabelle if game["team_a"] == team["id"] or game["team_b"] == team["id"]]) | ||
| 102 | |||
| 103 | # Make sure each ort is only used once per spieltag+week | ||
| 104 | for ort in data["orte"]: | ||
| 105 | ort_games = [game for game in tabelle if game["ort"] == ort["id"]] | ||
| 106 | for tag in list({game["tag"] for game in ort_games}): | ||
| 107 | model.add_all_different([variables[game["id"]] for game in ort_games if game["tag"] == tag ]) | ||
| 108 | |||
| 109 | # Make sure that Rueckrundenspiele only happen at Rueckrunde | ||
| 110 | for game in tabelle: | ||
| 111 | # Don't force this constraint on wildcard games | ||
| 112 | if game["ort"] == -1: continue | ||
| 113 | |||
| 114 | # Find Rueckspiel | ||
| 115 | rueckspiel = next((candidate for candidate in tabelle if candidate["team_a"] == game["team_b"] and candidate["team_b"] == game["team_a"]), None) | ||
| 116 | |||
| 117 | va = variables[game["id"]] | ||
| 118 | vb = variables[rueckspiel["id"]] | ||
| 119 | |||
| 120 | runde_a = model.new_int_var(0, 1, "tmpa") | ||
| 121 | runde_b = model.new_int_var(0, 1, "tmpb") | ||
| 122 | |||
| 123 | model.add_division_equality(runde_a, va, rueckrundenstart) | ||
| 124 | model.add_division_equality(runde_b, vb, rueckrundenstart) | ||
| 125 | model.add(runde_a != runde_b) | ||
| 126 | |||
| 127 | # Make sure that Heimspiele and Gastspiele alternate | ||
| 128 | violations = [] | ||
| 129 | for team in data["teams"]: | ||
| 130 | heimspiele = [candidate for candidate in tabelle if candidate["team_a"] == team["id"] ] | ||
| 131 | |||
| 132 | for heimspiel in heimspiele: | ||
| 133 | for conflict in heimspiele: | ||
| 134 | if heimspiel["id"] == conflict["id"]: continue | ||
| 135 | |||
| 136 | va = variables[heimspiel["id"]] | ||
| 137 | vb = variables[conflict["id"]] | ||
| 138 | |||
| 139 | tmpdiff_a = model.new_int_var(-max_spieltage, max_spieltage, "tmpa") | ||
| 140 | tmpdiff_b = model.new_int_var(-max_spieltage, max_spieltage, "tmpb") | ||
| 141 | |||
| 142 | model.add(tmpdiff_a == va - vb) | ||
| 143 | model.add(tmpdiff_b == vb - va) | ||
| 144 | |||
| 145 | tmpconsequtive_a = model.new_bool_var("tmpa") | ||
| 146 | tmpconsequtive_b = model.new_bool_var("tmpb") | ||
| 147 | |||
| 148 | model.add(tmpdiff_a == 1).only_enforce_if(tmpconsequtive_a) | ||
| 149 | model.add(tmpdiff_a != 1).only_enforce_if(tmpconsequtive_a.Not()) | ||
| 150 | |||
| 151 | model.add(tmpdiff_b == 1).only_enforce_if(tmpconsequtive_b) | ||
| 152 | model.add(tmpdiff_b != 1).only_enforce_if(tmpconsequtive_b.Not()) | ||
| 153 | |||
| 154 | is_consecutive = model.new_bool_var('is_consecutive') | ||
| 155 | |||
| 156 | model.add_bool_or([tmpconsequtive_a, tmpconsequtive_b]).OnlyEnforceIf(is_consecutive) | ||
| 157 | model.add_bool_and([tmpconsequtive_a.Not(), tmpconsequtive_b.Not()]).OnlyEnforceIf(is_consecutive.Not()) | ||
| 158 | |||
| 159 | violations.append(is_consecutive) | ||
| 160 | |||
| 161 | model.minimize(sum(violations)) | ||
| 162 | |||
| 163 | print ("All set, solving") | ||
| 164 | |||
| 165 | solver = cp_model.CpSolver() | ||
| 166 | solver.parameters.max_time_in_seconds = 30.0 | ||
| 167 | solver.parameters.random_seed = randint(0, 1_000_000) | ||
| 168 | status = solver.solve(model) | ||
| 169 | print(status, solver.status_name()) | ||
| 170 | |||
| 171 | from sys import exit | ||
| 172 | if status == cp_model.INFEASIBLE: | ||
| 173 | exit(-1) | ||
| 174 | |||
| 175 | for game in tabelle: | ||
| 176 | game["spieltag"] = solver.value(variables[game["id"]]) | ||
| 177 | |||
| 178 | # tabelle.sort(key=lambda game: game["spieltag"]) | ||
| 179 | |||
| 180 | # PRINT OUT RESULTS AS TABLE | ||
| 181 | all_teams = {team["id"]: team for team in data["teams"]} | ||
| 182 | all_teams[-1] = {"name": "*"} | ||
| 183 | all_orte = {ort["id"]: ort for ort in data["orte"]} | ||
| 184 | all_orte[-1] = {"name": "*"} | ||
| 185 | |||
| 186 | for league in range(league_count): | ||
| 187 | league_tabelle = [game for game in tabelle if game["liga"] == league] | ||
| 188 | league_tabelle.sort(key=lambda game: game["spieltag"]) | ||
| 189 | |||
| 190 | for game in league_tabelle: | ||
| 191 | print(game["spieltag"], all_teams[game["team_a"]]["name"], "::", all_teams[game["team_b"]]["name"], "::", all_orte[game["ort"]]["name"]) | ||
| 192 | |||
| 193 | #print( json.dumps(data)) | ||
| 194 | #print( json.dumps(tabelle)) | ||
| @@ -0,0 +1,181 @@ | |||
| 1 | !function() { | ||
| 2 | |||
| 3 | var CSP = {}, | ||
| 4 | FAILURE = 'FAILURE', | ||
| 5 | stepCounter = 0; | ||
| 6 | |||
| 7 | CSP.solve = function solve(csp) { | ||
| 8 | // Solves a constraint satisfaction problem. | ||
| 9 | // `csp` is an object that should have the properties: | ||
| 10 | // `variables` : object that holds variable names and their domain. | ||
| 11 | // `constraints`: list of constraints where each element is an | ||
| 12 | // array of [head node, tail node, constraint function] | ||
| 13 | // `cb`: callback function for visualizing assignments. It is passed in | ||
| 14 | // an "assigned" object, an "unassigned" object, and `csp`. | ||
| 15 | // `timeStep`: milliseconds between invocations of `cb`. | ||
| 16 | |||
| 17 | csp.timeStep = csp.timeStep || 1; | ||
| 18 | var result = backtrack({}, csp.variables, csp); | ||
| 19 | if (result == FAILURE) { return result; } | ||
| 20 | // Unwrap values from array containers. | ||
| 21 | for (var key in result) { | ||
| 22 | result[key] = result[key][0]; | ||
| 23 | } | ||
| 24 | return result; | ||
| 25 | } | ||
| 26 | |||
| 27 | function backtrack(_assigned, unassigned, csp) { | ||
| 28 | // Backtracking search. | ||
| 29 | |||
| 30 | // Copying assigned in necessary because we modify it. Without copying | ||
| 31 | // the object over, modifying assigned would also change values for old | ||
| 32 | // assigned objects (which are used in callbacks). | ||
| 33 | var assigned = {}; | ||
| 34 | for (var key in _assigned) { assigned[key] = _assigned[key]; } | ||
| 35 | |||
| 36 | if (finished(unassigned)) { return assigned; } // Base case. | ||
| 37 | var nextKey = selectUnassignedVariable(unassigned), | ||
| 38 | values = orderValues(nextKey, assigned, unassigned, csp); | ||
| 39 | delete unassigned[nextKey]; | ||
| 40 | |||
| 41 | for (var i = 0; i < values.length; i++) { | ||
| 42 | stepCounter++; | ||
| 43 | assigned[nextKey] = [values[i]]; // Assign a value to a variable. | ||
| 44 | var consistent = enforceConsistency(assigned, unassigned, csp); | ||
| 45 | var newUnassigned = {}, newAssigned = {}; | ||
| 46 | for (var key in consistent) { | ||
| 47 | if (assigned[key]) { newAssigned[key] = assigned[key].slice(); } | ||
| 48 | else { newUnassigned[key] = consistent[key].slice(); } | ||
| 49 | } | ||
| 50 | if (csp.cb) { | ||
| 51 | setTimeout( | ||
| 52 | // Need a closure to fix values of newAssigned and newUnassigned. | ||
| 53 | // Otherwise, _every_ call of the callback takes the on values of the last iteration. | ||
| 54 | (function (newAssigned, newUnassigned) { | ||
| 55 | return function () { csp.cb(newAssigned, newUnassigned, csp); }; | ||
| 56 | })(newAssigned, newUnassigned), | ||
| 57 | stepCounter * csp.timeStep | ||
| 58 | ); | ||
| 59 | } | ||
| 60 | if (anyEmpty(consistent)) { continue; } // Empty domains means failure. | ||
| 61 | var result = backtrack(newAssigned, newUnassigned, csp); | ||
| 62 | if (result != FAILURE) { return result; } | ||
| 63 | } | ||
| 64 | |||
| 65 | return FAILURE; | ||
| 66 | } | ||
| 67 | |||
| 68 | function finished(unassigned) { | ||
| 69 | // Checks if there are no more variables to assign. | ||
| 70 | return Object.keys(unassigned).length == 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | function anyEmpty(consistent) { | ||
| 74 | // Checks if any variable's domain is empty. | ||
| 75 | for (var key in consistent) { | ||
| 76 | if (consistent[key].length == 0) { return true; } | ||
| 77 | } | ||
| 78 | return false; | ||
| 79 | } | ||
| 80 | |||
| 81 | function partialAssignment(assigned, unassigned) { | ||
| 82 | // Combine unassigned and assigned for use in enforceConsistency. | ||
| 83 | var partial = {}; | ||
| 84 | for (var key in unassigned) { partial[key] = unassigned[key].slice(); } | ||
| 85 | for (var key in assigned) { partial[key] = assigned[key].slice(); } | ||
| 86 | return partial; | ||
| 87 | } | ||
| 88 | |||
| 89 | function enforceConsistency(assigned, unassigned, csp) { | ||
| 90 | // Enforces arc consistency by removing inconsistent values from | ||
| 91 | // every constraint's tail node. | ||
| 92 | |||
| 93 | function removeInconsistentValues(head, tail, constraint, variables) { | ||
| 94 | // Removes inconsistent values from the tail node. A value is | ||
| 95 | // inconsistent when if the `tail` is assigned that value, there are | ||
| 96 | // no values in `head`'s domain that satisfies the constraint. | ||
| 97 | var hv = variables[head], tv = variables[tail]; | ||
| 98 | var validTailValues = tv.filter(function (t) { | ||
| 99 | return hv.some(function (h) { | ||
| 100 | return constraint(h, t); | ||
| 101 | }); | ||
| 102 | }); | ||
| 103 | var removed = tv.length != validTailValues.length; | ||
| 104 | variables[tail] = validTailValues; | ||
| 105 | return removed; | ||
| 106 | } | ||
| 107 | |||
| 108 | function incomingConstraints(node) { | ||
| 109 | // Returns all the constraints where `node` is the head node. | ||
| 110 | return csp.constraints.filter(function (c) { | ||
| 111 | return c[0] == node; | ||
| 112 | }); | ||
| 113 | } | ||
| 114 | |||
| 115 | var queue = csp.constraints.slice(), | ||
| 116 | variables = partialAssignment(assigned, unassigned); | ||
| 117 | while (queue.length) { // While there are more constraints to test. | ||
| 118 | var c = queue.shift(), head = c[0], tail = c[1], constraint = c[2]; | ||
| 119 | if (removeInconsistentValues(head, tail, constraint, variables)) { | ||
| 120 | // If values from the tail have been removed, incoming constraints | ||
| 121 | // to the tail must be rechecked. | ||
| 122 | queue = queue.concat(incomingConstraints(tail)); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | return variables; | ||
| 126 | } | ||
| 127 | |||
| 128 | function selectUnassignedVariable(unassigned) { | ||
| 129 | // Picks the next variable to assign according to the Minimum | ||
| 130 | // Remaining Values heuristic. Pick the variable with the fewest | ||
| 131 | // values remaining in its domain. This helps identify domain | ||
| 132 | // failures earlier. | ||
| 133 | var minKey = null, minLen = Number.POSITIVE_INFINITY; | ||
| 134 | for (var key in unassigned) { | ||
| 135 | var len = unassigned[key].length; | ||
| 136 | if (len < minLen) { minKey = key, minLen = len; } | ||
| 137 | } | ||
| 138 | return minKey; | ||
| 139 | } | ||
| 140 | |||
| 141 | function orderValues(nextKey, assigned, unassigned, csp) { | ||
| 142 | // Orders the values of an unassigned variable according to the | ||
| 143 | // Least Constraining Values heuristic. Perform arc consistency | ||
| 144 | // on each possible value, and order variables according to the | ||
| 145 | // how many values were eliminated from all the domains (fewest | ||
| 146 | // eliminated in the front). This helps makes success more likely | ||
| 147 | // by keeping future options open. | ||
| 148 | |||
| 149 | function countValues(vars) { | ||
| 150 | var sum = 0; | ||
| 151 | for (var key in vars) { sum += vars[key].length; } | ||
| 152 | return sum; | ||
| 153 | } | ||
| 154 | |||
| 155 | function valuesEliminated(val) { | ||
| 156 | assigned[nextKey] = [val]; | ||
| 157 | var newLength = countValues(enforceConsistency(assigned, unassigned, csp)); | ||
| 158 | delete assigned[nextKey]; | ||
| 159 | return newLength; | ||
| 160 | } | ||
| 161 | |||
| 162 | // Cache valuesEliminated to be used in sort. | ||
| 163 | var cache = {}, values = unassigned[nextKey]; | ||
| 164 | values.forEach(function(val) { | ||
| 165 | cache[val] = valuesEliminated(val); | ||
| 166 | }); | ||
| 167 | // Descending order based on the number of domain values remaining. | ||
| 168 | values.sort(function (a, b) { return cache[b] - cache[a]; }); | ||
| 169 | return values; | ||
| 170 | } | ||
| 171 | |||
| 172 | // Taken from d3 source. Makes `csp` usable in other scripts. | ||
| 173 | if (typeof define === 'function' && define.amd) { | ||
| 174 | define(CSP); | ||
| 175 | } else if (typeof module === 'object' && module.exports) { | ||
| 176 | module.exports = CSP; | ||
| 177 | } else { | ||
| 178 | this.csp = CSP; | ||
| 179 | } | ||
| 180 | |||
| 181 | }(); | ||
diff --git a/data.json b/data.json new file mode 100644 index 0000000..8e6c1fa --- /dev/null +++ b/data.json | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | { | ||
| 2 | "teams": [ | ||
| 3 | {"name": "Die Stangendreher" }, | ||
| 4 | {"name": "FC Kurbelkraft" }, | ||
| 5 | {"name": "Die Kugelblitze" }, | ||
| 6 | {"name": "Drehmoment 04" }, | ||
| 7 | {"name": "Kickerknacker" }, | ||
| 8 | {"name": "Stangenterror" }, | ||
| 9 | {"name": "Die Plattenpanther" }, | ||
| 10 | {"name": "Vollstoff United" }, | ||
| 11 | {"name": "Kurbelkönige" }, | ||
| 12 | {"name": "Die Gleitlager" }, | ||
| 13 | {"name": "Dynamo Drehpunkt" }, | ||
| 14 | {"name": "FC Hartkurbel" }, | ||
| 15 | {"name": "Turbo-Tischkicker" }, | ||
| 16 | {"name": "Kugelkontrolle" }, | ||
| 17 | {"name": "Die Griffbanditen" }, | ||
| 18 | {"name": "Tischgewitter" }, | ||
| 19 | {"name": "Rapid Rotation" }, | ||
| 20 | {"name": "Kurbelschmiede" }, | ||
| 21 | {"name": "Die Schussscheiben" }, | ||
| 22 | {"name": "Die Querpassquäler" }, | ||
| 23 | {"name": "Reibungslose Racker" }, | ||
| 24 | {"name": "Die Kugeljäger" }, | ||
| 25 | {"name": "Kurbelclub Chaos" }, | ||
| 26 | {"name": "Die Seitenwechsel" }, | ||
| 27 | {"name": "Drehakademie" }, | ||
| 28 | {"name": "Die Griffgötter" }, | ||
| 29 | {"name": "Kickerkombinat" }, | ||
| 30 | {"name": "Rotationssportverein" }, | ||
| 31 | {"name": "Die Rillenritter" }, | ||
| 32 | {"name": "Stangenhelden" }, | ||
| 33 | {"name": "Kugelkommando" }, | ||
| 34 | {"name": "Kick’n’Twist" }, | ||
| 35 | {"name": "FC Schubkraft" }, | ||
| 36 | {"name": "Die Rutschbahn-Raketen" }, | ||
| 37 | {"name": "Die Taktikdreher" }, | ||
| 38 | {"name": "Die Kickkanonen" }, | ||
| 39 | {"name": "Die Blockbuster" }, | ||
| 40 | {"name": "Vollgas Vierer" }, | ||
| 41 | {"name": "Die Tischwölfe" }, | ||
| 42 | {"name": "Rotation Rangers" }, | ||
| 43 | {"name": "Die Drehlords" }, | ||
| 44 | {"name": "Griffbereit 99" }, | ||
| 45 | {"name": "Die Bandenkrieger" }, | ||
| 46 | {"name": "Ballmagneten" }, | ||
| 47 | {"name": "Stahlstangen SC" }, | ||
| 48 | {"name": "Die Kurbelkicker" }, | ||
| 49 | {"name": "Die Abroller" }, | ||
| 50 | {"name": "Die Plattenspieler" }, | ||
| 51 | {"name": "FC Gummipuffer" }, | ||
| 52 | {"name": "Griff & Gloria" } | ||
| 53 | ], | ||
| 54 | "orte": [ | ||
| 55 | {"name": "Kurbelpark Arena" }, | ||
| 56 | {"name": "Stangenstadion Nord" }, | ||
| 57 | {"name": "Drehpunkt Dome" }, | ||
| 58 | {"name": "Griffhalle West" }, | ||
| 59 | {"name": "Kugelwerk Ost" }, | ||
| 60 | {"name": "Twistground Central" }, | ||
| 61 | {"name": "Reibungsring Arena" }, | ||
| 62 | {"name": "Plattenpalast" }, | ||
| 63 | {"name": "Kickerforum SĂĽd" }, | ||
| 64 | {"name": "Drehkraft-Dome" }, | ||
| 65 | {"name": "Tischkampfarena Alte Platte" }, | ||
| 66 | {"name": "Kurbelkurve Stadion" }, | ||
| 67 | {"name": "Stangenwelle Stadion" }, | ||
| 68 | {"name": "Magnetfeld Mitte" }, | ||
| 69 | {"name": "Arena am Gleittisch" }, | ||
| 70 | {"name": "Schusshof Kurbeldorf" }, | ||
| 71 | {"name": "Rotationshalle 7" }, | ||
| 72 | {"name": "Griffzentrum Westkurve" }, | ||
| 73 | {"name": "Bandenbruch-Stadion" }, | ||
| 74 | {"name": "Kugeltempel Altstadt" }, | ||
| 75 | {"name": "Twistpark Westrand" }, | ||
| 76 | {"name": "GegenstoĂź-Galerie" }, | ||
| 77 | {"name": "Kurbelaue Nord" }, | ||
| 78 | {"name": "Kickerklotz Kolosseum" }, | ||
| 79 | {"name": "Griffgipfel Arena" }, | ||
| 80 | {"name": "Der Tischkessel" }, | ||
| 81 | {"name": "Lagerblock SĂĽd" }, | ||
| 82 | {"name": "Kugelkurve Klassik" }, | ||
| 83 | {"name": "Die Platte am Fluss" }, | ||
| 84 | {"name": "Haltepunkt Hohlgriff" } | ||
| 85 | ] | ||
| 86 | } | ||
diff --git a/example-output.txt b/example-output.txt new file mode 100644 index 0000000..05d35d2 --- /dev/null +++ b/example-output.txt | |||
| @@ -0,0 +1,912 @@ | |||
| 1 | 0 FC Kurbelkraft :: Rotation Rangers :: Stangenwelle Stadion | ||
| 2 | 0 Kickerknacker :: Die Kickkanonen :: Stangenwelle Stadion | ||
| 3 | 0 Kugelkontrolle :: Rapid Rotation :: Die Platte am Fluss | ||
| 4 | 0 Die Seitenwechsel :: FC Schubkraft :: Kurbelpark Arena | ||
| 5 | 0 * :: Kugelkommando :: * | ||
| 6 | 0 * :: Die Taktikdreher :: * | ||
| 7 | 1 * :: FC Kurbelkraft :: * | ||
| 8 | 1 * :: Kugelkontrolle :: * | ||
| 9 | 1 Rapid Rotation :: Kickerknacker :: Kugeltempel Altstadt | ||
| 10 | 1 * :: Die Seitenwechsel :: * | ||
| 11 | 1 Kugelkommando :: Rotation Rangers :: Twistpark Westrand | ||
| 12 | 1 FC Schubkraft :: * :: * | ||
| 13 | 1 Die Taktikdreher :: Die Kickkanonen :: Kurbelaue Nord | ||
| 14 | 2 FC Kurbelkraft :: Rapid Rotation :: Stangenstadion Nord | ||
| 15 | 2 Kickerknacker :: Kugelkommando :: Stangenwelle Stadion | ||
| 16 | 2 Kugelkontrolle :: FC Schubkraft :: Die Platte am Fluss | ||
| 17 | 2 Die Seitenwechsel :: Die Kickkanonen :: Schusshof Kurbeldorf | ||
| 18 | 2 * :: Die Taktikdreher :: * | ||
| 19 | 2 Rotation Rangers :: * :: * | ||
| 20 | 3 * :: FC Kurbelkraft :: * | ||
| 21 | 3 * :: Kickerknacker :: * | ||
| 22 | 3 * :: Kugelkontrolle :: * | ||
| 23 | 3 Rapid Rotation :: Die Seitenwechsel :: Kugeltempel Altstadt | ||
| 24 | 3 Kugelkommando :: Die Kickkanonen :: Twistpark Westrand | ||
| 25 | 3 FC Schubkraft :: Rotation Rangers :: Griffzentrum Westkurve | ||
| 26 | 3 Die Taktikdreher :: * :: * | ||
| 27 | 4 FC Kurbelkraft :: FC Schubkraft :: Stangenstadion Nord | ||
| 28 | 4 Kickerknacker :: Die Taktikdreher :: Haltepunkt Hohlgriff | ||
| 29 | 4 Die Seitenwechsel :: Kugelkontrolle :: Kurbelpark Arena | ||
| 30 | 4 Kugelkommando :: Rapid Rotation :: Twistpark Westrand | ||
| 31 | 4 Die Kickkanonen :: * :: * | ||
| 32 | 4 Rotation Rangers :: * :: * | ||
| 33 | 5 * :: FC Kurbelkraft :: * | ||
| 34 | 5 * :: Kickerknacker :: * | ||
| 35 | 5 Kugelkontrolle :: * :: * | ||
| 36 | 5 Rapid Rotation :: * :: * | ||
| 37 | 5 Die Seitenwechsel :: * :: * | ||
| 38 | 5 * :: Kugelkommando :: * | ||
| 39 | 5 FC Schubkraft :: * :: * | ||
| 40 | 5 Die Taktikdreher :: * :: * | ||
| 41 | 5 * :: Die Kickkanonen :: * | ||
| 42 | 5 * :: Rotation Rangers :: * | ||
| 43 | 6 FC Kurbelkraft :: * :: * | ||
| 44 | 6 Kickerknacker :: * :: * | ||
| 45 | 6 * :: Rapid Rotation :: * | ||
| 46 | 6 * :: Die Seitenwechsel :: * | ||
| 47 | 6 Kugelkommando :: Die Taktikdreher :: Twistpark Westrand | ||
| 48 | 6 * :: FC Schubkraft :: * | ||
| 49 | 6 Die Kickkanonen :: Kugelkontrolle :: Griffgipfel Arena | ||
| 50 | 6 Rotation Rangers :: * :: * | ||
| 51 | 7 * :: FC Kurbelkraft :: * | ||
| 52 | 7 Kugelkontrolle :: Kugelkommando :: Kickerklotz Kolosseum | ||
| 53 | 7 Rapid Rotation :: Die Taktikdreher :: Kugeltempel Altstadt | ||
| 54 | 7 Die Seitenwechsel :: Rotation Rangers :: Schusshof Kurbeldorf | ||
| 55 | 7 FC Schubkraft :: Kickerknacker :: Rotationshalle 7 | ||
| 56 | 7 * :: Die Kickkanonen :: * | ||
| 57 | 8 Kickerknacker :: FC Kurbelkraft :: Haltepunkt Hohlgriff | ||
| 58 | 8 Kugelkommando :: Die Seitenwechsel :: Twistpark Westrand | ||
| 59 | 8 * :: FC Schubkraft :: * | ||
| 60 | 8 Die Taktikdreher :: Kugelkontrolle :: Die Platte am Fluss | ||
| 61 | 8 Die Kickkanonen :: * :: * | ||
| 62 | 8 Rotation Rangers :: Rapid Rotation :: Kickerforum SĂĽd | ||
| 63 | 9 FC Kurbelkraft :: Die Taktikdreher :: Stangenstadion Nord | ||
| 64 | 9 Kugelkontrolle :: Kickerknacker :: Die Platte am Fluss | ||
| 65 | 9 Rapid Rotation :: Die Kickkanonen :: Twistpark Westrand | ||
| 66 | 9 Die Seitenwechsel :: * :: * | ||
| 67 | 9 * :: Kugelkommando :: * | ||
| 68 | 9 FC Schubkraft :: * :: * | ||
| 69 | 9 * :: Rotation Rangers :: * | ||
| 70 | 10 FC Kurbelkraft :: Die Seitenwechsel :: Stangenstadion Nord | ||
| 71 | 10 Kickerknacker :: * :: * | ||
| 72 | 10 * :: Rapid Rotation :: * | ||
| 73 | 10 Kugelkommando :: * :: * | ||
| 74 | 10 Die Taktikdreher :: FC Schubkraft :: Die Platte am Fluss | ||
| 75 | 10 Die Kickkanonen :: * :: * | ||
| 76 | 10 Rotation Rangers :: Kugelkontrolle :: Kickerforum SĂĽd | ||
| 77 | 11 * :: Kickerknacker :: * | ||
| 78 | 11 Kugelkontrolle :: FC Kurbelkraft :: Die Platte am Fluss | ||
| 79 | 11 * :: Rapid Rotation :: * | ||
| 80 | 11 Die Seitenwechsel :: * :: * | ||
| 81 | 11 FC Schubkraft :: Kugelkommando :: Griffzentrum Westkurve | ||
| 82 | 11 * :: Die Kickkanonen :: * | ||
| 83 | 11 Rotation Rangers :: Die Taktikdreher :: Kickerforum SĂĽd | ||
| 84 | 12 Kickerknacker :: Die Seitenwechsel :: Haltepunkt Hohlgriff | ||
| 85 | 12 * :: Kugelkontrolle :: * | ||
| 86 | 12 Rapid Rotation :: * :: * | ||
| 87 | 12 Kugelkommando :: * :: * | ||
| 88 | 12 * :: FC Schubkraft :: * | ||
| 89 | 12 * :: Die Taktikdreher :: * | ||
| 90 | 12 Die Kickkanonen :: FC Kurbelkraft :: Griffgipfel Arena | ||
| 91 | 12 * :: Rotation Rangers :: * | ||
| 92 | 13 FC Kurbelkraft :: * :: * | ||
| 93 | 13 * :: Kickerknacker :: * | ||
| 94 | 13 Kugelkontrolle :: * :: * | ||
| 95 | 13 * :: Kugelkommando :: * | ||
| 96 | 13 FC Schubkraft :: Rapid Rotation :: Rotationshalle 7 | ||
| 97 | 13 Die Taktikdreher :: Die Seitenwechsel :: Die Platte am Fluss | ||
| 98 | 13 Rotation Rangers :: Die Kickkanonen :: Kickerforum SĂĽd | ||
| 99 | 14 Kickerknacker :: Rotation Rangers :: Stangenwelle Stadion | ||
| 100 | 14 * :: Kugelkontrolle :: * | ||
| 101 | 14 * :: Rapid Rotation :: * | ||
| 102 | 14 Die Seitenwechsel :: * :: * | ||
| 103 | 14 Kugelkommando :: FC Kurbelkraft :: Twistpark Westrand | ||
| 104 | 14 * :: Die Taktikdreher :: * | ||
| 105 | 14 Die Kickkanonen :: FC Schubkraft :: Griffgipfel Arena | ||
| 106 | 15 Kugelkontrolle :: * :: * | ||
| 107 | 15 Rapid Rotation :: FC Kurbelkraft :: Kugeltempel Altstadt | ||
| 108 | 15 FC Schubkraft :: Die Seitenwechsel :: Rotationshalle 7 | ||
| 109 | 15 Die Taktikdreher :: Kickerknacker :: Die Platte am Fluss | ||
| 110 | 15 * :: Die Kickkanonen :: * | ||
| 111 | 15 Rotation Rangers :: Kugelkommando :: Kickerforum SĂĽd | ||
| 112 | 16 FC Kurbelkraft :: * :: * | ||
| 113 | 16 * :: Kugelkontrolle :: * | ||
| 114 | 16 Die Seitenwechsel :: Rapid Rotation :: Kurbelpark Arena | ||
| 115 | 16 Kugelkommando :: Kickerknacker :: Twistpark Westrand | ||
| 116 | 16 FC Schubkraft :: * :: * | ||
| 117 | 16 Die Kickkanonen :: Die Taktikdreher :: Griffgipfel Arena | ||
| 118 | 16 * :: Rotation Rangers :: * | ||
| 119 | 17 Kickerknacker :: * :: * | ||
| 120 | 17 Kugelkontrolle :: * :: * | ||
| 121 | 17 Rapid Rotation :: * :: * | ||
| 122 | 17 * :: FC Schubkraft :: * | ||
| 123 | 17 Die Taktikdreher :: FC Kurbelkraft :: Die Platte am Fluss | ||
| 124 | 17 Die Kickkanonen :: Kugelkommando :: Griffgipfel Arena | ||
| 125 | 17 Rotation Rangers :: Die Seitenwechsel :: Kickerforum SĂĽd | ||
| 126 | 18 FC Kurbelkraft :: Kugelkontrolle :: Stangenstadion Nord | ||
| 127 | 18 Rapid Rotation :: * :: * | ||
| 128 | 18 Die Seitenwechsel :: * :: * | ||
| 129 | 18 Kugelkommando :: * :: * | ||
| 130 | 18 FC Schubkraft :: * :: * | ||
| 131 | 18 * :: Die Taktikdreher :: * | ||
| 132 | 18 * :: Die Kickkanonen :: * | ||
| 133 | 18 Rotation Rangers :: Kickerknacker :: Kickerforum SĂĽd | ||
| 134 | 19 * :: FC Kurbelkraft :: * | ||
| 135 | 19 Kickerknacker :: Rapid Rotation :: Haltepunkt Hohlgriff | ||
| 136 | 19 Kugelkontrolle :: Rotation Rangers :: Kickerklotz Kolosseum | ||
| 137 | 19 * :: FC Schubkraft :: * | ||
| 138 | 19 Die Taktikdreher :: Kugelkommando :: Kurbelaue Nord | ||
| 139 | 19 Die Kickkanonen :: Die Seitenwechsel :: Griffgipfel Arena | ||
| 140 | 20 FC Kurbelkraft :: Kickerknacker :: Stangenstadion Nord | ||
| 141 | 20 Rapid Rotation :: * :: * | ||
| 142 | 20 Die Seitenwechsel :: Die Taktikdreher :: Kurbelpark Arena | ||
| 143 | 20 Kugelkommando :: Kugelkontrolle :: Twistpark Westrand | ||
| 144 | 20 FC Schubkraft :: * :: * | ||
| 145 | 20 Die Kickkanonen :: * :: * | ||
| 146 | 20 Rotation Rangers :: * :: * | ||
| 147 | 21 FC Kurbelkraft :: * :: * | ||
| 148 | 21 Kickerknacker :: * :: * | ||
| 149 | 21 Kugelkontrolle :: Die Kickkanonen :: Kickerklotz Kolosseum | ||
| 150 | 21 Rapid Rotation :: * :: * | ||
| 151 | 21 * :: Die Seitenwechsel :: * | ||
| 152 | 21 Kugelkommando :: FC Schubkraft :: Twistpark Westrand | ||
| 153 | 21 Die Taktikdreher :: Rotation Rangers :: Kurbelaue Nord | ||
| 154 | 22 * :: FC Kurbelkraft :: * | ||
| 155 | 22 * :: Rapid Rotation :: * | ||
| 156 | 22 Die Seitenwechsel :: Kugelkommando :: Schusshof Kurbeldorf | ||
| 157 | 22 FC Schubkraft :: Kugelkontrolle :: Rotationshalle 7 | ||
| 158 | 22 Die Taktikdreher :: * :: * | ||
| 159 | 22 Die Kickkanonen :: Kickerknacker :: Griffgipfel Arena | ||
| 160 | 22 Rotation Rangers :: * :: * | ||
| 161 | 23 FC Kurbelkraft :: * :: * | ||
| 162 | 23 Kickerknacker :: FC Schubkraft :: Haltepunkt Hohlgriff | ||
| 163 | 23 Rapid Rotation :: Kugelkontrolle :: Kugeltempel Altstadt | ||
| 164 | 23 * :: Die Seitenwechsel :: * | ||
| 165 | 23 Kugelkommando :: * :: * | ||
| 166 | 23 * :: Die Taktikdreher :: * | ||
| 167 | 23 Die Kickkanonen :: * :: * | ||
| 168 | 23 * :: Rotation Rangers :: * | ||
| 169 | 24 * :: Kickerknacker :: * | ||
| 170 | 24 Kugelkontrolle :: * :: * | ||
| 171 | 24 Die Seitenwechsel :: * :: * | ||
| 172 | 24 * :: Kugelkommando :: * | ||
| 173 | 24 FC Schubkraft :: FC Kurbelkraft :: Rotationshalle 7 | ||
| 174 | 24 Die Taktikdreher :: Rapid Rotation :: Die Platte am Fluss | ||
| 175 | 24 * :: Die Kickkanonen :: * | ||
| 176 | 24 Rotation Rangers :: * :: * | ||
| 177 | 25 FC Kurbelkraft :: Kugelkommando :: Stangenwelle Stadion | ||
| 178 | 25 Kickerknacker :: Kugelkontrolle :: Haltepunkt Hohlgriff | ||
| 179 | 25 Rapid Rotation :: FC Schubkraft :: Kugeltempel Altstadt | ||
| 180 | 25 * :: Die Seitenwechsel :: * | ||
| 181 | 25 Die Taktikdreher :: * :: * | ||
| 182 | 25 Die Kickkanonen :: Rotation Rangers :: Griffgipfel Arena | ||
| 183 | 26 * :: Kickerknacker :: * | ||
| 184 | 26 Kugelkontrolle :: * :: * | ||
| 185 | 26 Die Seitenwechsel :: FC Kurbelkraft :: Kurbelpark Arena | ||
| 186 | 26 Kugelkommando :: * :: * | ||
| 187 | 26 Die Taktikdreher :: * :: * | ||
| 188 | 26 Die Kickkanonen :: Rapid Rotation :: Griffgipfel Arena | ||
| 189 | 26 Rotation Rangers :: FC Schubkraft :: Kickerforum SĂĽd | ||
| 190 | 27 FC Kurbelkraft :: Die Kickkanonen :: Stangenwelle Stadion | ||
| 191 | 27 Kickerknacker :: * :: * | ||
| 192 | 27 * :: Kugelkontrolle :: * | ||
| 193 | 27 Rapid Rotation :: Kugelkommando :: Twistpark Westrand | ||
| 194 | 27 * :: Die Seitenwechsel :: * | ||
| 195 | 27 FC Schubkraft :: Die Taktikdreher :: Rotationshalle 7 | ||
| 196 | 27 * :: Rotation Rangers :: * | ||
| 197 | 28 Kugelkontrolle :: Die Taktikdreher :: Die Platte am Fluss | ||
| 198 | 28 * :: Rapid Rotation :: * | ||
| 199 | 28 Die Seitenwechsel :: Kickerknacker :: Kurbelpark Arena | ||
| 200 | 28 Kugelkommando :: * :: * | ||
| 201 | 28 * :: FC Schubkraft :: * | ||
| 202 | 28 Die Kickkanonen :: * :: * | ||
| 203 | 28 Rotation Rangers :: FC Kurbelkraft :: Kickerforum SĂĽd | ||
| 204 | 29 FC Kurbelkraft :: * :: * | ||
| 205 | 29 Kickerknacker :: * :: * | ||
| 206 | 29 Kugelkontrolle :: Die Seitenwechsel :: Die Platte am Fluss | ||
| 207 | 29 Rapid Rotation :: Rotation Rangers :: Twistpark Westrand | ||
| 208 | 29 * :: Kugelkommando :: * | ||
| 209 | 29 FC Schubkraft :: Die Kickkanonen :: Griffzentrum Westkurve | ||
| 210 | 29 Die Taktikdreher :: * :: * | ||
| 211 | 0 Die Kugelblitze :: Drehmoment 04 :: Haltepunkt Hohlgriff | ||
| 212 | 0 Die Querpassquäler :: Kurbelkönige :: Der Tischkessel | ||
| 213 | 0 Kick’n’Twist :: * :: * | ||
| 214 | 0 Die Rutschbahn-Raketen :: Die Gleitlager :: Kurbelaue Nord | ||
| 215 | 0 Griffbereit 99 :: * :: * | ||
| 216 | 0 Ballmagneten :: Turbo-Tischkicker :: Twistpark Westrand | ||
| 217 | 0 Stahlstangen SC :: Die Stangendreher :: Griffgipfel Arena | ||
| 218 | 1 Drehmoment 04 :: Die Stangendreher :: Plattenpalast | ||
| 219 | 1 Kurbelkönige :: Die Kugelblitze :: Griffgipfel Arena | ||
| 220 | 1 Die Gleitlager :: Griffbereit 99 :: Kickerklotz Kolosseum | ||
| 221 | 1 Turbo-Tischkicker :: * :: * | ||
| 222 | 1 * :: Die Querpassquäler :: * | ||
| 223 | 1 * :: Kick’n’Twist :: * | ||
| 224 | 1 * :: Die Rutschbahn-Raketen :: * | ||
| 225 | 1 Ballmagneten :: Stahlstangen SC :: Twistpark Westrand | ||
| 226 | 2 * :: Die Kugelblitze :: * | ||
| 227 | 2 Drehmoment 04 :: Die Gleitlager :: Rotationshalle 7 | ||
| 228 | 2 * :: Kurbelkönige :: * | ||
| 229 | 2 * :: Turbo-Tischkicker :: * | ||
| 230 | 2 Die Rutschbahn-Raketen :: Die Querpassquäler :: Kurbelaue Nord | ||
| 231 | 2 Griffbereit 99 :: Die Stangendreher :: Kickerforum SĂĽd | ||
| 232 | 2 * :: Ballmagneten :: * | ||
| 233 | 2 Stahlstangen SC :: Kick’n’Twist :: Griffgipfel Arena | ||
| 234 | 3 Die Stangendreher :: * :: * | ||
| 235 | 3 Die Kugelblitze :: Die Gleitlager :: Haltepunkt Hohlgriff | ||
| 236 | 3 Drehmoment 04 :: Die Querpassquäler :: Rotationshalle 7 | ||
| 237 | 3 Turbo-Tischkicker :: Stahlstangen SC :: Plattenpalast | ||
| 238 | 3 Kick’n’Twist :: Kurbelkönige :: Griffgipfel Arena | ||
| 239 | 3 Griffbereit 99 :: Die Rutschbahn-Raketen :: Kickerforum SĂĽd | ||
| 240 | 3 Ballmagneten :: * :: * | ||
| 241 | 4 Die Kugelblitze :: * :: * | ||
| 242 | 4 Drehmoment 04 :: Kick’n’Twist :: Rotationshalle 7 | ||
| 243 | 4 Kurbelkönige :: Griffbereit 99 :: Griffgipfel Arena | ||
| 244 | 4 Die Gleitlager :: Die Stangendreher :: Kickerklotz Kolosseum | ||
| 245 | 4 Turbo-Tischkicker :: Die Querpassquäler :: Kurbelkurve Stadion | ||
| 246 | 4 Die Rutschbahn-Raketen :: Ballmagneten :: Kurbelaue Nord | ||
| 247 | 4 Stahlstangen SC :: * :: * | ||
| 248 | 5 * :: Die Kugelblitze :: * | ||
| 249 | 5 * :: Kurbelkönige :: * | ||
| 250 | 5 Die Gleitlager :: * :: * | ||
| 251 | 5 Turbo-Tischkicker :: Die Rutschbahn-Raketen :: Plattenpalast | ||
| 252 | 5 Die Querpassquäler :: Stahlstangen SC :: Der Tischkessel | ||
| 253 | 5 Kick’n’Twist :: * :: * | ||
| 254 | 5 Griffbereit 99 :: Drehmoment 04 :: Kickerforum SĂĽd | ||
| 255 | 5 Ballmagneten :: Die Stangendreher :: Twistpark Westrand | ||
| 256 | 6 Die Stangendreher :: * :: * | ||
| 257 | 6 Die Kugelblitze :: Ballmagneten :: Bandenbruch-Stadion | ||
| 258 | 6 Drehmoment 04 :: * :: * | ||
| 259 | 6 Kurbelkönige :: * :: * | ||
| 260 | 6 * :: Die Gleitlager :: * | ||
| 261 | 6 Kick’n’Twist :: Die Querpassquäler :: Griffhalle West | ||
| 262 | 6 Die Rutschbahn-Raketen :: Stahlstangen SC :: Kurbelaue Nord | ||
| 263 | 6 Griffbereit 99 :: Turbo-Tischkicker :: Kickerforum SĂĽd | ||
| 264 | 7 Die Stangendreher :: Turbo-Tischkicker :: Griffgipfel Arena | ||
| 265 | 7 * :: Drehmoment 04 :: * | ||
| 266 | 7 Die Gleitlager :: * :: * | ||
| 267 | 7 Die Querpassquäler :: * :: * | ||
| 268 | 7 Kick’n’Twist :: Griffbereit 99 :: Griffgipfel Arena | ||
| 269 | 7 Die Rutschbahn-Raketen :: Kurbelkönige :: Kurbelaue Nord | ||
| 270 | 7 Ballmagneten :: * :: * | ||
| 271 | 7 Stahlstangen SC :: Die Kugelblitze :: Griffgipfel Arena | ||
| 272 | 8 Die Kugelblitze :: Die Stangendreher :: Bandenbruch-Stadion | ||
| 273 | 8 Kurbelkönige :: Drehmoment 04 :: Griffgipfel Arena | ||
| 274 | 8 Turbo-Tischkicker :: Die Gleitlager :: Kurbelkurve Stadion | ||
| 275 | 8 * :: Die Rutschbahn-Raketen :: * | ||
| 276 | 8 Griffbereit 99 :: Die Querpassquäler :: Kickerforum Süd | ||
| 277 | 8 Ballmagneten :: Kick’n’Twist :: Twistpark Westrand | ||
| 278 | 8 * :: Stahlstangen SC :: * | ||
| 279 | 9 Die Stangendreher :: Kick’n’Twist :: Griffgipfel Arena | ||
| 280 | 9 Die Kugelblitze :: Turbo-Tischkicker :: Haltepunkt Hohlgriff | ||
| 281 | 9 * :: Kurbelkönige :: * | ||
| 282 | 9 Die Gleitlager :: * :: * | ||
| 283 | 9 Die Querpassquäler :: Ballmagneten :: Der Tischkessel | ||
| 284 | 9 Die Rutschbahn-Raketen :: * :: * | ||
| 285 | 9 * :: Griffbereit 99 :: * | ||
| 286 | 9 Stahlstangen SC :: Drehmoment 04 :: Griffgipfel Arena | ||
| 287 | 10 * :: Die Stangendreher :: * | ||
| 288 | 10 * :: Die Kugelblitze :: * | ||
| 289 | 10 Kurbelkönige :: Ballmagneten :: Griffgipfel Arena | ||
| 290 | 10 Turbo-Tischkicker :: * :: * | ||
| 291 | 10 * :: Die Querpassquäler :: * | ||
| 292 | 10 Kick’n’Twist :: Die Gleitlager :: Griffhalle West | ||
| 293 | 10 Die Rutschbahn-Raketen :: Drehmoment 04 :: Kurbelaue Nord | ||
| 294 | 10 Griffbereit 99 :: * :: * | ||
| 295 | 10 * :: Stahlstangen SC :: * | ||
| 296 | 11 Die Stangendreher :: * :: * | ||
| 297 | 11 Die Kugelblitze :: Die Rutschbahn-Raketen :: Bandenbruch-Stadion | ||
| 298 | 11 * :: Drehmoment 04 :: * | ||
| 299 | 11 Die Gleitlager :: Ballmagneten :: Kickerklotz Kolosseum | ||
| 300 | 11 Die Querpassquäler :: * :: * | ||
| 301 | 11 Kick’n’Twist :: Turbo-Tischkicker :: Griffhalle West | ||
| 302 | 11 * :: Griffbereit 99 :: * | ||
| 303 | 11 Stahlstangen SC :: Kurbelkönige :: Griffgipfel Arena | ||
| 304 | 12 Drehmoment 04 :: Turbo-Tischkicker :: Rotationshalle 7 | ||
| 305 | 12 Kurbelkönige :: Die Stangendreher :: Griffgipfel Arena | ||
| 306 | 12 Die Querpassquäler :: Die Gleitlager :: Drehpunkt Dome | ||
| 307 | 12 Die Rutschbahn-Raketen :: Kick’n’Twist :: Kurbelaue Nord | ||
| 308 | 12 Griffbereit 99 :: Die Kugelblitze :: Kickerforum SĂĽd | ||
| 309 | 12 * :: Ballmagneten :: * | ||
| 310 | 12 * :: Stahlstangen SC :: * | ||
| 311 | 13 Die Stangendreher :: Die Rutschbahn-Raketen :: Griffgipfel Arena | ||
| 312 | 13 Die Kugelblitze :: Die Querpassquäler :: Haltepunkt Hohlgriff | ||
| 313 | 13 * :: Drehmoment 04 :: * | ||
| 314 | 13 Turbo-Tischkicker :: Kurbelkönige :: Plattenpalast | ||
| 315 | 13 Kick’n’Twist :: * :: * | ||
| 316 | 13 Ballmagneten :: Griffbereit 99 :: Twistpark Westrand | ||
| 317 | 13 Stahlstangen SC :: Die Gleitlager :: Griffgipfel Arena | ||
| 318 | 14 Drehmoment 04 :: Ballmagneten :: Plattenpalast | ||
| 319 | 14 Die Gleitlager :: Kurbelkönige :: Kickerklotz Kolosseum | ||
| 320 | 14 * :: Turbo-Tischkicker :: * | ||
| 321 | 14 Die Querpassquäler :: Die Stangendreher :: Der Tischkessel | ||
| 322 | 14 Kick’n’Twist :: Die Kugelblitze :: Griffhalle West | ||
| 323 | 14 * :: Die Rutschbahn-Raketen :: * | ||
| 324 | 14 Griffbereit 99 :: Stahlstangen SC :: Kickerforum SĂĽd | ||
| 325 | 15 Die Stangendreher :: Die Gleitlager :: Griffgipfel Arena | ||
| 326 | 15 Kurbelkönige :: * :: * | ||
| 327 | 15 Turbo-Tischkicker :: * :: * | ||
| 328 | 15 * :: Kick’n’Twist :: * | ||
| 329 | 15 Die Rutschbahn-Raketen :: Die Kugelblitze :: Kurbelaue Nord | ||
| 330 | 15 * :: Griffbereit 99 :: * | ||
| 331 | 15 Ballmagneten :: Drehmoment 04 :: Twistpark Westrand | ||
| 332 | 15 Stahlstangen SC :: Die Querpassquäler :: Griffgipfel Arena | ||
| 333 | 16 * :: Die Stangendreher :: * | ||
| 334 | 16 Die Kugelblitze :: Stahlstangen SC :: Bandenbruch-Stadion | ||
| 335 | 16 * :: Kurbelkönige :: * | ||
| 336 | 16 Die Gleitlager :: Die Rutschbahn-Raketen :: Kickerklotz Kolosseum | ||
| 337 | 16 * :: Turbo-Tischkicker :: * | ||
| 338 | 16 Die Querpassquäler :: Drehmoment 04 :: Drehpunkt Dome | ||
| 339 | 16 Kick’n’Twist :: Ballmagneten :: Griffgipfel Arena | ||
| 340 | 16 Griffbereit 99 :: * :: * | ||
| 341 | 17 Die Stangendreher :: Die Kugelblitze :: Griffgipfel Arena | ||
| 342 | 17 Kurbelkönige :: Die Querpassquäler :: Griffgipfel Arena | ||
| 343 | 17 * :: Die Gleitlager :: * | ||
| 344 | 17 Turbo-Tischkicker :: Drehmoment 04 :: Kurbelkurve Stadion | ||
| 345 | 17 * :: Kick’n’Twist :: * | ||
| 346 | 17 Die Rutschbahn-Raketen :: Griffbereit 99 :: Kurbelaue Nord | ||
| 347 | 17 Ballmagneten :: * :: * | ||
| 348 | 17 Stahlstangen SC :: * :: * | ||
| 349 | 18 Die Stangendreher :: Ballmagneten :: Griffgipfel Arena | ||
| 350 | 18 Die Kugelblitze :: * :: * | ||
| 351 | 18 Drehmoment 04 :: Kurbelkönige :: Plattenpalast | ||
| 352 | 18 Die Gleitlager :: * :: * | ||
| 353 | 18 Die Querpassquäler :: Turbo-Tischkicker :: Drehpunkt Dome | ||
| 354 | 18 Griffbereit 99 :: Kick’n’Twist :: Kickerforum Süd | ||
| 355 | 18 Stahlstangen SC :: Die Rutschbahn-Raketen :: Griffgipfel Arena | ||
| 356 | 19 Drehmoment 04 :: Griffbereit 99 :: Plattenpalast | ||
| 357 | 19 Kurbelkönige :: Die Gleitlager :: Griffgipfel Arena | ||
| 358 | 19 Turbo-Tischkicker :: Die Kugelblitze :: Kurbelkurve Stadion | ||
| 359 | 19 Kick’n’Twist :: * :: * | ||
| 360 | 19 Die Rutschbahn-Raketen :: Die Stangendreher :: Kurbelaue Nord | ||
| 361 | 19 Ballmagneten :: Die Querpassquäler :: Twistpark Westrand | ||
| 362 | 19 * :: Stahlstangen SC :: * | ||
| 363 | 20 Die Stangendreher :: Griffbereit 99 :: Griffgipfel Arena | ||
| 364 | 20 Die Kugelblitze :: * :: * | ||
| 365 | 20 Kurbelkönige :: Stahlstangen SC :: Griffgipfel Arena | ||
| 366 | 20 Die Gleitlager :: Drehmoment 04 :: Stangenstadion Nord | ||
| 367 | 20 Turbo-Tischkicker :: Ballmagneten :: Plattenpalast | ||
| 368 | 20 Die Querpassquäler :: Die Rutschbahn-Raketen :: Der Tischkessel | ||
| 369 | 20 * :: Kick’n’Twist :: * | ||
| 370 | 21 Die Kugelblitze :: Kurbelkönige :: Bandenbruch-Stadion | ||
| 371 | 21 Drehmoment 04 :: * :: * | ||
| 372 | 21 * :: Turbo-Tischkicker :: * | ||
| 373 | 21 Die Querpassquäler :: * :: * | ||
| 374 | 21 Kick’n’Twist :: Die Stangendreher :: Griffgipfel Arena | ||
| 375 | 21 Die Rutschbahn-Raketen :: * :: * | ||
| 376 | 21 Ballmagneten :: Die Gleitlager :: Twistpark Westrand | ||
| 377 | 21 Stahlstangen SC :: Griffbereit 99 :: Griffgipfel Arena | ||
| 378 | 22 Die Stangendreher :: Stahlstangen SC :: Griffgipfel Arena | ||
| 379 | 22 * :: Die Kugelblitze :: * | ||
| 380 | 22 * :: Drehmoment 04 :: * | ||
| 381 | 22 Kurbelkönige :: * :: * | ||
| 382 | 22 * :: Die Gleitlager :: * | ||
| 383 | 22 Turbo-Tischkicker :: Griffbereit 99 :: Plattenpalast | ||
| 384 | 22 * :: Die Querpassquäler :: * | ||
| 385 | 22 Kick’n’Twist :: Die Rutschbahn-Raketen :: Griffgipfel Arena | ||
| 386 | 22 * :: Ballmagneten :: * | ||
| 387 | 23 * :: Die Stangendreher :: * | ||
| 388 | 23 Drehmoment 04 :: Die Rutschbahn-Raketen :: Plattenpalast | ||
| 389 | 23 Die Gleitlager :: Kick’n’Twist :: Stangenstadion Nord | ||
| 390 | 23 Die Querpassquäler :: Die Kugelblitze :: Drehpunkt Dome | ||
| 391 | 23 * :: Griffbereit 99 :: * | ||
| 392 | 23 Ballmagneten :: Kurbelkönige :: Twistpark Westrand | ||
| 393 | 23 Stahlstangen SC :: Turbo-Tischkicker :: Griffgipfel Arena | ||
| 394 | 24 Die Stangendreher :: * :: * | ||
| 395 | 24 Die Kugelblitze :: Kick’n’Twist :: Haltepunkt Hohlgriff | ||
| 396 | 24 Drehmoment 04 :: * :: * | ||
| 397 | 24 Kurbelkönige :: Die Rutschbahn-Raketen :: Griffgipfel Arena | ||
| 398 | 24 Die Gleitlager :: Die Querpassquäler :: Stangenstadion Nord | ||
| 399 | 24 Turbo-Tischkicker :: * :: * | ||
| 400 | 24 Griffbereit 99 :: Ballmagneten :: Kickerforum SĂĽd | ||
| 401 | 24 Stahlstangen SC :: * :: * | ||
| 402 | 25 * :: Die Stangendreher :: * | ||
| 403 | 25 Die Kugelblitze :: Griffbereit 99 :: Bandenbruch-Stadion | ||
| 404 | 25 Drehmoment 04 :: * :: * | ||
| 405 | 25 Kurbelkönige :: Turbo-Tischkicker :: Griffgipfel Arena | ||
| 406 | 25 Die Gleitlager :: Stahlstangen SC :: Kickerklotz Kolosseum | ||
| 407 | 25 Die Querpassquäler :: Kick’n’Twist :: Drehpunkt Dome | ||
| 408 | 25 Die Rutschbahn-Raketen :: * :: * | ||
| 409 | 25 Ballmagneten :: * :: * | ||
| 410 | 26 Die Stangendreher :: Drehmoment 04 :: Griffgipfel Arena | ||
| 411 | 26 Kurbelkönige :: Kick’n’Twist :: Griffgipfel Arena | ||
| 412 | 26 Die Gleitlager :: Die Kugelblitze :: Stangenstadion Nord | ||
| 413 | 26 Die Querpassquäler :: * :: * | ||
| 414 | 26 Die Rutschbahn-Raketen :: Turbo-Tischkicker :: Kurbelaue Nord | ||
| 415 | 26 Griffbereit 99 :: * :: * | ||
| 416 | 26 Stahlstangen SC :: Ballmagneten :: Griffgipfel Arena | ||
| 417 | 27 Die Stangendreher :: Die Querpassquäler :: Griffgipfel Arena | ||
| 418 | 27 Drehmoment 04 :: Stahlstangen SC :: Plattenpalast | ||
| 419 | 27 * :: Die Gleitlager :: * | ||
| 420 | 27 Turbo-Tischkicker :: Kick’n’Twist :: Kurbelkurve Stadion | ||
| 421 | 27 * :: Die Rutschbahn-Raketen :: * | ||
| 422 | 27 Griffbereit 99 :: Kurbelkönige :: Kickerforum Süd | ||
| 423 | 27 Ballmagneten :: Die Kugelblitze :: Twistpark Westrand | ||
| 424 | 28 Die Kugelblitze :: * :: * | ||
| 425 | 28 Kurbelkönige :: * :: * | ||
| 426 | 28 Turbo-Tischkicker :: Die Stangendreher :: Plattenpalast | ||
| 427 | 28 * :: Die Querpassquäler :: * | ||
| 428 | 28 Kick’n’Twist :: Drehmoment 04 :: Griffhalle West | ||
| 429 | 28 Die Rutschbahn-Raketen :: * :: * | ||
| 430 | 28 Griffbereit 99 :: Die Gleitlager :: Kickerforum SĂĽd | ||
| 431 | 28 * :: Ballmagneten :: * | ||
| 432 | 28 Stahlstangen SC :: * :: * | ||
| 433 | 29 Die Stangendreher :: Kurbelkönige :: Griffgipfel Arena | ||
| 434 | 29 Drehmoment 04 :: Die Kugelblitze :: Rotationshalle 7 | ||
| 435 | 29 Die Gleitlager :: Turbo-Tischkicker :: Stangenstadion Nord | ||
| 436 | 29 Die Querpassquäler :: Griffbereit 99 :: Der Tischkessel | ||
| 437 | 29 Kick’n’Twist :: Stahlstangen SC :: Griffgipfel Arena | ||
| 438 | 29 Ballmagneten :: Die Rutschbahn-Raketen :: Twistpark Westrand | ||
| 439 | 0 Die Plattenpanther :: Kurbelschmiede :: Die Platte am Fluss | ||
| 440 | 0 Vollstoff United :: * :: * | ||
| 441 | 0 Dynamo Drehpunkt :: * :: * | ||
| 442 | 0 Reibungslose Racker :: Kickerkombinat :: Der Tischkessel | ||
| 443 | 0 Drehakademie :: Die Abroller :: Kugeltempel Altstadt | ||
| 444 | 0 Die Griffgötter :: Die Plattenspieler :: Kugelwerk Ost | ||
| 445 | 0 Die Blockbuster :: Die Kurbelkicker :: Kugeltempel Altstadt | ||
| 446 | 0 Die Drehlords :: * :: * | ||
| 447 | 1 * :: Die Plattenpanther :: * | ||
| 448 | 1 Vollstoff United :: Kickerkombinat :: Kugelkurve Klassik | ||
| 449 | 1 * :: Reibungslose Racker :: * | ||
| 450 | 1 Drehakademie :: Kurbelschmiede :: Kugeltempel Altstadt | ||
| 451 | 1 Die Griffgötter :: Die Abroller :: Kugelwerk Ost | ||
| 452 | 1 Die Blockbuster :: * :: * | ||
| 453 | 1 Die Drehlords :: Die Kurbelkicker :: Griffhalle West | ||
| 454 | 1 Die Plattenspieler :: Dynamo Drehpunkt :: Kurbelkurve Stadion | ||
| 455 | 2 Die Plattenpanther :: Die Drehlords :: Die Platte am Fluss | ||
| 456 | 2 Vollstoff United :: Die Kurbelkicker :: Kugelkurve Klassik | ||
| 457 | 2 Dynamo Drehpunkt :: Kurbelschmiede :: Kugelkurve Klassik | ||
| 458 | 2 Reibungslose Racker :: Die Blockbuster :: Der Tischkessel | ||
| 459 | 2 Drehakademie :: * :: * | ||
| 460 | 2 Die Griffgötter :: Kickerkombinat :: Kugelwerk Ost | ||
| 461 | 2 Die Abroller :: Die Plattenspieler :: Rotationshalle 7 | ||
| 462 | 3 Vollstoff United :: Dynamo Drehpunkt :: Kugelkurve Klassik | ||
| 463 | 3 Kurbelschmiede :: * :: * | ||
| 464 | 3 * :: Reibungslose Racker :: * | ||
| 465 | 3 Drehakademie :: Die Plattenpanther :: Kugeltempel Altstadt | ||
| 466 | 3 Die Griffgötter :: * :: * | ||
| 467 | 3 Kickerkombinat :: Die Drehlords :: Drehpunkt Dome | ||
| 468 | 3 Die Blockbuster :: * :: * | ||
| 469 | 3 Die Kurbelkicker :: Die Plattenspieler :: Drehkraft-Dome | ||
| 470 | 3 * :: Die Abroller :: * | ||
| 471 | 4 Die Plattenpanther :: * :: * | ||
| 472 | 4 Vollstoff United :: Die Griffgötter :: Kugelkurve Klassik | ||
| 473 | 4 Dynamo Drehpunkt :: * :: * | ||
| 474 | 4 Kurbelschmiede :: Die Abroller :: GegenstoĂź-Galerie | ||
| 475 | 4 Reibungslose Racker :: * :: * | ||
| 476 | 4 Kickerkombinat :: Die Blockbuster :: Drehpunkt Dome | ||
| 477 | 4 Die Drehlords :: Drehakademie :: Griffhalle West | ||
| 478 | 4 * :: Die Kurbelkicker :: * | ||
| 479 | 4 Die Plattenspieler :: * :: * | ||
| 480 | 5 * :: Vollstoff United :: * | ||
| 481 | 5 Kurbelschmiede :: Kickerkombinat :: GegenstoĂź-Galerie | ||
| 482 | 5 Drehakademie :: Die Plattenspieler :: Kugeltempel Altstadt | ||
| 483 | 5 * :: Die Griffgötter :: * | ||
| 484 | 5 Die Blockbuster :: Die Plattenpanther :: Kugeltempel Altstadt | ||
| 485 | 5 Die Drehlords :: Dynamo Drehpunkt :: Griffhalle West | ||
| 486 | 5 Die Kurbelkicker :: * :: * | ||
| 487 | 5 Die Abroller :: Reibungslose Racker :: Twistpark Westrand | ||
| 488 | 6 Vollstoff United :: Die Blockbuster :: Kugelkurve Klassik | ||
| 489 | 6 Kurbelschmiede :: Die Kurbelkicker :: GegenstoĂź-Galerie | ||
| 490 | 6 Reibungslose Racker :: Dynamo Drehpunkt :: Der Tischkessel | ||
| 491 | 6 Die Griffgötter :: Drehakademie :: Kugelwerk Ost | ||
| 492 | 6 Kickerkombinat :: Die Plattenpanther :: Drehpunkt Dome | ||
| 493 | 6 Die Drehlords :: Die Plattenspieler :: Griffhalle West | ||
| 494 | 6 * :: Die Abroller :: * | ||
| 495 | 7 Die Plattenpanther :: Reibungslose Racker :: Stangenwelle Stadion | ||
| 496 | 7 Dynamo Drehpunkt :: Die Blockbuster :: Kugelkurve Klassik | ||
| 497 | 7 Drehakademie :: Vollstoff United :: Kugeltempel Altstadt | ||
| 498 | 7 Kickerkombinat :: Die Plattenspieler :: Drehpunkt Dome | ||
| 499 | 7 Die Drehlords :: Kurbelschmiede :: Griffhalle West | ||
| 500 | 7 Die Kurbelkicker :: Die Griffgötter :: Drehkraft-Dome | ||
| 501 | 7 Die Abroller :: * :: * | ||
| 502 | 8 Vollstoff United :: * :: * | ||
| 503 | 8 Dynamo Drehpunkt :: Die Plattenpanther :: Kugelkurve Klassik | ||
| 504 | 8 Kurbelschmiede :: * :: * | ||
| 505 | 8 * :: Drehakademie :: * | ||
| 506 | 8 Die Griffgötter :: Reibungslose Racker :: Schusshof Kurbeldorf | ||
| 507 | 8 Die Blockbuster :: Die Plattenspieler :: Kugeltempel Altstadt | ||
| 508 | 8 Die Drehlords :: Die Abroller :: Griffhalle West | ||
| 509 | 8 Die Kurbelkicker :: Kickerkombinat :: Drehkraft-Dome | ||
| 510 | 9 Die Plattenpanther :: Die Plattenspieler :: Die Platte am Fluss | ||
| 511 | 9 Reibungslose Racker :: Kurbelschmiede :: Der Tischkessel | ||
| 512 | 9 Drehakademie :: * :: * | ||
| 513 | 9 Die Griffgötter :: * :: * | ||
| 514 | 9 Kickerkombinat :: Dynamo Drehpunkt :: Drehpunkt Dome | ||
| 515 | 9 Die Drehlords :: Die Blockbuster :: Griffhalle West | ||
| 516 | 9 * :: Die Kurbelkicker :: * | ||
| 517 | 9 Die Abroller :: Vollstoff United :: Rotationshalle 7 | ||
| 518 | 10 * :: Die Plattenpanther :: * | ||
| 519 | 10 Kurbelschmiede :: * :: * | ||
| 520 | 10 * :: Kickerkombinat :: * | ||
| 521 | 10 Die Blockbuster :: Drehakademie :: Kugeltempel Altstadt | ||
| 522 | 10 Die Drehlords :: Die Griffgötter :: Griffhalle West | ||
| 523 | 10 Die Kurbelkicker :: Reibungslose Racker :: Lagerblock SĂĽd | ||
| 524 | 10 Die Abroller :: Dynamo Drehpunkt :: Rotationshalle 7 | ||
| 525 | 10 Die Plattenspieler :: Vollstoff United :: Kurbelkurve Stadion | ||
| 526 | 11 Vollstoff United :: Reibungslose Racker :: Plattenpalast | ||
| 527 | 11 Drehakademie :: Dynamo Drehpunkt :: Kugeltempel Altstadt | ||
| 528 | 11 Die Griffgötter :: Die Plattenpanther :: Kugelwerk Ost | ||
| 529 | 11 Kickerkombinat :: * :: * | ||
| 530 | 11 Die Blockbuster :: * :: * | ||
| 531 | 11 * :: Die Drehlords :: * | ||
| 532 | 11 Die Abroller :: Die Kurbelkicker :: Rotationshalle 7 | ||
| 533 | 11 Die Plattenspieler :: Kurbelschmiede :: Kurbelkurve Stadion | ||
| 534 | 12 Dynamo Drehpunkt :: * :: * | ||
| 535 | 12 Reibungslose Racker :: Die Plattenspieler :: Der Tischkessel | ||
| 536 | 12 Die Griffgötter :: Kurbelschmiede :: Kugelwerk Ost | ||
| 537 | 12 Kickerkombinat :: Drehakademie :: Drehpunkt Dome | ||
| 538 | 12 Die Drehlords :: Vollstoff United :: Griffhalle West | ||
| 539 | 12 Die Kurbelkicker :: Die Plattenpanther :: Drehkraft-Dome | ||
| 540 | 12 Die Abroller :: Die Blockbuster :: Rotationshalle 7 | ||
| 541 | 13 Die Plattenpanther :: Die Abroller :: Die Platte am Fluss | ||
| 542 | 13 Kurbelschmiede :: Vollstoff United :: GegenstoĂź-Galerie | ||
| 543 | 13 Drehakademie :: Reibungslose Racker :: Stangenwelle Stadion | ||
| 544 | 13 * :: Kickerkombinat :: * | ||
| 545 | 13 Die Blockbuster :: Die Griffgötter :: Kugeltempel Altstadt | ||
| 546 | 13 * :: Die Drehlords :: * | ||
| 547 | 13 Die Kurbelkicker :: Dynamo Drehpunkt :: Drehkraft-Dome | ||
| 548 | 13 Die Plattenspieler :: * :: * | ||
| 549 | 14 Vollstoff United :: Die Plattenpanther :: Kugelkurve Klassik | ||
| 550 | 14 Die Griffgötter :: Dynamo Drehpunkt :: Kugelwerk Ost | ||
| 551 | 14 Die Blockbuster :: Kurbelschmiede :: Kugeltempel Altstadt | ||
| 552 | 14 Die Drehlords :: Reibungslose Racker :: Kurbelaue Nord | ||
| 553 | 14 Die Kurbelkicker :: Drehakademie :: Drehkraft-Dome | ||
| 554 | 14 Die Abroller :: Kickerkombinat :: Rotationshalle 7 | ||
| 555 | 14 * :: Die Plattenspieler :: * | ||
| 556 | 15 Die Plattenpanther :: Vollstoff United :: Die Platte am Fluss | ||
| 557 | 15 * :: Dynamo Drehpunkt :: * | ||
| 558 | 15 Reibungslose Racker :: * :: * | ||
| 559 | 15 * :: Die Griffgötter :: * | ||
| 560 | 15 * :: Die Blockbuster :: * | ||
| 561 | 15 Die Drehlords :: Kickerkombinat :: Griffhalle West | ||
| 562 | 15 * :: Die Kurbelkicker :: * | ||
| 563 | 15 Die Abroller :: Kurbelschmiede :: Rotationshalle 7 | ||
| 564 | 15 Die Plattenspieler :: Drehakademie :: Kurbelkurve Stadion | ||
| 565 | 16 * :: Vollstoff United :: * | ||
| 566 | 16 Dynamo Drehpunkt :: Die Plattenspieler :: Kugelkurve Klassik | ||
| 567 | 16 * :: Kurbelschmiede :: * | ||
| 568 | 16 Reibungslose Racker :: Die Plattenpanther :: Der Tischkessel | ||
| 569 | 16 * :: Drehakademie :: * | ||
| 570 | 16 Die Griffgötter :: * :: * | ||
| 571 | 16 Die Blockbuster :: Kickerkombinat :: Kugeltempel Altstadt | ||
| 572 | 16 Die Kurbelkicker :: Die Drehlords :: Drehkraft-Dome | ||
| 573 | 16 * :: Die Abroller :: * | ||
| 574 | 17 Kurbelschmiede :: Dynamo Drehpunkt :: GegenstoĂź-Galerie | ||
| 575 | 17 * :: Reibungslose Racker :: * | ||
| 576 | 17 Drehakademie :: Die Drehlords :: Kugeltempel Altstadt | ||
| 577 | 17 Kickerkombinat :: Die Griffgötter :: Drehpunkt Dome | ||
| 578 | 17 Die Kurbelkicker :: Vollstoff United :: Drehkraft-Dome | ||
| 579 | 17 Die Abroller :: Die Plattenpanther :: Rotationshalle 7 | ||
| 580 | 17 Die Plattenspieler :: Die Blockbuster :: Kurbelkurve Stadion | ||
| 581 | 18 Die Plattenpanther :: * :: * | ||
| 582 | 18 * :: Dynamo Drehpunkt :: * | ||
| 583 | 18 Reibungslose Racker :: * :: * | ||
| 584 | 18 * :: Drehakademie :: * | ||
| 585 | 18 Die Blockbuster :: Vollstoff United :: Kugeltempel Altstadt | ||
| 586 | 18 * :: Die Drehlords :: * | ||
| 587 | 18 Die Kurbelkicker :: Kurbelschmiede :: Drehkraft-Dome | ||
| 588 | 18 Die Abroller :: Die Griffgötter :: Rotationshalle 7 | ||
| 589 | 18 Die Plattenspieler :: Kickerkombinat :: Kurbelkurve Stadion | ||
| 590 | 19 Dynamo Drehpunkt :: Vollstoff United :: Kugelkurve Klassik | ||
| 591 | 19 Kurbelschmiede :: Die Plattenpanther :: GegenstoĂź-Galerie | ||
| 592 | 19 Drehakademie :: * :: * | ||
| 593 | 19 * :: Die Griffgötter :: * | ||
| 594 | 19 Kickerkombinat :: Reibungslose Racker :: Kickerforum SĂĽd | ||
| 595 | 19 * :: Die Blockbuster :: * | ||
| 596 | 19 Die Kurbelkicker :: Die Abroller :: Drehkraft-Dome | ||
| 597 | 19 Die Plattenspieler :: Die Drehlords :: Kurbelkurve Stadion | ||
| 598 | 20 Vollstoff United :: * :: * | ||
| 599 | 20 * :: Dynamo Drehpunkt :: * | ||
| 600 | 20 Kurbelschmiede :: Die Plattenspieler :: GegenstoĂź-Galerie | ||
| 601 | 20 Die Griffgötter :: Die Kurbelkicker :: Kugelwerk Ost | ||
| 602 | 20 Kickerkombinat :: * :: * | ||
| 603 | 20 Die Blockbuster :: Reibungslose Racker :: Twistpark Westrand | ||
| 604 | 20 Die Drehlords :: Die Plattenpanther :: Griffhalle West | ||
| 605 | 20 Die Abroller :: Drehakademie :: Rotationshalle 7 | ||
| 606 | 21 Die Plattenpanther :: * :: * | ||
| 607 | 21 Drehakademie :: Die Kurbelkicker :: Kugeltempel Altstadt | ||
| 608 | 21 Die Griffgötter :: Vollstoff United :: Kugelwerk Ost | ||
| 609 | 21 Kickerkombinat :: Kurbelschmiede :: Drehpunkt Dome | ||
| 610 | 21 Die Blockbuster :: Dynamo Drehpunkt :: Kugeltempel Altstadt | ||
| 611 | 21 Die Abroller :: Die Drehlords :: Rotationshalle 7 | ||
| 612 | 21 Die Plattenspieler :: Reibungslose Racker :: Griffzentrum Westkurve | ||
| 613 | 22 Dynamo Drehpunkt :: Die Kurbelkicker :: Kugelkurve Klassik | ||
| 614 | 22 Kurbelschmiede :: Die Griffgötter :: Gegenstoß-Galerie | ||
| 615 | 22 Reibungslose Racker :: Die Abroller :: Der Tischkessel | ||
| 616 | 22 Drehakademie :: Die Blockbuster :: Kugeltempel Altstadt | ||
| 617 | 22 Kickerkombinat :: Vollstoff United :: Drehpunkt Dome | ||
| 618 | 22 Die Drehlords :: * :: * | ||
| 619 | 22 Die Plattenspieler :: Die Plattenpanther :: Kurbelkurve Stadion | ||
| 620 | 23 Die Plattenpanther :: Die Kurbelkicker :: Die Platte am Fluss | ||
| 621 | 23 Dynamo Drehpunkt :: Die Abroller :: Kugelkurve Klassik | ||
| 622 | 23 Kurbelschmiede :: Die Drehlords :: GegenstoĂź-Galerie | ||
| 623 | 23 Reibungslose Racker :: Vollstoff United :: Der Tischkessel | ||
| 624 | 23 Drehakademie :: Kickerkombinat :: Kugeltempel Altstadt | ||
| 625 | 23 * :: Die Blockbuster :: * | ||
| 626 | 23 Die Plattenspieler :: Die Griffgötter :: Kurbelkurve Stadion | ||
| 627 | 24 Die Plattenpanther :: Die Blockbuster :: Die Platte am Fluss | ||
| 628 | 24 Vollstoff United :: Drehakademie :: Kugelkurve Klassik | ||
| 629 | 24 Dynamo Drehpunkt :: Kickerkombinat :: Kugelkurve Klassik | ||
| 630 | 24 * :: Kurbelschmiede :: * | ||
| 631 | 24 Reibungslose Racker :: Die Kurbelkicker :: Der Tischkessel | ||
| 632 | 24 Die Griffgötter :: Die Drehlords :: Kugelwerk Ost | ||
| 633 | 24 Die Abroller :: * :: * | ||
| 634 | 24 * :: Die Plattenspieler :: * | ||
| 635 | 25 Die Plattenpanther :: Kickerkombinat :: Die Platte am Fluss | ||
| 636 | 25 Vollstoff United :: Die Plattenspieler :: Kugelkurve Klassik | ||
| 637 | 25 Dynamo Drehpunkt :: Die Drehlords :: Kugelkurve Klassik | ||
| 638 | 25 Kurbelschmiede :: Drehakademie :: GegenstoĂź-Galerie | ||
| 639 | 25 Reibungslose Racker :: Die Griffgötter :: Der Tischkessel | ||
| 640 | 25 Die Blockbuster :: Die Abroller :: Kugeltempel Altstadt | ||
| 641 | 25 Die Kurbelkicker :: * :: * | ||
| 642 | 26 Die Plattenpanther :: Die Griffgötter :: Die Platte am Fluss | ||
| 643 | 26 * :: Vollstoff United :: * | ||
| 644 | 26 Dynamo Drehpunkt :: Drehakademie :: Kugelkurve Klassik | ||
| 645 | 26 Kurbelschmiede :: Die Blockbuster :: GegenstoĂź-Galerie | ||
| 646 | 26 Reibungslose Racker :: Die Drehlords :: Der Tischkessel | ||
| 647 | 26 Kickerkombinat :: * :: * | ||
| 648 | 26 Die Abroller :: * :: * | ||
| 649 | 26 Die Plattenspieler :: Die Kurbelkicker :: Kurbelkurve Stadion | ||
| 650 | 27 Die Plattenpanther :: Drehakademie :: Die Platte am Fluss | ||
| 651 | 27 Vollstoff United :: Die Abroller :: Kugelkurve Klassik | ||
| 652 | 27 Dynamo Drehpunkt :: Die Griffgötter :: Kugelkurve Klassik | ||
| 653 | 27 Kurbelschmiede :: Reibungslose Racker :: Griffzentrum Westkurve | ||
| 654 | 27 * :: Kickerkombinat :: * | ||
| 655 | 27 Die Blockbuster :: Die Drehlords :: Kugeltempel Altstadt | ||
| 656 | 27 Die Kurbelkicker :: * :: * | ||
| 657 | 27 Die Plattenspieler :: * :: * | ||
| 658 | 28 * :: Die Plattenpanther :: * | ||
| 659 | 28 Vollstoff United :: Die Drehlords :: Kugelkurve Klassik | ||
| 660 | 28 Dynamo Drehpunkt :: Reibungslose Racker :: Twistpark Westrand | ||
| 661 | 28 * :: Kurbelschmiede :: * | ||
| 662 | 28 Drehakademie :: Die Griffgötter :: Kugeltempel Altstadt | ||
| 663 | 28 Kickerkombinat :: Die Abroller :: Drehpunkt Dome | ||
| 664 | 28 Die Kurbelkicker :: Die Blockbuster :: Drehkraft-Dome | ||
| 665 | 28 * :: Die Plattenspieler :: * | ||
| 666 | 29 Die Plattenpanther :: Dynamo Drehpunkt :: Die Platte am Fluss | ||
| 667 | 29 Vollstoff United :: Kurbelschmiede :: Kugelkurve Klassik | ||
| 668 | 29 Reibungslose Racker :: Drehakademie :: Der Tischkessel | ||
| 669 | 29 Die Griffgötter :: Die Blockbuster :: Kugelwerk Ost | ||
| 670 | 29 Kickerkombinat :: Die Kurbelkicker :: Drehpunkt Dome | ||
| 671 | 29 Die Drehlords :: * :: * | ||
| 672 | 29 Die Plattenspieler :: Die Abroller :: Kurbelkurve Stadion | ||
| 673 | 0 Stangenterror :: Die Bandenkrieger :: Kugelwerk Ost | ||
| 674 | 0 FC Hartkurbel :: Griff & Gloria :: Drehkraft-Dome | ||
| 675 | 0 Die Griffbanditen :: Tischgewitter :: Schusshof Kurbeldorf | ||
| 676 | 0 Die Schussscheiben :: Die Kugeljäger :: Kickerklotz Kolosseum | ||
| 677 | 0 * :: Kurbelclub Chaos :: * | ||
| 678 | 0 Stangenhelden :: Die Rillenritter :: Bandenbruch-Stadion | ||
| 679 | 0 Vollgas Vierer :: Die Tischwölfe :: Gegenstoß-Galerie | ||
| 680 | 0 FC Gummipuffer :: Rotationssportverein :: Arena am Gleittisch | ||
| 681 | 1 Die Griffbanditen :: Die Schussscheiben :: Schusshof Kurbeldorf | ||
| 682 | 1 Tischgewitter :: Stangenterror :: Griffgipfel Arena | ||
| 683 | 1 Kurbelclub Chaos :: Stangenhelden :: Tischkampfarena Alte Platte | ||
| 684 | 1 Rotationssportverein :: FC Hartkurbel :: Drehkraft-Dome | ||
| 685 | 1 Die Rillenritter :: FC Gummipuffer :: Kickerklotz Kolosseum | ||
| 686 | 1 Vollgas Vierer :: Griff & Gloria :: GegenstoĂź-Galerie | ||
| 687 | 1 Die Tischwölfe :: * :: * | ||
| 688 | 1 Die Bandenkrieger :: Die Kugeljäger :: Griffzentrum Westkurve | ||
| 689 | 2 Stangenterror :: Die Schussscheiben :: Twistground Central | ||
| 690 | 2 Die Kugeljäger :: Kurbelclub Chaos :: Griffgipfel Arena | ||
| 691 | 2 Rotationssportverein :: * :: * | ||
| 692 | 2 Die Rillenritter :: Die Griffbanditen :: Kickerklotz Kolosseum | ||
| 693 | 2 Vollgas Vierer :: Stangenhelden :: GegenstoĂź-Galerie | ||
| 694 | 2 Die Tischwölfe :: FC Hartkurbel :: Gegenstoß-Galerie | ||
| 695 | 2 Die Bandenkrieger :: Tischgewitter :: Griffzentrum Westkurve | ||
| 696 | 2 Griff & Gloria :: FC Gummipuffer :: Drehkraft-Dome | ||
| 697 | 3 FC Hartkurbel :: * :: * | ||
| 698 | 3 Die Griffbanditen :: Vollgas Vierer :: Haltepunkt Hohlgriff | ||
| 699 | 3 Tischgewitter :: FC Gummipuffer :: Griffgipfel Arena | ||
| 700 | 3 Kurbelclub Chaos :: Stangenterror :: Tischkampfarena Alte Platte | ||
| 701 | 3 Die Rillenritter :: Die Kugeljäger :: Kickerklotz Kolosseum | ||
| 702 | 3 Die Tischwölfe :: Stangenhelden :: Gegenstoß-Galerie | ||
| 703 | 3 Die Bandenkrieger :: Rotationssportverein :: Drehkraft-Dome | ||
| 704 | 3 Griff & Gloria :: Die Schussscheiben :: Schusshof Kurbeldorf | ||
| 705 | 4 Stangenterror :: Rotationssportverein :: Kugelwerk Ost | ||
| 706 | 4 Tischgewitter :: Vollgas Vierer :: Griffgipfel Arena | ||
| 707 | 4 * :: Die Schussscheiben :: * | ||
| 708 | 4 Die Kugeljäger :: Die Tischwölfe :: Griffgipfel Arena | ||
| 709 | 4 Die Rillenritter :: FC Hartkurbel :: Kickerklotz Kolosseum | ||
| 710 | 4 Stangenhelden :: Die Bandenkrieger :: Die Platte am Fluss | ||
| 711 | 4 FC Gummipuffer :: Kurbelclub Chaos :: Schusshof Kurbeldorf | ||
| 712 | 4 Griff & Gloria :: Die Griffbanditen :: Drehkraft-Dome | ||
| 713 | 5 Stangenterror :: Vollgas Vierer :: Kugelwerk Ost | ||
| 714 | 5 FC Hartkurbel :: Die Bandenkrieger :: Drehkraft-Dome | ||
| 715 | 5 Die Griffbanditen :: FC Gummipuffer :: Haltepunkt Hohlgriff | ||
| 716 | 5 Tischgewitter :: Rotationssportverein :: Griffgipfel Arena | ||
| 717 | 5 Die Schussscheiben :: Die Rillenritter :: Kickerklotz Kolosseum | ||
| 718 | 5 Die Kugeljäger :: Stangenhelden :: Griffgipfel Arena | ||
| 719 | 5 Kurbelclub Chaos :: Die Tischwölfe :: Tischkampfarena Alte Platte | ||
| 720 | 5 * :: Griff & Gloria :: * | ||
| 721 | 6 Die Schussscheiben :: Rotationssportverein :: Kickerklotz Kolosseum | ||
| 722 | 6 Die Kugeljäger :: FC Hartkurbel :: Griffgipfel Arena | ||
| 723 | 6 Kurbelclub Chaos :: Vollgas Vierer :: Tischkampfarena Alte Platte | ||
| 724 | 6 * :: Die Rillenritter :: * | ||
| 725 | 6 Stangenhelden :: Die Griffbanditen :: Die Platte am Fluss | ||
| 726 | 6 Die Tischwölfe :: Stangenterror :: Gegenstoß-Galerie | ||
| 727 | 6 FC Gummipuffer :: Die Bandenkrieger :: Arena am Gleittisch | ||
| 728 | 6 Griff & Gloria :: Tischgewitter :: Schusshof Kurbeldorf | ||
| 729 | 7 FC Hartkurbel :: Stangenterror :: Drehkraft-Dome | ||
| 730 | 7 Die Griffbanditen :: * :: * | ||
| 731 | 7 Tischgewitter :: Die Tischwölfe :: Griffgipfel Arena | ||
| 732 | 7 Die Kugeljäger :: FC Gummipuffer :: Griffgipfel Arena | ||
| 733 | 7 Rotationssportverein :: Stangenhelden :: Drehkraft-Dome | ||
| 734 | 7 Die Rillenritter :: Die Bandenkrieger :: Kickerklotz Kolosseum | ||
| 735 | 7 Vollgas Vierer :: Die Schussscheiben :: Twistpark Westrand | ||
| 736 | 7 Griff & Gloria :: Kurbelclub Chaos :: Schusshof Kurbeldorf | ||
| 737 | 8 Stangenterror :: FC Gummipuffer :: Kugelwerk Ost | ||
| 738 | 8 Die Kugeljäger :: Die Griffbanditen :: Griffgipfel Arena | ||
| 739 | 8 Rotationssportverein :: Griff & Gloria :: Drehkraft-Dome | ||
| 740 | 8 Die Rillenritter :: Tischgewitter :: Kickerklotz Kolosseum | ||
| 741 | 8 Stangenhelden :: FC Hartkurbel :: Die Platte am Fluss | ||
| 742 | 8 * :: Vollgas Vierer :: * | ||
| 743 | 8 Die Tischwölfe :: Die Schussscheiben :: Kickerforum Süd | ||
| 744 | 8 Die Bandenkrieger :: Kurbelclub Chaos :: Griffzentrum Westkurve | ||
| 745 | 9 Stangenterror :: Griff & Gloria :: Kugelwerk Ost | ||
| 746 | 9 Die Griffbanditen :: FC Hartkurbel :: Haltepunkt Hohlgriff | ||
| 747 | 9 Tischgewitter :: Die Kugeljäger :: Griffgipfel Arena | ||
| 748 | 9 Die Schussscheiben :: Die Bandenkrieger :: Kickerklotz Kolosseum | ||
| 749 | 9 Kurbelclub Chaos :: Die Rillenritter :: Tischkampfarena Alte Platte | ||
| 750 | 9 Rotationssportverein :: Vollgas Vierer :: Drehkraft-Dome | ||
| 751 | 9 * :: Stangenhelden :: * | ||
| 752 | 9 FC Gummipuffer :: Die Tischwölfe :: Arena am Gleittisch | ||
| 753 | 10 FC Hartkurbel :: FC Gummipuffer :: Drehkraft-Dome | ||
| 754 | 10 * :: Tischgewitter :: * | ||
| 755 | 10 Kurbelclub Chaos :: Die Griffbanditen :: Tischkampfarena Alte Platte | ||
| 756 | 10 Rotationssportverein :: Die Kugeljäger :: Twistpark Westrand | ||
| 757 | 10 Die Rillenritter :: Stangenterror :: Kickerklotz Kolosseum | ||
| 758 | 10 Stangenhelden :: Die Schussscheiben :: Bandenbruch-Stadion | ||
| 759 | 10 Die Tischwölfe :: Griff & Gloria :: Gegenstoß-Galerie | ||
| 760 | 10 Die Bandenkrieger :: Vollgas Vierer :: Drehkraft-Dome | ||
| 761 | 11 Stangenterror :: * :: * | ||
| 762 | 11 Die Griffbanditen :: Die Bandenkrieger :: Haltepunkt Hohlgriff | ||
| 763 | 11 Die Schussscheiben :: Tischgewitter :: Kickerklotz Kolosseum | ||
| 764 | 11 Kurbelclub Chaos :: FC Hartkurbel :: Tischkampfarena Alte Platte | ||
| 765 | 11 Stangenhelden :: FC Gummipuffer :: Die Platte am Fluss | ||
| 766 | 11 Vollgas Vierer :: Die Kugeljäger :: Twistpark Westrand | ||
| 767 | 11 Die Tischwölfe :: Rotationssportverein :: Gegenstoß-Galerie | ||
| 768 | 11 Griff & Gloria :: Die Rillenritter :: Schusshof Kurbeldorf | ||
| 769 | 12 FC Hartkurbel :: Die Schussscheiben :: Schusshof Kurbeldorf | ||
| 770 | 12 Tischgewitter :: Kurbelclub Chaos :: Griffgipfel Arena | ||
| 771 | 12 Die Kugeljäger :: Stangenterror :: Griffgipfel Arena | ||
| 772 | 12 Rotationssportverein :: Die Griffbanditen :: Drehkraft-Dome | ||
| 773 | 12 Die Rillenritter :: Die Tischwölfe :: Kickerklotz Kolosseum | ||
| 774 | 12 Stangenhelden :: Griff & Gloria :: Die Platte am Fluss | ||
| 775 | 12 Die Bandenkrieger :: * :: * | ||
| 776 | 12 FC Gummipuffer :: Vollgas Vierer :: Arena am Gleittisch | ||
| 777 | 13 Die Griffbanditen :: Stangenterror :: Haltepunkt Hohlgriff | ||
| 778 | 13 Tischgewitter :: Stangenhelden :: Griffgipfel Arena | ||
| 779 | 13 Kurbelclub Chaos :: Die Schussscheiben :: Tischkampfarena Alte Platte | ||
| 780 | 13 Die Rillenritter :: Rotationssportverein :: Kickerklotz Kolosseum | ||
| 781 | 13 Vollgas Vierer :: FC Hartkurbel :: GegenstoĂź-Galerie | ||
| 782 | 13 Die Bandenkrieger :: Die Tischwölfe :: Drehkraft-Dome | ||
| 783 | 13 FC Gummipuffer :: * :: * | ||
| 784 | 13 Griff & Gloria :: Die Kugeljäger :: Schusshof Kurbeldorf | ||
| 785 | 14 FC Hartkurbel :: Tischgewitter :: Schusshof Kurbeldorf | ||
| 786 | 14 Die Kugeljäger :: * :: * | ||
| 787 | 14 Kurbelclub Chaos :: Rotationssportverein :: Tischkampfarena Alte Platte | ||
| 788 | 14 Die Rillenritter :: Vollgas Vierer :: Kickerklotz Kolosseum | ||
| 789 | 14 Stangenhelden :: Stangenterror :: Die Platte am Fluss | ||
| 790 | 14 Die Tischwölfe :: Die Griffbanditen :: Gegenstoß-Galerie | ||
| 791 | 14 FC Gummipuffer :: Die Schussscheiben :: Schusshof Kurbeldorf | ||
| 792 | 14 Griff & Gloria :: Die Bandenkrieger :: Drehkraft-Dome | ||
| 793 | 15 Stangenterror :: FC Hartkurbel :: Kugelwerk Ost | ||
| 794 | 15 Die Griffbanditen :: Die Tischwölfe :: Haltepunkt Hohlgriff | ||
| 795 | 15 Die Schussscheiben :: * :: * | ||
| 796 | 15 Rotationssportverein :: Die Bandenkrieger :: Drehkraft-Dome | ||
| 797 | 15 Die Rillenritter :: Griff & Gloria :: Kickerklotz Kolosseum | ||
| 798 | 15 Stangenhelden :: Kurbelclub Chaos :: Bandenbruch-Stadion | ||
| 799 | 15 Vollgas Vierer :: Tischgewitter :: Twistpark Westrand | ||
| 800 | 15 FC Gummipuffer :: Die Kugeljäger :: Schusshof Kurbeldorf | ||
| 801 | 16 FC Hartkurbel :: Kurbelclub Chaos :: Schusshof Kurbeldorf | ||
| 802 | 16 Tischgewitter :: Die Griffbanditen :: Griffgipfel Arena | ||
| 803 | 16 Die Kugeljäger :: Die Rillenritter :: Griffgipfel Arena | ||
| 804 | 16 Rotationssportverein :: Die Schussscheiben :: Twistpark Westrand | ||
| 805 | 16 Stangenhelden :: * :: * | ||
| 806 | 16 Vollgas Vierer :: FC Gummipuffer :: GegenstoĂź-Galerie | ||
| 807 | 16 Die Tischwölfe :: Die Bandenkrieger :: Gegenstoß-Galerie | ||
| 808 | 16 Griff & Gloria :: Stangenterror :: Drehkraft-Dome | ||
| 809 | 17 Stangenterror :: Die Tischwölfe :: Kugelwerk Ost | ||
| 810 | 17 * :: FC Hartkurbel :: * | ||
| 811 | 17 Die Kugeljäger :: Die Schussscheiben :: Griffgipfel Arena | ||
| 812 | 17 Die Rillenritter :: Kurbelclub Chaos :: Kickerklotz Kolosseum | ||
| 813 | 17 Vollgas Vierer :: Die Griffbanditen :: GegenstoĂź-Galerie | ||
| 814 | 17 Die Bandenkrieger :: Stangenhelden :: Drehkraft-Dome | ||
| 815 | 17 FC Gummipuffer :: Tischgewitter :: Schusshof Kurbeldorf | ||
| 816 | 17 Griff & Gloria :: Rotationssportverein :: Drehkraft-Dome | ||
| 817 | 18 Tischgewitter :: FC Hartkurbel :: Griffgipfel Arena | ||
| 818 | 18 Die Schussscheiben :: Die Griffbanditen :: Kickerklotz Kolosseum | ||
| 819 | 18 Kurbelclub Chaos :: FC Gummipuffer :: Tischkampfarena Alte Platte | ||
| 820 | 18 Rotationssportverein :: Die Rillenritter :: Twistpark Westrand | ||
| 821 | 18 Vollgas Vierer :: Stangenterror :: GegenstoĂź-Galerie | ||
| 822 | 18 Die Tischwölfe :: Die Kugeljäger :: Kickerforum Süd | ||
| 823 | 18 * :: Die Bandenkrieger :: * | ||
| 824 | 18 Griff & Gloria :: Stangenhelden :: Drehkraft-Dome | ||
| 825 | 19 FC Hartkurbel :: Vollgas Vierer :: Drehkraft-Dome | ||
| 826 | 19 * :: Die Griffbanditen :: * | ||
| 827 | 19 Die Schussscheiben :: Griff & Gloria :: Kickerklotz Kolosseum | ||
| 828 | 19 Kurbelclub Chaos :: Die Kugeljäger :: Tischkampfarena Alte Platte | ||
| 829 | 19 Rotationssportverein :: Tischgewitter :: Twistpark Westrand | ||
| 830 | 19 Stangenhelden :: Die Tischwölfe :: Die Platte am Fluss | ||
| 831 | 19 Die Bandenkrieger :: Stangenterror :: Drehkraft-Dome | ||
| 832 | 19 FC Gummipuffer :: Die Rillenritter :: Schusshof Kurbeldorf | ||
| 833 | 20 Stangenterror :: Kurbelclub Chaos :: Twistground Central | ||
| 834 | 20 FC Hartkurbel :: Stangenhelden :: Drehkraft-Dome | ||
| 835 | 20 Die Griffbanditen :: Griff & Gloria :: Haltepunkt Hohlgriff | ||
| 836 | 20 Tischgewitter :: Die Bandenkrieger :: Griffgipfel Arena | ||
| 837 | 20 Die Schussscheiben :: FC Gummipuffer :: Kickerklotz Kolosseum | ||
| 838 | 20 * :: Die Kugeljäger :: * | ||
| 839 | 20 Vollgas Vierer :: Rotationssportverein :: GegenstoĂź-Galerie | ||
| 840 | 20 Die Tischwölfe :: Die Rillenritter :: Kickerforum Süd | ||
| 841 | 21 FC Hartkurbel :: Die Rillenritter :: Schusshof Kurbeldorf | ||
| 842 | 21 Tischgewitter :: Griff & Gloria :: Griffgipfel Arena | ||
| 843 | 21 Die Schussscheiben :: Stangenterror :: Kickerklotz Kolosseum | ||
| 844 | 21 Die Kugeljäger :: Die Bandenkrieger :: Griffgipfel Arena | ||
| 845 | 21 Kurbelclub Chaos :: * :: * | ||
| 846 | 21 Rotationssportverein :: Die Tischwölfe :: Drehkraft-Dome | ||
| 847 | 21 Stangenhelden :: Vollgas Vierer :: Die Platte am Fluss | ||
| 848 | 21 FC Gummipuffer :: Die Griffbanditen :: Arena am Gleittisch | ||
| 849 | 22 Stangenterror :: Tischgewitter :: Twistground Central | ||
| 850 | 22 FC Hartkurbel :: Die Griffbanditen :: Drehkraft-Dome | ||
| 851 | 22 Die Schussscheiben :: Die Tischwölfe :: Kickerklotz Kolosseum | ||
| 852 | 22 Rotationssportverein :: FC Gummipuffer :: Drehkraft-Dome | ||
| 853 | 22 Die Rillenritter :: * :: * | ||
| 854 | 22 Stangenhelden :: Die Kugeljäger :: Bandenbruch-Stadion | ||
| 855 | 22 Vollgas Vierer :: Kurbelclub Chaos :: Twistpark Westrand | ||
| 856 | 22 Die Bandenkrieger :: Griff & Gloria :: Drehkraft-Dome | ||
| 857 | 23 FC Hartkurbel :: Die Kugeljäger :: Schusshof Kurbeldorf | ||
| 858 | 23 Die Griffbanditen :: Die Rillenritter :: Schusshof Kurbeldorf | ||
| 859 | 23 Tischgewitter :: * :: * | ||
| 860 | 23 Die Schussscheiben :: Stangenhelden :: Kickerklotz Kolosseum | ||
| 861 | 23 Kurbelclub Chaos :: Griff & Gloria :: Tischkampfarena Alte Platte | ||
| 862 | 23 Rotationssportverein :: Stangenterror :: Drehkraft-Dome | ||
| 863 | 23 Die Tischwölfe :: Vollgas Vierer :: Gegenstoß-Galerie | ||
| 864 | 23 Die Bandenkrieger :: FC Gummipuffer :: Drehkraft-Dome | ||
| 865 | 24 Die Griffbanditen :: Stangenhelden :: Haltepunkt Hohlgriff | ||
| 866 | 24 Die Schussscheiben :: Kurbelclub Chaos :: Kickerklotz Kolosseum | ||
| 867 | 24 Die Kugeljäger :: Vollgas Vierer :: Griffgipfel Arena | ||
| 868 | 24 * :: Rotationssportverein :: * | ||
| 869 | 24 Die Tischwölfe :: Tischgewitter :: Kickerforum Süd | ||
| 870 | 24 Die Bandenkrieger :: Die Rillenritter :: Griffzentrum Westkurve | ||
| 871 | 24 FC Gummipuffer :: Stangenterror :: Arena am Gleittisch | ||
| 872 | 24 Griff & Gloria :: FC Hartkurbel :: Drehkraft-Dome | ||
| 873 | 25 Stangenterror :: Stangenhelden :: Kugelwerk Ost | ||
| 874 | 25 FC Hartkurbel :: Die Tischwölfe :: Drehkraft-Dome | ||
| 875 | 25 Die Griffbanditen :: Rotationssportverein :: Haltepunkt Hohlgriff | ||
| 876 | 25 Die Kugeljäger :: Griff & Gloria :: Griffgipfel Arena | ||
| 877 | 25 Kurbelclub Chaos :: Tischgewitter :: Tischkampfarena Alte Platte | ||
| 878 | 25 Die Rillenritter :: Die Schussscheiben :: Kickerklotz Kolosseum | ||
| 879 | 25 Vollgas Vierer :: Die Bandenkrieger :: GegenstoĂź-Galerie | ||
| 880 | 25 * :: FC Gummipuffer :: * | ||
| 881 | 26 * :: Stangenterror :: * | ||
| 882 | 26 Tischgewitter :: Die Rillenritter :: Griffgipfel Arena | ||
| 883 | 26 Die Schussscheiben :: FC Hartkurbel :: Kickerklotz Kolosseum | ||
| 884 | 26 Die Kugeljäger :: Rotationssportverein :: Griffgipfel Arena | ||
| 885 | 26 Die Tischwölfe :: Kurbelclub Chaos :: Kickerforum Süd | ||
| 886 | 26 Die Bandenkrieger :: Die Griffbanditen :: Drehkraft-Dome | ||
| 887 | 26 FC Gummipuffer :: Stangenhelden :: Arena am Gleittisch | ||
| 888 | 26 Griff & Gloria :: Vollgas Vierer :: Drehkraft-Dome | ||
| 889 | 27 Stangenterror :: Die Rillenritter :: Twistground Central | ||
| 890 | 27 FC Hartkurbel :: Rotationssportverein :: Drehkraft-Dome | ||
| 891 | 27 Die Griffbanditen :: Die Kugeljäger :: Schusshof Kurbeldorf | ||
| 892 | 27 Die Schussscheiben :: Vollgas Vierer :: Kickerklotz Kolosseum | ||
| 893 | 27 Kurbelclub Chaos :: Die Bandenkrieger :: Tischkampfarena Alte Platte | ||
| 894 | 27 Stangenhelden :: Tischgewitter :: Bandenbruch-Stadion | ||
| 895 | 27 * :: Die Tischwölfe :: * | ||
| 896 | 27 FC Gummipuffer :: Griff & Gloria :: Arena am Gleittisch | ||
| 897 | 28 Stangenterror :: Die Kugeljäger :: Twistground Central | ||
| 898 | 28 Die Griffbanditen :: Kurbelclub Chaos :: Schusshof Kurbeldorf | ||
| 899 | 28 Tischgewitter :: Die Schussscheiben :: Griffgipfel Arena | ||
| 900 | 28 Stangenhelden :: Rotationssportverein :: Die Platte am Fluss | ||
| 901 | 28 Vollgas Vierer :: Die Rillenritter :: Twistpark Westrand | ||
| 902 | 28 Die Tischwölfe :: FC Gummipuffer :: Gegenstoß-Galerie | ||
| 903 | 28 Die Bandenkrieger :: FC Hartkurbel :: Drehkraft-Dome | ||
| 904 | 28 Griff & Gloria :: * :: * | ||
| 905 | 29 Stangenterror :: Die Griffbanditen :: Kugelwerk Ost | ||
| 906 | 29 Die Kugeljäger :: Tischgewitter :: Griffgipfel Arena | ||
| 907 | 29 Rotationssportverein :: Kurbelclub Chaos :: Twistpark Westrand | ||
| 908 | 29 Die Rillenritter :: Stangenhelden :: Kickerklotz Kolosseum | ||
| 909 | 29 Vollgas Vierer :: * :: * | ||
| 910 | 29 Die Bandenkrieger :: Die Schussscheiben :: Griffzentrum Westkurve | ||
| 911 | 29 FC Gummipuffer :: FC Hartkurbel :: Arena am Gleittisch | ||
| 912 | 29 Griff & Gloria :: Die Tischwölfe :: Drehkraft-Dome | ||
diff --git a/index.html b/index.html new file mode 100644 index 0000000..298723e --- /dev/null +++ b/index.html | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8"> | ||
| 5 | <title>Tabula Rasa</title> | ||
| 6 | <link rel="stylesheet" href="style.css"> | ||
| 7 | <script src="csp.js"></script> | ||
| 8 | <script src="tabularasa.js" defer></script> | ||
| 9 | </head> | ||
| 10 | <body> | ||
| 11 | <div id="anchor" /> | ||
| 12 | </body> | ||
| 13 | </html> | ||
diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4adfed0 --- /dev/null +++ b/requirements.txt | |||
| @@ -0,0 +1 @@ | |||
| ortools | |||
diff --git a/style.css b/style.css new file mode 100644 index 0000000..47d2d84 --- /dev/null +++ b/style.css | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | body { | ||
| 2 | font-family: "HelveticaNeueLight", "HelveticaNeue-Light", "Helvetica Neue Light", "HelveticaNeue", "Helvetica Neue", "TeXGyreHerosRegular", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; font-weight:400; font-stretch:normal; | ||
| 3 | } | ||
| 4 | |||
| 5 | table { | ||
| 6 | border-collapse: collapse; | ||
| 7 | margin: 25px 0; | ||
| 8 | font-size: 0.9em; | ||
| 9 | font-family: sans-serif; | ||
| 10 | min-width: 50%; | ||
| 11 | max-width: 50%; | ||
| 12 | box-sizing: border-box; | ||
| 13 | } | ||
| 14 | |||
| 15 | thead { | ||
| 16 | position: sticky; | ||
| 17 | top: 0px; | ||
| 18 | background-color: Canvas; | ||
| 19 | text-align: left; | ||
| 20 | } | ||
| 21 | |||
diff --git a/tabularasa.js b/tabularasa.js new file mode 100644 index 0000000..ee45493 --- /dev/null +++ b/tabularasa.js | |||
| @@ -0,0 +1,284 @@ | |||
| 1 | // let API = "http://localhost:8080/example.json"; | ||
| 2 | let API = "example.json"; | ||
| 3 | |||
| 4 | var tabelle = [] /* Will contain all pairings */ | ||
| 5 | var leagues = [] /* List of league ids */ | ||
| 6 | var max_spieltage = 0; | ||
| 7 | var next_pairing_id = 0; | ||
| 8 | |||
| 9 | function weekday_to_string(weekday) { | ||
| 10 | return new Date(Date.UTC(1970, 0, 6+weekday)).toLocaleDateString(undefined, { weekday: 'long' }); | ||
| 11 | } | ||
| 12 | |||
| 13 | var wildcard = JSON.parse('{"id":"-1", "name":"*"}'); | ||
| 14 | var nowhere = JSON.parse('{"id":"-1", "name":"*"}'); | ||
| 15 | |||
| 16 | class paarung { | ||
| 17 | static _next_id = 0; | ||
| 18 | constructor(team_a, team_b, league, ort) { | ||
| 19 | this.id = next_pairing_id++; | ||
| 20 | this.team_a = team_a; | ||
| 21 | this.team_b = team_b; | ||
| 22 | this.league = league; | ||
| 23 | this.ort = ort; | ||
| 24 | } | ||
| 25 | |||
| 26 | get weekday() { | ||
| 27 | if (this.team_a.id != -1 && this.team_b.id != -1) | ||
| 28 | return weekday_to_string(this.team_a.tag); | ||
| 29 | return "*"; | ||
| 30 | } | ||
| 31 | |||
| 32 | get spieltag() { | ||
| 33 | if (!this.spieltage.size) | ||
| 34 | return -1; | ||
| 35 | return [...this.spieltage][0]; | ||
| 36 | } | ||
| 37 | |||
| 38 | get name() { | ||
| 39 | return this.team_a.name + " :: " + this.team_b.name + ", Liga " + this.league; | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | function is_same(team_a, team_b) { | ||
| 44 | if (team_a.id == -1 || team_b.id == -1 || team_a.id != team_b.id) | ||
| 45 | return false; | ||
| 46 | return true; | ||
| 47 | } | ||
| 48 | |||
| 49 | function is_same_ort(ort_a, ort_b) { | ||
| 50 | if (ort_a.id == -1 || ort_b.id == -1 || ort_a.id != ort_b.id) | ||
| 51 | return false; | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | function createTextElement(name, text) { | ||
| 56 | let elem = document.createElement(name); | ||
| 57 | elem.appendChild(document.createTextNode(text)); | ||
| 58 | return elem; | ||
| 59 | } | ||
| 60 | |||
| 61 | function appendChildList(elem, name, ...texts) { | ||
| 62 | for (const text of texts) | ||
| 63 | elem.appendChild(createTextElement(name, text)); | ||
| 64 | } | ||
| 65 | |||
| 66 | function draw_table() { | ||
| 67 | /* Draw tables for each league */ | ||
| 68 | let anchor = document.getElementById("anchor"); | ||
| 69 | for (league of leagues) { | ||
| 70 | anchor.appendChild(createTextElement("h2", "Liga " + league.toString())); | ||
| 71 | |||
| 72 | let table = document.createElement("table"); | ||
| 73 | let thead = document.createElement("thead"); | ||
| 74 | let tr = document.createElement("tr"); | ||
| 75 | appendChildList(tr, "th", "Heim", "Gäste", "Wochentag", "Tisch", "Spieltag"); | ||
| 76 | thead.appendChild(tr); | ||
| 77 | table.appendChild(thead); | ||
| 78 | |||
| 79 | for (paar of tabelle.filter(paar => paar.league == league).sort((paar_a, paar_b) => { if (!paar_a.spieltage.size || !paar_b.spieltage.size) return -1; return paar_a.spieltag - paar_b.spieltag } )) { | ||
| 80 | let tr = document.createElement("tr"); | ||
| 81 | appendChildList(tr, "td", paar.team_a.name, paar.team_b.name, paar.weekday, paar.ort.name, 1 + paar.spieltag); | ||
| 82 | |||
| 83 | table.appendChild(tr); | ||
| 84 | } | ||
| 85 | anchor.appendChild(table); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | function fill_table(data) { | ||
| 90 | leagues = [...new Set(data.teams.map(team => team.liga))].sort(); | ||
| 91 | |||
| 92 | /* Init some objects */ | ||
| 93 | for (ort of data.orte) | ||
| 94 | ort.pairings = new Array(); | ||
| 95 | |||
| 96 | /* Count necessary spieltage */ | ||
| 97 | for (league of leagues) { | ||
| 98 | let pairings_count = data.teams.filter(team => team.liga == league).sort((a,b) => a.id > b.id).length; | ||
| 99 | if (pairings_count % 2) | ||
| 100 | pairings_count++; | ||
| 101 | max_spieltage = Math.max(2 * (pairings_count - 1), max_spieltage); | ||
| 102 | } | ||
| 103 | |||
| 104 | /* Fill out complete table for all leagues */ | ||
| 105 | for (league of leagues) { | ||
| 106 | let league_teams = data.teams.filter(team => team.liga == league).sort((a,b) => a.id > b.id); | ||
| 107 | console.log( "liga " + league_teams.length ); | ||
| 108 | |||
| 109 | for (team_a of league_teams) { | ||
| 110 | var game_count = 0; | ||
| 111 | for (team_b of league_teams) { | ||
| 112 | if (team_a == team_b) | ||
| 113 | continue; | ||
| 114 | |||
| 115 | /* If Heimspiel-Team is smokers and the Gastteam is not, the alternative | ||
| 116 | location needs to be chosen */ | ||
| 117 | var ort = data.orte.find(ort => ort.id == team_a.heimort); | ||
| 118 | if (team_b.nichtraucher && ort.raucher) | ||
| 119 | ort = data.orte.find(ort => ort.id == team_a.ersatzort); | ||
| 120 | |||
| 121 | pair = new paarung(team_a, team_b, league, ort); | ||
| 122 | tabelle.push(pair); | ||
| 123 | ort.pairings.push(pair); | ||
| 124 | game_count++; | ||
| 125 | } | ||
| 126 | /* Fill rest of this team's games with wildcard games */ | ||
| 127 | while (game_count < max_spieltage / 2) { | ||
| 128 | tabelle.push(new paarung(team_a, wildcard, league, nowhere)); | ||
| 129 | tabelle.push(new paarung(wildcard, team_a, league, nowhere)); | ||
| 130 | game_count++; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | /* Fill all leagues with uneven or fewer spieltage with wildcard games */ | ||
| 136 | for (league of leagues) { | ||
| 137 | |||
| 138 | } | ||
| 139 | |||
| 140 | /* Check if an ort is over-provisioned | ||
| 141 | for (ort of data.orte) { | ||
| 142 | for (weekday of [...new Set(ort.pairings.map(pair => pair.weekday))].sort()) { | ||
| 143 | var games_on_day = ort.pairings.filter(pair => pair.weekday = weekday); | ||
| 144 | if (games_on_day > max_spieltage) | ||
| 145 | alert("Ort " + ort.name + "over provisioned on weekday " + weekday_to_string(weekday)); | ||
| 146 | } | ||
| 147 | } */ | ||
| 148 | } | ||
| 149 | |||
| 150 | function shuffle_array(array) { | ||
| 151 | return array.map(value => ({ value, sort: Math.random() })) | ||
| 152 | .sort((a, b) => a.sort - b.sort) | ||
| 153 | .map(({ value }) => value); | ||
| 154 | } | ||
| 155 | |||
| 156 | function not_equal_function(s1, s2) { return s1 != s2; } | ||
| 157 | |||
| 158 | function find_csp_solution() { | ||
| 159 | var all_spieltage = new Array(); | ||
| 160 | for (let i=0; i < max_spieltage; i++) | ||
| 161 | all_spieltage.push(i); | ||
| 162 | |||
| 163 | for (league of leagues) { | ||
| 164 | var sub = tabelle.filter(paar => paar.league == league); | ||
| 165 | var candidate = {}, variables = {}, constraints = []; | ||
| 166 | for (outer of sub) { | ||
| 167 | variables[outer.id] = [...all_spieltage]; | ||
| 168 | for (inner of tabelle.filter(inner => | ||
| 169 | inner.id > outer.id && ( | ||
| 170 | is_same(outer.team_a, inner.team_a) || | ||
| 171 | is_same(outer.team_b, inner.team_a) || | ||
| 172 | is_same(outer.team_a, inner.team_b) || | ||
| 173 | is_same(outer.team_b, inner.team_b)))) | ||
| 174 | { | ||
| 175 | constraints.push([outer.id, inner.id, not_equal_function]); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | candidate.variables = variables; | ||
| 180 | candidate.constraints = constraints; | ||
| 181 | |||
| 182 | var result = csp.solve(candidate); | ||
| 183 | console.log(result); | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | |||
| 188 | function find_table_configuration() { | ||
| 189 | /* Check if there is one possible configuration that fulfills the following criteria: | ||
| 190 | 1) each team must have 0 or 1 games on any given week | ||
| 191 | 2) each location+weekday combo must have 0 or 1 games on any given week | ||
| 192 | 3) each pairing needs a week and a location | ||
| 193 | */ | ||
| 194 | var candidates = tabelle; /* Take a copy of the array */ | ||
| 195 | |||
| 196 | /* Add all possible spieltage to the list for | ||
| 197 | them to be later reduced */ | ||
| 198 | for (paar of candidates) { | ||
| 199 | paar.spieltage = new Set(); | ||
| 200 | for (let i=0; i < max_spieltage; i++) | ||
| 201 | paar.spieltage.add(i); | ||
| 202 | } | ||
| 203 | |||
| 204 | /* TODO: Add more initial constraints */ | ||
| 205 | |||
| 206 | while (candidates.length) { | ||
| 207 | /* First pick the pairings that have the least amount of spieltage to fit in */ | ||
| 208 | candidates = shuffle_array(candidates).sort((a, b) => a.spieltage.size <= b.spieltage.size); | ||
| 209 | |||
| 210 | var looking_at = candidates.pop(); | ||
| 211 | |||
| 212 | /* Pick random spieltag out of the possible ones */ | ||
| 213 | let spieltag = Array.from(looking_at.spieltage)[Math.floor(Math.random() * looking_at.spieltage.size)]; | ||
| 214 | |||
| 215 | /* Now we have to remove all new conflicting dates from other unset pairings: */ | ||
| 216 | |||
| 217 | /* Filter out all pairings on the same spieltag with the current team */ | ||
| 218 | for (paar of candidates.filter(paar => | ||
| 219 | is_same(paar.team_a, looking_at.team_a) || | ||
| 220 | is_same(paar.team_b, looking_at.team_a) || | ||
| 221 | is_same(paar.team_a, looking_at.team_b) || | ||
| 222 | is_same(paar.team_b, looking_at.team_b))) | ||
| 223 | { | ||
| 224 | paar.spieltage.delete(spieltag); | ||
| 225 | } | ||
| 226 | |||
| 227 | /* Filter out all pairing on the same spieltag with the same ort and weekday | ||
| 228 | for (paar of candidates.filter(paar => | ||
| 229 | is_same_ort(paar.ort, looking_at.ort) && | ||
| 230 | paar.weekday == looking_at.weekday)) | ||
| 231 | { | ||
| 232 | if (paar.ort.id != -1 && looking_at.ort.id != -1) | ||
| 233 | paar.spieltage.delete(spieltag); | ||
| 234 | } | ||
| 235 | */ | ||
| 236 | |||
| 237 | /* Filter out the reverse pairing until the second half of the season (Rueckrunde). | ||
| 238 | If it doesn't exist, we're probably already in Rueckrunde | ||
| 239 | var runden_start = Math.floor(max_spieltage * Math.floor(spieltag * 2 / max_spieltage) / 2); | ||
| 240 | for (paar of candidates.filter(paar => | ||
| 241 | is_same(paar.team_a, looking_at.team_b) || | ||
| 242 | is_same(paar.team_b, looking_at.team_a))) { | ||
| 243 | for (var exclude = 0; exclude < max_spieltage / 2; exclude++) | ||
| 244 | paar.spieltage.delete(runden_start + exclude); | ||
| 245 | } | ||
| 246 | */ | ||
| 247 | /* Filter out home rounds for the home team on next spieltag and guest rounds for | ||
| 248 | guest team on next spieltag, except for end of Hinrunde | ||
| 249 | if (spieltag != max_spieltage / 2 - 1) | ||
| 250 | for (paar of candidates.filter(paar => | ||
| 251 | is_same(paar.team_a, looking_at.team_a) || | ||
| 252 | is_same(paar.team_b, looking_at.team_b))) | ||
| 253 | paar.spieltage.delete(spieltag + 1); | ||
| 254 | */ | ||
| 255 | |||
| 256 | for (paar of candidates) | ||
| 257 | if (paar.spieltage.size == 0) { | ||
| 258 | console.log(candidates.length); | ||
| 259 | return false; | ||
| 260 | } | ||
| 261 | |||
| 262 | /* Now fix the date */ | ||
| 263 | looking_at.spieltage = new Set(); | ||
| 264 | looking_at.spieltage.add(spieltag); | ||
| 265 | } | ||
| 266 | return true; | ||
| 267 | } | ||
| 268 | |||
| 269 | function init() { | ||
| 270 | var xhttp = new XMLHttpRequest(); | ||
| 271 | xhttp.onreadystatechange = function() { | ||
| 272 | if (this.readyState == 4 && this.status == 200) { | ||
| 273 | fill_table(xhttp.response); | ||
| 274 | //find_table_configuration(); | ||
| 275 | find_csp_solution(); | ||
| 276 | draw_table(); | ||
| 277 | } | ||
| 278 | }; | ||
| 279 | xhttp.responseType = "json"; | ||
| 280 | xhttp.open("GET", API, true); | ||
| 281 | xhttp.send(); | ||
| 282 | } | ||
| 283 | |||
| 284 | init(); | ||
