Merge pull request #1442 from sirDonovan/tours

Tournaments: minor style fixes
This commit is contained in:
Guangcong Luo 2015-01-16 18:30:34 -08:00
commit 4ec86ce94a
2 changed files with 91 additions and 121 deletions

View File

@ -20,8 +20,9 @@ function fixSingleChildNode(parentNode) {
}
var value = parentNode.getValue();
for (var key in value)
for (var key in value) {
delete value[key];
}
Object.merge(value, parentNode.removeChildAt(0).getValue());
return parentNode;
}
@ -29,35 +30,34 @@ function fixSingleChildNode(parentNode) {
var Elimination = (function () {
function Elimination(maxSubtrees) {
maxSubtrees = maxSubtrees || 1;
if (typeof maxSubtrees === 'string' && maxSubtrees.toLowerCase() === 'infinity')
if (typeof maxSubtrees === 'string' && maxSubtrees.toLowerCase() === 'infinity') {
maxSubtrees = Infinity;
else if (typeof maxSubtrees !== 'number')
} else if (typeof maxSubtrees !== 'number') {
maxSubtrees = parseInt(maxSubtrees, 10);
if (!maxSubtrees || maxSubtrees < 1)
maxSubtrees = 1;
}
if (!maxSubtrees || maxSubtrees < 1) maxSubtrees = 1;
this.maxSubtrees = maxSubtrees;
this.isBracketFrozen = false;
this.tree = null;
this.users = new Map();
if (nameMap[maxSubtrees])
if (nameMap[maxSubtrees]) {
this.name = nameMap[maxSubtrees] + " " + this.name;
else if (maxSubtrees === Infinity)
} else if (maxSubtrees === Infinity) {
this.name = "N-" + this.name;
else
} else {
this.name = maxSubtrees + "-tuple " + this.name;
}
}
Elimination.prototype.name = "Elimination";
Elimination.prototype.isDrawingSupported = false;
Elimination.prototype.addUser = function (user) {
if (this.isBracketFrozen)
return 'BracketFrozen';
if (this.isBracketFrozen) return 'BracketFrozen';
if (this.users.has(user))
return 'UserAlreadyAdded';
if (this.users.has(user)) return 'UserAlreadyAdded';
this.users.set(user, {});
if (!this.tree) {
@ -88,23 +88,22 @@ var Elimination = (function () {
}
};
Elimination.prototype.removeUser = function (user) {
if (this.isBracketFrozen)
return 'BracketFrozen';
if (this.isBracketFrozen) return 'BracketFrozen';
if (!this.users.has(user))
return 'UserNotAdded';
if (!this.users.has(user)) return 'UserNotAdded';
this.users.delete(user);
var targetNode;
for (var n = 0; n < this.tree.currentLayerLeafNodes.length && !targetNode; ++n)
for (var n = 0; n < this.tree.currentLayerLeafNodes.length && !targetNode; ++n) {
if (this.tree.currentLayerLeafNodes[n].getValue().user === user) {
targetNode = this.tree.currentLayerLeafNodes[n];
this.tree.currentLayerLeafNodes.splice(n, 1);
}
}
if (targetNode) {
if (this.users.size === 0)
if (this.users.size === 0) {
this.tree = null;
else if (this.tree.nextLayerLeafNodes.length === 0) {
} else if (this.tree.nextLayerLeafNodes.length === 0) {
this.tree.nextLayerLeafNodes = this.tree.currentLayerLeafNodes;
var parentNode = targetNode.getParent();
@ -125,33 +124,36 @@ var Elimination = (function () {
return;
}
for (var n = 0; n < this.tree.nextLayerLeafNodes.length && !targetNode; ++n)
for (var n = 0; n < this.tree.nextLayerLeafNodes.length && !targetNode; ++n) {
if (this.tree.nextLayerLeafNodes[n].getValue().user === user) {
targetNode = this.tree.nextLayerLeafNodes[n];
this.tree.nextLayerLeafNodes.splice(n, 1);
}
}
var parentNode = targetNode.getParent();
parentNode.removeChild(targetNode);
this.tree.nextLayerLeafNodes.splice(this.tree.nextLayerLeafNodes.indexOf(parentNode.getChildAt(0)), 1);
this.tree.currentLayerLeafNodes.push(fixSingleChildNode(parentNode));
};
Elimination.prototype.replaceUser = function (user, replacementUser) {
if (!this.users.has(user))
return 'UserNotAdded';
if (!this.users.has(user)) return 'UserNotAdded';
if (this.users.has(replacementUser))
return 'UserAlreadyAdded';
if (this.users.has(replacementUser)) return 'UserAlreadyAdded';
this.users.delete(user);
this.users.set(user, {});
var targetNode;
for (var n = 0; n < this.tree.currentLayerLeafNodes.length && !targetNode; ++n)
if (this.tree.currentLayerLeafNodes[n].getValue().user === user)
for (var n = 0; n < this.tree.currentLayerLeafNodes.length && !targetNode; ++n) {
if (this.tree.currentLayerLeafNodes[n].getValue().user === user) {
targetNode = this.tree.currentLayerLeafNodes[n];
for (var n = 0; n < this.tree.nextLayerLeafNodes.length && !targetNode; ++n)
if (this.tree.nextLayerLeafNodes[n].getValue().user === user)
}
}
for (var n = 0; n < this.tree.nextLayerLeafNodes.length && !targetNode; ++n) {
if (this.tree.nextLayerLeafNodes[n].getValue().user === user) {
targetNode = this.tree.nextLayerLeafNodes[n];
}
}
targetNode.getValue().user = replacementUser;
};
Elimination.prototype.getUsers = function (remaining) {
@ -174,9 +176,9 @@ var Elimination = (function () {
frame.toNode.children.push(node);
var fromNodeValues = frame.fromNode.getValue();
if (frame.fromNode.isLeaf())
if (frame.fromNode.isLeaf()) {
node.team = fromNodeValues.user || null;
else {
} else {
node.state = fromNodeValues.state || 'unavailable';
if (node.state === 'finished') {
node.team = fromNodeValues.user;
@ -210,11 +212,9 @@ var Elimination = (function () {
var queue = [{node: this.tree.tree, depth: 0}];
while (queue.length > 0) {
var frame = queue.shift();
if (frame.node.isLeaf() || frame.node.getValue().onLoseNode)
continue;
if (frame.node.isLeaf() || frame.node.getValue().onLoseNode) continue;
if (!matchesByDepth[frame.depth])
matchesByDepth[frame.depth] = [];
if (!matchesByDepth[frame.depth]) matchesByDepth[frame.depth] = [];
matchesByDepth[frame.depth].push(frame.node);
queue.push({node: frame.node.getChildAt(0), depth: frame.depth + 1});
@ -229,8 +229,7 @@ var Elimination = (function () {
newTree.currentLayerLeafNodes.push(newTree.tree);
for (var m in matchesByDepth) {
if (m === '0')
continue;
if (m === '0') continue;
var n = 0;
for (; n < matchesByDepth[m].length - 1; n += 2) {
// Replace old leaf with:
@ -294,11 +293,9 @@ var Elimination = (function () {
};
Elimination.prototype.disqualifyUser = function (user) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
if (!this.users.has(user))
return 'UserNotAdded';
if (!this.users.has(user)) return 'UserNotAdded';
this.users.get(user).isDisqualified = true;
@ -306,7 +303,7 @@ var Elimination = (function () {
var match = null;
var result;
this.tree.tree.traverse(function (node) {
if (node.getValue().state === 'available')
if (node.getValue().state === 'available') {
if (node.getChildAt(0).getValue().user === user) {
match = [user, node.getChildAt(1).getValue().user];
result = 'loss';
@ -314,43 +311,41 @@ var Elimination = (function () {
match = [node.getChildAt(0).getValue().user, user];
result = 'win';
}
}
return !match;
});
if (match) {
var error = this.setMatchResult(match, result);
if (error)
if (error) {
throw new Error("Unexpected " + error + " from setMatchResult([" + match.join(", ") + "], " + result + ")");
}
}
};
Elimination.prototype.getUserBusy = function (user) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
if (!this.users.has(user))
return 'UserNotAdded';
if (!this.users.has(user)) return 'UserNotAdded';
return this.users.get(user).isBusy;
};
Elimination.prototype.setUserBusy = function (user, isBusy) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
if (!this.users.has(user))
return 'UserNotAdded';
if (!this.users.has(user)) return 'UserNotAdded';
this.users.get(user).isBusy = isBusy;
};
Elimination.prototype.getAvailableMatches = function () {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
var matches = [];
this.tree.tree.traverse(function (node) {
if (node.getValue().state === 'available') {
var userA = node.getChildAt(0).getValue().user;
var userB = node.getChildAt(1).getValue().user;
if (!this.users.get(userA).isBusy && !this.users.get(userB).isBusy)
if (!this.users.get(userA).isBusy && !this.users.get(userB).isBusy) {
matches.push([userA, userB]);
}
}
}, this);
return matches;
@ -366,8 +361,9 @@ var Elimination = (function () {
this.tree.tree.traverse(function (node) {
if (node.getValue().state === 'available' &&
node.getChildAt(0).getValue().user === match[0] &&
node.getChildAt(1).getValue().user === match[1])
node.getChildAt(1).getValue().user === match[1]) {
targetNode = node;
}
return !targetNode;
});
if (!targetNode) return 'InvalidMatch';
@ -430,8 +426,9 @@ var Elimination = (function () {
else if (this.users.get(userB).isDisqualified)
error = this.setMatchResult([userA, userB], 'win');
if (error)
if (error) {
throw new Error("Unexpected " + error + " from setMatchResult([" + userA + ", " + userB + "], ...)");
}
}
}
};
@ -441,20 +438,19 @@ var Elimination = (function () {
};
Elimination.prototype.getResults = function () {
if (!this.isTournamentEnded())
return 'TournamentNotEnded';
if (!this.isTournamentEnded()) return 'TournamentNotEnded';
var results = [];
var currentNode = this.tree.tree;
for (var n = 0; n < this.maxSubtrees; ++n) {
results.push([currentNode.getValue().user]);
currentNode = currentNode.getChildAt(currentNode.getValue().result === 'loss' ? 0 : 1);
if (!currentNode)
break;
if (!currentNode) break;
}
if (this.users.size - 1 === this.maxSubtrees && currentNode)
if (this.users.size - 1 === this.maxSubtrees && currentNode) {
results.push([currentNode.getValue().user]);
}
return results;
};

View File

@ -8,39 +8,32 @@ var RoundRobin = (function () {
this.userScores = null;
this.pendingMatches = 0;
if (isDoubles)
this.name = "Double " + this.name;
if (isDoubles) this.name = "Double " + this.name;
}
RoundRobin.prototype.name = "Round Robin";
RoundRobin.prototype.isDrawingSupported = true;
RoundRobin.prototype.addUser = function (user) {
if (this.isBracketFrozen)
return 'BracketFrozen';
if (this.isBracketFrozen) return 'BracketFrozen';
if (this.users.indexOf(user) >= 0)
return 'UserAlreadyAdded';
if (this.users.indexOf(user) >= 0) return 'UserAlreadyAdded';
this.users.push(user);
};
RoundRobin.prototype.removeUser = function (user) {
if (this.isBracketFrozen)
return 'BracketFrozen';
if (this.isBracketFrozen) return 'BracketFrozen';
var userIndex = this.users.indexOf(user);
if (userIndex < 0)
return 'UserNotAdded';
if (userIndex < 0) return 'UserNotAdded';
this.users.splice(userIndex, 1);
};
RoundRobin.prototype.replaceUser = function (user, replacementUser) {
var userIndex = this.users.indexOf(user);
if (userIndex < 0)
return 'UserNotAdded';
if (userIndex < 0) return 'UserNotAdded';
if (this.users.indexOf(replacementUser) >= 0)
return 'UserAlreadyAdded';
if (this.users.indexOf(replacementUser) >= 0) return 'UserAlreadyAdded';
this.users[userIndex] = replacementUser;
};
@ -57,15 +50,13 @@ var RoundRobin = (function () {
};
data.tableContents = this.users.map(function (userA, row) {
return this.users.map(function (userB, col) {
if (!this.isDoubles && col >= row)
return null;
if (userA === userB)
return null;
if (!this.isDoubles && col >= row) return null;
if (userA === userB) return null;
var cell = {};
if (!this.isBracketFrozen)
if (!this.isBracketFrozen) {
cell.state = 'unavailable';
else {
} else {
var match = this.matches[row][col];
cell.state = match.state;
if (match.state === 'finished') {
@ -86,10 +77,8 @@ var RoundRobin = (function () {
this.isUsersBusy = this.users.map(function () { return false; });
this.matches = this.users.map(function (userA, row) {
return this.users.map(function (userB, col) {
if (!this.isDoubles && col >= row)
return null;
if (userA === userB)
return null;
if (!this.isDoubles && col >= row) return null;
if (userA === userB) return null;
++this.pendingMatches;
return {state: 'available'};
}, this);
@ -98,16 +87,13 @@ var RoundRobin = (function () {
};
RoundRobin.prototype.disqualifyUser = function (user) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
var userIndex = this.users.indexOf(user);
if (userIndex < 0)
return 'UserNotAdded';
if (userIndex < 0) return 'UserNotAdded';
this.matches[userIndex].forEach(function (match, col) {
if (!match || match.state !== 'available')
return;
if (!match || match.state !== 'available') return;
match.state = 'finished';
match.result = 'loss';
match.score = [0, 1];
@ -117,8 +103,7 @@ var RoundRobin = (function () {
this.matches.forEach(function (challenges, row) {
var match = challenges[userIndex];
if (!match || match.state !== 'available')
return;
if (!match || match.state !== 'available') return;
match.state = 'finished';
match.result = 'win';
match.score = [1, 0];
@ -127,65 +112,55 @@ var RoundRobin = (function () {
}, this);
};
RoundRobin.prototype.getUserBusy = function (user) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
var userIndex = this.users.indexOf(user);
if (userIndex < 0)
return 'UserNotAdded';
if (userIndex < 0) return 'UserNotAdded';
return this.isUsersBusy[userIndex];
};
RoundRobin.prototype.setUserBusy = function (user, isBusy) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
var userIndex = this.users.indexOf(user);
if (userIndex < 0)
return 'UserNotAdded';
if (userIndex < 0) return 'UserNotAdded';
this.isUsersBusy[userIndex] = isBusy;
};
RoundRobin.prototype.getAvailableMatches = function () {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
var matches = [];
this.matches.forEach(function (challenges, row) {
challenges.forEach(function (match, col) {
if (!match)
return;
if (match.state === 'available' &&
!this.isUsersBusy[row] && !this.isUsersBusy[col])
if (!match) return;
if (match.state === 'available' && !this.isUsersBusy[row] && !this.isUsersBusy[col]) {
matches.push([this.users[row], this.users[col]]);
}
}, this);
}, this);
return matches;
};
RoundRobin.prototype.setMatchResult = function (match, result, score) {
if (!this.isBracketFrozen)
return 'BracketNotFrozen';
if (!this.isBracketFrozen) return 'BracketNotFrozen';
if (!(result in {win:1, loss:1, draw:1}))
return 'InvalidMatchResult';
if (!(result in {win:1, loss:1, draw:1})) return 'InvalidMatchResult';
var userIndexA = this.users.indexOf(match[0]);
var userIndexB = this.users.indexOf(match[1]);
if (userIndexA < 0 || userIndexB < 0)
return 'UserNotAdded';
if (userIndexA < 0 || userIndexB < 0) return 'UserNotAdded';
match = this.matches[userIndexA][userIndexB];
if (!match || match.state !== 'available')
return 'InvalidMatch';
if (!match || match.state !== 'available') return 'InvalidMatch';
var virtualScore;
if (result === 'win')
if (result === 'win') {
virtualScore = [1, 0];
else if (result === 'loss')
} else if (result === 'loss') {
virtualScore = [0, 1];
else
} else {
virtualScore = [0.5, 0.5];
if (!score)
score = virtualScore;
}
if (!score) score = virtualScore;
match.state = 'finished';
match.result = result;
@ -200,8 +175,7 @@ var RoundRobin = (function () {
};
RoundRobin.prototype.getResults = function () {
if (!this.isTournamentEnded())
return 'TournamentNotEnded';
if (!this.isTournamentEnded()) return 'TournamentNotEnded';
var sortedScores = this.userScores.map(function (score, userIndex) {
return {userIndex: userIndex, score: score};