-
Notifications
You must be signed in to change notification settings - Fork 232
/
game.py
139 lines (118 loc) · 4.37 KB
/
game.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from config import ADMIN_LIST, OPEN_LOBBY, DEFAULT_GAMEMODE, ENABLE_TRANSLATIONS
from datetime import datetime
from deck import Deck
import card as c
class Game(object):
""" This class represents a game of UNO """
current_player = None
reversed = False
choosing_color = False
started = False
draw_counter = 0
players_won = 0
starter = None
mode = DEFAULT_GAMEMODE
job = None
owner = ADMIN_LIST
open = OPEN_LOBBY
translate = ENABLE_TRANSLATIONS
def __init__(self, chat):
self.chat = chat
self.last_card = None
self.deck = Deck()
self.logger = logging.getLogger(__name__)
@property
def players(self):
"""Returns a list of all players in this game"""
players = list()
if not self.current_player:
return players
current_player = self.current_player
itplayer = current_player.next
players.append(current_player)
while itplayer and itplayer != current_player:
players.append(itplayer)
itplayer = itplayer.next
return players
def start(self):
if self.mode == None or self.mode != "wild":
self.deck._fill_classic_()
else:
self.deck._fill_wild_()
self._first_card_()
self.started = True
def set_mode(self, mode):
self.mode = mode
def reverse(self):
"""Reverses the direction of game"""
self.reversed = not self.reversed
def turn(self):
"""Marks the turn as over and change the current player"""
self.logger.debug("Next Player")
self.current_player = self.current_player.next
self.current_player.drew = False
self.current_player.turn_started = datetime.now()
self.choosing_color = False
def _first_card_(self):
# In case that the player did not select a game mode
if not self.deck.cards:
self.set_mode(DEFAULT_GAMEMODE)
# The first card should not be a special card
while not self.last_card or self.last_card.special:
self.last_card = self.deck.draw()
# If the card drawn was special, return it to the deck and loop again
if self.last_card.special:
self.deck.dismiss(self.last_card)
self.play_card(self.last_card)
def play_card(self, card):
"""
Plays a card and triggers its effects.
Should be called only from Player.play or on game start to play the
first card
"""
self.deck.dismiss(self.last_card)
self.last_card = card
self.logger.info("Playing card " + repr(card))
if card.value == c.SKIP:
self.turn()
elif card.special == c.DRAW_FOUR:
self.draw_counter += 4
self.logger.debug("Draw counter increased by 4")
elif card.value == c.DRAW_TWO:
self.draw_counter += 2
self.logger.debug("Draw counter increased by 2")
elif card.value == c.REVERSE:
# Special rule for two players
if self.current_player == self.current_player.next.next:
self.turn()
else:
self.reverse()
# Don't turn if the current player has to choose a color
if card.special not in (c.CHOOSE, c.DRAW_FOUR):
self.turn()
else:
self.logger.debug("Choosing Color...")
self.choosing_color = True
def choose_color(self, color):
"""Carries out the color choosing and turns the game"""
self.last_card.color = color
self.turn()