Combining with "patch" branch (#29)
* Update unobot.po * Update test_player.py * Update test_player.py * Update test_player.py * Update test_player.py * Update player.py * Update player.py * Update internationalization.py * Update internationalization.py * Update test_player.py * Update test_player.py * Update test_player.py * Update player.py * Update player.py * Update player.py * Update test_player.py * Update test_player.py * revert play 4 then 4 rule * Update test_player.py * Update player.py * Update player.py * Update player.py * Update game.py * Update game_manager.py * Update game_manager.py * Update game_manager.py * Update player.py * Update test_player.py * Update player.py * Update bot.py * Update credentials.py * Update credentials.py * Update bot.py * Update game.py * Update game_manager.py * Update game_manager.py * Update player.py
This commit is contained in:
parent
284eb91633
commit
615bb35359
5 changed files with 228 additions and 12 deletions
10
bot.py
10
bot.py
|
@ -694,9 +694,10 @@ def do_call_bluff(bot, player):
|
|||
|
||||
if player.prev.bluffing:
|
||||
send_async(bot, chat.id,
|
||||
text=__("Bluff called! Giving 4 cards to {name}",
|
||||
text=__("Bluff called! Giving {numbers} cards to {name}",
|
||||
multi=game.translate)
|
||||
.format(name=player.prev.user.first_name))
|
||||
.format(name=player.prev.user.first_name,
|
||||
numbers=game.draw_counter))
|
||||
|
||||
try:
|
||||
player.prev.draw()
|
||||
|
@ -708,10 +709,11 @@ def do_call_bluff(bot, player):
|
|||
else:
|
||||
game.draw_counter += 2
|
||||
send_async(bot, chat.id,
|
||||
text=__("{name1} didn't bluff! Giving 6 cards to {name2}",
|
||||
text=__("{name1} didn't bluff! Giving {numbers} cards to {name2}",
|
||||
multi=game.translate)
|
||||
.format(name1=player.prev.user.first_name,
|
||||
name2=player.user.first_name))
|
||||
name2=player.user.first_name,
|
||||
numbers=game.draw_counter))
|
||||
try:
|
||||
player.draw()
|
||||
except DeckEmptyError:
|
||||
|
|
1
game.py
1
game.py
|
@ -40,6 +40,7 @@ class Game(object):
|
|||
def __init__(self, chat):
|
||||
self.chat = chat
|
||||
self.last_card = None
|
||||
self.joined_before = [] #FIXME: Change it as set()
|
||||
|
||||
while not self.last_card or self.last_card.special:
|
||||
self.deck = Deck()
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
|
||||
import logging
|
||||
import random
|
||||
|
||||
from game import Game
|
||||
from player import Player
|
||||
|
@ -77,7 +78,8 @@ class GameManager(object):
|
|||
# Don not re-add a player and remove the player from previous games in
|
||||
# this chat, if he is in one of them
|
||||
for player in players:
|
||||
if player in game.players:
|
||||
# Try to pervent someone win or leave then join again.
|
||||
if player in game.players or user.id in game.joined_before:
|
||||
raise AlreadyJoinedError()
|
||||
else:
|
||||
try:
|
||||
|
@ -93,8 +95,14 @@ class GameManager(object):
|
|||
players = self.userid_players[user.id]
|
||||
|
||||
player = Player(game, user)
|
||||
|
||||
players.append(player)
|
||||
|
||||
# Randomize player position.
|
||||
game.joined_before.append(user.id)
|
||||
if len(players) > 2:
|
||||
players.insert(random.randrange(len(players)), player)
|
||||
else:
|
||||
players.append(player)
|
||||
|
||||
self.userid_current[user.id] = player
|
||||
|
||||
def leave_game(self, user, chat):
|
||||
|
|
13
player.py
13
player.py
|
@ -167,17 +167,20 @@ class Player(object):
|
|||
self.logger.debug("Card's color or value doesn't match")
|
||||
is_playable = False
|
||||
elif last.value == c.DRAW_TWO and not \
|
||||
card.value == c.DRAW_TWO and self.game.draw_counter:
|
||||
(card.value == c.DRAW_TWO or card.special == c.DRAW_FOUR) and self.game.draw_counter:
|
||||
self.logger.debug("Player has to draw and can't counter")
|
||||
is_playable = False
|
||||
elif last.special == c.DRAW_FOUR and self.game.draw_counter:
|
||||
elif last.special == c.DRAW_FOUR and self.game.draw_counter and not card.special == c.DRAW_FOUR:
|
||||
self.logger.debug("Player has to draw and can't counter")
|
||||
is_playable = False
|
||||
elif (last.special == c.CHOOSE or last.special == c.DRAW_FOUR) and \
|
||||
(card.special == c.CHOOSE or card.special == c.DRAW_FOUR):
|
||||
elif (last.special == c.CHOOSE) and \
|
||||
(card.special == c.CHOOSE or card.special == c.DRAW_FOUR) or \
|
||||
(last.special == c.DRAW_FOUR and card.special == c.CHOOSE):
|
||||
self.logger.debug("Can't play colorchooser on another one")
|
||||
is_playable = False
|
||||
elif not last.color:
|
||||
# Pervent game locks by choose colors.
|
||||
# When player is going leave and he didn't selected a color, it cause game locks.
|
||||
elif not last.color and not (last.special == c.CHOOSE or last.special == c.DRAW_FOUR):
|
||||
self.logger.debug("Last card has no color")
|
||||
is_playable = False
|
||||
|
||||
|
|
202
test_player.py
Normal file
202
test_player.py
Normal file
|
@ -0,0 +1,202 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Telegram bot to play UNO in group chats
|
||||
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
|
||||
#
|
||||
# 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 unittest
|
||||
|
||||
import telegram
|
||||
from game import Game
|
||||
from player import Player
|
||||
import card as c
|
||||
|
||||
import logging
|
||||
logging.basicConfig(
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
level=logging.DEBUG)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
game = None
|
||||
|
||||
def setUp(self):
|
||||
self.game = Game(None)
|
||||
|
||||
def test_insert(self):
|
||||
p0 = Player(self.game, "Player 0")
|
||||
p1 = Player(self.game, "Player 1")
|
||||
p2 = Player(self.game, "Player 2")
|
||||
|
||||
self.assertEqual(p0, p2.next)
|
||||
self.assertEqual(p1, p0.next)
|
||||
self.assertEqual(p2, p1.next)
|
||||
|
||||
self.assertEqual(p0.prev, p2)
|
||||
self.assertEqual(p1.prev, p0)
|
||||
self.assertEqual(p2.prev, p1)
|
||||
|
||||
def test_reverse(self):
|
||||
p0 = Player(self.game, "Player 0")
|
||||
p1 = Player(self.game, "Player 1")
|
||||
p2 = Player(self.game, "Player 2")
|
||||
self.game.reverse()
|
||||
p3 = Player(self.game, "Player 3")
|
||||
|
||||
self.assertEqual(p0, p3.next)
|
||||
self.assertEqual(p1, p2.next)
|
||||
self.assertEqual(p2, p0.next)
|
||||
self.assertEqual(p3, p1.next)
|
||||
|
||||
self.assertEqual(p0, p2.prev)
|
||||
self.assertEqual(p1, p3.prev)
|
||||
self.assertEqual(p2, p1.prev)
|
||||
self.assertEqual(p3, p0.prev)
|
||||
|
||||
def test_leave(self):
|
||||
p0 = Player(self.game, "Player 0")
|
||||
p1 = Player(self.game, "Player 1")
|
||||
p2 = Player(self.game, "Player 2")
|
||||
|
||||
p1.leave()
|
||||
|
||||
self.assertEqual(p0, p2.next)
|
||||
self.assertEqual(p2, p0.next)
|
||||
|
||||
def test_draw(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
deck_before = len(self.game.deck.cards)
|
||||
top_card = self.game.deck.cards[-1]
|
||||
|
||||
p.draw()
|
||||
|
||||
self.assertEqual(top_card, p.cards[-1])
|
||||
self.assertEqual(deck_before, len(self.game.deck.cards) + 1)
|
||||
|
||||
def test_draw_two(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
deck_before = len(self.game.deck.cards)
|
||||
self.game.draw_counter = 2
|
||||
|
||||
p.draw()
|
||||
|
||||
self.assertEqual(deck_before, len(self.game.deck.cards) + 2)
|
||||
|
||||
def test_playable_cards_simple(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
self.game.last_card = c.Card(c.RED, '5')
|
||||
|
||||
p.cards = [c.Card(c.RED, '0'), c.Card(c.RED, '5'), c.Card(c.BLUE, '0'),
|
||||
c.Card(c.GREEN, '5'), c.Card(c.GREEN, '8')]
|
||||
|
||||
expected = [c.Card(c.RED, '0'), c.Card(c.RED, '5'),
|
||||
c.Card(c.GREEN, '5')]
|
||||
|
||||
self.assertListEqual(p.playable_cards(), expected)
|
||||
|
||||
def test_playable_cards_on_draw_two(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
self.game.last_card = c.Card(c.RED, c.DRAW_TWO)
|
||||
self.game.draw_counter = 2
|
||||
|
||||
p.cards = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.RED, '5'),
|
||||
c.Card(c.BLUE, '0'), c.Card(c.GREEN, '5'),
|
||||
c.Card(c.GREEN, c.DRAW_TWO)]
|
||||
|
||||
expected = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.GREEN, c.DRAW_TWO)]
|
||||
|
||||
self.assertListEqual(p.playable_cards(), expected)
|
||||
|
||||
def test_playable_cards_on_draw_two_then_four(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
self.game.last_card = c.Card(c.RED, c.DRAW_TWO)
|
||||
self.game.draw_counter = 2
|
||||
|
||||
p.cards = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.RED, '5'),
|
||||
c.Card(c.BLUE, '0'), c.Card(c.GREEN, '5'),
|
||||
c.Card(c.GREEN, c.DRAW_TWO),
|
||||
c.Card(None, None, c.DRAW_FOUR)]
|
||||
|
||||
expected = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.GREEN, c.DRAW_TWO), c.Card(None, None, c.DRAW_FOUR)]
|
||||
|
||||
self.assertListEqual(p.playable_cards(), expected)
|
||||
|
||||
def test_playable_cards_on_draw_four(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
|
||||
self.game.last_card = c.Card(c.RED, None, c.DRAW_FOUR)
|
||||
self.game.draw_counter = 4
|
||||
|
||||
p.cards = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.RED, '5'),
|
||||
c.Card(c.BLUE, '0'), c.Card(c.GREEN, '5'),
|
||||
c.Card(c.GREEN, c.DRAW_TWO),
|
||||
c.Card(None, None, c.DRAW_FOUR),
|
||||
c.Card(None, None, c.CHOOSE)]
|
||||
|
||||
expected = [c.Card(None, None, c.DRAW_FOUR)]
|
||||
self.assertListEqual(p.playable_cards(), expected)
|
||||
|
||||
# def test_playable_cards_on_draw_four_then_four(self):
|
||||
# p = Player(self.game, "Player 0")
|
||||
|
||||
# self.game.last_card = c.Card(c.RED, None, c.DRAW_FOUR)
|
||||
# self.game.draw_counter = 4
|
||||
|
||||
# p.cards = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.RED, '5'),
|
||||
# c.Card(c.BLUE, '0'), c.Card(c.GREEN, '5'),
|
||||
# c.Card(c.GREEN, c.DRAW_TWO),
|
||||
# c.Card(None, None, c.DRAW_FOUR)]
|
||||
|
||||
# expected = [c.Card(None, None, c.DRAW_FOUR)]
|
||||
# self.assertListEqual(p.playable_cards(), expected)
|
||||
|
||||
def test_bluffing(self):
|
||||
p = Player(self.game, "Player 0")
|
||||
Player(self.game, "Player 01")
|
||||
|
||||
self.game.last_card = c.Card(c.RED, '1')
|
||||
|
||||
p.cards = [c.Card(c.RED, c.DRAW_TWO), c.Card(c.RED, '5'),
|
||||
c.Card(c.BLUE, '0'), c.Card(c.GREEN, '5'),
|
||||
c.Card(c.RED, '5'), c.Card(c.GREEN, c.DRAW_TWO),
|
||||
c.Card(None, None, c.DRAW_FOUR),
|
||||
c.Card(None, None, c.CHOOSE)]
|
||||
|
||||
p.playable_cards()
|
||||
self.assertTrue(p.bluffing)
|
||||
|
||||
p.cards = [c.Card(c.BLUE, '1'), c.Card(c.GREEN, '1'),
|
||||
c.Card(c.GREEN, c.DRAW_TWO),
|
||||
c.Card(None, None, c.DRAW_FOUR),
|
||||
c.Card(None, None, c.CHOOSE)]
|
||||
|
||||
p.playable_cards()
|
||||
|
||||
p.play(c.Card(None, None, c.DRAW_FOUR))
|
||||
self.game.choose_color(c.GREEN)
|
||||
|
||||
self.assertFalse(self.game.current_player.prev.bluffing)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in a new issue