easterobot 1.3.1__py3-none-any.whl → 1.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easterobot/bot.py +14 -1
- easterobot/casino/__init__.py +1 -0
- easterobot/casino/roulette.py +269 -0
- easterobot/commands/__init__.py +2 -0
- easterobot/commands/game.py +127 -118
- easterobot/commands/info.py +2 -2
- easterobot/commands/reset.py +11 -14
- easterobot/commands/roulette.py +34 -0
- easterobot/commands/top.py +73 -65
- easterobot/config.py +35 -8
- easterobot/games/{connect.py → connect4.py} +25 -28
- easterobot/games/game.py +126 -54
- easterobot/games/rock_paper_scissor.py +33 -30
- easterobot/games/skyjo.py +805 -0
- easterobot/games/tic_tac_toe.py +19 -18
- easterobot/hunts/hunt.py +49 -18
- easterobot/hunts/luck.py +15 -10
- easterobot/hunts/rank.py +24 -2
- easterobot/locker.py +180 -0
- easterobot/models.py +9 -0
- easterobot/resources/config.example.yml +18 -12
- easterobot/resources/credits.txt +2 -0
- easterobot/resources/emotes/placements/s1.png +0 -0
- easterobot/resources/emotes/placements/s10.png +0 -0
- easterobot/resources/emotes/placements/s11.png +0 -0
- easterobot/resources/emotes/placements/s12.png +0 -0
- easterobot/resources/emotes/placements/s2.png +0 -0
- easterobot/resources/emotes/placements/s3.png +0 -0
- easterobot/resources/emotes/placements/s4.png +0 -0
- easterobot/resources/emotes/placements/s5.png +0 -0
- easterobot/resources/emotes/placements/s6.png +0 -0
- easterobot/resources/emotes/placements/s7.png +0 -0
- easterobot/resources/emotes/placements/s8.png +0 -0
- easterobot/resources/emotes/placements/s9.png +0 -0
- easterobot/resources/emotes/placements/sA.png +0 -0
- easterobot/resources/emotes/placements/sB.png +0 -0
- easterobot/resources/emotes/placements/sC.png +0 -0
- easterobot/resources/emotes/placements/sD.png +0 -0
- easterobot/resources/emotes/placements/sE.png +0 -0
- easterobot/resources/emotes/placements/sF.png +0 -0
- easterobot/resources/emotes/placements/sG.png +0 -0
- easterobot/resources/emotes/placements/sH.png +0 -0
- easterobot/resources/emotes/placements/sI.png +0 -0
- easterobot/resources/emotes/placements/sJ.png +0 -0
- easterobot/resources/emotes/placements/sK.png +0 -0
- easterobot/resources/emotes/placements/sL.png +0 -0
- easterobot/resources/emotes/placements/sM.png +0 -0
- easterobot/resources/emotes/placements/sN.png +0 -0
- easterobot/resources/emotes/placements/sO.png +0 -0
- easterobot/resources/emotes/placements/sP.png +0 -0
- easterobot/resources/emotes/placements/sQ.png +0 -0
- easterobot/resources/emotes/placements/sR.png +0 -0
- easterobot/resources/emotes/placements/sS.png +0 -0
- easterobot/resources/emotes/placements/sT.png +0 -0
- easterobot/resources/emotes/placements/sU.png +0 -0
- easterobot/resources/emotes/placements/sV.png +0 -0
- easterobot/resources/emotes/placements/sW.png +0 -0
- easterobot/resources/emotes/placements/sX.png +0 -0
- easterobot/resources/emotes/placements/sY.png +0 -0
- easterobot/resources/emotes/placements/sZ.png +0 -0
- easterobot/resources/emotes/placements/s_.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_back.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_m1.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_m2.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p0.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p1.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p10.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p11.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p12.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p2.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p3.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p4.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p5.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p6.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p7.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p8.png +0 -0
- easterobot/resources/emotes/skyjo/skyjo_p9.png +0 -0
- {easterobot-1.3.1.dist-info → easterobot-1.5.1.dist-info}/METADATA +1 -1
- easterobot-1.5.1.dist-info/RECORD +130 -0
- easterobot-1.3.1.dist-info/RECORD +0 -70
- {easterobot-1.3.1.dist-info → easterobot-1.5.1.dist-info}/WHEEL +0 -0
- {easterobot-1.3.1.dist-info → easterobot-1.5.1.dist-info}/entry_points.txt +0 -0
- {easterobot-1.3.1.dist-info → easterobot-1.5.1.dist-info}/licenses/LICENSE +0 -0
easterobot/commands/reset.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
"""Module for reset command."""
|
2
2
|
|
3
3
|
import asyncio
|
4
|
-
from typing import cast
|
5
4
|
|
6
5
|
import discord
|
7
6
|
from sqlalchemy import and_, delete
|
@@ -9,6 +8,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
|
9
8
|
|
10
9
|
from easterobot.hunts.hunt import embed
|
11
10
|
from easterobot.models import Cooldown, Egg, Hunt
|
11
|
+
from easterobot.utils import in_seconds
|
12
12
|
|
13
13
|
from .base import Context, Interaction, controlled_command, egg_command_group
|
14
14
|
|
@@ -95,21 +95,18 @@ async def reset_command(ctx: Context) -> None:
|
|
95
95
|
|
96
96
|
cancel.callback = cancel_callback # type: ignore[assignment]
|
97
97
|
confirm.callback = confirm_callback # type: ignore[assignment]
|
98
|
-
message =
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
"et temps d'attentes vont être réinitialisatiés."
|
106
|
-
),
|
107
|
-
# TODO(dashstrom): add timer
|
108
|
-
footer="Vous avez 30 secondes pour confirmer",
|
98
|
+
message = await ctx.followup.send(
|
99
|
+
embed=embed(
|
100
|
+
title="Demande de réinitialisation",
|
101
|
+
description=(
|
102
|
+
"L'ensemble des salons, œufs "
|
103
|
+
"et temps d'attentes vont être réinitialisatiés."
|
104
|
+
f"\n\n-# Vous devez confirmer {in_seconds(30)}"
|
109
105
|
),
|
110
|
-
ephemeral=True,
|
111
|
-
view=view,
|
112
106
|
),
|
107
|
+
ephemeral=True,
|
108
|
+
view=view,
|
109
|
+
wait=True,
|
113
110
|
)
|
114
111
|
await asyncio.sleep(30.0)
|
115
112
|
if not done:
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"""Command basket."""
|
2
|
+
|
3
|
+
import discord
|
4
|
+
|
5
|
+
from easterobot.casino.roulette import RouletteManager
|
6
|
+
from easterobot.commands.base import (
|
7
|
+
Context,
|
8
|
+
controlled_command,
|
9
|
+
egg_command_group,
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
@egg_command_group.command(
|
14
|
+
name="roulette",
|
15
|
+
description="Lancer la roulette",
|
16
|
+
)
|
17
|
+
@controlled_command(cooldown=True, manage_channels=True)
|
18
|
+
async def roulette_command(
|
19
|
+
ctx: Context,
|
20
|
+
) -> None:
|
21
|
+
"""Show current user basket."""
|
22
|
+
# Delay the response
|
23
|
+
if not isinstance(ctx.channel, discord.TextChannel):
|
24
|
+
await ctx.response.send_message(
|
25
|
+
"Salon invalide !",
|
26
|
+
ephemeral=True,
|
27
|
+
)
|
28
|
+
return
|
29
|
+
await ctx.response.send_message(
|
30
|
+
"Lancement de la roulette !",
|
31
|
+
ephemeral=True,
|
32
|
+
)
|
33
|
+
roulette = RouletteManager(ctx.client)
|
34
|
+
await roulette.run(ctx.channel)
|
easterobot/commands/top.py
CHANGED
@@ -1,55 +1,91 @@
|
|
1
1
|
"""Command top."""
|
2
2
|
|
3
3
|
import logging
|
4
|
-
from
|
5
|
-
from typing import Optional
|
4
|
+
from typing import TYPE_CHECKING
|
6
5
|
|
7
6
|
import discord
|
8
|
-
from sqlalchemy import distinct, func, select
|
9
7
|
from sqlalchemy.ext.asyncio import AsyncSession
|
10
8
|
|
11
9
|
from easterobot.hunts.hunt import embed
|
12
10
|
from easterobot.hunts.rank import Ranking
|
13
|
-
from easterobot.models import Egg
|
14
11
|
|
15
|
-
from .base import Context,
|
12
|
+
from .base import Context, controlled_command, egg_command_group
|
13
|
+
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from easterobot.bot import Easterobot
|
16
16
|
|
17
17
|
PAGE_SIZE = 10
|
18
18
|
logger = logging.getLogger(__name__)
|
19
19
|
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
class PaginationRanking(discord.ui.View):
|
22
|
+
embed: discord.Embed
|
23
|
+
|
24
|
+
def __init__(
|
25
|
+
self,
|
26
|
+
*,
|
27
|
+
ranking: Ranking,
|
28
|
+
page: int = 0,
|
29
|
+
limit: int = PAGE_SIZE,
|
30
|
+
timeout: int = 180,
|
31
|
+
) -> None:
|
32
|
+
"""Instantiate PaginationRanking."""
|
33
|
+
super().__init__(timeout=timeout)
|
34
|
+
self._page = 0
|
35
|
+
self._limit = limit
|
36
|
+
self._ranking = ranking
|
37
|
+
self.page = page
|
38
|
+
|
39
|
+
@property
|
40
|
+
def page(self) -> int:
|
41
|
+
"""Current page."""
|
42
|
+
return self._page
|
43
|
+
|
44
|
+
@page.setter
|
45
|
+
def page(self, n: int) -> None:
|
46
|
+
self._page = min(max(n, 0), self._ranking.count_page(PAGE_SIZE) - 1)
|
47
|
+
self._update()
|
48
|
+
|
49
|
+
def _update(self) -> None:
|
50
|
+
count_page = self._ranking.count_page(PAGE_SIZE)
|
51
|
+
self.previous.disabled = self._page <= 0
|
52
|
+
self.next.disabled = self._page >= count_page - 1
|
53
|
+
hunters = self._ranking.page(self._page, limit=PAGE_SIZE)
|
31
54
|
if hunters:
|
32
|
-
|
55
|
+
text = "\n".join(hunter.record for hunter in hunters)
|
33
56
|
else:
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
)
|
57
|
+
text = "\n:spider_web: Personne n'a d'œuf"
|
58
|
+
emb = embed(
|
59
|
+
title="Chasse aux œufs",
|
60
|
+
description=text,
|
61
|
+
footer=(f"Page {self._page + 1}/{count_page or 1}"),
|
39
62
|
)
|
40
|
-
if
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
description=text,
|
48
|
-
footer=f"Page {page + 1}/{total + 1}",
|
63
|
+
if hasattr(self, "embed"):
|
64
|
+
emb.colour = self.embed.colour
|
65
|
+
self.embed = emb
|
66
|
+
|
67
|
+
@discord.ui.button(
|
68
|
+
label="<",
|
69
|
+
style=discord.ButtonStyle.gray,
|
49
70
|
)
|
50
|
-
|
51
|
-
|
52
|
-
|
71
|
+
async def previous(
|
72
|
+
self,
|
73
|
+
interaction: discord.Interaction["Easterobot"],
|
74
|
+
button: discord.ui.Button["PaginationRanking"], # noqa: ARG002
|
75
|
+
) -> None:
|
76
|
+
"""Get previous page."""
|
77
|
+
self.page -= 1
|
78
|
+
await interaction.response.edit_message(view=self, embed=self.embed)
|
79
|
+
|
80
|
+
@discord.ui.button(label=">", style=discord.ButtonStyle.gray)
|
81
|
+
async def next(
|
82
|
+
self,
|
83
|
+
interaction: discord.Interaction["Easterobot"],
|
84
|
+
button: discord.ui.Button["PaginationRanking"], # noqa: ARG002
|
85
|
+
) -> None:
|
86
|
+
"""Get next page."""
|
87
|
+
self.page += 1
|
88
|
+
await interaction.response.edit_message(view=self, embed=self.embed)
|
53
89
|
|
54
90
|
|
55
91
|
@egg_command_group.command(
|
@@ -60,35 +96,7 @@ async def top_command(ctx: Context) -> None:
|
|
60
96
|
"""Top command."""
|
61
97
|
await ctx.response.defer(ephemeral=True)
|
62
98
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
)
|
67
|
-
view.add_item(previous_page)
|
68
|
-
next_page: discord.ui.Button[discord.ui.View] = discord.ui.Button(
|
69
|
-
label=">", style=discord.ButtonStyle.gray
|
70
|
-
)
|
71
|
-
view.add_item(next_page)
|
72
|
-
page = 0
|
73
|
-
|
74
|
-
async def edit(interaction: Interaction) -> None:
|
75
|
-
previous_page.disabled = page <= 0
|
76
|
-
emb, next_page.disabled = await embed_rank(
|
77
|
-
ctx, page, base_embed.colour
|
78
|
-
)
|
79
|
-
await interaction.response.edit_message(view=view, embed=emb)
|
80
|
-
|
81
|
-
async def previous_callback(interaction: Interaction) -> None:
|
82
|
-
nonlocal page
|
83
|
-
page = max(page - 1, 0)
|
84
|
-
await edit(interaction)
|
85
|
-
|
86
|
-
async def next_callback(interaction: Interaction) -> None:
|
87
|
-
nonlocal page
|
88
|
-
page += 1
|
89
|
-
await edit(interaction)
|
90
|
-
|
91
|
-
previous_page.callback = previous_callback # type: ignore[assignment]
|
92
|
-
next_page.callback = next_callback # type: ignore[assignment]
|
93
|
-
base_embed, next_page.disabled = await embed_rank(ctx, page)
|
94
|
-
await ctx.followup.send(embed=base_embed, ephemeral=True, view=view)
|
99
|
+
async with AsyncSession(ctx.client.engine) as session:
|
100
|
+
ranking = await Ranking.from_guild(session, ctx.guild_id)
|
101
|
+
view = PaginationRanking(ranking=ranking, timeout=180)
|
102
|
+
await ctx.followup.send(embed=view.embed, ephemeral=True, view=view)
|
easterobot/config.py
CHANGED
@@ -124,6 +124,21 @@ class ConjugableText(Serializable[str]):
|
|
124
124
|
return text.replace("{user}", f"<@{member.id}>")
|
125
125
|
|
126
126
|
|
127
|
+
class CasinoEvent(msgspec.Struct):
|
128
|
+
duration: float
|
129
|
+
|
130
|
+
|
131
|
+
class MCasino(msgspec.Struct):
|
132
|
+
probability: float
|
133
|
+
roulette: CasinoEvent
|
134
|
+
|
135
|
+
def sample_event(self) -> Optional[CasinoEvent]:
|
136
|
+
"""Get a random event."""
|
137
|
+
if self.probability < RAND.random():
|
138
|
+
return None
|
139
|
+
return self.roulette
|
140
|
+
|
141
|
+
|
127
142
|
class RandomItem(
|
128
143
|
Serializable[list[T]], # Stored form
|
129
144
|
):
|
@@ -258,6 +273,7 @@ class MCommands(msgspec.Struct, forbid_unknown_fields=True):
|
|
258
273
|
help: MCommand
|
259
274
|
edit: MCommand
|
260
275
|
connect4: MCommand
|
276
|
+
skyjo: MCommand
|
261
277
|
info: MCommand
|
262
278
|
tictactoe: MCommand
|
263
279
|
rockpaperscissor: MCommand
|
@@ -282,6 +298,7 @@ class MConfig(msgspec.Struct, dict=True):
|
|
282
298
|
database: str
|
283
299
|
group: str
|
284
300
|
hunt: MHunt
|
301
|
+
casino: MCasino
|
285
302
|
conjugation: Conjugation
|
286
303
|
failed: RandomConjugableText
|
287
304
|
hidden: RandomConjugableText
|
@@ -314,16 +331,27 @@ class MConfig(msgspec.Struct, dict=True):
|
|
314
331
|
"%(data)s", "/" + self.working_directory.as_posix()
|
315
332
|
)
|
316
333
|
|
334
|
+
def is_sleep_hours(self, hour: time) -> bool:
|
335
|
+
"""Get if bot is currently in sleep mode.
|
336
|
+
|
337
|
+
Examples:
|
338
|
+
>>> config.is_sleep_hours(time(hour=0, minute=59))
|
339
|
+
False
|
340
|
+
>>> config.is_sleep_hours(time(hour=2))
|
341
|
+
True
|
342
|
+
>>> config.is_sleep_hours(time(hour=1))
|
343
|
+
True
|
344
|
+
"""
|
345
|
+
if self.sleep.start < self.sleep.end:
|
346
|
+
return self.sleep.start <= hour < self.sleep.end
|
347
|
+
if self.sleep.start > self.sleep.end:
|
348
|
+
return self.sleep.end > hour or self.sleep.start <= hour
|
349
|
+
return False
|
350
|
+
|
317
351
|
def in_sleep_hours(self) -> bool:
|
318
352
|
"""Get if bot is currently in sleep mode."""
|
319
353
|
hour = datetime.now(tz=timezone.utc).time()
|
320
|
-
|
321
|
-
if self.sleep.start < hour < self.sleep.end:
|
322
|
-
return True
|
323
|
-
elif self.sleep.start > self.sleep.end: # noqa: SIM102
|
324
|
-
if not self.sleep.start < hour < self.sleep.end:
|
325
|
-
return True
|
326
|
-
return False
|
354
|
+
return self.is_sleep_hours(hour)
|
327
355
|
|
328
356
|
def verified_token(self) -> str:
|
329
357
|
"""Get the safe token."""
|
@@ -409,7 +437,6 @@ class MConfig(msgspec.Struct, dict=True):
|
|
409
437
|
disable_existing_loggers=False,
|
410
438
|
defaults=defaults,
|
411
439
|
)
|
412
|
-
self.__logging_flag = True
|
413
440
|
|
414
441
|
def __str__(self) -> str:
|
415
442
|
"""Represent the Configuration."""
|
@@ -1,11 +1,12 @@
|
|
1
1
|
"""Connect4 and Connect3."""
|
2
2
|
|
3
|
-
|
3
|
+
import asyncio
|
4
4
|
from typing import Optional
|
5
5
|
|
6
6
|
import discord
|
7
7
|
from typing_extensions import override
|
8
8
|
|
9
|
+
from easterobot.bot import Easterobot
|
9
10
|
from easterobot.games.game import Game, Player
|
10
11
|
from easterobot.utils import in_seconds
|
11
12
|
|
@@ -22,36 +23,38 @@ EMOJIS_MAPPER = {
|
|
22
23
|
"🔟": 9,
|
23
24
|
}
|
24
25
|
EMOJIS = tuple(EMOJIS_MAPPER)
|
26
|
+
ROWS = 6
|
27
|
+
COLS = 7
|
28
|
+
WIN_COUNT = 4
|
25
29
|
|
26
30
|
|
27
|
-
class
|
28
|
-
def __init__(
|
31
|
+
class Connect4(Game):
|
32
|
+
def __init__(
|
29
33
|
self,
|
30
|
-
|
31
|
-
player2: discord.Member,
|
34
|
+
bot: Easterobot,
|
32
35
|
message: discord.Message,
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
+
*members: discord.Member,
|
37
|
+
rows: int = ROWS,
|
38
|
+
cols: int = COLS,
|
39
|
+
win_count: int = WIN_COUNT,
|
36
40
|
) -> None:
|
37
41
|
"""Instantiate Connect4."""
|
38
42
|
self.grid: list[list[Optional[Player]]] = [
|
39
43
|
[None] * rows for _ in range(cols)
|
40
44
|
]
|
41
45
|
self.timeout = False
|
42
|
-
self.player1 = Player(player1, 1)
|
43
|
-
self.player2 = Player(player2, 2)
|
44
46
|
self.rows = rows
|
45
47
|
self.cols = cols
|
46
48
|
self.win_count = win_count
|
47
49
|
self.turn = 0
|
48
|
-
super().__init__(message)
|
50
|
+
super().__init__(bot, message, *members)
|
49
51
|
|
50
52
|
async def on_start(self) -> None:
|
51
53
|
"""Run."""
|
52
54
|
await self.update()
|
53
55
|
await self.start_timer(61)
|
54
56
|
for emoji in EMOJIS[: self.cols]:
|
57
|
+
await asyncio.sleep(0.1)
|
55
58
|
await self.message.add_reaction(emoji)
|
56
59
|
|
57
60
|
async def update(self) -> None:
|
@@ -64,12 +67,12 @@ class Connect(Game):
|
|
64
67
|
player: Optional[Player] = self.current
|
65
68
|
elif self.winner:
|
66
69
|
forfait = "par forfait " if self.timeout else ""
|
67
|
-
footer = f"\n## Gagnant {forfait}{self.winner.mention} 🎉"
|
70
|
+
footer = f"\n## Gagnant {forfait}{self.winner.member.mention} 🎉"
|
68
71
|
player = self.current
|
69
72
|
else:
|
70
73
|
footer = (
|
71
|
-
f"\n## Égalité entre {self.
|
72
|
-
f"et {self.
|
74
|
+
f"\n## Égalité entre {self.players[0].member.mention} "
|
75
|
+
f"et {self.players[1].member.mention} 🤝"
|
73
76
|
)
|
74
77
|
player = None
|
75
78
|
content = label
|
@@ -93,10 +96,7 @@ class Connect(Game):
|
|
93
96
|
)
|
94
97
|
self.message = await self.message.edit(
|
95
98
|
embed=embed,
|
96
|
-
content=(
|
97
|
-
f"-# {self.player1.member.mention} "
|
98
|
-
f"{self.player2.member.mention}"
|
99
|
-
),
|
99
|
+
content=f"-# {' '.join(p.member.mention for p in self.players)}",
|
100
100
|
view=None,
|
101
101
|
)
|
102
102
|
|
@@ -116,15 +116,15 @@ class Connect(Game):
|
|
116
116
|
@property
|
117
117
|
def current(self) -> Player:
|
118
118
|
"""Get the current member playing."""
|
119
|
-
return
|
119
|
+
return self.players[self.turn % 2]
|
120
120
|
|
121
121
|
def piece(self, member: Optional[Player]) -> str:
|
122
122
|
"""Get the current member playing."""
|
123
123
|
if member is None:
|
124
124
|
return "⚪"
|
125
|
-
if member == self.
|
125
|
+
if member == self.players[0]:
|
126
126
|
return "🔴"
|
127
|
-
if member == self.
|
127
|
+
if member == self.players[1]:
|
128
128
|
return "🟡"
|
129
129
|
error_message = f"Invalid member: {member!r}"
|
130
130
|
raise ValueError(error_message)
|
@@ -133,9 +133,9 @@ class Connect(Game):
|
|
133
133
|
"""Get the current player playing."""
|
134
134
|
if player is None:
|
135
135
|
return discord.Colour.from_str("#d4d5d6") # Grey
|
136
|
-
if player == self.
|
136
|
+
if player == self.players[0]:
|
137
137
|
return discord.Colour.from_str("#ca2a3e") # Red
|
138
|
-
if player == self.
|
138
|
+
if player == self.players[1]:
|
139
139
|
return discord.Colour.from_str("#e9bb51") # Yellow
|
140
140
|
error_message = f"Invalid player: {player!r}"
|
141
141
|
raise ValueError(error_message)
|
@@ -160,7 +160,7 @@ class Connect(Game):
|
|
160
160
|
else:
|
161
161
|
return # Can't be placed
|
162
162
|
if winner:
|
163
|
-
await self.set_winner(
|
163
|
+
await self.set_winner(winner)
|
164
164
|
elif all( # Draw case
|
165
165
|
self.grid[col][-1] is not None for col in range(self.cols)
|
166
166
|
):
|
@@ -174,7 +174,7 @@ class Connect(Game):
|
|
174
174
|
async def on_timeout(self) -> None:
|
175
175
|
self.turn += 1
|
176
176
|
self.timeout = True
|
177
|
-
await self.set_winner(self.current
|
177
|
+
await self.set_winner(self.current)
|
178
178
|
await self.update()
|
179
179
|
|
180
180
|
def _is_winner(self, col: int, row: int, player: Player) -> bool:
|
@@ -202,6 +202,3 @@ class Connect(Game):
|
|
202
202
|
c += dx
|
203
203
|
r += dy
|
204
204
|
return count
|
205
|
-
|
206
|
-
|
207
|
-
Connect4 = partial(Connect, rows=6, cols=7, win_count=4)
|