Table renumbering ; various bugfixes and enhancements
This commit is contained in:
@@ -16,7 +16,7 @@ interface PairgothApiHandler: ApiHandler {
|
|||||||
fun Tournament<*>.dispatchEvent(event: Event, data: Json? = null) {
|
fun Tournament<*>.dispatchEvent(event: Event, data: Json? = null) {
|
||||||
Event.dispatch(event, Json.Object("tournament" to id, "data" to data))
|
Event.dispatch(event, Json.Object("tournament" to id, "data" to data))
|
||||||
// when storage is not in memory, the tournament has to be persisted
|
// when storage is not in memory, the tournament has to be persisted
|
||||||
if (event != Event.tournamentAdded && event != Event.tournamentDeleted)
|
if (event != Event.TournamentAdded && event != Event.TournamentDeleted)
|
||||||
Store.replaceTournament(this)
|
Store.replaceTournament(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,7 +7,6 @@ import org.jeudego.pairgoth.model.Game
|
|||||||
import org.jeudego.pairgoth.model.getID
|
import org.jeudego.pairgoth.model.getID
|
||||||
import org.jeudego.pairgoth.model.toID
|
import org.jeudego.pairgoth.model.toID
|
||||||
import org.jeudego.pairgoth.model.toJson
|
import org.jeudego.pairgoth.model.toJson
|
||||||
import org.jeudego.pairgoth.server.Event
|
|
||||||
import org.jeudego.pairgoth.server.Event.*
|
import org.jeudego.pairgoth.server.Event.*
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import javax.servlet.http.HttpServletResponse
|
import javax.servlet.http.HttpServletResponse
|
||||||
@@ -59,7 +58,7 @@ object PairingHandler: PairgothApiHandler {
|
|||||||
}
|
}
|
||||||
val games = tournament.pair(round, pairables)
|
val games = tournament.pair(round, pairables)
|
||||||
val ret = games.map { it.toJson() }.toJsonArray()
|
val ret = games.map { it.toJson() }.toJsonArray()
|
||||||
tournament.dispatchEvent(gamesAdded, Json.Object("round" to round, "games" to ret))
|
tournament.dispatchEvent(GamesAdded, Json.Object("round" to round, "games" to ret))
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +77,7 @@ object PairingHandler: PairgothApiHandler {
|
|||||||
game.black = payload.getID("b") ?: badRequest("missing black player id")
|
game.black = payload.getID("b") ?: badRequest("missing black player id")
|
||||||
game.white = payload.getID("w") ?: badRequest("missing white player id")
|
game.white = payload.getID("w") ?: badRequest("missing white player id")
|
||||||
tournament.recomputeDUDD(round, game.id)
|
tournament.recomputeDUDD(round, game.id)
|
||||||
|
val previousTable = game.table;
|
||||||
// temporary
|
// temporary
|
||||||
payload.getInt("dudd")?.let { game.drawnUpDown = it }
|
payload.getInt("dudd")?.let { game.drawnUpDown = it }
|
||||||
val black = tournament.pairables[game.black] ?: badRequest("invalid black player id")
|
val black = tournament.pairables[game.black] ?: badRequest("invalid black player id")
|
||||||
@@ -90,10 +90,15 @@ object PairingHandler: PairgothApiHandler {
|
|||||||
if (playing.contains(white.id)) badRequest("white is already in another game")
|
if (playing.contains(white.id)) badRequest("white is already in another game")
|
||||||
if (payload.containsKey("h")) game.handicap = payload.getString("h")?.toIntOrNull() ?: badRequest("invalid handicap")
|
if (payload.containsKey("h")) game.handicap = payload.getString("h")?.toIntOrNull() ?: badRequest("invalid handicap")
|
||||||
if (payload.containsKey("t")) {
|
if (payload.containsKey("t")) {
|
||||||
// TODO CB - update *all* tables numbers accordingly
|
|
||||||
game.table = payload.getString("t")?.toIntOrNull() ?: badRequest("invalid table number")
|
game.table = payload.getString("t")?.toIntOrNull() ?: badRequest("invalid table number")
|
||||||
}
|
}
|
||||||
tournament.dispatchEvent(gameUpdated, Json.Object("round" to round, "game" to game.toJson()))
|
tournament.dispatchEvent(GameUpdated, Json.Object("round" to round, "game" to game.toJson()))
|
||||||
|
if (game.table != previousTable && tournament.renumberTables(round, game)) {
|
||||||
|
val games = tournament.games(round).values.sortedBy {
|
||||||
|
if (it.table == 0) Int.MAX_VALUE else it.table
|
||||||
|
}
|
||||||
|
tournament.dispatchEvent(TablesRenumbered, Json.Object("round" to round, "games" to games.map { it.toJson() }.toCollection(Json.MutableArray())))
|
||||||
|
}
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +116,7 @@ object PairingHandler: PairgothApiHandler {
|
|||||||
payload.forEach {
|
payload.forEach {
|
||||||
val id = (it as Number).toInt()
|
val id = (it as Number).toInt()
|
||||||
val game = tournament.games(round)[id] ?: throw Error("invalid game id")
|
val game = tournament.games(round)[id] ?: throw Error("invalid game id")
|
||||||
if (game.result != Game.Result.UNKNOWN) {
|
if (game.result != Game.Result.UNKNOWN && game.black != 0 && game.white != 0) {
|
||||||
ApiHandler.logger.error("cannot unpair game id ${game.id}: it has a result")
|
ApiHandler.logger.error("cannot unpair game id ${game.id}: it has a result")
|
||||||
// we'll only skip it
|
// we'll only skip it
|
||||||
// throw Error("cannot unpair ")
|
// throw Error("cannot unpair ")
|
||||||
@@ -120,7 +125,7 @@ object PairingHandler: PairgothApiHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tournament.dispatchEvent(gamesDeleted, Json.Object("round" to round, "games" to payload))
|
tournament.dispatchEvent(GamesDeleted, Json.Object("round" to round, "games" to payload))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,6 @@ import com.republicate.kson.toJsonArray
|
|||||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||||
import org.jeudego.pairgoth.model.Player
|
import org.jeudego.pairgoth.model.Player
|
||||||
import org.jeudego.pairgoth.model.fromJson
|
import org.jeudego.pairgoth.model.fromJson
|
||||||
import org.jeudego.pairgoth.server.Event
|
|
||||||
import org.jeudego.pairgoth.server.Event.*
|
import org.jeudego.pairgoth.server.Event.*
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import javax.servlet.http.HttpServletResponse
|
import javax.servlet.http.HttpServletResponse
|
||||||
@@ -25,7 +24,7 @@ object PlayerHandler: PairgothApiHandler {
|
|||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val player = Player.fromJson(payload)
|
val player = Player.fromJson(payload)
|
||||||
tournament.players[player.id] = player
|
tournament.players[player.id] = player
|
||||||
tournament.dispatchEvent(playerAdded, player.toJson())
|
tournament.dispatchEvent(PlayerAdded, player.toJson())
|
||||||
return Json.Object("success" to true, "id" to player.id)
|
return Json.Object("success" to true, "id" to player.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +35,7 @@ object PlayerHandler: PairgothApiHandler {
|
|||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val updated = Player.fromJson(payload, player)
|
val updated = Player.fromJson(payload, player)
|
||||||
tournament.players[updated.id] = updated
|
tournament.players[updated.id] = updated
|
||||||
tournament.dispatchEvent(playerUpdated, player.toJson())
|
tournament.dispatchEvent(PlayerUpdated, player.toJson())
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ object PlayerHandler: PairgothApiHandler {
|
|||||||
val tournament = getTournament(request)
|
val tournament = getTournament(request)
|
||||||
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid player selector")
|
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid player selector")
|
||||||
tournament.players.remove(id) ?: badRequest("invalid player id")
|
tournament.players.remove(id) ?: badRequest("invalid player id")
|
||||||
tournament.dispatchEvent(playerDeleted, Json.Object("id" to id))
|
tournament.dispatchEvent(PlayerDeleted, Json.Object("id" to id))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ object ResultsHandler: PairgothApiHandler {
|
|||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val game = tournament.games(round)[payload.getInt("id")] ?: badRequest("invalid game id")
|
val game = tournament.games(round)[payload.getInt("id")] ?: badRequest("invalid game id")
|
||||||
game.result = Game.Result.fromSymbol(payload.getChar("result") ?: badRequest("missing result"))
|
game.result = Game.Result.fromSymbol(payload.getChar("result") ?: badRequest("missing result"))
|
||||||
tournament.dispatchEvent(Event.resultUpdated, Json.Object("round" to round, "data" to game))
|
tournament.dispatchEvent(Event.ResultUpdated, Json.Object("round" to round, "data" to game))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import com.republicate.kson.Json
|
|||||||
import com.republicate.kson.toJsonArray
|
import com.republicate.kson.toJsonArray
|
||||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||||
import org.jeudego.pairgoth.model.TeamTournament
|
import org.jeudego.pairgoth.model.TeamTournament
|
||||||
import org.jeudego.pairgoth.server.Event
|
|
||||||
import org.jeudego.pairgoth.server.Event.*
|
import org.jeudego.pairgoth.server.Event.*
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import javax.servlet.http.HttpServletResponse
|
import javax.servlet.http.HttpServletResponse
|
||||||
@@ -26,7 +25,7 @@ object TeamHandler: PairgothApiHandler {
|
|||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val team = tournament.teamFromJson(payload)
|
val team = tournament.teamFromJson(payload)
|
||||||
tournament.teams[team.id] = team
|
tournament.teams[team.id] = team
|
||||||
tournament.dispatchEvent(teamAdded, team.toJson())
|
tournament.dispatchEvent(TeamAdded, team.toJson())
|
||||||
return Json.Object("success" to true, "id" to team.id)
|
return Json.Object("success" to true, "id" to team.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ object TeamHandler: PairgothApiHandler {
|
|||||||
val payload = getObjectPayload(request)
|
val payload = getObjectPayload(request)
|
||||||
val updated = tournament.teamFromJson(payload, team)
|
val updated = tournament.teamFromJson(payload, team)
|
||||||
tournament.teams[updated.id] = updated
|
tournament.teams[updated.id] = updated
|
||||||
tournament.dispatchEvent(teamUpdated, team.toJson())
|
tournament.dispatchEvent(TeamUpdated, team.toJson())
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +46,7 @@ object TeamHandler: PairgothApiHandler {
|
|||||||
if (tournament !is TeamTournament) badRequest("tournament is not a team tournament")
|
if (tournament !is TeamTournament) badRequest("tournament is not a team tournament")
|
||||||
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid team selector")
|
val id = getSubSelector(request)?.toIntOrNull() ?: badRequest("missing or invalid team selector")
|
||||||
tournament.teams.remove(id) ?: badRequest("invalid team id")
|
tournament.teams.remove(id) ?: badRequest("invalid team id")
|
||||||
tournament.dispatchEvent(teamDeleted, Json.Object("id" to id))
|
tournament.dispatchEvent(TeamDeleted, Json.Object("id" to id))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,6 @@ import org.jeudego.pairgoth.model.fromJson
|
|||||||
import org.jeudego.pairgoth.model.toJson
|
import org.jeudego.pairgoth.model.toJson
|
||||||
import org.jeudego.pairgoth.store.Store
|
import org.jeudego.pairgoth.store.Store
|
||||||
import org.jeudego.pairgoth.server.ApiServlet
|
import org.jeudego.pairgoth.server.ApiServlet
|
||||||
import org.jeudego.pairgoth.server.Event
|
|
||||||
import org.jeudego.pairgoth.server.Event.*
|
import org.jeudego.pairgoth.server.Event.*
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
@@ -44,7 +43,7 @@ object TournamentHandler: PairgothApiHandler {
|
|||||||
else -> badRequest("missing or invalid payload")
|
else -> badRequest("missing or invalid payload")
|
||||||
}
|
}
|
||||||
Store.addTournament(tournament)
|
Store.addTournament(tournament)
|
||||||
tournament.dispatchEvent(tournamentAdded, tournament.toJson())
|
tournament.dispatchEvent(TournamentAdded, tournament.toJson())
|
||||||
return Json.Object("success" to true, "id" to tournament.id)
|
return Json.Object("success" to true, "id" to tournament.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,14 +63,14 @@ object TournamentHandler: PairgothApiHandler {
|
|||||||
clear()
|
clear()
|
||||||
putAll(tournament.games(round))
|
putAll(tournament.games(round))
|
||||||
}
|
}
|
||||||
updated.dispatchEvent(tournamentUpdated, updated.toJson())
|
updated.dispatchEvent(TournamentUpdated, updated.toJson())
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(request: HttpServletRequest): Json {
|
override fun delete(request: HttpServletRequest): Json {
|
||||||
val tournament = getTournament(request)
|
val tournament = getTournament(request)
|
||||||
Store.deleteTournament(tournament)
|
Store.deleteTournament(tournament)
|
||||||
tournament.dispatchEvent(tournamentDeleted, Json.Object("id" to tournament.id))
|
tournament.dispatchEvent(TournamentDeleted, Json.Object("id" to tournament.id))
|
||||||
return Json.Object("success" to true)
|
return Json.Object("success" to true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -90,6 +90,23 @@ sealed class Tournament <P: Pairable>(
|
|||||||
val blackplayer = solver.pairables.find { p-> p.id == game.black }!!
|
val blackplayer = solver.pairables.find { p-> p.id == game.black }!!
|
||||||
game.drawnUpDown = solver.dudd(blackplayer, whiteplayer)
|
game.drawnUpDown = solver.dudd(blackplayer, whiteplayer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun renumberTables(round: Int, pivot: Game? = null): Boolean {
|
||||||
|
var changed = false
|
||||||
|
var nextTable = 1
|
||||||
|
games(round).values.filter{ game -> pivot?.let { pivot.id != game.id } ?: true }.sortedBy { game ->
|
||||||
|
val whiteRank = pairables[game.white]?.rating ?: Int.MIN_VALUE
|
||||||
|
val blackRank = pairables[game.black]?.rating ?: Int.MIN_VALUE
|
||||||
|
-(2 * whiteRank + 2 * blackRank) / 2
|
||||||
|
}.forEach { game ->
|
||||||
|
if (pivot != null && nextTable == pivot.table) {
|
||||||
|
++nextTable
|
||||||
|
}
|
||||||
|
changed = changed || game.table != nextTable
|
||||||
|
game.table = nextTable++
|
||||||
|
}
|
||||||
|
return changed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// standard tournament of individuals
|
// standard tournament of individuals
|
||||||
|
@@ -4,19 +4,20 @@ import info.macias.sse.events.MessageEvent
|
|||||||
import java.util.concurrent.atomic.AtomicLong
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
|
|
||||||
enum class Event {
|
enum class Event {
|
||||||
tournamentAdded,
|
TournamentAdded,
|
||||||
tournamentUpdated,
|
TournamentUpdated,
|
||||||
tournamentDeleted,
|
TournamentDeleted,
|
||||||
playerAdded,
|
PlayerAdded,
|
||||||
playerUpdated,
|
PlayerUpdated,
|
||||||
playerDeleted,
|
PlayerDeleted,
|
||||||
teamAdded,
|
TeamAdded,
|
||||||
teamUpdated,
|
TeamUpdated,
|
||||||
teamDeleted,
|
TeamDeleted,
|
||||||
gamesAdded,
|
GamesAdded,
|
||||||
gamesDeleted,
|
GamesDeleted,
|
||||||
gameUpdated,
|
GameUpdated,
|
||||||
resultUpdated,
|
ResultUpdated,
|
||||||
|
TablesRenumbered
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@@ -45,4 +45,17 @@ class PairgothTool {
|
|||||||
"SDC" to "Simplified direct confrontation", // Simplified direct confrontation
|
"SDC" to "Simplified direct confrontation", // Simplified direct confrontation
|
||||||
"DC" to "Direct confrontation", // Direct confrontation
|
"DC" to "Direct confrontation", // Direct confrontation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun getResultsStats(games: Collection<Json.Object>): Json.Object {
|
||||||
|
var total = 0
|
||||||
|
var known = 0
|
||||||
|
games
|
||||||
|
.filter{ it.getInt("b")!! != 0 && it.getInt("w")!! != 0 }
|
||||||
|
.map { it -> it.getString("r") }
|
||||||
|
.forEach {
|
||||||
|
++total
|
||||||
|
if ("?" != it) ++known
|
||||||
|
}
|
||||||
|
return Json.Object("total" to total, "known" to known)
|
||||||
|
}
|
||||||
}
|
}
|
@@ -425,6 +425,9 @@
|
|||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
line-height: 1.1rem !important;
|
line-height: 1.1rem !important;
|
||||||
min-width: 60vw;
|
min-width: 60vw;
|
||||||
|
&::before {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -145,5 +145,6 @@ the configuration guide le guide de configuration
|
|||||||
to à
|
to à
|
||||||
unpairable players joueurs non disponibles
|
unpairable players joueurs non disponibles
|
||||||
version 0.1 supports the version 0.1 supporte le système d’appariement
|
version 0.1 supports the version 0.1 supporte le système d’appariement
|
||||||
|
white blanc
|
||||||
white vs. black blanc vs. Noir
|
white vs. black blanc vs. Noir
|
||||||
confirmed. confirmé(s).
|
confirmed. confirmé(s).
|
@@ -1,4 +1,4 @@
|
|||||||
function setResult(id, result) {
|
function setResult(id, result, previous) {
|
||||||
api.putJson(`tour/${tour_id}/res/${activeRound}`, { id: id, result: result })
|
api.putJson(`tour/${tour_id}/res/${activeRound}`, { id: id, result: result })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res !== 'error') {
|
if (res !== 'error') {
|
||||||
@@ -19,6 +19,16 @@ function setResult(id, result) {
|
|||||||
let resultCell = row.find('td.result');
|
let resultCell = row.find('td.result');
|
||||||
resultCell.text(dispResult).data('result', result);
|
resultCell.text(dispResult).data('result', result);
|
||||||
standingsUpToDate = false;
|
standingsUpToDate = false;
|
||||||
|
|
||||||
|
if (previous === '?') {
|
||||||
|
let indicator = $('#known')[0];
|
||||||
|
let known = parseInt(indicator.innerText);
|
||||||
|
indicator.innerText = ++known;
|
||||||
|
} else if (result === '?') {
|
||||||
|
let indicator = $('#known')[0];
|
||||||
|
let known = parseInt(indicator.innerText);
|
||||||
|
indicator.innerText = --known;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -36,9 +46,9 @@ onLoad(()=>{
|
|||||||
$('#results-table .result').on('click', e => {
|
$('#results-table .result').on('click', e => {
|
||||||
let cell = e.target.closest('.result');
|
let cell = e.target.closest('.result');
|
||||||
let gameId = e.target.closest('tr').data('id');
|
let gameId = e.target.closest('tr').data('id');
|
||||||
let result = cell.data('result');
|
let oldResult = cell.data('result');
|
||||||
let index = results.indexOf(result);
|
let index = results.indexOf(oldResult);
|
||||||
result = results[(index + 1)%results.length];
|
let newResult = results[(index + 1)%results.length];
|
||||||
setResult(gameId, result);
|
setResult(gameId, newResult, oldResult);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -4,6 +4,8 @@
|
|||||||
<button class="ui floating choose-round prev-round button">«</button>
|
<button class="ui floating choose-round prev-round button">«</button>
|
||||||
<span class="active-round">$round</span>
|
<span class="active-round">$round</span>
|
||||||
<button class="ui floating choose-round next-round button">»</button>
|
<button class="ui floating choose-round next-round button">»</button>
|
||||||
|
#set($stats = $utils.getResultsStats($games))
|
||||||
|
<span class="norbeak"><span id="known">$stats.known</span> / $stats.total</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="results-list" class="roundbox">
|
<div id="results-list" class="roundbox">
|
||||||
<table id="results-table" class="ui celled striped table">
|
<table id="results-table" class="ui celled striped table">
|
||||||
@@ -23,7 +25,7 @@
|
|||||||
<td>#$game.t</td>
|
<td>#$game.t</td>
|
||||||
<td class="white player #if($game.r == 'w' || $game.r == '#') winner #elseif($game.r == 'b' || $game.r == '0') looser #end" data-id="$white.id" data-sort="$white.name $white.firstname"><span>#if($white)$white.name $white.firstname #rank($white.rank)#{else}BIP#end</span></td>
|
<td class="white player #if($game.r == 'w' || $game.r == '#') winner #elseif($game.r == 'b' || $game.r == '0') looser #end" data-id="$white.id" data-sort="$white.name $white.firstname"><span>#if($white)$white.name $white.firstname #rank($white.rank)#{else}BIP#end</span></td>
|
||||||
<td class="black player #if($game.r == 'b' || $game.r == '#') winner #elseif($game.r == 'w' || $game.r == '0') looser #end" data-id="$black.id" data-sort="$black.name $black.firstname"><span>#if($black)$black.name $black.firstname #rank($black.rank)#{else}BIP#end</span></td>
|
<td class="black player #if($game.r == 'b' || $game.r == '#') winner #elseif($game.r == 'w' || $game.r == '0') looser #end" data-id="$black.id" data-sort="$black.name $black.firstname"><span>#if($black)$black.name $black.firstname #rank($black.rank)#{else}BIP#end</span></td>
|
||||||
<td class="result centered" data-result="$game.r">$dispRst[$game.r]</td>
|
<td class="result centered" data-sort="$game.r" data-result="$game.r">$dispRst[$game.r]</td>
|
||||||
</tr>
|
</tr>
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
Reference in New Issue
Block a user