FIx: Fixed Coverage Screenshots And htmlRepot.

This commit is contained in:
GabrieleRadice
2026-06-19 22:57:43 +02:00
parent a4dc8b2540
commit 0129efe400
316 changed files with 4566 additions and 4497 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 239 KiB

Before

Width:  |  Height:  |  Size: 89 B

After

Width:  |  Height:  |  Size: 89 B

Before

Width:  |  Height:  |  Size: 91 B

After

Width:  |  Height:  |  Size: 91 B

@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -125,7 +125,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -157,18 +157,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -184,26 +184,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -219,10 +219,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -235,10 +235,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -282,10 +282,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -298,10 +298,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -320,7 +320,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -329,7 +329,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -345,10 +345,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -361,10 +361,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -383,7 +383,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -399,7 +399,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -458,10 +458,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -469,7 +469,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -523,7 +523,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -539,7 +539,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -593,7 +593,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -601,7 +601,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -609,7 +609,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -636,7 +636,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -671,7 +671,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -679,7 +679,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -698,7 +698,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -706,7 +706,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -714,7 +714,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -730,10 +730,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -746,10 +746,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -145,7 +145,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -154,7 +154,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -189,7 +189,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -243,7 +243,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -259,7 +259,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -313,7 +313,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -321,7 +321,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -329,7 +329,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -356,7 +356,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -391,7 +391,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -399,7 +399,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -418,7 +418,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -426,7 +426,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -434,7 +434,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -450,10 +450,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -466,10 +466,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -493,18 +493,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -520,26 +520,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -563,10 +563,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -574,7 +574,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -590,10 +590,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -606,10 +606,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -660,10 +660,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -676,10 +676,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -695,10 +695,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -711,10 +711,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -733,7 +733,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -117,7 +117,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -149,10 +149,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -165,10 +165,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -184,10 +184,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -200,10 +200,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -254,10 +254,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -270,10 +270,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -297,10 +297,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -308,7 +308,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -324,26 +324,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -367,18 +367,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -394,10 +394,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -410,10 +410,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -432,7 +432,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -440,7 +440,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -448,7 +448,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -475,7 +475,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -483,7 +483,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -510,7 +510,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -537,7 +537,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -545,7 +545,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -553,7 +553,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -607,7 +607,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -623,7 +623,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -685,7 +685,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -693,7 +693,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -712,7 +712,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -721,7 +721,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -125,7 +125,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -187,7 +187,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -203,7 +203,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -257,7 +257,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -265,7 +265,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -273,7 +273,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -300,7 +300,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -335,7 +335,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -343,7 +343,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -362,7 +362,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -370,7 +370,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -378,7 +378,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -402,18 +402,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -429,10 +429,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -445,10 +445,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -464,26 +464,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -499,10 +499,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -515,10 +515,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -562,10 +562,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -578,10 +578,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -600,7 +600,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -609,7 +609,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -625,10 +625,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -641,10 +641,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -663,7 +663,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -679,7 +679,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -738,10 +738,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -122,10 +122,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -187,7 +187,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -203,7 +203,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -219,10 +219,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -235,10 +235,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -257,7 +257,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -266,7 +266,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -282,10 +282,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -298,10 +298,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -345,10 +345,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -361,10 +361,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -380,26 +380,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -415,10 +415,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -431,10 +431,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -458,18 +458,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -488,7 +488,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -496,7 +496,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -504,7 +504,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -531,7 +531,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -539,7 +539,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -566,7 +566,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -593,7 +593,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -601,7 +601,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -609,7 +609,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -663,7 +663,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -679,7 +679,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -741,7 +741,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -125,7 +125,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -187,7 +187,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -203,7 +203,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -257,7 +257,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -265,7 +265,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -273,7 +273,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -300,7 +300,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -335,7 +335,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -343,7 +343,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -362,7 +362,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -370,7 +370,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -378,7 +378,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -394,10 +394,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -410,10 +410,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -437,18 +437,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -464,26 +464,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -542,10 +542,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -553,7 +553,42 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_LINE.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.3%
</span>
<span class="absValue">
(50/53)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
97.2%
</span>
<span class="absValue">
(103/106)
</span>
</td>
</tr>
@@ -569,10 +604,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -583,12 +618,47 @@ Current scope: all classes
(25/25)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.1%
</span>
<span class="absValue">
(52/53)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_LINE.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(58/58)
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.7%
</span>
<span class="absValue">
(36/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.4%
</span>
<span class="absValue">
(127/129)
</span>
</td>
</tr>
@@ -618,41 +688,6 @@ Current scope: all classes
<span class="absValue">
(7/7)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_LINE.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(38/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(129/129)
</span>
</td>
</tr>
<tr>
@@ -670,7 +705,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -679,42 +714,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_LINE.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(49/49)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(108/108)
(26/26)
</span>
</td>
</tr>
@@ -733,7 +733,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -117,7 +117,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -133,42 +133,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_LINE_DESC.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(49/49)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(108/108)
(93/93)
</span>
</td>
</tr>
@@ -187,7 +152,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -196,42 +161,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_LINE_DESC.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(38/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(129/129)
(26/26)
</span>
</td>
</tr>
@@ -261,6 +191,41 @@ Current scope: all classes
<span class="absValue">
(7/7)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_LINE_DESC.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.7%
</span>
<span class="absValue">
(36/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.4%
</span>
<span class="absValue">
(127/129)
</span>
</td>
</tr>
<tr>
@@ -275,10 +240,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -289,12 +254,47 @@ Current scope: all classes
(25/25)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.1%
</span>
<span class="absValue">
(52/53)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_LINE_DESC.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(58/58)
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.3%
</span>
<span class="absValue">
(50/53)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
97.2%
</span>
<span class="absValue">
(103/106)
</span>
</td>
</tr>
@@ -318,10 +318,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -329,7 +329,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -380,26 +380,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -423,18 +423,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -450,10 +450,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -466,10 +466,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -488,7 +488,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -496,7 +496,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -504,7 +504,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -531,7 +531,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -539,7 +539,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -566,7 +566,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -593,7 +593,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -601,7 +601,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -609,7 +609,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -663,7 +663,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -679,7 +679,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -741,7 +741,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -125,7 +125,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -187,7 +187,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -203,7 +203,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -257,7 +257,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -265,7 +265,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -273,7 +273,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -300,7 +300,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -335,7 +335,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -343,7 +343,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -362,7 +362,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -370,7 +370,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -378,7 +378,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -402,18 +402,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -429,10 +429,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -445,10 +445,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -464,26 +464,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -520,6 +520,76 @@ Current scope: all classes
<span class="absValue">
(120/136)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_METHOD.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.3%
</span>
<span class="absValue">
(50/53)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
97.2%
</span>
<span class="absValue">
(103/106)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_METHOD.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.7%
</span>
<span class="absValue">
(36/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.4%
</span>
<span class="absValue">
(127/129)
</span>
</td>
</tr>
<tr>
@@ -534,10 +604,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -550,10 +620,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -583,41 +653,6 @@ Current scope: all classes
<span class="absValue">
(7/7)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_METHOD.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(38/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(129/129)
</span>
</td>
</tr>
<tr>
@@ -635,7 +670,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -644,42 +679,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_METHOD.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(49/49)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(108/108)
(26/26)
</span>
</td>
</tr>
@@ -698,7 +698,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -714,7 +714,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -738,10 +738,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -122,10 +122,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -133,7 +133,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -152,7 +152,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -168,42 +168,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_METHOD_DESC.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(49/49)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(108/108)
(93/93)
</span>
</td>
</tr>
@@ -222,7 +187,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -231,42 +196,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_METHOD_DESC.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(38/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(129/129)
(26/26)
</span>
</td>
</tr>
@@ -310,10 +240,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -324,12 +254,82 @@ Current scope: all classes
(25/25)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.1%
</span>
<span class="absValue">
(52/53)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-6/index_SORT_BY_METHOD_DESC.html">it.polimi.ingsw.gc14.Model.Cards.Building.Effects</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(58/58)
(7/7)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.7%
</span>
<span class="absValue">
(36/38)
</span>
</td>
<td class="coverageStat">
<span class="percent">
92%
</span>
<span class="absValue">
(46/50)
</span>
</td>
<td class="coverageStat">
<span class="percent">
98.4%
</span>
<span class="absValue">
(127/129)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="ns-8/index_SORT_BY_METHOD_DESC.html">it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(6/6)
</span>
</td>
<td class="coverageStat">
<span class="percent">
94.3%
</span>
<span class="absValue">
(50/53)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(40/40)
</span>
</td>
<td class="coverageStat">
<span class="percent">
97.2%
</span>
<span class="absValue">
(103/106)
</span>
</td>
</tr>
@@ -380,26 +380,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -415,10 +415,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -431,10 +431,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -458,18 +458,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -488,7 +488,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -496,7 +496,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -504,7 +504,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -531,7 +531,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -539,7 +539,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -566,7 +566,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -593,7 +593,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -601,7 +601,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -609,7 +609,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -663,7 +663,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -679,7 +679,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -741,7 +741,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,26 +52,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
45.4%
45.1%
</span>
<span class="absValue">
(333/734)
(330/731)
</span>
</td>
<td class="coverageStat">
<span class="percent">
43.2%
42.8%
</span>
<span class="absValue">
(664/1536)
(660/1542)
</span>
</td>
<td class="coverageStat">
<span class="percent">
36%
35.6%
</span>
<span class="absValue">
(1326/3684)
(1308/3671)
</span>
</td>
</tr>
@@ -114,10 +114,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -130,10 +130,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -152,7 +152,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -160,7 +160,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -168,7 +168,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -195,7 +195,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -203,7 +203,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -230,7 +230,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -257,7 +257,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
<td class="coverageStat">
@@ -265,7 +265,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/36)
(0/38)
</span>
</td>
<td class="coverageStat">
@@ -273,7 +273,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/113)
(0/105)
</span>
</td>
</tr>
@@ -327,7 +327,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/41)
(0/40)
</span>
</td>
<td class="coverageStat">
@@ -343,7 +343,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/175)
(0/162)
</span>
</td>
</tr>
@@ -402,10 +402,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
88.2%
89.2%
</span>
<span class="absValue">
(67/76)
(66/74)
</span>
</td>
<td class="coverageStat">
@@ -413,7 +413,7 @@ Current scope: all classes
96.5%
</span>
<span class="absValue">
(111/115)
(110/114)
</span>
</td>
</tr>
@@ -467,7 +467,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(24/24)
(28/28)
</span>
</td>
<td class="coverageStat">
@@ -483,7 +483,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(91/91)
(93/93)
</span>
</td>
</tr>
@@ -499,10 +499,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.3%
</span>
<span class="absValue">
(49/49)
(50/53)
</span>
</td>
<td class="coverageStat">
@@ -515,10 +515,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
97.2%
</span>
<span class="absValue">
(108/108)
(103/106)
</span>
</td>
</tr>
@@ -537,7 +537,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(15/15)
(12/12)
</span>
</td>
<td class="coverageStat"/>
@@ -546,7 +546,7 @@ Current scope: all classes
100%
</span>
<span class="absValue">
(29/29)
(26/26)
</span>
</td>
</tr>
@@ -562,10 +562,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
94.7%
</span>
<span class="absValue">
(38/38)
(36/38)
</span>
</td>
<td class="coverageStat">
@@ -578,10 +578,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.4%
</span>
<span class="absValue">
(129/129)
(127/129)
</span>
</td>
</tr>
@@ -625,10 +625,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
95%
</span>
<span class="absValue">
(20/20)
(19/20)
</span>
</td>
<td class="coverageStat">
@@ -641,10 +641,10 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
100%
98.1%
</span>
<span class="absValue">
(58/58)
(52/53)
</span>
</td>
</tr>
@@ -660,26 +660,26 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
77.6%
78.5%
</span>
<span class="absValue">
(97/125)
(95/121)
</span>
</td>
<td class="coverageStat">
<span class="percent">
73.5%
72.8%
</span>
<span class="absValue">
(349/475)
(343/471)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82%
82.1%
</span>
<span class="absValue">
(547/667)
(541/659)
</span>
</td>
</tr>
@@ -703,18 +703,18 @@ Current scope: all classes
</td>
<td class="coverageStat">
<span class="percent">
69.2%
70%
</span>
<span class="absValue">
(18/26)
(21/30)
</span>
</td>
<td class="coverageStat">
<span class="percent">
65.6%
66.2%
</span>
<span class="absValue">
(42/64)
(47/71)
</span>
</td>
</tr>
@@ -741,7 +741,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -749,7 +749,7 @@ Current scope: all classes
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -775,7 +775,7 @@ Current scope: all classes
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -146,7 +146,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -154,7 +154,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -225,7 +225,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -244,7 +244,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -260,7 +260,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -288,7 +288,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -323,7 +323,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -183,7 +183,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -202,7 +202,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -210,7 +210,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -218,7 +218,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -253,7 +253,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -272,7 +272,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -288,7 +288,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -323,7 +323,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -223,7 +223,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -267,7 +267,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -146,7 +146,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -154,7 +154,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -225,7 +225,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -244,7 +244,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -260,7 +260,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -288,7 +288,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -323,7 +323,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -232,7 +232,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -279,7 +279,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -287,7 +287,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -295,7 +295,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -146,7 +146,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -154,7 +154,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -225,7 +225,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -244,7 +244,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -260,7 +260,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -288,7 +288,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -323,7 +323,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -232,7 +232,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -279,7 +279,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -287,7 +287,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -295,7 +295,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -146,7 +146,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -154,7 +154,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -225,7 +225,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -244,7 +244,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -260,7 +260,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -288,7 +288,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -323,7 +323,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -232,7 +232,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -279,7 +279,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -287,7 +287,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -295,7 +295,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/149)
(0/144)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/394)
(0/391)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -232,7 +232,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -279,7 +279,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -287,7 +287,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -295,7 +295,7 @@ it.polimi.ingsw.gc14</div>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -350,7 +350,7 @@ it.polimi.ingsw.gc14</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -116,12 +116,15 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; *
&nbsp; * @param args command-line arguments passed to the JavaFX runtime.
&nbsp; */
&nbsp; public static void main(String[] args) {
&nbsp; static void main(String[] args) {
<b class="nc">&nbsp; System.setProperty(&quot;glass.gtk.uiScale&quot;, &quot;1.0&quot;);</b>
<b class="nc">&nbsp; System.setProperty(&quot;glass.win.uiScale&quot;, &quot;1.0&quot;);</b>
<b class="nc">&nbsp; Application.launch(GUIApp.class, args);</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Inner {@link Application} subclass that wires the GUI to the client controller
&nbsp; * and hands off control to {@link GUI#start(Stage)}.
&nbsp; */
<b class="nc">&nbsp; public static class GUIApp extends Application {</b>
&nbsp; @Override
&nbsp; public void start(Stage stage) throws Exception {
@@ -155,7 +158,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -59,7 +59,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/11)
(0/12)
</span>
</td>
<td class="coverageStat">
@@ -67,7 +67,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/67)
(0/62)
</span>
</td>
<td class="coverageStat">
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/142)
(0/139)
</span>
</td>
</tr>
@@ -91,6 +91,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp;import it.polimi.ingsw.gc14.Controller.ClientController;
&nbsp;import it.polimi.ingsw.gc14.Model.GamePackage.GameStages;
&nbsp;import it.polimi.ingsw.gc14.Network.IClient;
&nbsp;import it.polimi.ingsw.gc14.Network.NetworkConfig;
&nbsp;import it.polimi.ingsw.gc14.Network.InterfaceResolver;
&nbsp;import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
@@ -114,13 +115,13 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Handles login, connects to the server, and drives the JLine-powered command loop.
&nbsp; */
<b class="nc">&nbsp;public class ClientLauncherTUI {</b>
&nbsp; //TODO
&nbsp; /** TUI view shared with the client controller. */
&nbsp; private TUI view;
&nbsp; //TODO
&nbsp; /** JLine terminal used for all input/output. */
&nbsp; private Terminal terminal;
&nbsp; //TODO
&nbsp; /** Line reader used during active gameplay, with tab-completion wired. */
&nbsp; private LineReader gameReader;
&nbsp; //TODO
&nbsp; /** Username of the currently logged-in player; empty string before login. */
<b class="nc">&nbsp; private String currentUsername = &quot;&quot;;</b>
&nbsp;
&nbsp; private static final String BUILDING_DETAILS =
@@ -170,17 +171,21 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; &quot;HUNTERS — Adding a Hunter without the \uD83C\uDF56 icon: nothing. Adding a Hunter WITH the \uD83C\uDF56 icon:\n&quot; +
&nbsp; &quot; immediately take 1 \uD83C\uDF56 for each Hunter in your tribe (with or without the icon).\n&quot; +
&nbsp; &quot; During Hunt Event, take \uD83C\uDF56 and gain PP based on your Hunter count (see &#39;details events&#39;).&quot;;
&nbsp; //TODO
&nbsp; public static void main(String[] args) throws InterruptedException {
&nbsp; /**
&nbsp; * Launches the TUI client.
&nbsp; *
&nbsp; * @param args command-line arguments (unused).
&nbsp; * @throws InterruptedException if the thread is interrupted during startup.
&nbsp; */
&nbsp; static void main(String[] args) throws InterruptedException {
<b class="nc">&nbsp; new ClientLauncherTUI().start();</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Starts the TUI client. Creates a JLine terminal, loops through login → game → rematch.
&nbsp; *
&nbsp; * @throws InterruptedException if the thread is interrupted while waiting.
&nbsp; */
&nbsp; private void start() throws InterruptedException {
&nbsp; private void start() {
&nbsp; try {
<b class="nc">&nbsp; System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));</b>
<b class="nc">&nbsp; System.setErr(new PrintStream(System.err, true, StandardCharsets.UTF_8));</b>
@@ -204,7 +209,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; if (!doLogin(controller)) continue;</b>
&nbsp;
<b class="nc">&nbsp; while (controller.getClient() != null) {</b>
<b class="nc">&nbsp; String prompt = buildPrompt(controller);</b>
<b class="nc">&nbsp; String prompt = buildPrompt();</b>
&nbsp; String line;
&nbsp; try {
<b class="nc">&nbsp; line = gameReader.readLine(prompt);</b>
@@ -221,7 +226,12 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Prompts for username, player count, network type, and server IP, then connects.
&nbsp; *
&nbsp; * @param controller the client controller to connect.
&nbsp; * @return {@code true} on successful connection; {@code false} if input is invalid or connection fails.
&nbsp; */
&nbsp; private boolean doLogin(ClientController controller) {
<b class="nc">&nbsp; LineReader loginReader = LineReaderBuilder.builder()</b>
<b class="nc">&nbsp; .terminal(terminal)</b>
@@ -232,6 +242,22 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; .completer(new StringsCompleter(&quot;localhost&quot;))</b>
<b class="nc">&nbsp; .build();</b>
&nbsp;
<b class="nc">&nbsp; view.setLineReader(loginReader);</b>
&nbsp; try {
<b class="nc">&nbsp; return doLoginInner(controller, loginReader, ipReader);</b>
&nbsp; } finally {
<b class="nc">&nbsp; view.setLineReader(gameReader);</b>
&nbsp; }
&nbsp; }
&nbsp; /**
&nbsp; * Reads login fields from the terminal and connects to the server.
&nbsp; *
&nbsp; * @param controller the client controller to connect.
&nbsp; * @param loginReader line reader used for username, player count, and network type.
&nbsp; * @param ipReader line reader with localhost auto-complete for the server IP.
&nbsp; * @return {@code true} on successful connection; {@code false} if input is invalid or connection fails.
&nbsp; */
&nbsp; private boolean doLoginInner(ClientController controller, LineReader loginReader, LineReader ipReader) {
&nbsp; String username, networkStr, ip;
&nbsp; int nPlayers;
&nbsp;
@@ -245,7 +271,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; System.exit(0);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; } catch (NumberFormatException e) {
<b class="nc">&nbsp; System.out.println(&quot;Invalid number of players.&quot;);</b>
<b class="nc">&nbsp; loginReader.printAbove(&quot;\033[H\033[2J&quot; + &quot;\033[31mERROR: Invalid number of players.\033[0m&quot;);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; }
&nbsp;
@@ -253,45 +279,47 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; view.setUsername(username);</b>
<b class="nc">&nbsp; controller.setMyUsername(username);</b>
&nbsp;
&nbsp; IClient client;
<b class="nc">&nbsp; if (networkStr.equals(&quot;rmi&quot;)) {</b>
&nbsp; String myIP;
&nbsp; try {
<b class="nc">&nbsp; myIP = InterfaceResolver.resolveLocalInterface(ip);</b>
&nbsp; } catch (Exception e) {
<b class="nc">&nbsp; System.out.println(&quot;Cannot resolve local interface: &quot; + e.getMessage());</b>
<b class="nc">&nbsp; loginReader.printAbove(&quot;\033[H\033[2J&quot; + &quot;\033[31mERROR: Cannot resolve local interface: &quot; + e.getMessage() + &quot;\033[0m&quot;);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; }
<b class="nc">&nbsp; System.setProperty(&quot;java.rmi.server.hostname&quot;, myIP);</b>
<b class="nc">&nbsp; RMIClient client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, myIP);</b>
<b class="nc">&nbsp; client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, myIP);</b>
<b class="nc">&nbsp; ErrorType err = client.connect(username, nPlayers);</b>
<b class="nc">&nbsp; if (err != null) {</b>
<b class="nc">&nbsp; terminal.writer().print(&quot;\033[H\033[2J&quot;);</b>
<b class="nc">&nbsp; terminal.writer().flush();</b>
<b class="nc">&nbsp; System.out.println(&quot;Errore: &quot; + err);</b>
<b class="nc">&nbsp; loginReader.printAbove(&quot;\033[H\033[2J&quot; + &quot;\033[31mERROR: &quot; + err + &quot;\033[0m&quot;);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; }
<b class="nc">&nbsp; System.out.println(&quot;Connected via RMI.&quot;);</b>
<b class="nc">&nbsp; System.out.println(&quot;Connected via RMI, waiting for other players...&quot;);</b>
<b class="nc">&nbsp; controller.setClient(client);</b>
&nbsp;
<b class="nc">&nbsp; } else if (networkStr.equals(&quot;tcp&quot;)) {</b>
<b class="nc">&nbsp; TCPClient client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);</b>
<b class="nc">&nbsp; client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);</b>
<b class="nc">&nbsp; ErrorType err = client.connect(username, nPlayers);</b>
<b class="nc">&nbsp; if (err != null) {</b>
<b class="nc">&nbsp; terminal.writer().print(&quot;\033[H\033[2J&quot;);</b>
<b class="nc">&nbsp; terminal.writer().flush();</b>
<b class="nc">&nbsp; System.out.println(&quot;Errore: &quot; + err);</b>
<b class="nc">&nbsp; loginReader.printAbove(&quot;\033[H\033[2J&quot; + &quot;\033[31mERROR: &quot; + err + &quot;\033[0m&quot;);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; }
<b class="nc">&nbsp; System.out.println(&quot;Connected via TCP.&quot;);</b>
<b class="nc">&nbsp; System.out.println(&quot;Connected via TCP, waiting for other players...&quot;);</b>
<b class="nc">&nbsp; controller.setClient(client);</b>
&nbsp;
&nbsp; } else {
<b class="nc">&nbsp; System.out.println(&quot;Unknown network type &#39;&quot; + networkStr + &quot;&#39;. Use rmi or tcp.&quot;);</b>
<b class="nc">&nbsp; loginReader.printAbove(&quot;\033[H\033[2J&quot; + &quot;\033[31mERROR: Unknown network type &#39;&quot; + networkStr + &quot;&#39;. Use rmi or tcp.\033[0m&quot;);</b>
<b class="nc">&nbsp; return false;</b>
&nbsp; }
<b class="nc">&nbsp; return true;</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Builds the JLine {@link LineReader} used during gameplay, with tab-completion
&nbsp; * for all valid commands.
&nbsp; *
&nbsp; * @return the configured {@link LineReader}.
&nbsp; */
&nbsp; private LineReader buildGameReader() {
<b class="nc">&nbsp; Completer completer = new TreeCompleter(</b>
<b class="nc">&nbsp; node(&quot;slot&quot;),</b>
@@ -304,8 +332,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; node(&quot;building&quot;))),</b>
<b class="nc">&nbsp; node(&quot;totem&quot;),</b>
<b class="nc">&nbsp; node(&quot;skip&quot;),</b>
<b class="nc">&nbsp; node(&quot;render&quot;),</b>
<b class="nc">&nbsp; node(&quot;help&quot;),</b>
<b class="nc">&nbsp; node(&quot;clear&quot;),</b>
<b class="nc">&nbsp; node(&quot;details&quot;, node(&quot;buildings&quot;), node(&quot;events&quot;), node(&quot;characters&quot;)),</b>
<b class="nc">&nbsp; node(&quot;rematch&quot;),</b>
<b class="nc">&nbsp; node(&quot;quit&quot;)</b>
@@ -316,8 +343,12 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; .option(LineReader.Option.DISABLE_EVENT_EXPANSION, true)</b>
<b class="nc">&nbsp; .build();</b>
&nbsp; }
&nbsp; //TODO
&nbsp; private String buildPrompt(ClientController controller) {
&nbsp; /**
&nbsp; * Returns the command-line prompt string showing the current username.
&nbsp; *
&nbsp; * @return the prompt string.
&nbsp; */
&nbsp; private String buildPrompt() {
<b class="nc">&nbsp; return currentUsername.isEmpty() ? &quot;&gt; &quot; : currentUsername + &quot;&gt; &quot;;</b>
&nbsp; }
&nbsp;
@@ -329,16 +360,15 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; switch (cmd) {</b>
&nbsp; case &quot;slot&quot; -&gt; {
<b class="nc">&nbsp; int pos = parsePos(parts, 1);</b>
<b class="nc">&nbsp; if (pos &gt;= 0) controller.slotChoice(pos);</b>
<b class="nc">&nbsp; controller.slotChoice(pos);</b>
&nbsp; }
<b class="nc">&nbsp; case &quot;draw&quot; -&gt; handleDraw(parts, controller);</b>
&nbsp; case &quot;totem&quot; -&gt; {
<b class="nc">&nbsp; int pos = parsePos(parts, 1);</b>
<b class="nc">&nbsp; if (pos &gt;= 0) controller.totemChoice(pos);</b>
<b class="nc">&nbsp; controller.totemChoice(pos);</b>
&nbsp; }
<b class="nc">&nbsp; case &quot;skip&quot; -&gt; controller.skipTurn();</b>
<b class="nc">&nbsp; case &quot;render&quot; -&gt; handleRender(parts);</b>
<b class="nc">&nbsp; case &quot;help&quot; -&gt; gameReader.printAbove(&quot;Commands: slot, draw, totem, skip, render, help, details, rematch, quit&quot;);</b>
<b class="nc">&nbsp; case &quot;clear&quot; -&gt; handleRender();</b>
&nbsp; case &quot;details&quot; -&gt; {
<b class="nc">&nbsp; if (parts.length &gt; 1 &amp;&amp; parts[1].equalsIgnoreCase(&quot;buildings&quot;))</b>
<b class="nc">&nbsp; gameReader.printAbove(BUILDING_DETAILS);</b>
@@ -368,7 +398,12 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
<b class="nc">&nbsp; return false;</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Handles the {@code draw} command, dispatching to the appropriate controller draw method.
&nbsp; *
&nbsp; * @param parts the tokenized command: {@code [draw, upper|lower, tribe|building, pos]}.
&nbsp; * @param controller the client controller to invoke.
&nbsp; */
&nbsp; private void handleDraw(String[] parts, ClientController controller) {
<b class="nc">&nbsp; if (parts.length &lt; 4) {</b>
<b class="nc">&nbsp; view.showError(ErrorType.GENERIC_ERROR, &quot;Usage: draw upper|lower tribe|building &lt;pos&gt;&quot;);</b>
@@ -384,11 +419,20 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; else if (tribe) controller.drawLowerTribeCard(pos);</b>
<b class="nc">&nbsp; else controller.drawLowerBuildingCard(pos);</b>
&nbsp; }
&nbsp; //TODO
&nbsp; private void handleRender(String[] parts) {
&nbsp; /**
&nbsp; * Handles the {@code clear} command by triggering a full board re-render.
&nbsp; *
&nbsp; */
&nbsp; private void handleRender() {
<b class="nc">&nbsp; view.renderBoard();</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Parses an integer position argument at {@code idx} in {@code parts}.
&nbsp; *
&nbsp; * @param parts the tokenized command array.
&nbsp; * @param idx index of the position argument.
&nbsp; * @return the parsed integer, or {@code -1} if missing or malformed.
&nbsp; */
&nbsp; private int parsePos(String[] parts, int idx) {
<b class="nc">&nbsp; if (parts.length &lt;= idx) {</b>
<b class="nc">&nbsp; view.showError(ErrorType.GENERIC_ERROR, &quot;Missing position argument.&quot;);</b>
@@ -402,7 +446,11 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return -1;</b>
&nbsp; }
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Disconnects the client if one is currently connected; safe to call when already disconnected.
&nbsp; *
&nbsp; * @param controller the client controller to disconnect.
&nbsp; */
&nbsp; private void safeQuit(ClientController controller) {
<b class="nc">&nbsp; if (controller.getClient() != null) controller.disconnect();</b>
&nbsp; }
@@ -430,7 +478,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -79,19 +79,39 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp;/** Enumeration of error types that can be returned by server-side operations. */
<b class="nc">&nbsp;public enum ErrorType {</b>
<b class="nc">&nbsp; USER_NOT_FOUND(&quot;User not found&quot;),</b>
<b class="nc">&nbsp; USERNAME_ALREADY_USED(&quot;Username is already in use&quot;),</b>
&nbsp; /** The chosen username is already taken by another connected player. */
<b class="nc">&nbsp; INVALID_USERNAME(&quot;Username is already in use or too long&quot;),</b>
&nbsp; /** The user is already connected to the server. */
<b class="nc">&nbsp; USER_ALREADY_CONNECTED(&quot;User is already connected&quot;),</b>
&nbsp; /** The requested number of players is outside the allowed range. */
<b class="nc">&nbsp; WRONG_PLAYER_NUMBER(&quot;Wrong player number&quot;),</b>
&nbsp; /** The server has crashed or become unreachable. */
<b class="nc">&nbsp; SERVER_CRASHED(&quot;Server crashed&quot;),</b>
&nbsp; /** The server is unreachable. */
<b class="nc">&nbsp; SERVER_UNREACHABLE(&quot;Server unreachable&quot;),</b>
&nbsp; /** A generic, unclassified error occurred. */
<b class="nc">&nbsp; GENERIC_ERROR(&quot;Generic error&quot;),</b>
&nbsp; /** The game has already started and cannot accept new players. */
<b class="nc">&nbsp; GAME_ALREADY_STARTED(&quot;Game already started&quot;),</b>
&nbsp; /** The action attempted is not valid in the current game state. */
<b class="nc">&nbsp; WRONG_ACTION(&quot;Wrong action&quot;);</b>
&nbsp; //TODO
&nbsp; /** Human-readable description of this error, returned by {@link #toString()}. */
&nbsp; private final String description;
&nbsp;
&nbsp; /**
&nbsp; * Creates an error type constant with the given human-readable description.
&nbsp; *
&nbsp; * @param description the message returned by {@link #toString()}.
&nbsp; */
<b class="nc">&nbsp; ErrorType(String description) {</b>
<b class="nc">&nbsp; this.description = description;</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Returns the human-readable description of this error.
&nbsp; *
&nbsp; * @return the error description string.
&nbsp; */
&nbsp; @Override
&nbsp; public String toString() {
<b class="nc">&nbsp; return description;</b>
@@ -120,7 +140,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/107)
(0/110)
</span>
</td>
</tr>
@@ -110,7 +110,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/108)
(0/111)
</span>
</td>
</tr>
@@ -144,7 +144,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * &lt;p&gt;The three top-level states that determine routing are:
&nbsp; * &lt;ul&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;Inactive&lt;/b&gt; no game model is present, or the game has ended.
&nbsp; * Only disconnection clean-up is performed.&lt;/li&gt;
&nbsp; * Only disconnection cleanup is performed.&lt;/li&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;Suspended&lt;/b&gt; a forfeit timer is running because exactly one
&nbsp; * player remains online. Only reconnection events are accepted.&lt;/li&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;Active&lt;/b&gt; normal gameplay; every event is applied, saved,
@@ -156,11 +156,15 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * thread via {@link #doFirstEvent()}.
&nbsp; */
&nbsp;public class GameEventProcessor {
&nbsp;
&nbsp; /** Queue from which incoming client events are consumed one at a time. */
&nbsp; private final BlockingQueue&lt;NetworkEvent&gt; actionQueue;
&nbsp; /** Server-side game controller; all model mutations go through this. */
&nbsp; private final GameController gameController;
&nbsp; /** Shared map tracking each player&#39;s online status ({@code true} = online). */
&nbsp; private final LimitedMap&lt;String, Boolean&gt; playerList;
&nbsp; /** Broadcaster used to push events and model snapshots to all connected clients. */
&nbsp; private final CompositeClientBroadcaster broadcaster;
&nbsp; /** Persists and deletes game save files. */
&nbsp; private final SaveManager saveManager;
&nbsp;
&nbsp; /** Single-thread executor used exclusively for the forfeit timer. Daemon so it does not block JVM shutdown. */
@@ -173,7 +177,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp; /**
&nbsp; * Handle to the running forfeit timer, or {@code null} when no timer is active.
&nbsp; * A non-null value signals that the game is in the {@em suspended} state.
&nbsp; * A non-null value signals that the game is in the suspended state.
&nbsp; */
&nbsp; private ScheduledFuture&lt;?&gt; disconnectionTimer;
&nbsp;
@@ -199,7 +203,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; this.saveManager = saveManager;</b>
&nbsp; }
&nbsp;
&nbsp; // ── Public entry point ────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Blocks until one event is available in the queue, then routes it to the
@@ -220,7 +223,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; // ── State guards ──────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Returns {@code true} when there is an ongoing game that has not yet ended.
@@ -239,11 +241,10 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return disconnectionTimer != null;</b>
&nbsp; }
&nbsp;
&nbsp; // ── Inactive game path ────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Handles events that arrive when no active game exists (not yet started,
&nbsp; * or already ended). Only disconnection clean-up is relevant here.
&nbsp; * or already ended). Only disconnection cleanup is relevant here.
&nbsp; *
&nbsp; * @param event the incoming event.
&nbsp; */
@@ -259,7 +260,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; }</b>
&nbsp; }
&nbsp;
&nbsp; // ── Suspended game path ───────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Routes events while the game is suspended waiting for a reconnection.
@@ -303,7 +303,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; broadcaster.notifyAll(event);</b>
&nbsp; }
&nbsp;
&nbsp; // ── Active game path ──────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Applies the event to the game controller, saves the updated state,
@@ -331,6 +330,9 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; if (!saveManager.save(game)) {</b>
<b class="nc">&nbsp; System.out.println(&quot;\n!!! Save failed !!!\n&quot;);</b>
&nbsp; }
&nbsp; else {
<b class="nc">&nbsp; System.out.println(event.getUsername()+&quot;: &quot;+ event.getEventType() + &quot; save successful.&quot;);</b>
&nbsp; }
&nbsp;
&nbsp; // During the lobby phase a disconnection only removes the player
&nbsp; // from the list; no broadcast is needed.
@@ -378,7 +380,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Schedules the 60-second forfeit timer if a disconnection has left
&nbsp; * exactly one player online.
&nbsp; *
&nbsp; * &lt;p&gt;If a previous timer is still pending it is cancelled first to avoid
&nbsp; * &lt;p&gt;If a previous timer is still pending it is canceled first to avoid
&nbsp; * duplicate timers.
&nbsp; *
&nbsp; * @param event the event that was just applied.
@@ -391,12 +393,14 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
<b class="nc">&nbsp; if (disconnectionTimer != null &amp;&amp; !disconnectionTimer.isDone()) {</b>
<b class="nc">&nbsp; disconnectionTimer.cancel(false);</b>
<b class="nc">&nbsp; System.out.println(&quot;Disconnection TIMER reset&quot;);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; disconnectionTimer = timerExecutor.schedule(</b>
<b class="nc">&nbsp; () -&gt; endGameForfeit(game),</b>
&nbsp; 1, TimeUnit.MINUTES
&nbsp; );
<b class="nc">&nbsp; System.out.println(&quot;Disconnection TIMER started, 60 seconds from now...&quot; );</b>
&nbsp; }
&nbsp;
&nbsp; /**
@@ -459,7 +463,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; // ── Utilities ─────────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Returns the number of players currently marked as online in the player list.
@@ -517,7 +520,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -59,7 +59,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/16)
(0/15)
</span>
</td>
<td class="coverageStat">
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/28)
(0/27)
</span>
</td>
</tr>
@@ -103,7 +103,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * @param &lt;V&gt; the type of mapped values.
&nbsp; */
&nbsp;public class LimitedMap&lt;K, V&gt; implements Map&lt;K, V&gt; {
&nbsp;
&nbsp; /** The underlying thread-safe hash map storing all key-value pairs. */
<b class="nc">&nbsp; private final ConcurrentHashMap&lt;K, V&gt; map = new ConcurrentHashMap&lt;&gt;();</b>
&nbsp;
&nbsp; /**
@@ -191,13 +191,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; public void setLimit(int num) { this.limit = num; }</b>
&nbsp;
&nbsp; /**
&nbsp; * Returns the current size limit of this map.
&nbsp; *
&nbsp; * @return the current limit.
&nbsp; */
<b class="nc">&nbsp; public int getLimit() { return limit; }</b>
&nbsp;
&nbsp; /**
&nbsp; * Sets a new action to execute when the map size reaches or exceeds the limit.
&nbsp; *
&nbsp; * @param action the new action to set; must not be {@code null}.
@@ -230,7 +223,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -63,7 +63,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/23)
(0/22)
</span>
</td>
</tr>
@@ -142,7 +142,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; try (ObjectOutputStream oos = new ObjectOutputStream(</b>
<b class="nc">&nbsp; new BufferedOutputStream(new FileOutputStream(filePath.toFile())))) {</b>
<b class="nc">&nbsp; oos.writeObject(game);</b>
<b class="nc">&nbsp; System.out.println(&quot;Game saved to: &quot; + filePath.toAbsolutePath());</b>
<b class="nc">&nbsp; return true;</b>
&nbsp; }
&nbsp; } catch (IOException e) {
@@ -210,7 +209,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/72)
(0/71)
</span>
</td>
</tr>
@@ -143,17 +143,16 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; actionQueue, gameController, playerList, broadcaster, saveManager);
&nbsp; }
&nbsp;
&nbsp; // ── Entry point ───────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Initialises all server components, wires them together, restores a saved
&nbsp; * Initializes all server components, wires them together, restores a saved
&nbsp; * game if available, and starts the event-processing loop and both network
&nbsp; * servers.
&nbsp; *
&nbsp; * @param args command-line arguments (unused).
&nbsp; * @throws RemoteException if the RMI server cannot be created.
&nbsp; */
&nbsp; public static void main(String[] args) throws RemoteException {
&nbsp; static void main(String[] args) throws RemoteException {
<b class="nc">&nbsp; LimitedMap&lt;String, Boolean&gt; playerList = new LimitedMap&lt;&gt;(5, () -&gt; {});</b>
<b class="nc">&nbsp; BlockingQueue&lt;NetworkEvent&gt; actionQueue = new LinkedBlockingQueue&lt;&gt;();</b>
<b class="nc">&nbsp; GameController gameController = new GameController();</b>
@@ -206,10 +205,8 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
<b class="nc">&nbsp; rmiServer.start();</b>
<b class="nc">&nbsp; new Thread(() -&gt; tcpServer.start()).start();</b>
<b class="nc">&nbsp; System.out.println(&quot;Server RMI: &quot; + System.getProperty(&quot;java.rmi.server.hostname&quot;));</b>
&nbsp; }
&nbsp;
&nbsp; // ── Game loop ─────────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Runs the event-processing loop until the thread is interrupted.
@@ -227,14 +224,13 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; // ── Crash recovery ────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Attempts to restore a previously saved game.
&nbsp; *
&nbsp; * &lt;p&gt;The save is discarded if all but at most one player was offline at the
&nbsp; * time of the crash, since there would be nobody to resume the game with.
&nbsp; * Otherwise the model is restored, the player-list limit is set, and each
&nbsp; * Otherwise, the model is restored, the player-list limit is set, and each
&nbsp; * player who was offline at crash time is pre-populated as offline so the
&nbsp; * reconnection flow can handle them correctly.
&nbsp; *
@@ -270,7 +266,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; System.out.println(&quot;Game restored from save (&quot; + game.getNPlayers() + &quot; players).&quot;);</b>
&nbsp; }
&nbsp;
&nbsp; // ── Network interface selection ───────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Lists active non-loopback IPv4 network interfaces and prompts the operator
@@ -334,7 +329,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.Network.TCP.Client</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -67,7 +67,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/26)
(0/24)
</span>
</td>
<td class="coverageStat">
@@ -107,7 +107,9 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Client TCP. Sends and receives messages with the TCP server.
&nbsp; */
&nbsp;public class TCPClient implements IClient {
&nbsp; /** Byte value sent by the client to signal it is still alive. */
&nbsp; private static final int PING = 1;
&nbsp; /** Byte value expected from the server in response to a {@link #PING}. */
&nbsp; private static final int PONG = 2;
&nbsp;
&nbsp; /** Socket TCP */
@@ -120,18 +122,21 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; private ObjectOutputStream socketSend;
&nbsp;
&nbsp; /** Client game&#39;s controller */
&nbsp; private ClientController controller;
&nbsp; private final ClientController controller;
&nbsp;
&nbsp; /** IP address of the server to connect to */
&nbsp; private String hostname;
&nbsp;
&nbsp; private final String hostname;
&nbsp; /** {@code true} while the connection is active; set to {@code false} on disconnect. */
&nbsp; private boolean running;
&nbsp; /** TCP port */
&nbsp; private int mainPort;
&nbsp;
&nbsp; private int heartbeatPort;
&nbsp; private final int mainPort;
&nbsp; /** TCP port dedicated to heartbeat communication. */
&nbsp; private final int heartbeatPort;
&nbsp; /** Socket used exclusively for heartbeat ping/pong exchange. */
&nbsp; private Socket heartbeatSocket;
&nbsp; /** Output stream of {@link #heartbeatSocket}, used to write {@link #PING} bytes. */
&nbsp; private OutputStream heartbeatOut;
&nbsp; /** Input stream of {@link #heartbeatSocket}, used to read {@link #PONG} bytes. */
&nbsp; private InputStream heartbeatIn;
&nbsp;
&nbsp;
@@ -157,7 +162,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Otherwise, a listener thread is started.
&nbsp; * @param user The username of the player
&nbsp; * @param proposedNPlayers The desired number of players for the game
&nbsp; * @return true if the connection is successful, false otherwise.
&nbsp; * @return null if the connection is successful, GENERIC_ERROR otherwise.
&nbsp; */
&nbsp; public ErrorType connect(String user, int proposedNPlayers) {
&nbsp; try {
@@ -194,10 +199,14 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp; } catch (IOException e) {
<b class="nc">&nbsp; e.printStackTrace();</b>
<b class="nc">&nbsp; return ErrorType.GENERIC_ERROR;</b>
<b class="nc">&nbsp; return ErrorType.SERVER_UNREACHABLE;</b>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Sends a {@link #PING} byte to the server every 3 seconds and waits for a {@link #PONG} reply.
&nbsp; * If no reply arrives within {@value NetworkConfig#SILENCE_THRESHOLD_MS} ms, the server is
&nbsp; * considered unreachable and {@link #disconnect()} is called.
&nbsp; */
&nbsp; private void heartbeatLoop() {
<b class="nc">&nbsp; ScheduledExecutorService sender = Executors.newSingleThreadScheduledExecutor();</b>
<b class="nc">&nbsp; sender.scheduleAtFixedRate(() -&gt; {</b>
@@ -223,7 +232,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; heartbeatSocket.setSoTimeout((int) NetworkConfig.SILENCE_THRESHOLD_MS);</b>
<b class="nc">&nbsp; while (running) {</b>
<b class="nc">&nbsp; int b = heartbeatIn.read();</b>
<b class="nc">&nbsp; if (b == -1 || b != PONG) {</b>
<b class="nc">&nbsp; if (b != PONG) {</b>
<b class="nc">&nbsp; disconnect();</b>
<b class="nc">&nbsp; controller.getView().showError(ErrorType.SERVER_CRASHED, ErrorType.SERVER_CRASHED.toString());</b>
&nbsp; break;
@@ -243,6 +252,10 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; sender.shutdownNow();</b>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Disconnects the player and cleans model and controller
&nbsp; */
&nbsp; private synchronized void disconnect() {
<b class="nc">&nbsp; if (!running) return;</b>
<b class="nc">&nbsp; running = false;</b>
@@ -423,7 +436,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -196,7 +196,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -196,7 +196,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -196,7 +196,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -196,7 +196,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -196,7 +196,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/50)
(0/52)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/166)
(0/164)
</span>
</td>
</tr>
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -231,7 +231,7 @@ it.polimi.ingsw.gc14.Network.TCP.Server</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/32)
(0/31)
</span>
</td>
</tr>
@@ -90,7 +90,6 @@ Current scope: <a href="../../index.html">all classes</a>
<code class="sourceCode" id="sourceCode">&nbsp;package it.polimi.ingsw.gc14.Network.TCP.Server;
&nbsp;
&nbsp;import it.polimi.ingsw.gc14.LimitedMap;
&nbsp;import it.polimi.ingsw.gc14.Model.Game;
&nbsp;import it.polimi.ingsw.gc14.Model.MiniModel;
&nbsp;import it.polimi.ingsw.gc14.Network.NetworkEvent;
&nbsp;import it.polimi.ingsw.gc14.Network.NetworkEvents.DisconnectedPlayer;
@@ -111,7 +110,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * The username of the connected client on this handler
&nbsp; */
&nbsp; private final String username;
&nbsp;
&nbsp; /** {@code true} while the handler is actively reading from the socket; set to {@code false} on disconnect. */
&nbsp; private volatile boolean running;
&nbsp;
&nbsp; /**
@@ -123,25 +122,25 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return username;</b>
&nbsp; }
&nbsp; /** The TCP socket */
&nbsp; private Socket clientSocket;
&nbsp; private final Socket clientSocket;
&nbsp;
&nbsp; /** Input stream used to receive objects from the client */
&nbsp; private ObjectInputStream in;
&nbsp; private final ObjectInputStream in;
&nbsp;
&nbsp; /** Output stream used to send objects to the client */
&nbsp; private ObjectOutputStream out;
&nbsp; private final ObjectOutputStream out;
&nbsp;
&nbsp; /**
&nbsp; * Shared list of all client handlers.
&nbsp; * This handler removes itself from the list when disconnected.
&nbsp; */
&nbsp; private List&lt;ClientHandler&gt; clientHandlers;
&nbsp; private final List&lt;ClientHandler&gt; clientHandlers;
&nbsp;
&nbsp; /** Maps each connected player&#39;s username to their connection state (true = connected). */
&nbsp; private LimitedMap&lt;String, Boolean&gt; limitedMap;
&nbsp; private final LimitedMap&lt;String, Boolean&gt; limitedMap;
&nbsp;
&nbsp; /** Queue containing the events to be applied to the game model */
&nbsp; private BlockingQueue&lt;NetworkEvent&gt; actionQueue;
&nbsp; private final BlockingQueue&lt;NetworkEvent&gt; actionQueue;
&nbsp;
&nbsp;
&nbsp; /**
@@ -181,7 +180,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp; } catch (IOException e) {
<b class="nc">&nbsp; System.err.println(&quot;Error in incoming connection/disconnection: &quot; + username);</b>
&nbsp; } catch (ClassNotFoundException e) {
<b class="nc">&nbsp; System.err.println(&quot;Class not found: &quot; + username);</b>
&nbsp; } finally {
@@ -234,7 +232,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; clientHandlers.remove(this);</b>
<b class="nc">&nbsp; limitedMap.put(username, false);</b>
<b class="nc">&nbsp; actionQueue.add(new DisconnectedPlayer(username));</b>
<b class="nc">&nbsp; System.out.println(&quot;Disconnected player: &quot; + username);</b>
<b class="nc">&nbsp; System.err.println(&quot;(TCP) Disconnected player: &quot; + username);</b>
<b class="nc">&nbsp; try { clientSocket.close(); } catch (IOException ignored) {}</b>
&nbsp; }
&nbsp;}
@@ -261,7 +259,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/29)
(0/28)
</span>
</td>
</tr>
@@ -105,10 +105,13 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * both the heartbeat connection and the main client connection are disconnected.
&nbsp; */
&nbsp;public class HeartbeatHandler implements Runnable {
&nbsp;
&nbsp; /** Username of the client associated with this heartbeat connection. */
&nbsp; private final String username;
&nbsp; /** Dedicated socket used solely for heartbeat ping/pong exchange. */
&nbsp; private final Socket socket;
&nbsp; /** Input stream of {@link #socket} used to receive {@code PING} bytes from the client. */
&nbsp; private final InputStream in;
&nbsp; /** Output stream of {@link #socket} used to send {@code PONG} bytes back to the client. */
&nbsp; private final OutputStream out;
&nbsp;
&nbsp; /**
@@ -173,10 +176,10 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; startWatchdog();</b>
&nbsp; try {
<b class="nc">&nbsp; while (running) {</b>
<b class="nc">&nbsp; int b = in.read(); // blocks until a byte arrives</b>
<b class="nc">&nbsp; int b = in.read();</b>
<b class="nc">&nbsp; if (b == -1) {</b>
<b class="nc">&nbsp; disconnect();</b>
&nbsp; break; // stream closed
&nbsp; break;
&nbsp; }
<b class="nc">&nbsp; if (b == PING) {</b>
<b class="nc">&nbsp; lastReceivedTime = System.currentTimeMillis();</b>
@@ -213,8 +216,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; private synchronized void disconnect() {
<b class="nc">&nbsp; running = false;</b>
<b class="nc">&nbsp; watchdog.shutdownNow();</b>
<b class="nc">&nbsp; mainHandler.disconnect(); // disconnette anche il socket principale</b>
<b class="nc">&nbsp; System.out.println(&quot;Disconnected: &quot; + username);</b>
<b class="nc">&nbsp; mainHandler.disconnect();</b>
<b class="nc">&nbsp; try { socket.close(); } catch (IOException ignored) {}</b>
&nbsp; }
&nbsp;}
@@ -241,7 +243,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -67,7 +67,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/28)
(0/30)
</span>
</td>
<td class="coverageStat">
@@ -124,12 +124,12 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /**
&nbsp; * Main TCP port used for standard client-server communication.
&nbsp; */
&nbsp; private int port;
&nbsp; private final int port;
&nbsp;
&nbsp; /**
&nbsp; * TCP port dedicated to heartbeat communication.
&nbsp; */
&nbsp; private int heartbeatPort;
&nbsp; private final int heartbeatPort;
&nbsp;
&nbsp; /**
&nbsp; * Main server socket used to accept client connections.
@@ -149,17 +149,17 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /**
&nbsp; * Queue containing network events received from clients.
&nbsp; */
&nbsp; private BlockingQueue&lt;NetworkEvent&gt; actionQueue;
&nbsp; private final BlockingQueue&lt;NetworkEvent&gt; actionQueue;
&nbsp;
&nbsp; /**
&nbsp; * Map storing the online/offline status of connected players.
&nbsp; */
&nbsp; private LimitedMap&lt;String, Boolean&gt; playerList;
&nbsp; private final LimitedMap&lt;String, Boolean&gt; playerList;
&nbsp;
&nbsp; /**
&nbsp; * List of active TCP client handlers.
&nbsp; */
&nbsp; private CopyOnWriteArrayList&lt;ClientHandler&gt; clientHandlers;
&nbsp; private final CopyOnWriteArrayList&lt;ClientHandler&gt; clientHandlers;
&nbsp;
&nbsp;
&nbsp; /**
@@ -214,7 +214,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; System.out.println(&quot;TCP server started on port: &quot; + port);</b>
<b class="nc">&nbsp; System.out.println(&quot;Heartbeat server started on port: &quot; + heartbeatPort);</b>
<b class="nc">&nbsp; System.out.println(&quot;TCP heartbeat server started on port: &quot; + heartbeatPort);</b>
&nbsp;
<b class="nc">&nbsp; new Thread(this::acceptHeartbeat, &quot;heartbeat-acceptor&quot;).start();</b>
&nbsp;
@@ -249,11 +249,11 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; synchronized (controller) {</b>
<b class="nc">&nbsp; String username = eventAddPlayer.getUsername();</b>
&nbsp; //reconnect players after a server crash
<b class="nc">&nbsp; if (playerList.isEmpty()&amp;&amp; controller.getModel()==null) {</b>
<b class="nc">&nbsp; if (playerList.isEmpty() &amp;&amp;(controller.getModel()==null || controller.getModel().getCurrentState().getGameStage().equals(GameStages.WAITING))) {</b>
<b class="nc">&nbsp; Game model = new Game(eventAddPlayer.getProposedNPlayer());</b>
<b class="nc">&nbsp; controller.setModel(model);</b>
<b class="nc">&nbsp; playerList.setLimit(eventAddPlayer.getProposedNPlayer());</b>
<b class="nc">&nbsp; System.out.println(&quot;Game Created With :&quot;+eventAddPlayer.getProposedNPlayer()+&quot; Players&quot;);</b>
<b class="nc">&nbsp; System.out.println(&quot;Game Created With: &quot;+eventAddPlayer.getProposedNPlayer()+&quot; Players&quot;);</b>
&nbsp; }
<b class="nc">&nbsp; if(controller.getModel().getCurrentState().getGameStage()!= GameStages.WAITING ) {</b>
<b class="nc">&nbsp; if (controller.getModel().getPlayers().stream().noneMatch(p -&gt; p.getUserName().equals(username))|| controller.getModel().getCurrentState().getGameStage()==GameStages.ENDED) {</b>
@@ -275,7 +275,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; new Thread(handler).start();</b>
<b class="nc">&nbsp; continue;</b>
&nbsp; } else {
<b class="nc">&nbsp; eventAddPlayer.setErrorType(ErrorType.USERNAME_ALREADY_USED);</b>
<b class="nc">&nbsp; eventAddPlayer.setErrorType(ErrorType.INVALID_USERNAME);</b>
<b class="nc">&nbsp; eventAddPlayer.setIsError(true);</b>
<b class="nc">&nbsp; clientSend.writeObject(eventAddPlayer);</b>
&nbsp; clientSocket.close();
@@ -432,7 +432,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -258,7 +258,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -266,7 +266,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -258,7 +258,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -266,7 +266,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -293,7 +293,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -301,7 +301,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -309,7 +309,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -258,7 +258,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -266,7 +266,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -293,7 +293,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -301,7 +301,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -309,7 +309,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -258,7 +258,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -266,7 +266,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -293,7 +293,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -301,7 +301,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -309,7 +309,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -126,7 +126,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -204,7 +204,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -258,7 +258,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -266,7 +266,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -293,7 +293,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -301,7 +301,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -309,7 +309,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -56,7 +56,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/130)
(0/132)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/291)
(0/302)
</span>
</td>
<td class="coverageStat">
@@ -72,7 +72,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/1000)
(0/1014)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -161,7 +161,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -239,7 +239,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -274,7 +274,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -293,7 +293,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -301,7 +301,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -309,7 +309,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -336,7 +336,7 @@ it.polimi.ingsw.gc14.View.GUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -48,7 +48,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/6)
(0/5)
</span>
</td>
<td class="coverageStat">
@@ -56,7 +56,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/31)
(0/29)
</span>
</td>
<td class="coverageStat">
@@ -64,7 +64,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/50)
(0/49)
</span>
</td>
</tr>
@@ -129,7 +129,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/15)
(0/14)
</span>
</td>
<td class="coverageStat">
@@ -137,7 +137,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/73)
(0/71)
</span>
</td>
<td class="coverageStat">
@@ -145,7 +145,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/123)
(0/122)
</span>
</td>
</tr>
@@ -169,23 +169,50 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import java.util.List;
&nbsp;import java.util.Random;
&nbsp;
&nbsp;//TODO ALL JAVADOC
&nbsp;/**
&nbsp; * Ambient fire-particle effect rendered on a transparent overlay pane.
&nbsp; *
&nbsp; * &lt;p&gt;Three particle types float from the screen corners toward the center:
&nbsp; * &lt;ul&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;embers&lt;/b&gt; (type 0) — slow, glowing orange circles with a soft halo.&lt;/li&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;sparks&lt;/b&gt; (type 1) — fast, short-lived bright particles.&lt;/li&gt;
&nbsp; * &lt;li&gt;&lt;b&gt;dust&lt;/b&gt; (type 2) — large, translucent brown drifting circles.&lt;/li&gt;
&nbsp; * &lt;/ul&gt;
&nbsp; *
&nbsp; * &lt;p&gt;Call {@link #start()} after adding {@link #getPane()} to the scene graph
&nbsp; */
&nbsp;public class FireParticleSystem {
&nbsp;
&nbsp; /** Maximum number of live particles at any given time. */
&nbsp; private static final int MAX_PARTICLES = 30;
&nbsp; /** Minimum nanoseconds between particle spawn batches. */
&nbsp; private static final long SPAWN_INTERVAL_NS = 100_000_000L;
&nbsp; private static final long FRAME_INTERVAL_NS = 1_000_000_000L / 30; // 30 fps cap
&nbsp; private static final int STEPS_PER_FRAME = 3; // physics steps per frame → 3× speed
&nbsp; /** Minimum nanoseconds between rendered frames (30 fps cap). */
&nbsp; private static final long FRAME_INTERVAL_NS = 1_000_000_000L / 30;
&nbsp; /** Physics update steps applied per rendered frame (multiplies effective speed). */
&nbsp; private static final int STEPS_PER_FRAME = 3;
&nbsp;
&nbsp; /** Mouse-transparent overlay pane that hosts all particle nodes. */
&nbsp; private final Pane pane;
&nbsp; /** The scene whose dimensions are used to position and fade particles. */
&nbsp; private final Scene scene;
&nbsp; /** Currently live particles. */
<b class="nc">&nbsp; private final List&lt;Particle&gt; particles = new ArrayList&lt;&gt;();</b>
&nbsp; /** Shared random source for particle initialization and physics noise. */
<b class="nc">&nbsp; private final Random rnd = new Random();</b>
&nbsp; private AnimationTimer timer;
&nbsp; /** Timestamp (ns) of the last particle spawn batch. */
<b class="nc">&nbsp; private long lastSpawn = 0;</b>
&nbsp; /** Timestamp (ns) of the last rendered frame. */
<b class="nc">&nbsp; private long lastFrame = 0;</b>
&nbsp; /** {@code true} after the first tick pre-populates the particle pool. */
<b class="nc">&nbsp; private boolean warmedUp = false;</b>
&nbsp;
&nbsp; /**
&nbsp; * Creates the particle system bound to the given scene.
&nbsp; * The internal overlay pane is transparent and mouse-transparent.
&nbsp; *
&nbsp; * @param scene the scene whose dimensions are used for particle positioning and fading.
&nbsp; */
<b class="nc">&nbsp; public FireParticleSystem(Scene scene) {</b>
<b class="nc">&nbsp; this.scene = scene;</b>
<b class="nc">&nbsp; pane = new Pane();</b>
@@ -193,12 +220,16 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; pane.setPickOnBounds(false);</b>
&nbsp; }
&nbsp;
&nbsp; /** Returns the transparent overlay pane that holds all particle nodes. */
&nbsp; /**
&nbsp; * Returns the transparent overlay pane that holds all particle nodes.
&nbsp; *
&nbsp; * @return the mouse-transparent {@link Pane} overlay.
&nbsp; */
<b class="nc">&nbsp; public Pane getPane() { return pane; }</b>
&nbsp;
&nbsp; /** Starts the animation timer. */
&nbsp; public void start() {
<b class="nc">&nbsp; timer = new AnimationTimer() {</b>
<b class="nc">&nbsp; AnimationTimer timer = new AnimationTimer() {</b>
&nbsp; @Override
&nbsp; public void handle(long now) {
<b class="nc">&nbsp; if (now - lastFrame &lt; FRAME_INTERVAL_NS) return;</b>
@@ -209,11 +240,12 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; timer.start();</b>
&nbsp; }
&nbsp;
&nbsp; /** Stops the animation timer. */
&nbsp; public void stop() {
<b class="nc">&nbsp; if (timer != null) timer.stop();</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Advances the simulation by one frame: pre-warms on first call, spawns new particles,
&nbsp; * steps existing ones, removes dead ones, and updates their visual state.
&nbsp; *
&nbsp; * @param now the current timestamp in nanoseconds from the animation timer.
&nbsp; */
&nbsp; private void tick(long now) {
<b class="nc">&nbsp; double w = scene.getWidth();</b>
<b class="nc">&nbsp; double h = scene.getHeight();</b>
@@ -256,6 +288,13 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Creates a new particle starting near one of the four screen corners.
&nbsp; *
&nbsp; * @param w scene width in pixels.
&nbsp; * @param h scene height in pixels.
&nbsp; * @return the newly constructed {@link Particle}.
&nbsp; */
&nbsp; private Particle spawnParticle(double w, double h) {
<b class="nc">&nbsp; int corner = rnd.nextInt(4);</b>
<b class="nc">&nbsp; double margin = 0.12;</b>
@@ -269,20 +308,52 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return new Particle(x, y, w, h, corner, rnd);</b>
&nbsp; }
&nbsp;
&nbsp; // ── Particle ──────────────────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * A single fire particle with position, velocity, wobble, and JavaFX visual nodes.
&nbsp; * Particles are typed: 0 = ember, 1 = spark, 2 = dust.
&nbsp; */
&nbsp; private static class Particle {
&nbsp;
&nbsp; double x, y, vx, vy;
&nbsp; /** Current X position in scene pixels. */
&nbsp; double x;
&nbsp; /** Current Y position in scene pixels. */
&nbsp; double y;
&nbsp; /** Horizontal velocity component. */
&nbsp; double vx;
&nbsp; /** Vertical velocity component. */
&nbsp; double vy;
&nbsp; /** Remaining life fraction (1.0 = full, 0.0 = dead); only decrements for sparks. */
&nbsp; double life;
&nbsp; double size;
&nbsp; double wobblePhase, wobbleSpeed, wobbleAmp;
&nbsp; /** Visual radius of the particle&#39;s core circle. */
&nbsp; final double size;
&nbsp; /** Current phase of the sinusoidal wobble. */
&nbsp; double wobblePhase;
&nbsp; /** Angular speed of the wobble oscillation. */
&nbsp; final double wobbleSpeed;
&nbsp; /** Amplitude factor of the wobble displacement. */
&nbsp; final double wobbleAmp;
&nbsp; /** Particle type: 0 = ember, 1 = spark, 2 = dust. */
&nbsp; final int type;
&nbsp; /** Shared random source used during physics updates. */
&nbsp; final Random rnd;
&nbsp;
&nbsp; /** Primary visible circle node. */
&nbsp; final Circle core;
&nbsp; final Circle glow; // non-null only for embers
&nbsp; /** Soft glow halo circle behind {@link #core}; non-null only for embers (type 0). */
&nbsp; final Circle glow;
&nbsp;
&nbsp; /**
&nbsp; * Initializes the particle at position ({@code x}, {@code y}) with velocity
&nbsp; * aimed roughly from the given {@code corner} toward the scene center.
&nbsp; *
&nbsp; * @param x spawn X coordinate.
&nbsp; * @param y spawn Y coordinate.
&nbsp; * @param w scene width (used to compute target direction).
&nbsp; * @param h scene height (used to compute target direction).
&nbsp; * @param corner spawn corner index: 0 = bottom-left, 1 = bottom-right, 2 = top-left, 3 = top-right.
&nbsp; * @param rnd shared random source.
&nbsp; */
<b class="nc">&nbsp; Particle(double x, double y, double w, double h, int corner, Random rnd) {</b>
<b class="nc">&nbsp; this.x = x;</b>
<b class="nc">&nbsp; this.y = y;</b>
@@ -296,17 +367,17 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; double angle = baseAngle + (rnd.nextDouble() - 0.5) * (Math.PI / 3.5);</b>
&nbsp;
&nbsp; double speed;
<b class="nc">&nbsp; if (type == 0) { // ember</b>
<b class="nc">&nbsp; if (type == 0) {</b>
<b class="nc">&nbsp; speed = 0.5 + rnd.nextDouble() * 0.7;</b>
<b class="nc">&nbsp; size = rnd.nextDouble() * 3 + 2;</b>
<b class="nc">&nbsp; glow = new Circle(size * 2.2);</b>
<b class="nc">&nbsp; core = new Circle(size / 2);</b>
<b class="nc">&nbsp; } else if (type == 1) { // spark</b>
<b class="nc">&nbsp; } else if (type == 1) {</b>
<b class="nc">&nbsp; speed = 1.5 + rnd.nextDouble() * 2.0;</b>
<b class="nc">&nbsp; size = rnd.nextDouble() * 1.5 + 0.5;</b>
<b class="nc">&nbsp; glow = null;</b>
<b class="nc">&nbsp; core = new Circle(size / 2);</b>
&nbsp; } else { // dust
&nbsp; } else {
<b class="nc">&nbsp; speed = 0.2 + rnd.nextDouble() * 0.35;</b>
<b class="nc">&nbsp; size = rnd.nextDouble() * 8 + 5;</b>
<b class="nc">&nbsp; glow = null;</b>
@@ -321,6 +392,12 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; wobbleAmp = 0.1 + rnd.nextDouble() * 0.4;</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Returns a particle type weighted toward embers (55% ember, 23% spark, 22% dust).
&nbsp; *
&nbsp; * @param rnd the random source.
&nbsp; * @return particle type: 0, 1, or 2.
&nbsp; */
&nbsp; private static int weightedType(Random rnd) {
<b class="nc">&nbsp; double r = rnd.nextDouble();</b>
<b class="nc">&nbsp; if (r &lt; 0.55) return 0;</b>
@@ -328,16 +405,27 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return 2;</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Adds this particle&#39;s visual nodes to {@code pane} (glow first so core renders on top).
&nbsp; *
&nbsp; * @param pane the overlay pane to add nodes to.
&nbsp; */
&nbsp; void addTo(Pane pane) {
<b class="nc">&nbsp; if (glow != null) pane.getChildren().add(glow);</b>
<b class="nc">&nbsp; pane.getChildren().add(core);</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Removes this particle&#39;s visual nodes from {@code pane}.
&nbsp; *
&nbsp; * @param pane the overlay pane to remove nodes from.
&nbsp; */
&nbsp; void removeFrom(Pane pane) {
<b class="nc">&nbsp; pane.getChildren().remove(core);</b>
<b class="nc">&nbsp; if (glow != null) pane.getChildren().remove(glow);</b>
&nbsp; }
&nbsp;
&nbsp; /** Advances this particle by one physics step: applies wobble, moves, and decrements spark life. */
&nbsp; void update() {
<b class="nc">&nbsp; wobblePhase += wobbleSpeed;</b>
<b class="nc">&nbsp; vx += Math.sin(wobblePhase) * wobbleAmp * 0.05;</b>
@@ -347,12 +435,26 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; if (type == 1) life -= 0.008 + rnd.nextDouble() * 0.006;</b>
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Returns {@code true} when this particle has left the scene bounds or, for sparks, its life reached zero.
&nbsp; *
&nbsp; * @param w scene width.
&nbsp; * @param h scene height.
&nbsp; * @return {@code true} if the particle should be removed.
&nbsp; */
&nbsp; boolean isDead(double w, double h) {
<b class="nc">&nbsp; double pad = size * 4;</b>
<b class="nc">&nbsp; return x &lt; -pad || x &gt; w + pad || y &lt; -pad || y &gt; h + pad</b>
&nbsp; || (type == 1 &amp;&amp; life &lt;= 0);
&nbsp; }
&nbsp;
&nbsp; /**
&nbsp; * Updates color, opacity, and translate position of this particle&#39;s visual nodes
&nbsp; * based on distance from scene edges and remaining life.
&nbsp; *
&nbsp; * @param w scene width.
&nbsp; * @param h scene height.
&nbsp; */
&nbsp; void updateVisual(double w, double h) {
<b class="nc">&nbsp; double edge = Math.min(w, h) * 0.05;</b>
<b class="nc">&nbsp; double fadeX = Math.min(x / edge, Math.min((w - x) / edge, 1.0));</b>
@@ -407,7 +509,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/116)
(0/110)
</span>
</td>
</tr>
@@ -104,8 +104,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import javafx.scene.input.KeyEvent;
&nbsp;import javafx.scene.input.KeyCombination;
&nbsp;import javafx.scene.layout.StackPane;
&nbsp;import javafx.scene.media.Media;
&nbsp;import javafx.scene.media.MediaPlayer;
&nbsp;
&nbsp;import javafx.scene.paint.Color;
&nbsp;import javafx.scene.shape.Rectangle;
&nbsp;import javafx.stage.Screen;
@@ -122,49 +121,45 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * main game, and leaderboard scenes based on the current game state.
&nbsp; */
<b class="nc">&nbsp;public class GUI extends Application implements IView {</b>
&nbsp; //TODO
&nbsp; /** The primary JavaFX stage. */
&nbsp; private Stage primaryStage;
&nbsp; //TODO
&nbsp; /** Latest mini model received from the server. */
&nbsp; private volatile MiniModel miniModel;
&nbsp; //TODO
&nbsp; /** FXML loader for the login scene. */
&nbsp; private FXMLLoader loaderLogin;
&nbsp; //TODO
&nbsp; /** The login scene. */
&nbsp; private Scene loginScene;
&nbsp; //TODO
&nbsp; /** Controller for the login FXML scene. */
&nbsp; private LoginFXMLController controllerLogin;
&nbsp; //TODO
&nbsp; /** FXML loader for the totem selection scene. */
&nbsp; private FXMLLoader loaderTotem;
&nbsp; //TODO
&nbsp; /** The totem selection scene. */
&nbsp; private Scene totemScene;
&nbsp; //TODO
&nbsp; /** Controller for the totem FXML scene. */
&nbsp; private TotemFXMLController controllerTotem;
&nbsp; //TODO
&nbsp; /** FXML loader for the main game scene. */
&nbsp; private FXMLLoader loaderMain;
&nbsp;
&nbsp; //TODO
&nbsp; /** The main game scene. */
&nbsp; private Scene mainScene;
&nbsp; //TODO
&nbsp; /** Controller for the main FXML scene. */
&nbsp; private MainFXMLController controllerMain;
&nbsp; //TODO
&nbsp; /** FXML loader for the leaderboard scene. */
&nbsp; private FXMLLoader loaderLeaderboard;
&nbsp; //TODO
&nbsp; /** The end-of-game leaderboard scene. */
&nbsp; private Scene leaderboardScene;
&nbsp; //TODO
&nbsp; /** Controller for the leaderboard FXML scene. */
&nbsp; private LeaderboardFXMLController controllerLeaderboard;
&nbsp;
&nbsp; //TODO
&nbsp; /** Client controller injected before JavaFX startup. */
&nbsp; private ClientController controller;
&nbsp; //TODO
&nbsp; /** When {@code true}, the app re-enters fullscreen automatically after ESC is pressed. */
<b class="nc">&nbsp; private boolean autoReenterFullscreen = true;</b>
&nbsp; //TODO
&nbsp; /** Guards against overlapping fade transitions. */
<b class="nc">&nbsp; private boolean isFading = false;</b>
&nbsp; //TODO
&nbsp; private MediaPlayer bgMusic;
&nbsp;
&nbsp;
&nbsp; /**
&nbsp; * JavaFX entry point: loads all FXML scenes, wires up controllers,
&nbsp; * configures fullscreen behaviour, and shows the login scene.
&nbsp; * configures fullscreen behavior, and shows the login scene.
&nbsp; *
&nbsp; * @param stage the primary stage provided by the JavaFX runtime.
&nbsp; * @throws Exception if any FXML resource cannot be loaded.
@@ -196,7 +191,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; controllerLogin.updateLoginButton(true);</b>
<b class="nc">&nbsp; controllerLogin.showError(&quot;&quot;);</b>
<b class="nc">&nbsp; fadeToScene(loginScene);</b>
&nbsp; }, loginScene);
&nbsp; });
&nbsp;
&nbsp;
&nbsp;
@@ -247,15 +242,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; primaryStage.show();</b>
<b class="nc">&nbsp; Platform.runLater(() -&gt; primaryStage.setFullScreen(true));</b>
&nbsp;
&nbsp; try {
<b class="nc">&nbsp; String musicUrl = getClass().getResource(&quot;/Audio/Music.mp3&quot;).toExternalForm();</b>
<b class="nc">&nbsp; bgMusic = new MediaPlayer(new Media(musicUrl));</b>
<b class="nc">&nbsp; bgMusic.setCycleCount(MediaPlayer.INDEFINITE);</b>
<b class="nc">&nbsp; bgMusic.setVolume(0.4);</b>
<b class="nc">&nbsp; bgMusic.play();</b>
&nbsp; } catch (Exception e) {
<b class="nc">&nbsp; System.err.println(&quot;Audio unavailable: &quot; + e.getMessage());</b>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp;
@@ -297,12 +283,22 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; }
&nbsp; });
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Wraps the current root of {@code scene} in a {@link StackPane} so that
&nbsp; * fade overlay rectangles can be layered over it during scene transitions.
&nbsp; *
&nbsp; * @param scene the scene whose root to wrap.
&nbsp; */
&nbsp; private void wrapScene(Scene scene) {
<b class="nc">&nbsp; Parent root = scene.getRoot();</b>
<b class="nc">&nbsp; scene.setRoot(new StackPane(root));</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Performs a black-overlay crossfade from the current scene to {@code newScene}.
&nbsp; * No-op if already fading or if {@code newScene} is already displayed.
&nbsp; *
&nbsp; * @param newScene the scene to transition to.
&nbsp; */
&nbsp; private void fadeToScene(Scene newScene) {
<b class="nc">&nbsp; Scene currentScene = primaryStage.getScene();</b>
<b class="nc">&nbsp; if (currentScene == newScene || isFading) return;</b>
@@ -348,7 +344,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Displays an error on the JavaFX application thread.
&nbsp; *
&nbsp; * &lt;p&gt;If the server crashed, returns to the login scene and re-enables the login button.
&nbsp; * Otherwise delegates to the active scene&#39;s error display.
&nbsp; * Otherwise, delegates to the active scene&#39;s error display.
&nbsp; *
&nbsp; * @param error the error type.
&nbsp; * @param message a human-readable description of the error.
@@ -392,7 +388,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/182)
(0/181)
</span>
</td>
</tr>
@@ -95,7 +95,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import it.polimi.ingsw.gc14.Model.PlayableCard;
&nbsp;import javafx.event.Event;
&nbsp;import javafx.fxml.FXML;
&nbsp;import javafx.scene.Scene;
&nbsp;import javafx.scene.control.ScrollPane;
&nbsp;import javafx.stage.Popup;
&nbsp;import javafx.geometry.Insets;
@@ -113,7 +112,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import javafx.scene.paint.Stop;
&nbsp;import javafx.scene.paint.CycleMethod;
&nbsp;import javafx.scene.text.Font;
&nbsp;import javafx.stage.Stage;
&nbsp;import javafx.stage.Window;
&nbsp;import javafx.util.Duration;
&nbsp;
@@ -125,29 +123,28 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * &lt;p&gt;Displays the final player rankings and a winner/game-over banner.
&nbsp; */
<b class="nc">&nbsp;public class LeaderboardFXMLController {</b>
&nbsp;
&nbsp; /** Root pane of the leaderboard scene; used to set the background and anchor the popup. */
&nbsp; @FXML private StackPane rootPane;
&nbsp; /** Main vertical container holding the outcome label and ranking rows. */
&nbsp; @FXML private VBox mainVBox;
&nbsp; /** Vertical list populated with one {@code HBox} row per ranked player. */
&nbsp; @FXML private VBox rankingList;
&nbsp; // title label removed; outcome text is added dynamically in render()
&nbsp; //TODO
&nbsp; private ClientController controller;
&nbsp; //TODO
&nbsp; private Popup popup;
&nbsp; //TODO
&nbsp; private VBox popupContent;
&nbsp; //TODO
<b class="nc">&nbsp; private static final Map&lt;String, Image&gt; imageCache = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; private Scene loginScene;
&nbsp;
&nbsp; //TODO
&nbsp; /** Client controller for fetching game state and sending actions. */
&nbsp; private ClientController controller;
&nbsp; /** Auto-hiding popup that shows detailed player card information. */
&nbsp; private Popup popup;
&nbsp; /** Content container inside {@link #popup}. */
&nbsp; private VBox popupContent;
&nbsp; /** Shared image cache to avoid reloading resources multiple times. */
<b class="nc">&nbsp; private static final Map&lt;String, Image&gt; imageCache = new HashMap&lt;&gt;();</b>
&nbsp; /** Action run when the player returns to the login screen (disconnect + scene switch). */
&nbsp; private Runnable action;
&nbsp;
&nbsp; /** Returns a cached {@link Image} for the given classpath {@code path}, loading it on first access. */
&nbsp; private Image loadImage(String path) {
<b class="nc">&nbsp; return imageCache.computeIfAbsent(path,</b>
<b class="nc">&nbsp; p -&gt; new Image(getClass().getResourceAsStream(p)));</b>
<b class="nc">&nbsp; p -&gt; new Image(Objects.requireNonNull(getClass().getResourceAsStream(p))));</b>
&nbsp; }
&nbsp;
&nbsp;
@@ -156,11 +153,9 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; *
&nbsp; * @param controller the client controller.
&nbsp; * @param action the action to run when the player returns to the login screen.
&nbsp; * @param loginScene the login scene to show on exit.
&nbsp; */
&nbsp; public void setController(ClientController controller, Runnable action, Scene loginScene) {
&nbsp; public void setController(ClientController controller, Runnable action) {
<b class="nc">&nbsp; this.controller = controller;</b>
<b class="nc">&nbsp; this.loginScene = loginScene;</b>
<b class="nc">&nbsp; this.action = action;</b>
&nbsp; }
&nbsp;
@@ -492,7 +487,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -91,6 +91,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp;import it.polimi.ingsw.gc14.Controller.ClientController;
&nbsp;import it.polimi.ingsw.gc14.ErrorType;
&nbsp;import it.polimi.ingsw.gc14.Network.IClient;
&nbsp;import it.polimi.ingsw.gc14.Network.NetworkConfig;
&nbsp;import it.polimi.ingsw.gc14.Network.InterfaceResolver;
&nbsp;import it.polimi.ingsw.gc14.Network.RMI.Client.RMIClient;
@@ -108,8 +109,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import javafx.stage.Screen;
&nbsp;import javafx.util.Duration;
&nbsp;
&nbsp;import java.net.*;
&nbsp;import java.util.Enumeration;
&nbsp;import java.util.Objects;
&nbsp;
&nbsp;/**
&nbsp; * FXML controller for the login scene.
@@ -118,33 +118,33 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * and initiates the connection to the server.
&nbsp; */
<b class="nc">&nbsp;public class LoginFXMLController {</b>
&nbsp; //TODO
&nbsp; /** Background image displayed behind the login form. */
&nbsp; @FXML private ImageView backgroundImage;
&nbsp; //TODO
&nbsp; /** Text field for the player&#39;s username. */
&nbsp; @FXML private TextField campoNome;
&nbsp; //TODO
&nbsp; /** Text field for the desired number of players. */
&nbsp; @FXML private TextField campoNumPlayers;
&nbsp; //TODO
&nbsp; /** Text field for the server IP address. */
&nbsp; @FXML private TextField campoIP;
&nbsp; //TODO
&nbsp; /** Button that submits the login form. */
&nbsp; @FXML private Button btnAccedi;
&nbsp; //TODO
&nbsp; /** Label used to show error or success messages. */
&nbsp; @FXML private Label labelErrore;
&nbsp; //TODO
&nbsp; /** VBox containing the login form controls. */
&nbsp; @FXML private VBox formPanel;
&nbsp; //TODO
&nbsp; /** Toggle container for switching between RMI and TCP. */
&nbsp; @FXML private StackPane protocolToggle;
&nbsp; //TODO
&nbsp; /** Sliding thumb inside the protocol toggle. */
&nbsp; @FXML private Region toggleThumb;
&nbsp; //TODO
&nbsp; /** Label for the RMI side of the protocol toggle. */
&nbsp; @FXML private Label labelRMI;
&nbsp; //TODO
&nbsp; /** Label for the TCP side of the protocol toggle. */
&nbsp; @FXML private Label labelTCP;
&nbsp; //TODO
&nbsp; /** {@code true} when RMI is selected; {@code false} for TCP. */
<b class="nc">&nbsp; private boolean isRMI = true;</b>
&nbsp; //TODO
&nbsp; /** Client controller used to initiate the connection. */
&nbsp; private ClientController controller;
&nbsp; //TODO
&nbsp; /** CSS pseudo-class applied to the active protocol label. */
<b class="nc">&nbsp; private final PseudoClass activeProtocolPseudo = PseudoClass.getPseudoClass(&quot;active-protocol&quot;);</b>
&nbsp;
&nbsp; /**
@@ -160,7 +160,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; @FXML
&nbsp; public void initialize() {
&nbsp; // Background setup
<b class="nc">&nbsp; Image img = new Image(getClass().getResourceAsStream(&quot;/GUIImages/BackgroundLogin.png&quot;));</b>
<b class="nc">&nbsp; Image img = new Image(Objects.requireNonNull(getClass().getResourceAsStream(&quot;/GUIImages/BackgroundLogin.png&quot;)));</b>
<b class="nc">&nbsp; backgroundImage.setImage(img);</b>
<b class="nc">&nbsp; Rectangle2D screenBounds = Screen.getPrimary().getBounds();</b>
<b class="nc">&nbsp; backgroundImage.setFitWidth(screenBounds.getWidth());</b>
@@ -185,7 +185,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; tt.setToX(isRMI ? 0 : 110);</b>
<b class="nc">&nbsp; tt.play();</b>
&nbsp;
&nbsp; // pseudoClassStateChanged preserves layout properties unlike direct style mutation
<b class="nc">&nbsp; labelRMI.pseudoClassStateChanged(activeProtocolPseudo, isRMI);</b>
<b class="nc">&nbsp; labelTCP.pseudoClassStateChanged(activeProtocolPseudo, !isRMI);</b>
&nbsp; }
@@ -248,8 +247,9 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp; /** Connects to the server using the selected protocol and transitions to the waiting state on success. */
&nbsp; private void connect(String nome, String ip, int numPlayers, String localInterface) {
&nbsp; IClient client;
<b class="nc">&nbsp; if (isRMI) {</b>
<b class="nc">&nbsp; RMIClient client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, localInterface);</b>
<b class="nc">&nbsp; client = new RMIClient(controller, ip, NetworkConfig.RMI_PORT, localInterface);</b>
<b class="nc">&nbsp; ErrorType serverResponse = client.connect(nome, numPlayers);</b>
<b class="nc">&nbsp; if (serverResponse == null) {</b>
<b class="nc">&nbsp; controller.setClient(client);</b>
@@ -261,7 +261,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; });
&nbsp; }
&nbsp; } else {
<b class="nc">&nbsp; TCPClient client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);</b>
<b class="nc">&nbsp; client = new TCPClient(controller, ip, NetworkConfig.TCP_PORT, NetworkConfig.HEARTBEAT_PORT);</b>
<b class="nc">&nbsp; ErrorType serverResponse = client.connect(nome, numPlayers);</b>
<b class="nc">&nbsp; if (serverResponse == null) {</b>
<b class="nc">&nbsp; controller.setClient(client);</b>
@@ -323,7 +323,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -59,7 +59,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/50)
(0/53)
</span>
</td>
<td class="coverageStat">
@@ -67,7 +67,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/124)
(0/137)
</span>
</td>
<td class="coverageStat">
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/426)
(0/448)
</span>
</td>
</tr>
@@ -95,21 +95,16 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import it.polimi.ingsw.gc14.Model.Cards.TribeCard;
&nbsp;import it.polimi.ingsw.gc14.Model.Orders.OrderPlayer;
&nbsp;import it.polimi.ingsw.gc14.Network.EventType;
&nbsp;import it.polimi.ingsw.gc14.Network.NetworkEvent;
&nbsp;import javafx.application.Platform;
&nbsp;import javafx.animation.PauseTransition;
&nbsp;import javafx.animation.ScaleTransition;
&nbsp;import javafx.animation.TranslateTransition;
&nbsp;import javafx.application.Platform;
&nbsp;import javafx.beans.value.ChangeListener;
&nbsp;import javafx.beans.value.ObservableValue;
&nbsp;import javafx.event.Event;
&nbsp;import javafx.fxml.FXML;
&nbsp;import javafx.geometry.Bounds;
&nbsp;import javafx.geometry.Insets;
&nbsp;import javafx.geometry.Pos;
&nbsp;import javafx.geometry.Rectangle2D;
&nbsp;import javafx.scene.Cursor;
&nbsp;import javafx.scene.Node;
&nbsp;import javafx.scene.Scene;
&nbsp;import javafx.scene.control.Button;
&nbsp;import javafx.scene.control.Label;
&nbsp;import javafx.scene.control.ScrollPane;
@@ -122,7 +117,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import javafx.scene.shape.*;
&nbsp;import javafx.scene.text.Font;
&nbsp;import javafx.stage.Popup;
&nbsp;import javafx.stage.Screen;
&nbsp;import javafx.stage.Window;
&nbsp;import javafx.util.Duration;
&nbsp;
@@ -135,47 +129,49 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * the player&#39;s hand, and action buttons (skip, details).
&nbsp; */
<b class="nc">&nbsp;public class MainFXMLController {</b>
&nbsp; //TODO
&nbsp; @FXML private GridPane leftGrid;
&nbsp; //TODO
&nbsp; /** Scrollable container holding all player side-panel cards. */
&nbsp; @FXML private ScrollPane playerSide;
&nbsp; //TODO
&nbsp; /** Root HBox containing all main scene elements. */
&nbsp; @FXML private HBox mainHBox;
&nbsp; //TODO
&nbsp; @FXML private ImageView backgroundImage;
&nbsp; //TODO
&nbsp; /** HBox holding the board slot and order cards. */
&nbsp; @FXML private HBox board;
&nbsp; //TODO
&nbsp; /** HBox holding the upper tribe card row (and upper building stack). */
&nbsp; @FXML private HBox upperList;
&nbsp; //TODO
&nbsp; /** HBox holding the lower tribe card row (and lower building stack). */
&nbsp; @FXML private HBox lowerList;
&nbsp; //TODO
&nbsp; /** HBox displaying the local player&#39;s card piles. */
&nbsp; @FXML private HBox myHand;
&nbsp; //TODO
&nbsp; /** Button that sends a skip-turn command. */
&nbsp; @FXML private Button skipBtn;
&nbsp; //TODO
&nbsp; /** Button that opens the game details popup. */
&nbsp; @FXML private Button detailsBtn;
&nbsp; //TODO
&nbsp; /** Button that disconnects and closes the client. */
&nbsp; @FXML private Button quitBtn;
&nbsp; /** Label showing the current round number and game stage. */
&nbsp; @FXML private Label infoText;
&nbsp; //TODO
&nbsp; /** Maps each player&#39;s username to their current food-value label in the side panel. */
<b class="nc">&nbsp; private final Map&lt;String, Label&gt; foodLabels = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; /** Maps each player&#39;s username to their current prestige-value label in the side panel. */
<b class="nc">&nbsp; private final Map&lt;String, Label&gt; prestigeLabels = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; /** Maps each player&#39;s username to their player-card VBox in the side panel. */
<b class="nc">&nbsp; private final Map&lt;String, VBox&gt; playerCards = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; /** Maps each player&#39;s username to their ordered list of card-type icon ImageViews. */
<b class="nc">&nbsp; private final Map&lt;String, List&lt;ImageView&gt;&gt; iconViews = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; /** Shared popup used for card previews and building selection. */
&nbsp; private Popup popup;
&nbsp; //TODO
&nbsp; /** HBox inside {@link #popup} that holds the displayed card images. */
&nbsp; private HBox popupCards;
&nbsp; //TODO
&nbsp; /** Client controller for fetching game state and sending player actions. */
&nbsp; private ClientController controller;
&nbsp;
&nbsp; /** {@code true} when the last received event was an error response. */
&nbsp; private boolean isError;
&nbsp;
&nbsp; /** Sets the error flag; called by {@link GUI} before delegating to {@link #render()}. */
&nbsp; /**
&nbsp; * Sets the error flag; called by {@link GUI} before delegating to {@link #render()}.
&nbsp; *
&nbsp; * @param error {@code true} if the last received event was an error response.
&nbsp; */
<b class="nc">&nbsp; public void setError(boolean error) { this.isError = error; }</b>
&nbsp;
&nbsp; // ==== IMAGE CACHE ====
@@ -184,7 +180,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /** Returns a cached {@link Image} for the given classpath {@code path}, loading it on first access. */
&nbsp; private Image loadImage(String path) {
<b class="nc">&nbsp; return imageCache.computeIfAbsent(path,</b>
<b class="nc">&nbsp; p -&gt; new Image(getClass().getResourceAsStream(p)));</b>
<b class="nc">&nbsp; p -&gt; new Image(Objects.requireNonNull(getClass().getResourceAsStream(p))));</b>
&nbsp; }
&nbsp;
&nbsp; /**
@@ -195,6 +191,30 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; public void setController(ClientController controller) {
<b class="nc">&nbsp; this.controller = controller;</b>
<b class="nc">&nbsp; skipBtn.setOnAction(e -&gt; controller.skipTurn());</b>
&nbsp;
<b class="nc">&nbsp; PauseTransition quitTimer = new PauseTransition(javafx.util.Duration.seconds(3));</b>
<b class="nc">&nbsp; quitTimer.setOnFinished(e -&gt; {</b>
<b class="nc">&nbsp; quitBtn.setText(&quot;Quit&quot;);</b>
<b class="nc">&nbsp; quitBtn.setStyle(&quot;&quot;);</b>
&nbsp; });
<b class="nc">&nbsp; final boolean[] quitPending = {false};</b>
<b class="nc">&nbsp; quitBtn.setOnAction(e -&gt; {</b>
<b class="nc">&nbsp; if (quitPending[0]) {</b>
<b class="nc">&nbsp; controller.disconnect();</b>
<b class="nc">&nbsp; Platform.exit();</b>
<b class="nc">&nbsp; System.exit(0);</b>
&nbsp; } else {
<b class="nc">&nbsp; quitPending[0] = true;</b>
<b class="nc">&nbsp; quitBtn.setText(&quot;Sure?&quot;);</b>
<b class="nc">&nbsp; quitBtn.setStyle(&quot;-fx-background-color: #c0392b; -fx-text-fill: white;&quot;);</b>
<b class="nc">&nbsp; quitTimer.playFromStart();</b>
<b class="nc">&nbsp; quitTimer.setOnFinished(ev -&gt; {</b>
<b class="nc">&nbsp; quitPending[0] = false;</b>
<b class="nc">&nbsp; quitBtn.setText(&quot;Quit&quot;);</b>
<b class="nc">&nbsp; quitBtn.setStyle(&quot;&quot;);</b>
&nbsp; });
&nbsp; }
&nbsp; });
&nbsp; }
&nbsp;
&nbsp; /** Initializes the scene: loads fonts, sets up the popup, and registers input listeners. */
@@ -204,6 +224,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
<b class="nc">&nbsp; addHoverZoom(skipBtn);</b>
<b class="nc">&nbsp; addHoverZoom(detailsBtn);</b>
<b class="nc">&nbsp; addHoverZoom(quitBtn);</b>
<b class="nc">&nbsp; popup = new Popup();</b>
<b class="nc">&nbsp; mainHBox.sceneProperty().addListener((obs, oldScene, newScene) -&gt; {</b>
<b class="nc">&nbsp; if (newScene != null) {</b>
@@ -234,7 +255,9 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /** Incrementally re-renders only the parts of the scene affected by the last network event. */
&nbsp; public void render() {
<b class="nc">&nbsp; if(foodLabels.isEmpty() || controller.getMiniModel().lastEvent == null</b>
<b class="nc">&nbsp; || controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE))</b>
<b class="nc">&nbsp; || controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE)</b>
<b class="nc">&nbsp; || controller.getMiniModel().lastEvent.getEventType().equals(EventType.RECONNECT_PLAYER)</b>
<b class="nc">&nbsp; || controller.getMiniModel().lastEvent.getEventType().equals(EventType.DISCONNECTED_PLAYER))</b>
<b class="nc">&nbsp; buildSidePanel();</b>
<b class="nc">&nbsp; if(isError)</b>
&nbsp; {
@@ -242,7 +265,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; isError=false;</b>
&nbsp; return;
&nbsp; }
<b class="nc">&nbsp; if(controller.getMiniModel().lastEvent==null ||controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.NEXT_ROUND)) {</b>
<b class="nc">&nbsp; if(controller.getMiniModel().lastEvent==null ||controller.getMiniModel().lastEvent.getEventType().equals(EventType.TOTEM_CHOICE) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.NEXT_ROUND) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.RECONNECT_PLAYER) || controller.getMiniModel().lastEvent.getEventType().equals(EventType.DISCONNECTED_PLAYER)) {</b>
<b class="nc">&nbsp; renderMyHand();</b>
<b class="nc">&nbsp; renderUpper();</b>
<b class="nc">&nbsp; renderBoard();</b>
@@ -478,7 +501,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; // ==== GROUPS ====
&nbsp; /** Builds the full side panel from scratch, creating a player card for each connected player. */
&nbsp; private void buildSidePanel() {
<b class="nc">&nbsp; infoText.setText(&quot;Round: &quot;+Integer.toString(controller.getMiniModel().currentState.getRound()) + &quot;&quot; + controller.getMiniModel().currentState.getGameStage().toString());</b>
<b class="nc">&nbsp; infoText.setText(&quot;Round: &quot;+ controller.getMiniModel().currentState.getRound() + &quot;&quot; + controller.getMiniModel().currentState.getGameStage().toString());</b>
<b class="nc">&nbsp; VBox playerList = new VBox();</b>
<b class="nc">&nbsp; playerList.setFillWidth(true);</b>
<b class="nc">&nbsp; for (Player p : controller.getMiniModel().players.values()) {</b>
@@ -491,10 +514,9 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp; /** Updates food/prestige labels, current-player highlight, card-icon opacity, and plays error shake if needed. */
&nbsp; private void updateSidePanel() {
<b class="nc">&nbsp; infoText.setText(&quot;Round: &quot;+Integer.toString(controller.getMiniModel().currentState.getRound()) + &quot;&quot; + controller.getMiniModel().currentState.getGameStage().toString());</b>
<b class="nc">&nbsp; infoText.setText(&quot;Round: &quot;+ controller.getMiniModel().currentState.getRound() + &quot;&quot; + controller.getMiniModel().currentState.getGameStage().toString());</b>
<b class="nc">&nbsp; if (controller.getMiniModel().currentState.getCurrentPlayer() == null) return;</b>
<b class="nc">&nbsp; String current = controller.getMiniModel().currentState.getCurrentPlayer().getUserName();</b>
&nbsp; // ordine: building, artists, gatherers, inventors, builders, shamans, hunters
<b class="nc">&nbsp; String[] fields = {&quot;building&quot;, &quot;artists&quot;, &quot;gatherers&quot;, &quot;inventors&quot;, &quot;builders&quot;, &quot;shamans&quot;, &quot;hunters&quot;};</b>
&nbsp;
<b class="nc">&nbsp; for (Player p : controller.getMiniModel().players.values()) {</b>
@@ -625,8 +647,13 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; int i = 0;</b>
<b class="nc">&nbsp; for (TribeCard card : controller.getMiniModel().upperListTribeCards) {</b>
<b class="nc">&nbsp; final int index = i;</b>
<b class="nc">&nbsp; StackPane img = createCard(card, true, true, upperList);</b>
<b class="nc">&nbsp; img.setOnMouseClicked(e -&gt; controller.drawUpperTribeCard(index));</b>
&nbsp; StackPane img;
<b class="nc">&nbsp; if(!card.isEventCard()) {</b>
<b class="nc">&nbsp; img = createCard(card, true, true, upperList);</b>
<b class="nc">&nbsp; img.setOnMouseClicked(e -&gt; controller.drawUpperTribeCard(index));</b>
&nbsp; } else {
<b class="nc">&nbsp; img = createCard(card, false, false, upperList);</b>
&nbsp; }
<b class="nc">&nbsp; upperList.getChildren().add(img);</b>
<b class="nc">&nbsp; i++;</b>
&nbsp; }
@@ -642,8 +669,13 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; int i = 0;</b>
<b class="nc">&nbsp; for (TribeCard card : controller.getMiniModel().lowerListTribeCards) {</b>
<b class="nc">&nbsp; final int index = i;</b>
<b class="nc">&nbsp; StackPane img = createCard(card, true, true, lowerList);</b>
<b class="nc">&nbsp; img.setOnMouseClicked(e -&gt; controller.drawLowerTribeCard(index));</b>
&nbsp; StackPane img;
<b class="nc">&nbsp; if(!card.isEventCard()) {</b>
<b class="nc">&nbsp; img = createCard(card, true, true, lowerList);</b>
<b class="nc">&nbsp; img.setOnMouseClicked(e -&gt; controller.drawLowerTribeCard(index));</b>
&nbsp; } else {
<b class="nc">&nbsp; img = createCard(card, false, false, lowerList);</b>
&nbsp; }
<b class="nc">&nbsp; lowerList.getChildren().add(img);</b>
<b class="nc">&nbsp; i++;</b>
&nbsp; }
@@ -678,7 +710,6 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /** Adds the era-specific deck back image to the board. */
&nbsp; private void renderDeck() {
<b class="nc">&nbsp; String path = switch (controller.getMiniModel().currentState.getEra()) {</b>
<b class="nc">&nbsp; case 1 -&gt; &quot;/GUIImages/Backs/back-001.png&quot;;</b>
<b class="nc">&nbsp; case 2 -&gt; &quot;/GUIImages/Backs/back-030.png&quot;;</b>
<b class="nc">&nbsp; case 3 -&gt; &quot;/GUIImages/Backs/back-058.png&quot;;</b>
<b class="nc">&nbsp; default -&gt; &quot;/GUIImages/Backs/back-001.png&quot;;</b>
@@ -687,8 +718,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; back.fitHeightProperty().bind(board.sceneProperty().get().heightProperty().subtract(56).divide(4).multiply(0.94));</b>
<b class="nc">&nbsp; back.setPreserveRatio(true);</b>
<b class="nc">&nbsp; addClip(back);</b>
<b class="nc">&nbsp; addShadow(back);</b>
<b class="nc">&nbsp; addHoverZoom(back);</b>
<b class="nc">&nbsp; board.getChildren().add(back);</b>
&nbsp; }
&nbsp;
@@ -736,7 +765,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; totem.setLayoutX(nv.doubleValue() * 0.364);</b>
&nbsp; });
&nbsp;
&nbsp; // initialize immediately if already laid out
<b class="nc">&nbsp; if (card.getHeight() &gt; 0) totem.setLayoutY(card.getHeight() *(yRatio-0.196));</b>
<b class="nc">&nbsp; if (card.getWidth() &gt; 0) totem.setLayoutX(card.getWidth() * 0.364);</b>
&nbsp;
@@ -896,7 +924,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -105,6 +105,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;import javafx.util.Duration;
&nbsp;
&nbsp;import java.util.Locale;
&nbsp;import java.util.Objects;
&nbsp;
&nbsp;/**
&nbsp; * FXML controller for the totem selection scene.
@@ -113,20 +114,20 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * other players see a waiting banner.
&nbsp; */
<b class="nc">&nbsp;public class TotemFXMLController {</b>
&nbsp; //TODO
&nbsp; /** Background image displayed behind the totem selection grid. */
&nbsp; @FXML private ImageView backgroundImage;
&nbsp; //TODO
&nbsp; /** HBox containing the totem card widgets. */
&nbsp; @FXML private HBox mainHBox;
&nbsp; //TODO
&nbsp; /** Banner label showing whose turn it is to choose a totem. */
&nbsp; @FXML private Label turnBanner;
&nbsp; //TODO
&nbsp; /** Button that submits the selected totem to the server. */
&nbsp; @FXML private Button confirmButton;
&nbsp;
&nbsp; //TODO
&nbsp; /** Client controller for sending the totem choice. */
&nbsp; private ClientController controller;
&nbsp; //TODO
&nbsp; /** Index of the currently selected totem, or {@code -1} if none selected. */
<b class="nc">&nbsp; private int selectedIndex = -1;</b>
&nbsp; //TODO
&nbsp; /** The {@link StackPane} frame of the currently selected totem card, or {@code null}. */
<b class="nc">&nbsp; private StackPane selectedFrame = null;</b>
&nbsp;
&nbsp; /**
@@ -141,7 +142,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; /** Initializes the scene: sets the background image to fill the screen. */
&nbsp; @FXML
&nbsp; public void initialize() {
<b class="nc">&nbsp; Image img = new Image(getClass().getResourceAsStream(&quot;/GUIImages/Background.png&quot;));</b>
<b class="nc">&nbsp; Image img = new Image(Objects.requireNonNull(getClass().getResourceAsStream(&quot;/GUIImages/Background.png&quot;)));</b>
<b class="nc">&nbsp; backgroundImage.setImage(img);</b>
<b class="nc">&nbsp; Rectangle2D screenBounds = Screen.getPrimary().getBounds();</b>
<b class="nc">&nbsp; backgroundImage.setFitWidth(screenBounds.getWidth());</b>
@@ -211,7 +212,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
&nbsp; /** Builds a totem card widget; if {@code interactive}, wires click/hover handlers and selection logic. */
&nbsp; private VBox buildCard(Totems totem, int idx, boolean interactive) {
<b class="nc">&nbsp; ImageView img = new ImageView(new Image(getClass().getResourceAsStream(&quot;/GUIImages/Totems/totem_&quot; + String.valueOf(totem).toLowerCase(Locale.ROOT) + &quot;.png&quot;)));</b>
<b class="nc">&nbsp; ImageView img = new ImageView(new Image(Objects.requireNonNull(getClass().getResourceAsStream(&quot;/GUIImages/Totems/totem_&quot; + String.valueOf(totem).toLowerCase(Locale.ROOT) + &quot;.png&quot;))));</b>
<b class="nc">&nbsp; img.setFitHeight(150);</b>
<b class="nc">&nbsp; img.setPreserveRatio(true);</b>
&nbsp;
@@ -301,7 +302,7 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; &quot;-fx-text-fill: &quot; + (selected ? &quot;#FFD700&quot; : &quot;#ffffff&quot;) + &quot;;&quot;;</b>
&nbsp; }
&nbsp;
&nbsp; /** Returns the totem name with only the first letter capitalised. */
&nbsp; /** Returns the totem name with only the first letter capitalized. */
&nbsp; private String capitalize(Totems t) {
<b class="nc">&nbsp; String s = t.name().toLowerCase(Locale.ROOT);</b>
<b class="nc">&nbsp; return Character.toUpperCase(s.charAt(0)) + s.substring(1);</b>
@@ -339,7 +340,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -150,19 +150,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -115,19 +115,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -146,7 +146,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -162,7 +162,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -153,7 +153,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -169,7 +169,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -185,19 +185,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -185,19 +185,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -115,19 +115,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -185,19 +185,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -115,19 +115,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -134,35 +134,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="sources/source-2.html">BorderStyle</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(1/1)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
</span>
<span class="absValue">
(14/17)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
</span>
<span class="absValue">
(24/27)
(0/131)
</span>
</td>
</tr>
@@ -199,6 +171,34 @@ it.polimi.ingsw.gc14.View.TUI</div>
<span class="absValue">
(60/73)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="sources/source-2.html">BorderStyle</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(1/1)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(22/22)
</span>
</td>
</tr>
</table>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -103,6 +103,34 @@ it.polimi.ingsw.gc14.View.TUI</div>
<a href="index_SORT_BY_LINE.html">Line, %</a>
</th>
</tr>
<tr>
<td class="name"><a href="sources/source-2.html">BorderStyle</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(1/1)
</span>
</td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(22/22)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="sources/source-1.html">AsciiTable</a></td>
<td class="coverageStat">
@@ -136,34 +164,6 @@ it.polimi.ingsw.gc14.View.TUI</div>
<span class="absValue">
(60/73)
</span>
</td>
</tr>
<tr>
<td class="name"><a href="sources/source-2.html">BorderStyle</a></td>
<td class="coverageStat">
<span class="percent">
100%
</span>
<span class="absValue">
(1/1)
</span>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
</span>
<span class="absValue">
(14/17)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
</span>
<span class="absValue">
(24/27)
</span>
</td>
</tr>
<tr>
@@ -181,7 +181,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -197,7 +197,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -53,10 +53,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
53.3%
58.5%
</span>
<span class="absValue">
(24/45)
(24/41)
</span>
</td>
<td class="coverageStat">
@@ -69,10 +69,10 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
38.7%
36.3%
</span>
<span class="absValue">
(84/217)
(82/226)
</span>
</td>
</tr>
@@ -118,7 +118,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -134,7 +134,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -150,19 +150,19 @@ it.polimi.ingsw.gc14.View.TUI</div>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat"/>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -224,7 +224,7 @@ it.polimi.ingsw.gc14.View.TUI</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -110,33 +110,62 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * }&lt;/pre&gt;
&nbsp; */
&nbsp;public class AsciiTable {
&nbsp; //TODO
&nbsp; /** Border style used to draw corners, lines, and junctions. */
&nbsp; private final BorderStyle s;
&nbsp; //TODO
&nbsp;
&nbsp; /** Number of columns in this table. */
&nbsp; private final int cols;
&nbsp; //TODO
&nbsp;
&nbsp; /** All rows of the table, in insertion order. */
<b class="fc">&nbsp; private final List&lt;List&lt;String&gt;&gt; rows = new ArrayList&lt;&gt;();</b>
&nbsp; //TODO
&nbsp;
&nbsp; /** Indices of rows after which a horizontal separator line is drawn. */
<b class="fc">&nbsp; private final List&lt;Integer&gt; separators = new ArrayList&lt;&gt;();</b>
&nbsp; //TODO
&nbsp;
&nbsp; /**
&nbsp; * Creates a new empty table with the given border style and column count.
&nbsp; *
&nbsp; * @param s the border style to use when rendering.
&nbsp; * @param cols the number of columns.
&nbsp; */
<b class="fc">&nbsp; public AsciiTable(BorderStyle s, int cols) {</b>
<b class="fc">&nbsp; this.s = s; this.cols = cols;</b>
&nbsp; }
&nbsp; //TODO
&nbsp;
&nbsp; /**
&nbsp; * Appends a row using varargs cells.
&nbsp; *
&nbsp; * @param cells one value per column.
&nbsp; */
<b class="fc">&nbsp; public void addRow(String... cells) { rows.add(Arrays.asList(cells)); }</b>
&nbsp; //TODO
&nbsp;
&nbsp; /**
&nbsp; * Appends a row from an existing list.
&nbsp; *
&nbsp; * @param cells one value per column.
&nbsp; */
<b class="fc">&nbsp; public void addRow(List&lt;String&gt; cells) { rows.add(cells); }</b>
&nbsp; //TODO
&nbsp;
&nbsp; /**
&nbsp; * Inserts a header row at position 0 and marks it with a separator line below it.
&nbsp; *
&nbsp; * @param cells one header label per column.
&nbsp; */
&nbsp; public void addHeader(String... cells) {
<b class="fc">&nbsp; rows.add(0, Arrays.asList(cells));</b>
<b class="fc">&nbsp; separators.add(0);</b>
&nbsp; }
&nbsp; //TODO
&nbsp;
&nbsp; /**
&nbsp; * Marks a separator line to be drawn after the last row added so far.
&nbsp; */
<b class="fc">&nbsp; public void addSeparator() { separators.add(rows.size() - 1); }</b>
&nbsp;
&nbsp; /**
&nbsp; * Renders the table to a multi-line string.
&nbsp; * Column width is the widest cell in display columns (wide chars = 2), plus 1.
&nbsp; *
&nbsp; * @return the fully rendered table as a multi-line string.
&nbsp; */
&nbsp; public String build() {
<b class="fc">&nbsp; var sb = new StringBuilder();</b>
@@ -156,11 +185,19 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="fc">&nbsp; sb.append(hline(s.bl(), s.mb(), s.br(), maxWidth));</b>
<b class="fc">&nbsp; return sb.toString();</b>
&nbsp; }
&nbsp; //TODO
&nbsp; /**
&nbsp; * Builds a single horizontal borderline across all columns.
&nbsp; *
&nbsp; * @param l left-end character.
&nbsp; * @param m middle junction character (between columns).
&nbsp; * @param r right-end character.
&nbsp; * @param maxWidth width in display columns of each cell (including padding).
&nbsp; * @return the rendered horizontal line string.
&nbsp; */
&nbsp; private String hline(String l, String m, String r, int maxWidth) {
<b class="fc">&nbsp; var sb = new StringBuilder(l);</b>
<b class="fc">&nbsp; for (int i = 0; i &lt; cols; i++) {</b>
<b class="fc">&nbsp; sb.append(s.h().repeat(maxWidth));</b>
<b class="fc">&nbsp; sb.repeat(Objects.requireNonNull(s.h()), maxWidth);</b>
<b class="fc">&nbsp; if (i &lt; cols - 1) sb.append(m);</b>
&nbsp; }
<b class="fc">&nbsp; return sb.append(r).toString();</b>
@@ -180,6 +217,11 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Places two pre-rendered text blocks side by side, separated by a gap.
&nbsp; * Left-block lines are padded to a uniform display width so the right block
&nbsp; * always starts at the same column. Uses {@link #displayWidth} for measurement.
&nbsp; *
&nbsp; * @param left lines of the left block.
&nbsp; * @param right lines of the right block.
&nbsp; * @param gap number of space characters between the two blocks.
&nbsp; * @return the combined multi-line string.
&nbsp; */
&nbsp; public static String sideBySide(List&lt;String&gt; left, List&lt;String&gt; right, int gap) {
<b class="nc">&nbsp; int leftWidth = left.stream().mapToInt(AsciiTable::displayWidth).max().orElse(0);</b>
@@ -196,11 +238,13 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return sb.toString();</b>
&nbsp; }
&nbsp;
&nbsp; // ── Wide-character width ──────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Returns the number of terminal columns required to display {@code s}.
&nbsp; * Wide characters (emoji, CJK, full-width) count as 2; all others as 1.
&nbsp; *
&nbsp; * @param s the string to measure; ANSI escape sequences are stripped before counting.
&nbsp; * @return the display width in terminal columns.
&nbsp; */
&nbsp; public static int displayWidth(String s) {
<b class="fc">&nbsp; s = s.replaceAll(&quot;\033\\[[^m]*m&quot;, &quot;&quot;);</b>
@@ -220,34 +264,33 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; */
&nbsp; private static boolean isWide(int cp) {
<b class="fc">&nbsp; if (cp &lt; 0x1100) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0x115F) return true; // Hangul Jamo</b>
<b class="pc">&nbsp; if (cp &lt;= 0x115F) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0x2E80) {</b>
&nbsp; // Specific wide symbols below 0x2E80
<b class="nc">&nbsp; return cp == 0x2B50 // ⭐ STAR</b>
&nbsp; || cp == 0x2B55; // ⭕ HEAVY LARGE CIRCLE
<b class="nc">&nbsp; return cp == 0x2B50</b>
&nbsp; || cp == 0x2B55;
&nbsp; }
<b class="pc">&nbsp; if (cp &lt;= 0x303E) return true; // CJK Radicals, Kangxi, CJK Symbols</b>
<b class="pc">&nbsp; if (cp &lt;= 0x303E) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0x3041) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xA4CF) return true; // Hiragana, Katakana, Bopomofo, CJK Unified</b>
<b class="pc">&nbsp; if (cp &lt;= 0xA4CF) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xA960) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xA97F) return true; // Hangul Jamo Extended-A</b>
<b class="pc">&nbsp; if (cp &lt;= 0xA97F) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xAC00) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xD7AF) return true; // Hangul Syllables</b>
<b class="pc">&nbsp; if (cp &lt;= 0xD7AF) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xF900) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFAFF) return true; // CJK Compatibility Ideographs</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFAFF) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xFE10) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFE1F) return true; // Vertical Forms</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFE1F) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xFE30) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFE6F) return true; // CJK Compatibility Forms</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFE6F) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xFF00) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFF60) return true; // Fullwidth Latin, punctuation</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFF60) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0xFFE0) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFFE6) return true; // Fullwidth Signs</b>
<b class="pc">&nbsp; if (cp &lt;= 0xFFE6) return true;</b>
<b class="pc">&nbsp; if (cp &lt; 0x1F004) return false;</b>
<b class="pc">&nbsp; if (cp &lt;= 0x1FAFF) return true; // Emoji (mahjong, playing cards, flags,</b>
&nbsp; // misc symbols, transport, 🍖 U+1F357, ...)
<b class="pc">&nbsp; if (cp &lt;= 0x1FAFF) return true;</b>
&nbsp;
<b class="nc">&nbsp; if (cp &lt; 0x20000) return false;</b>
<b class="nc">&nbsp; return cp &lt;= 0x3FFFD; // CJK Extension B through G</b>
<b class="nc">&nbsp; return cp &lt;= 0x3FFFD;</b>
&nbsp; }
&nbsp;}
</code>
@@ -273,7 +316,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -52,18 +52,18 @@ Current scope: <a href="../../index.html">all classes</a>
</td>
<td class="coverageStat">
<span class="percent">
82.4%
100%
</span>
<span class="absValue">
(14/17)
(14/14)
</span>
</td>
<td class="coverageStat">
<span class="percent">
88.9%
100%
</span>
<span class="absValue">
(24/27)
(22/22)
</span>
</td>
</tr>
@@ -84,23 +84,14 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * &lt;p&gt;Each style stores the characters needed to draw table corners,
&nbsp; * horizontal and vertical lines, and junctions.
&nbsp; */
<b class="fc">&nbsp;public enum BorderStyle {</b>
&nbsp;
&nbsp; /**
&nbsp; * Unicode box-drawing border style.
&nbsp; */
<b class="fc">&nbsp; UNICODE(&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;),</b>
&nbsp;
&nbsp; /**
&nbsp; * Plain ASCII border style.
&nbsp; */
<b class="fc">&nbsp; ASCII (&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;-&quot;,&quot;|&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;,&quot;+&quot;),</b>
<b class="fc">&nbsp;@SuppressWarnings(&quot;ALL&quot;)</b>
&nbsp;public enum BorderStyle {
&nbsp;
&nbsp; /**
&nbsp; * Rounded Unicode border style.
&nbsp; */
<b class="fc">&nbsp; ROUNDED(&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;);</b>
&nbsp;
&nbsp; /** Corner (tl/tr/bl/br), line (h/v), outer junction (ml/mr/mt/mb/x), and separator junction (sl/sr/sx) characters. */
&nbsp; private final String tl,tr,bl,br,h,v,ml,mr,mt,mb,x,sl,sr,sx;
&nbsp;
&nbsp; BorderStyle(String tl,String tr,String bl,String br,
@@ -148,16 +139,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="fc">&nbsp; public String v() { return v; }</b>
&nbsp;
&nbsp; /**
&nbsp; * @return the middle-left junction character.
&nbsp; */
<b class="nc">&nbsp; public String ml() { return ml; }</b>
&nbsp;
&nbsp; /**
&nbsp; * @return the middle-right junction character.
&nbsp; */
<b class="nc">&nbsp; public String mr() { return mr; }</b>
&nbsp;
&nbsp; /**
&nbsp; * @return the top-middle junction character.
&nbsp; */
<b class="fc">&nbsp; public String mt() { return mt; }</b>
@@ -168,11 +149,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="fc">&nbsp; public String mb() { return mb; }</b>
&nbsp;
&nbsp; /**
&nbsp; * @return the center junction character.
&nbsp; */
<b class="nc">&nbsp; public String x() { return x; }</b>
&nbsp;
&nbsp; /**
&nbsp; * @return the separator-left junction character.
&nbsp; */
<b class="fc">&nbsp; public String sl() { return sl; }</b>
@@ -210,7 +186,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -59,7 +59,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/17)
(0/16)
</span>
</td>
<td class="coverageStat">
@@ -75,7 +75,7 @@ Current scope: <a href="../../index.html">all classes</a>
0%
</span>
<span class="absValue">
(0/117)
(0/131)
</span>
</td>
</tr>
@@ -135,14 +135,21 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; this.username = &quot;&quot;;</b>
&nbsp; }
&nbsp;
&nbsp; // ── Setters ───────────────────────────────────────────────────────────────
&nbsp;
&nbsp; /** Sets the username of the local player. */
&nbsp; /**
&nbsp; * Sets the username of the local player.
&nbsp; *
&nbsp; * @param username the username to assign.
&nbsp; */
&nbsp; public void setUsername(String username) {
<b class="nc">&nbsp; this.username = username;</b>
&nbsp; }
&nbsp;
&nbsp; /** Updates the model stored in this view. */
&nbsp; /**
&nbsp; * Updates the model stored in this view.
&nbsp; *
&nbsp; * @param model the latest mini model to display.
&nbsp; */
&nbsp; @Override
&nbsp; public void setModel(MiniModel model) {
<b class="nc">&nbsp; this.model = model;</b>
@@ -152,13 +159,14 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; * Registers the active JLine {@link LineReader}.
&nbsp; * Once set, all output routes through {@link LineReader#printAbove} so the
&nbsp; * prompt survives background-thread renders.
&nbsp; *
&nbsp; * @param lineReader the JLine reader to use for output; also provides the terminal reference.
&nbsp; */
&nbsp; public void setLineReader(LineReader lineReader) {
<b class="nc">&nbsp; this.lineReader = lineReader;</b>
<b class="nc">&nbsp; this.terminal = lineReader.getTerminal();</b>
&nbsp; }
&nbsp;
&nbsp; // ── Public render entry points ────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Default render: dispatches to the right view based on game stage.
@@ -169,21 +177,20 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; GameStages stage = model.currentState.getGameStage();</b>
<b class="nc">&nbsp; if (stage == GameStages.TOTEM_CHOICE) {</b>
<b class="nc">&nbsp; display(buildTotemsContent());</b>
<b class="nc">&nbsp; printLine(&quot;\033[2mCommands: totem &lt;pos&gt;\033[0m&quot;);</b>
<b class="nc">&nbsp; } else if (stage == GameStages.ENDED) {</b>
<b class="nc">&nbsp; display(buildStandingContent() + &quot;\nType &#39;rematch&#39; to play again or &#39;quit&#39; to exit&quot;);</b>
<b class="nc">&nbsp; display(buildStandingContent());</b>
<b class="nc">&nbsp; printLine(&quot;Type &#39;rematch&#39; to play again or &#39;quit&#39; to exit&quot;);</b>
&nbsp; } else {
<b class="nc">&nbsp; display(buildBoardContent());</b>
<b class="nc">&nbsp; printLine(&quot;\033[2mCommands: slot &lt;pos&gt; | draw upper/lower tribe/building &lt;pos&gt; | totem &lt;pos&gt; | skip | clear | details buildings/events/characters | quit\033[0m&quot;);</b>
&nbsp; }
&nbsp; }
&nbsp;
&nbsp; /** Renders the board + menu (top) and all players&#39; hands in a grid (bottom). */
&nbsp; public void renderBoard() {
<b class="nc">&nbsp; display(buildBoardContent());</b>
&nbsp; }
&nbsp;
&nbsp; /** Renders the totem-choice panel. */
&nbsp; public void renderTotems() {
<b class="nc">&nbsp; display(buildTotemsContent());</b>
<b class="nc">&nbsp; printLine(&quot;\033[2mCommands: slot &lt;pos&gt; | draw upper/lower tribe/building &lt;pos&gt; | totem &lt;pos&gt; | skip | clear | details buildings/events/characters | quit\033[0m&quot;);</b>
&nbsp; }
&nbsp;
&nbsp; /**
@@ -206,10 +213,10 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; text += &quot;\nPress any key to continue&quot;;</b>
&nbsp; }
&nbsp; }
<b class="nc">&nbsp; printLine(text);</b>
<b class="nc">&nbsp; render();</b>
<b class="nc">&nbsp; printLine(&quot;\033[31m&quot; + text + &quot;\033[0m&quot;);</b>
&nbsp; }
&nbsp;
&nbsp; // ── Content builders (return strings, do not print) ───────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Builds the main view: board + menu side by side, followed by all players&#39;
@@ -227,6 +234,7 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp; */
&nbsp; private String buildAllHandsContent() {
<b class="nc">&nbsp; List&lt;Player&gt; players = new ArrayList&lt;&gt;(model.players.values());</b>
<b class="nc">&nbsp; players.removeIf(p -&gt; model.disconnectedPlayers.contains(p.getUserName()));</b>
<b class="nc">&nbsp; if (players.isEmpty()) return &quot;&quot;;</b>
&nbsp;
<b class="nc">&nbsp; int n = players.size();</b>
@@ -237,11 +245,23 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; for (int i = 0; i &lt; leftCount; i++) leftSb.append(players.get(i).toString()).append(&quot;\n&quot;);</b>
<b class="nc">&nbsp; for (int i = leftCount; i &lt; n; i++) rightSb.append(players.get(i).toString()).append(&quot;\n&quot;);</b>
&nbsp;
<b class="nc">&nbsp; if (rightSb.isEmpty()) return leftSb.toString();</b>
&nbsp; String handsBlock;
<b class="nc">&nbsp; if (rightSb.isEmpty()) {</b>
<b class="nc">&nbsp; handsBlock = leftSb.toString();</b>
&nbsp; } else {
<b class="nc">&nbsp; handsBlock = AsciiTable.sideBySide(</b>
<b class="nc">&nbsp; List.of(leftSb.toString().split(&quot;\n&quot;, -1)),</b>
<b class="nc">&nbsp; List.of(rightSb.toString().split(&quot;\n&quot;, -1)), 3);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; return AsciiTable.sideBySide(</b>
<b class="nc">&nbsp; List.of(leftSb.toString().split(&quot;\n&quot;, -1)),</b>
<b class="nc">&nbsp; List.of(rightSb.toString().split(&quot;\n&quot;, -1)), 3);</b>
<b class="nc">&nbsp; if (!model.disconnectedPlayers.isEmpty()) {</b>
<b class="nc">&nbsp; var box = new AsciiTable(BorderStyle.ROUNDED, 1);</b>
<b class="nc">&nbsp; box.addHeader(&quot;Disconnected&quot;);</b>
<b class="nc">&nbsp; model.disconnectedPlayers.forEach(box::addRow);</b>
<b class="nc">&nbsp; handsBlock += &quot;\n&quot; + box.build();</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; return handsBlock;</b>
&nbsp; }
&nbsp;
&nbsp; private String buildTotemsContent() {
@@ -254,31 +274,29 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; String current = model.currentState.getCurrentPlayer() != null</b>
<b class="nc">&nbsp; ? model.currentState.getCurrentPlayer().getUserName() + &quot;&quot;</b>
<b class="nc">&nbsp; : &quot;&quot;;</b>
<b class="nc">&nbsp; return current + &quot;TOTEMS AVAILABLE:\n&quot; + table.build() + &quot;\nType: totem &lt;pos&gt;&quot;;</b>
<b class="nc">&nbsp; return current + &quot;TOTEMS AVAILABLE:\n&quot; + table.build();</b>
&nbsp; }
&nbsp;
&nbsp; private String buildStandingContent() {
<b class="nc">&nbsp; if (model.standingPlayers == null || model.standingPlayers.isEmpty()) return &quot;&quot;;</b>
<b class="nc">&nbsp; StringBuilder sb = new StringBuilder();</b>
<b class="nc">&nbsp; int size = model.standingPlayers.size();</b>
<b class="nc">&nbsp; for (int i = 0; i &lt; size / 2; i++) {</b>
<b class="nc">&nbsp; sb.append(AsciiTable.sideBySide(</b>
<b class="nc">&nbsp; List.of(model.standingPlayers.get(i * 2).toString().split(&quot;\n&quot;)),</b>
<b class="nc">&nbsp; List.of(model.standingPlayers.get(i * 2 + 1).toString().split(&quot;\n&quot;)), 2));</b>
<b class="nc">&nbsp; String banner = model.standingPlayers.get(0).getUserName().equals(username)</b>
<b class="nc">&nbsp; ? &quot;WINNER!&quot; : &quot;GAME OVER&quot;;</b>
<b class="nc">&nbsp; List&lt;String&gt; lines = new ArrayList&lt;&gt;();</b>
<b class="nc">&nbsp; for (int i = 0; i &lt; model.standingPlayers.size(); i++) {</b>
<b class="nc">&nbsp; var p = model.standingPlayers.get(i);</b>
<b class="nc">&nbsp; lines.add((i + 1) + &quot;. &quot; + p.getUserName()</b>
<b class="nc">&nbsp; + &quot; (&quot; + p.getTotem().toString() + &quot;)&quot;</b>
<b class="nc">&nbsp; + &quot; \uD83C\uDF56:&quot; + p.getFoodValue()</b>
<b class="nc">&nbsp; + &quot; \uD83C\uDFC5:&quot; + p.getPrestigeValue());</b>
&nbsp; }
<b class="nc">&nbsp; sb.append(&quot;\n&quot;);</b>
<b class="nc">&nbsp; if (size % 2 != 0) {</b>
<b class="nc">&nbsp; sb.append(model.standingPlayers.get(size - 1)).append(&quot;\n&quot;);</b>
&nbsp; }
<b class="nc">&nbsp; if (model.standingPlayers.get(0).getUserName().equals(username)) {</b>
<b class="nc">&nbsp; sb.append(&quot;GAME ENDED: !!!YOU WON!!!&quot;);</b>
&nbsp; } else {
<b class="nc">&nbsp; sb.append(&quot;GAME ENDED: !!!YOU LOST!!!&quot;);</b>
&nbsp; }
<b class="nc">&nbsp; return sb.toString();</b>
<b class="nc">&nbsp; int contentWidth = lines.stream().mapToInt(AsciiTable::displayWidth).max().orElse(0);</b>
<b class="nc">&nbsp; int pad = Math.max(0, (contentWidth - AsciiTable.displayWidth(banner)) / 2);</b>
<b class="nc">&nbsp; var table = new AsciiTable(BorderStyle.ROUNDED, 1);</b>
<b class="nc">&nbsp; table.addHeader(&quot; &quot;.repeat(pad) + banner);</b>
<b class="nc">&nbsp; lines.forEach(table::addRow);</b>
<b class="nc">&nbsp; return table.build();</b>
&nbsp; }
&nbsp;
&nbsp; // ── Core display primitive ────────────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Clears the terminal and displays {@code content}, horizontally centered.
@@ -345,7 +363,6 @@ Current scope: <a href="../../index.html">all classes</a>
<b class="nc">&nbsp; return AsciiTable.displayWidth(line);</b>
&nbsp; }
&nbsp;
&nbsp; // ── Board / players stamp helpers ─────────────────────────────────────────
&nbsp;
&nbsp; /**
&nbsp; * Returns the board state as a multi-line string: turn order, upper cards,
@@ -366,20 +383,20 @@ Current scope: <a href="../../index.html">all classes</a>
&nbsp;
<b class="nc">&nbsp; var upperCards = new AsciiTable(BorderStyle.ROUNDED, 2);</b>
<b class="nc">&nbsp; var lowerCards = new AsciiTable(BorderStyle.ROUNDED, 2);</b>
<b class="nc">&nbsp; upperCards.addHeader(&quot;Char/Events&quot;, &quot;Building&quot;);</b>
<b class="nc">&nbsp; lowerCards.addHeader(&quot;Char/Events&quot;, &quot;Building&quot;);</b>
<b class="nc">&nbsp; upperCards.addHeader(&quot;Char/\033[38;5;180mEvents\033[0m&quot;, &quot;Building&quot;);</b>
<b class="nc">&nbsp; lowerCards.addHeader(&quot;Char/\033[38;5;180mEvents\033[0m&quot;, &quot;Building&quot;);</b>
&nbsp;
<b class="nc">&nbsp; int maxU = Math.max(model.upperListTribeCards.size(), model.upperListBuildingCards.size());</b>
<b class="nc">&nbsp; for (int i = 0; i &lt; maxU; i++) {</b>
<b class="nc">&nbsp; String t = i &lt; model.upperListTribeCards.size() ? i + model.upperListTribeCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; String b = i &lt; model.upperListBuildingCards.size() ? i + model.upperListBuildingCards.get(i).toString() : &quot;&quot;;</b>
<b class="nc">&nbsp; String t = i &lt; model.upperListTribeCards.size() ? i + &quot;:&quot; + model.upperListTribeCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; String b = i &lt; model.upperListBuildingCards.size() ? i + &quot;:&quot; + model.upperListBuildingCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; upperCards.addRow(t, b);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; int maxL = Math.max(model.lowerListTribeCards.size(), model.lowerListBuildingCards.size());</b>
<b class="nc">&nbsp; for (int i = 0; i &lt; maxL; i++) {</b>
<b class="nc">&nbsp; String t = i &lt; model.lowerListTribeCards.size() ? i + model.lowerListTribeCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; String b = i &lt; model.lowerListBuildingCards.size() ? i + model.lowerListBuildingCards.get(i).toString() : &quot;&quot;;</b>
<b class="nc">&nbsp; String t = i &lt; model.lowerListTribeCards.size() ? i + &quot;:&quot; + model.lowerListTribeCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; String b = i &lt; model.lowerListBuildingCards.size() ? i + &quot;:&quot; + model.lowerListBuildingCards.get(i).toStringBoard() : &quot;&quot;;</b>
<b class="nc">&nbsp; lowerCards.addRow(t, b);</b>
&nbsp; }
&nbsp;
@@ -422,7 +439,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.View</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -88,7 +88,7 @@ Current scope: <a href="../../index.html">all classes</a>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>
@@ -62,7 +62,7 @@ it.polimi.ingsw.gc14.Network.RMI.Common</div>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
<div style="float:right;">generated on 2026-06-19 22:53</div>
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More