Skip to content

Commit c5aaf92

Browse files
committed
add player statistics
1 parent a0ebf75 commit c5aaf92

File tree

6 files changed

+226
-24
lines changed

6 files changed

+226
-24
lines changed

grails-app/controllers/skatdb/PlayerController.groovy

+85
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package skatdb
22

3+
import org.apache.log4j.Logger;
4+
35
class PlayerController {
46

57
def beforeInterceptor = [action:this.&auth]
@@ -17,4 +19,87 @@ class PlayerController {
1719
}
1820
}
1921

22+
def show() {
23+
def player = Player.get(params.id)
24+
if(player == null) {
25+
return response.sendError(404, "Player with id " + params.id + " not found.")
26+
}
27+
28+
// misc stuff
29+
def c = Game.createCriteria()
30+
List<Game> games = c {
31+
eq("player", player)
32+
order("modifyDate", "asc")
33+
}
34+
int won = 0,lost = 0,longestWon = 0, longestLost = 0
35+
Game bestGame = null, worstGame = null
36+
for(Game g : games) {
37+
if(bestGame == null && worstGame == null) {
38+
bestGame = worstGame = g
39+
}
40+
if(g.won) {
41+
won++
42+
lost = 0
43+
} else {
44+
lost++
45+
won = 0
46+
}
47+
if(won > longestWon) {
48+
longestWon = won
49+
}
50+
if(lost > longestLost) {
51+
longestLost = lost
52+
}
53+
if(bestGame.value < g.value) {
54+
bestGame = g
55+
}
56+
if(worstGame.value > g.value) {
57+
worstGame = g
58+
}
59+
}
60+
61+
// tournament stuff
62+
int tournamentsPlayed = 0
63+
List<String> firstPlaces = []
64+
List<String> secondPlaces = []
65+
List<String> thirdPlaces = []
66+
67+
List<Tournament> tournaments = Tournament.findAllByStatus(2).findAll {
68+
if(it.players.contains(player)) {
69+
tournamentsPlayed++
70+
Set<Player> ranks = it.getRanks()
71+
if(player.equals(ranks.toArray()[0])) {
72+
firstPlaces.add(it.id)
73+
}
74+
if(player.equals(ranks.toArray()[1])) {
75+
secondPlaces.add(it.id)
76+
}
77+
if(player.equals(ranks.toArray()[2])) {
78+
thirdPlaces.add(it.id)
79+
}
80+
}
81+
}
82+
[
83+
playerInstance: player,
84+
games: Game.countByPlayer(player),
85+
suitGames: Game.countByPlayerAndGameTypeBetween(player, 9, 12),
86+
grands: Game.countByPlayerAndGameType(player, 24),
87+
nullGames: Game.countByPlayerAndGameTypeInList(player, [23, 35, 46, 59]),
88+
gamesWon: Game.countByPlayerAndWon(player, true),
89+
suitGamesWon: Game.countByPlayerAndGameTypeBetweenAndWon(player, 9, 12, true),
90+
grandsWon: Game.countByPlayerAndGameTypeAndWon(player, 24, true),
91+
nullGamesWon: Game.countByPlayerAndGameTypeInListAndWon(player, [23, 35, 46, 59], true),
92+
93+
wonSeries: longestWon,
94+
lostSeries: longestLost,
95+
bestGame: bestGame,
96+
worstGame: worstGame,
97+
98+
tournamentsPlayed: tournamentsPlayed,
99+
firstPlaces: firstPlaces,
100+
secondPlaces: secondPlaces,
101+
thirdPlaces: thirdPlaces
102+
]
103+
}
104+
20105
}

grails-app/domain/skatdb/Tournament.groovy

+31-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ class Tournament extends SkatGroup {
1111

1212
static hasMany = [players: Player, rounds: TournamentRound]
1313

14-
static constraints = {
14+
static constraints = {
1515
gamesPerRound(inList: [12, 24, 36, 48, 60])
1616
status(inList: [0, 1, 2])
17-
}
17+
}
1818

1919
def addGame(Game game) {
2020
if(status == 2) {
@@ -41,4 +41,33 @@ class Tournament extends SkatGroup {
4141
return null;
4242
}
4343

44+
def Set<Player> getRanks() {
45+
List<Game> games = Game.findAllByGroup(this)
46+
Map<Player, Integer> m = new HashMap<>();
47+
for(Game g : games) {
48+
Integer v = m.get(g.player)
49+
m.put(g.player, v == null ? g.value : v + g.value)
50+
}
51+
m = sortByValue(m)
52+
return m.keySet()
53+
}
54+
55+
/**
56+
* @see http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java
57+
*/
58+
public static <Player, Integer extends Comparable<? super Integer>> Map<Player, Integer> sortByValue( Map<Player, Integer> map ) {
59+
List<Map.Entry<Player, Integer>> list = new LinkedList<>( map.entrySet() );
60+
Collections.sort( list, new Comparator<Map.Entry<Player, Integer>>() {
61+
@Override
62+
public int compare( Map.Entry<Player, Integer> o1, Map.Entry<Player, Integer> o2 ) {
63+
return -(o1.getValue()).compareTo( o2.getValue() );
64+
}
65+
});
66+
Map<Player, Integer> result = new LinkedHashMap<>();
67+
for (Map.Entry<Player, Integer> entry : list) {
68+
result.put( entry.getKey(), entry.getValue() );
69+
}
70+
return result;
71+
}
72+
4473
}

grails-app/views/player/show.gsp

+110-22
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
11

2+
<%@page import="skatdb.Tournament"%>
23
<%@ page import="skatdb.Player" %>
34
<!doctype html>
45
<html>
56
<head>
67
<meta name="layout" content="main">
78
<g:set var="entityName" value="${message(code: 'player.label', default: 'Player')}" />
89
<title><g:message code="default.show.label" args="[entityName]" /></title>
10+
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
11+
<style>
12+
body {
13+
margin: auto;
14+
}
15+
div.contentdiv {
16+
margin: 0 3em;
17+
}
18+
.nav > ul {
19+
margin-bottom: 0;
20+
}
21+
div.nav {
22+
padding-left: 0.75em;
23+
}
24+
td, th {
25+
padding: 0.2em 0.4em;
26+
}
27+
</style>
928
</head>
1029
<body>
1130
<a href="#show-player" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content&hellip;"/></a>
@@ -17,33 +36,102 @@
1736
</ul>
1837
</div>
1938
<div id="show-player" class="content scaffold-show" role="main">
20-
<h1><g:message code="default.show.label" args="[entityName]" /></h1>
39+
<h1>${playerInstance?.name}</h1>
2140
<g:if test="${flash.message}">
2241
<div class="message" role="status">${flash.message}</div>
2342
</g:if>
24-
<ol class="property-list player">
25-
26-
<g:if test="${playerInstance?.name}">
27-
<li class="fieldcontain">
28-
<span id="name-label" class="property-label"><g:message code="player.name.label" default="Name" /></span>
29-
30-
<span class="property-value" aria-labelledby="name-label"><g:fieldValue bean="${playerInstance}" field="name"/></span>
31-
32-
</li>
43+
<div class="contentdiv">
44+
<h2>Spiele</h2>
45+
<table>
46+
<tr>
47+
<th></th>
48+
<th>Anzahl</th>
49+
<th>Anteilig %</th>
50+
<th>Gewonnen</th>
51+
<th>Verloren</th>
52+
<th>Gewonnen %</th>
53+
</tr>
54+
<tr>
55+
<g:set var="gamesLost" value="${games != 0 ? games-gamesWon : 0}"></g:set>
56+
<g:set var="gamesWinPercent" value="${gamesLost != 0 ? (gamesWon/(games) * 100) : 100}"></g:set>
57+
<td><b>Spiele</b></td>
58+
<td>${games}</td>
59+
<td>100%</td>
60+
<td>${gamesWon}</td>
61+
<td>${gamesLost}</td>
62+
<td><g:formatNumber number="${gamesWinPercent}" format="0.00" />%</td>
63+
</tr>
64+
<tr>
65+
<g:set var="suitGamesLost" value="${suitGames != 0 ? suitGames-suitGamesWon : 0}"></g:set>
66+
<g:set var="suitGamesPercent" value="${suitGames != 0 ? (suitGames/games * 100) : 0}"></g:set>
67+
<g:set var="suitGamesWinPercent" value="${suitGames != 0 ? (suitGamesWon/suitGames * 100) : 0}"></g:set>
68+
<td><b>Farbspiele</b></td>
69+
<td>${suitGames}</td>
70+
<td><g:formatNumber number="${suitGamesPercent}" format="0.00" />%</td>
71+
<td>${suitGamesWon}</td>
72+
<td>${suitGamesLost}</td>
73+
<td><g:formatNumber number="${suitGamesWinPercent}" format="0.00" />%</td>
74+
</tr>
75+
<tr>
76+
<g:set var="grandsLost" value="${grands != 0 ? grands-grandsWon : 0}"></g:set>
77+
<g:set var="grandsPercent" value="${grands != 0 ? (grands/games * 100) : 0}"></g:set>
78+
<g:set var="grandsWinPercent" value="${grands != 0 ? (grandsWon/grands * 100) : 0}"></g:set>
79+
<td><b>Grands</b></td>
80+
<td>${grands}</td>
81+
<td><g:formatNumber number="${grandsPercent}" format="0.00" />%</td>
82+
<td>${grandsWon}</td>
83+
<td>${grandsLost}</td>
84+
<td><g:formatNumber number="${grandsWinPercent}" format="0.00" />%</td>
85+
</tr>
86+
<tr>
87+
<g:set var="nullGamesLost" value="${nullGames != 0 ? nullGames-nullGamesWon : 0}"></g:set>
88+
<g:set var="nullGamesPercent" value="${nullGames != 0 ? (nullGames/games * 100) : 0}"></g:set>
89+
<g:set var="nullGamesWinPercent" value="${nullGames != 0 ? (nullGamesWon/nullGames * 100) : 0}"></g:set>
90+
<td><b>Nullspiele</b></td>
91+
<td>${nullGames}</td>
92+
<td><g:formatNumber number="${nullGamesPercent}" format="0.00" />%</td>
93+
<td>${nullGamesWon}</td>
94+
<td>${nullGamesLost}</td>
95+
<td><g:formatNumber number="${nullGamesWinPercent}" format="0.00" />%</td>
96+
</tr>
97+
</table>
98+
<h2>Sonstiges</h2>
99+
<div>längste Siegesserie: ${wonSeries}</div>
100+
<div>längste Verlustserie: ${lostSeries}</div>
101+
<g:if test="${bestGame != null}">
102+
<div>bestes Spiel: <g:link controller="game" action="show" id="${bestGame.id}">${bestGame.value} Punkte</g:link></div>
33103
</g:if>
34-
35-
<g:if test="${playerInstance?.games}">
36-
<li class="fieldcontain">
37-
<span id="games-label" class="property-label"><g:message code="player.games.label" default="Games" /></span>
38-
39-
<g:each in="${playerInstance.games}" var="g">
40-
<span class="property-value" aria-labelledby="games-label"><g:link controller="game" action="show" id="${g.id}">${g?.encodeAsHTML()}</g:link></span>
41-
</g:each>
42-
43-
</li>
104+
<g:if test="${worstGame != null}">
105+
<div>schlechtestes Spiel: <g:link controller="game" action="show" id="${worstGame.id}">${worstGame.value} Punkte</g:link></div>
44106
</g:if>
45-
46-
</ol>
107+
<h2>Turniere</h2>
108+
<g:if test="${tournamentsPlayed <= 0}">
109+
<p>Noch keine Turniere gespielt</p>
110+
</g:if>
111+
<g:if test="${tournamentsPlayed > 0}">
112+
<div>Turniere gespielt: ${tournamentsPlayed}</div>
113+
<div>
114+
<g:each in="${firstPlaces}">
115+
<g:set var="t" value="${Tournament.findById(it)}" />
116+
<g:link controller="tournament" action="show" id="${t.id}">
117+
<g:img file="first.png" title="${t.name}" />
118+
</g:link>
119+
</g:each>
120+
<g:each in="${secondPlaces}">
121+
<g:set var="t" value="${Tournament.findById(it)}" />
122+
<g:link controller="tournament" action="show" id="${t.id}">
123+
<g:img file="second.png" title="${t.name}" />
124+
</g:link>
125+
</g:each>
126+
<g:each in="${thirdPlaces}">
127+
<g:set var="t" value="${Tournament.findById(it)}" />
128+
<g:link controller="tournament" action="show" id="${t.id}">
129+
<g:img file="third.png" title="${t.name}" />
130+
</g:link>
131+
</g:each>
132+
</div>
133+
</g:if>
134+
</div>
47135
<g:form>
48136
<fieldset class="buttons">
49137
<g:hiddenField name="id" value="${playerInstance?.id}" />

web-app/images/first.png

12.4 KB
Loading

web-app/images/second.png

14.3 KB
Loading

web-app/images/third.png

14.3 KB
Loading

0 commit comments

Comments
 (0)