我正在尝试为我的游戏小组创建一个排名系统,在他们的Clash of Clans和Clash Royale游戏的Android / iOS系统中与Supercell的Trophy System类似。
我已经找到了所有排名的布局,我们已经有一个适用的点系统......我只需要在实际排名中进行编程。
排名非常简单:个人的积分余额属于特定值,与该值对应的排名是该人的排名。我创建了一个简单的表来显示我的意思...这里是它的外观摘录:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
<style>
text {
fill: black;
font-family: arial;
}
</style>
</head>
<body>
<script>
var dataNodes = [{
id: 1,
x: 10,
y: 30,
text: "node 1",
muteText: false
}, {
id: 2,
x: 30,
y: 50,
text: "node 2",
muteText: false
}, {
id: 3,
x: 50,
y: 70,
text: "node 3",
muteText: false
}];
var svg = d3.select('body')
.append('svg')
.attr('width', 500)
.attr('height', 500);
redraw([{
id: 1,
x: 10,
y: 30,
text: "node 1",
muteText: false
}, {
id: 2,
x: 30,
y: 50,
text: "node 2",
muteText: false
}, {
id: 3,
x: 50,
y: 70,
text: "node 3",
muteText: false
}]);
setTimeout(function() {
redraw([{
id: 1,
x: 10,
y: 30,
text: "node 1",
muteText: true
}, {
id: 2,
x: 100,
y: 50,
text: "node 2",
muteText: false
}, {
id: 3,
x: 50,
y: 70,
text: "node 3",
muteText: true
}])
}, 2000)
setTimeout(function() {
redraw([{
id: 1,
x: 10,
y: 30,
text: "node 1",
muteText: true
}, {
id: 2,
x: 100,
y: 50,
text: "node 2",
muteText: false
}, {
id: 3,
x: 50,
y: 70,
text: "node 3",
muteText: false
},{
id: 4,
x: 60,
y: 90,
text: "node 4",
muteText: false
}])
}, 4000)
function redraw(someData) {
var node = svg
.selectAll("g.node")
.data(someData);
var nodeE = node.enter()
.append("g")
.attr("class", "node")
.attr("transform", d => "translate(" + d.x + "," + d.y + ")");
nodeE.append("text")
.text(d => d.text)
.style("opacity", 0)
.transition()
.style("opacity", 1);
node = nodeE.merge(node);
node.exit()
.style("opacity", "0");
node.transition().duration(500)
.attr("transform", d => "translate(" + d.x + "," + d.y + ")");
node.filter(function(d) {
return d.muteText
})
.select("text")
.transition()
.style("opacity", 0);
}
</script>
</body>
</html>
所以这里是简单的等级系统布局,它一直到Commander的42,000点。我的问题是:如何将Rank与点值相关联,而不必像这样输入所有代码行?
Rank: Balance Range
Private: 0-500
Private I: 501-1000
Private II: 1001-1500
Private III: 1501-2500
Corporal: 2501-3000
...
答案 0 :(得分:1)
您可以使用bisect。
from bisect import bisect
def get_rank(score):
points = [500, 1000, 1500, 2500, 3000]
ranks = ["Private", "Private I", "Private II", "Private III", "Corporal"]
div = bisect(points, score)
return ranks[div]
答案 1 :(得分:0)
丹尼尔罗斯曼的bisect
解决方案略有改进,将使用单个2元组列表:
from bisect import bisect_right
RANKS = [
# max balance, rank
(500, 'Private'),
(1000, 'Private I'),
(1500, 'Private II'),
(2500, 'Private III'),
(3000, 'Corporal'),
# ...
(42000, 'Commander')
]
def get_rank(balance):
index = bisect_right(RANKS, (balance, ''))
try:
return RANKS[index][1]
except IndexError:
return RANKS[-1][1]
这里的优点是一目了然更容易阅读,并且在编辑代码以引入新等级,调整限制等时更不容易出错。
当提供的分数余额高于RANKS
(在评论中指定)中的任何分数时,它也会返回最高排名,而非提出异常。
示例:
>>> for n in range(0,42001,500):
... print("%5d %s" % (n, get_rank(n)))
... print("%5d %s" % (n + 1, get_rank(n + 1)))
...
0 Private
1 Private
500 Private
501 Private I
1000 Private I
1001 Private II
1500 Private II
1501 Private III
2000 Private III
2001 Private III
2500 Private III
2501 Corporal
3000 Corporal
# ...
42000 Commander
42001 Commander