110 Commits

Author SHA1 Message Date
14bd90ea92 Update bot.py 2017-03-04 09:30:09 +08:00
9dde74381e Update bot.py
Removing Typos
2017-03-04 09:17:52 +08:00
683d203984 Update bot.py
Adding mode function
2017-03-04 09:17:20 +08:00
d8dfb438a3 Update game_manager.py
Changing the function end_game order to (self, user, chat)
2017-03-03 19:40:40 +08:00
52296e6df8 Update player.py 2017-02-24 14:16:52 +08:00
4c386218b0 Update player.py
Adding a new mode part in the function _card_playable.
2017-02-24 14:15:08 +08:00
393da434e8 Update game.py
Adding a new option "mode"
2017-02-24 13:39:14 +08:00
fae55f758d Merge pull request #30 from jh0ker/master
Update README.md
2017-02-24 13:32:34 +08:00
01640d1df9 Update README.md 2017-02-24 13:26:58 +08:00
92c07d12ad Update bot.py
Changing the function process_result on result_id in c.COLORS such that there is a try-except statement to prevent a deadlock in choosing colors.
2017-02-18 00:06:41 +08:00
bffd7fb1c3 Update errors.py
Adding a new PlayerLeftError
2017-02-17 22:55:11 +08:00
69dc39bb56 Update player.py
Correcting the code once again as the last commit.
2017-02-17 22:47:16 +08:00
75e3076285 Update player.py
Reverting back to the original rule.
2017-02-17 22:05:24 +08:00
f2e7a14318 Update bot.py
Adding the function notify_me more texts in else part.
Adding the function new_game to make players create a new game and join the game with the same command.
Changing the function reset_waiting_time to 60 seconds.
Changing the function skip_player in the else part to include the stats part for skipped_player.
2017-02-17 19:35:56 +08:00
0114fe774d Update game.py
Using set()) instead of list in  self.joined_before
2017-02-17 11:45:53 +08:00
615bb35359 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
2017-02-16 18:43:44 +08:00
284eb91633 Merge pull request #23 from jimchen5209/patch-2
Update unobot.po
2017-02-04 13:56:46 +08:00
bd307b6195 Merge pull request #24 from maildian/master
simple fix for botan
2017-02-04 13:56:20 +08:00
82ecec2d45 Merge pull request #26 from KazamaSion/master
fix some translate mistake in zh-CN.
2017-02-04 13:54:13 +08:00
e1d559e546 fix some translate mistake in zh-CN. 2017-01-29 22:57:50 +08:00
2abdc46ad1 simple fix for botan 2016-11-22 17:51:37 +07:00
3dad1dfebb Update unobot.po 2016-11-21 20:25:30 +08:00
192bbf4b27 fix name of zh_tw 2016-11-19 11:57:14 +01:00
c3a35e739e Fixes list number (#22) 2016-11-18 19:58:04 +01:00
58555f5f21 Fix end-of-line within string 2016-11-18 18:37:53 +01:00
b2ff307964 Adds ru_RU language (#21) 2016-11-18 18:29:01 +01:00
35f0e9308e Zh-Tw Translatiion (#20)
I found many translation mistakes in this translation and some of the new strings weren't translated ,and I have re-translated from English.
2016-11-18 18:27:40 +01:00
09319faf94 Merge pull request #19 from editpes/master
Create requirements.txt
2016-11-08 22:50:56 +01:00
eae0a1a1b7 Update requirements.txt
change python-telegram-bot to version 5
2016-11-06 18:12:24 +07:00
22b046e961 Create requirements.txt 2016-10-30 13:00:15 +07:00
9d2524da5a replace mau_mau_bot by unobot 2016-10-27 14:44:08 +02:00
7d499b21aa Update README.md 2016-10-27 14:01:23 +02:00
b2f78fdbaa Setup instructions 2016-09-01 03:58:46 +02:00
9c74d408b7 Update README.md 2016-08-08 02:27:24 +02:00
f1b241d808 correct command handler 2016-07-05 00:40:36 +02:00
ba81ab614a use set instead of list for notify_me command 2016-07-05 00:38:02 +02:00
b0ca73a3c9 update de_DE translation 2016-07-04 22:09:01 +02:00
ede3aba641 formatting 2016-07-04 22:08:48 +02:00
d64d8c00a9 Merge pull request #14 from TiagoDanin/Translation
Update and Fix Translation
2016-07-04 22:00:02 +02:00
d78f8dcac6 Ops 2016-07-02 14:35:53 -05:00
a5eefdc1d0 Update and Fix Translation 2016-07-02 14:34:06 -05:00
8fe190133f Merge branch 'qubitnerd-qubitnerd_remind_feature' 2016-07-02 20:38:19 +02:00
b136bdf997 formatting, exception handling, documentation 2016-07-02 20:37:35 +02:00
e28bcc58ad add qubitnerd to AUTHORS 2016-07-02 20:36:29 +02:00
2a710145f6 added next_game , get a pm from when next game starts 2016-07-02 21:23:34 +05:30
7f15aac773 missing arg in funciton call 2016-06-04 12:44:21 +02:00
2a52f6e36c for-variable 2016-06-04 12:43:06 +02:00
ad2ae0a752 remove player even if its not registered in player list of user (fix) 2016-06-03 08:00:13 +02:00
fe98147377 remove player even if its not registered in player list of user 2016-06-03 07:58:05 +02:00
91947abce0 remove old, empty games 2016-06-02 15:51:07 +02:00
8dcd05dbb2 kind-of bugfix for duplicate players 2016-06-02 15:36:40 +02:00
5c87e74ae2 small fixes 2016-06-02 15:03:33 +02:00
beaa46f8e4 translation issues 2016-05-27 14:03:12 +02:00
b8e8a7e5de improve unit test of bluffing 2016-05-27 14:02:22 +02:00
569850fade get game before ending it 2016-05-27 11:31:06 +02:00
87251eeb2e add zh_CN to available locales 2016-05-25 20:18:40 +02:00
0f72532825 Merge branch 'imlonghao-zh_CN-patch' 2016-05-25 16:58:30 +02:00
cafa398ec8 Merge branch 'zh_CN-patch' of https://github.com/imlonghao/unocn_bot into imlonghao-zh_CN-patch
Conflicts:
	TRANSLATORS.md
2016-05-25 16:58:04 +02:00
cc88876c69 make zh_CN compatible with plurals 2016-05-25 22:44:51 +08:00
d8d31604e3 update TRANSLATORS.md 2016-05-25 05:56:18 +02:00
e53c45ed2f lang empty by default 2016-05-25 05:54:12 +02:00
857c17b3d4 change lang default en -> en_US 2016-05-25 05:35:30 +02:00
fea63f764a ultima carta 2016-05-25 04:36:47 +02:00
9e98de41c8 add plurals to es_ES (incomplete) 2016-05-25 04:25:10 +02:00
9f88f7ff32 make zh_TW compatible with plurals 2016-05-25 04:15:04 +02:00
6877063a2c make zh_HK compatible with plurals 2016-05-25 04:08:35 +02:00
fb86f6df05 add plurals to it_IT (incomplete) 2016-05-25 03:59:22 +02:00
5a71cbaae0 singular first place 2016-05-25 03:46:25 +02:00
f43cfc2190 fix english plurales 2016-05-25 03:14:07 +02:00
7672e1b47a remove logging call 2016-05-25 03:01:37 +02:00
7c250c6f79 don't record played cards if stats not enabled 2016-05-25 03:01:25 +02:00
bcaea68ef9 Merge pull request #12 from TiagoDanin/Update-pt_BR
Update pt_BR (Add plurals)
2016-05-24 17:10:06 +02:00
3ba225e7a5 Update pt_BR (Add plurals) 2016-05-24 10:02:17 -05:00
6901e7f4d0 implement plurals, update de_DE translation to use plurals 2016-05-24 15:49:23 +02:00
c54ffd83e5 update translator names and links 2016-05-24 11:25:20 +02:00
2041e3cb1f add icon attributions to source command 2016-05-24 09:58:04 +02:00
72515e37ed fix games first place stats 2016-05-24 09:58:04 +02:00
d5cac440ec use icons for draw and pass 2016-05-24 09:58:04 +02:00
23adfe2cb6 Merge pull request #11 from TiagoDanin/master
Small update in translations
2016-05-24 09:46:07 +02:00
de177e1137 Small update in translations 2016-05-23 12:57:41 -05:00
962f550f96 Add me to the Translators.md 2016-05-23 20:11:26 +08:00
06ae098a5f add locale: zh_CN 2016-05-23 20:08:02 +08:00
4a51c7bfb6 change loglevel to INFO 2016-05-23 13:30:57 +02:00
7fd3c662a5 fix issue where people would join a game twice 2016-05-23 13:14:42 +02:00
ecc0b3adc7 add id_ID locale 2016-05-23 13:08:43 +02:00
e7e3fbf4ce add locales: es_ES, zh_HK, zh_TW 2016-05-23 12:20:31 +02:00
0c3f623cd9 small fixes & translation updates 2016-05-23 01:54:56 +02:00
0e680c6e30 update it_IT and add pt_BR 2016-05-23 00:45:44 +02:00
c7b6649438 add italian translations (big thanks to Carola and nick!) 2016-05-22 23:35:16 +02:00
c477701b75 Merge pull request #8 from jh0ker/fix-code
Fix code
2016-05-22 19:24:59 +02:00
ba47f4c19e final version? 2016-05-22 19:21:51 +02:00
4cdffffa5f Optional multi-translations 2016-05-22 17:02:27 +02:00
005445c4dd add database file to gitignore 2016-05-22 14:47:26 +02:00
6c610c1aeb settings UI added, save locale to database 2016-05-22 14:45:51 +02:00
cddf13dc5d add __ function to translate complete stack, add dummy decorators to pull locales from db 2016-05-22 03:13:05 +02:00
5ece46527a locales are working, added de_DE locale 2016-05-21 21:41:38 +02:00
becc7e28dc fix broken method call 2016-05-21 18:56:58 +02:00
a02813477a more stable first-card drawing 2016-05-21 18:56:27 +02:00
73365f49fc draw method reset draw counter on empty deck 2016-05-21 18:55:53 +02:00
d5b76c5c12 fix result list generation 2016-05-21 18:55:03 +02:00
a39fa85b3b more translation supprt 2016-05-20 18:35:21 +02:00
aee310ec9c handle empty decks on player join 2016-05-20 18:34:27 +02:00
0dcd1f6cdc use regular formatting 2016-05-20 17:55:08 +02:00
2316ab8a1c pot formatting 2016-05-20 17:53:01 +02:00
8af8852d05 initial translation support 2016-05-19 23:18:05 +02:00
204b057810 add encoding 2016-05-19 23:15:46 +02:00
9936d97373 update test_end_game 2016-05-19 21:29:07 +02:00
424219d825 fix end_game 2016-05-19 21:28:04 +02:00
c9f7c09a46 update readme 2016-05-19 20:57:32 +02:00
6204868a18 separate game logic from bot interface,
introduce exceptions instead of boolean returns,
remove repetitive code,
begin unit tests,
improve docstrings,
update to python-telegram-bot==4.1.1,
add ponyorm settings classes (unused)
2016-05-19 20:56:52 +02:00
40 changed files with 6553 additions and 557 deletions

5
.gitignore vendored
View File

@ -47,7 +47,7 @@ coverage.xml
# Translations # Translations
*.mo *.mo
*.pot # *.pot
# Django stuff: # Django stuff:
*.log *.log
@ -63,3 +63,6 @@ target/
# PyCharm # PyCharm
.idea .idea
# Database file
uno.sqlite3

View File

@ -7,5 +7,6 @@
The following wonderful people contributed directly or indirectly to this project: The following wonderful people contributed directly or indirectly to this project:
- [imlonghao](https://github.com/imlonghao) - [imlonghao](https://github.com/imlonghao)
- [qubitnerd](https://github.com/qubitnerd)
Please add yourself here alphabetically when you submit your first pull request. Please add yourself here alphabetically when you submit your first pull request.

View File

@ -1,10 +1,19 @@
# UNO Bot # UNO Bot
Telegram Bot that allows you to play the popular card game UNO via inline queries. The bot currently runs as [@mau_mau_bot](http://telegram.me/mau_mau_bot)
[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](./LICENSE)
Telegram Bot that allows you to play the popular card game UNO via inline queries. The bot currently runs as [@unobot](http://telegram.me/unobot)
To run the bot yourself, you will need: To run the bot yourself, you will need:
- Python (tested with 3.4 and 3.5) - Python (tested with 3.4 and 3.5)
- The [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) module version 4.0.3 - The [python-telegram-bot](https://github.com/python-telegram-bot/python-telegram-bot) module version 5.0.0
- [Pony ORM](https://ponyorm.com/)
Get a bot token from [@BotFather](http://telegram.me/BotFather), place it in `credentials.py` and run the bot with `python3 bot.py` ## Setup
- Get a bot token from [@BotFather](http://telegram.me/BotFather) and place it in `credentials.py`
- Convert all language files from .po to .mo using `msgfmt unobot.po -o unobot.mo`
- Use `/setinline` and `/setinlinefeedback` with BotFather for your bot
Then run the bot with `python3 bot.py`
Code documentation is minimal but there Code documentation is minimal but there

16
TRANSLATORS.md Normal file
View File

@ -0,0 +1,16 @@
# Translators
The following awesome people contributed to this project by translating it:
| Locale | Translators |
|--------|----------------------------------------------------------------------|
| de_DE | [Jannes Höke](https://github.com/jh0ker) |
| es_ES | [Ricardo Valverde Hernández](https://telegram.me/rivh1), Victor, Yuga|
| id_ID | [Erwin Guo](https://www.facebook.com/erwinfransiscus) |
| it_IT | Carola Mariano, ɳick |
| pt_BR | [João Rodrigo Couto de Oliveira](http://twitter.com/JoaoRodrigoJR) |
| zh_CN | [imlonghao](https://github.com/imlonghao) |
| zh_HK | [Jed Cheng](https://www.facebook.com/profile.php?id=100002258388821) |
| zh_TW | [Eugene Lam](https://www.facebook.com/eugenelam1118) |
Please add yourself here alphabetically when you submit your first translation.

902
bot.py

File diff suppressed because it is too large Load Diff

15
card.py
View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
@ -115,8 +116,8 @@ STICKERS = {
'y_reverse': 'BQADBAADQQIAAl9XmQABZdQFahGG6UQC', 'y_reverse': 'BQADBAADQQIAAl9XmQABZdQFahGG6UQC',
'draw_four': 'BQADBAAD9QEAAl9XmQABVlkSNfhn76cC', 'draw_four': 'BQADBAAD9QEAAl9XmQABVlkSNfhn76cC',
'colorchooser': 'BQADBAAD8wEAAl9XmQABl9rUOPqx4E4C', 'colorchooser': 'BQADBAAD8wEAAl9XmQABl9rUOPqx4E4C',
'option_draw': 'BQADBAADzAIAAl9XmQABTkPaOqA5HIMC', 'option_draw': 'BQADBAAD-AIAAl9XmQABxEjEcFM-VHIC',
'option_pass': 'BQADBAADzgIAAl9XmQABWSDq3RIg3c0C', 'option_pass': 'BQADBAAD-gIAAl9XmQABcEkAAbaZ4SicAg',
'option_bluff': 'BQADBAADygIAAl9XmQABJoLfB9ntI2UC', 'option_bluff': 'BQADBAADygIAAl9XmQABJoLfB9ntI2UC',
'option_info': 'BQADBAADxAIAAl9XmQABC5v3Z77VLfEC' 'option_info': 'BQADBAADxAIAAl9XmQABC5v3Z77VLfEC'
} }
@ -180,9 +181,7 @@ STICKERS_GREY = {
class Card(object): class Card(object):
""" """This class represents an UNO card"""
This class represents a card.
"""
def __init__(self, color, value, special=None): def __init__(self, color, value, special=None):
self.color = color self.color = color
@ -205,16 +204,16 @@ class Card(object):
return '%s%s' % (COLOR_ICONS[self.color], self.value.capitalize()) return '%s%s' % (COLOR_ICONS[self.color], self.value.capitalize())
def __eq__(self, other): def __eq__(self, other):
""" Needed for sorting the cards """ """Needed for sorting the cards"""
return str(self) == str(other) return str(self) == str(other)
def __lt__(self, other): def __lt__(self, other):
""" Needed for sorting the cards """ """Needed for sorting the cards"""
return str(self) < str(other) return str(self) < str(other)
def from_str(string): def from_str(string):
""" Decode a Card object from a string """ """Decodes a Card object from a string"""
if string not in SPECIALS: if string not in SPECIALS:
color, value = string.split('_') color, value = string.split('_')
return Card(color, value) return Card(color, value)

21
chat_setting.py Normal file
View File

@ -0,0 +1,21 @@
#!/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/>.
pass

24
database.py Normal file
View File

@ -0,0 +1,24 @@
#!/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/>.
from pony.orm import Database, db_session, Optional, Required, Set, PrimaryKey
# Database singleton
db = Database()

22
deck.py
View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
@ -18,9 +19,11 @@
from random import shuffle from random import shuffle
import logging
import card as c import card as c
from card import Card from card import Card
import logging from errors import DeckEmptyError
class Deck(object): class Deck(object):
@ -45,22 +48,25 @@ class Deck(object):
self.shuffle() self.shuffle()
def shuffle(self): def shuffle(self):
""" Shuffle the deck """ """Shuffles the deck"""
self.logger.debug("Shuffling Deck") self.logger.debug("Shuffling Deck")
shuffle(self.cards) shuffle(self.cards)
def draw(self): def draw(self):
""" Draw a card from this deck """ """Draws a card from this deck"""
try: try:
card = self.cards.pop() card = self.cards.pop()
self.logger.debug("Drawing card " + str(card)) self.logger.debug("Drawing card " + str(card))
return card return card
except IndexError: except IndexError:
while len(self.graveyard): if len(self.graveyard):
self.cards.append(self.graveyard.pop()) while len(self.graveyard):
self.shuffle() self.cards.append(self.graveyard.pop())
return self.draw() self.shuffle()
return self.draw()
else:
raise DeckEmptyError()
def dismiss(self, card): def dismiss(self, card):
""" All played cards should be returned into the deck """ """Returns a card to the deck"""
self.graveyard.append(card) self.graveyard.append(card)

42
errors.py Normal file
View File

@ -0,0 +1,42 @@
#!/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/>.
class NoGameInChatError(Exception):
pass
class AlreadyJoinedError(Exception):
pass
class LobbyClosedError(Exception):
pass
class NotEnoughPlayersError(Exception):
pass
class DeckEmptyError(Exception):
pass
class PlayerLeftError(Exception):
pass

30
game.py
View File

@ -1,7 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 - 2017 Jannes Höke <uno@jhoeke.de> and Karho Yau
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -33,21 +34,24 @@ class Game(object):
started = False started = False
owner = None owner = None
open = True open = True
translate = False
players_won = 0
mode = 0
def __init__(self, chat): def __init__(self, chat):
self.chat = chat self.chat = chat
self.deck = Deck() self.last_card = None
self.last_card = self.deck.draw() self.joined_before = set()
while self.last_card.special: while not self.last_card or self.last_card.special:
self.deck.dismiss(self.last_card) self.deck = Deck()
self.deck.shuffle()
self.last_card = self.deck.draw() self.last_card = self.deck.draw()
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
@property @property
def players(self): def players(self):
"""Returns a list of all players in this game"""
players = list() players = list()
if not self.current_player: if not self.current_player:
return players return players
@ -61,18 +65,23 @@ class Game(object):
return players return players
def reverse(self): def reverse(self):
""" Reverse the direction of play """ """Reverses the direction of game"""
self.reversed = not self.reversed self.reversed = not self.reversed
def turn(self): def turn(self):
""" Mark the turn as over and change the current player """ """Marks the turn as over and change the current player"""
self.logger.debug("Next Player") self.logger.debug("Next Player")
self.current_player = self.current_player.next self.current_player = self.current_player.next
self.current_player.drew = False self.current_player.drew = False
self.current_player.turn_started = datetime.now() self.current_player.turn_started = datetime.now()
self.choosing_color = False
def play_card(self, card): def play_card(self, card):
""" Play a card and trigger its effects """ """
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.deck.dismiss(self.last_card)
self.last_card = card self.last_card = card
@ -100,7 +109,6 @@ class Game(object):
self.choosing_color = True self.choosing_color = True
def choose_color(self, color): def choose_color(self, color):
""" Carries out the color choosing and turns the game """ """Carries out the color choosing and turns the game"""
self.last_card.color = color self.last_card.color = color
self.turn() self.turn()
self.choosing_color = False

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
@ -18,9 +19,12 @@
import logging import logging
import random
from game import Game from game import Game
from player import Player from player import Player
from errors import (AlreadyJoinedError, LobbyClosedError, NoGameInChatError,
NotEnoughPlayersError)
class GameManager(object): class GameManager(object):
@ -30,6 +34,8 @@ class GameManager(object):
self.chatid_games = dict() self.chatid_games = dict()
self.userid_players = dict() self.userid_players = dict()
self.userid_current = dict() self.userid_current = dict()
self.remind_dict = dict()
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
def new_game(self, chat): def new_game(self, chat):
@ -38,22 +44,31 @@ class GameManager(object):
""" """
chat_id = chat.id chat_id = chat.id
self.logger.info("Creating new game with id " + str(chat_id)) self.logger.debug("Creating new game in chat " + str(chat_id))
game = Game(chat) game = Game(chat)
if chat_id not in self.chatid_games: if chat_id not in self.chatid_games:
self.chatid_games[chat_id] = list() self.chatid_games[chat_id] = list()
# remove old games
for g in list(self.chatid_games[chat_id]):
if not g.players:
self.chatid_games[chat_id].remove(g)
self.chatid_games[chat_id].append(game) self.chatid_games[chat_id].append(game)
return game return game
def join_game(self, chat_id, user): def join_game(self, user, chat):
""" Create a player from the Telegram user and add it to the game """ """ Create a player from the Telegram user and add it to the game """
self.logger.info("Joining game with id " + str(chat_id)) self.logger.info("Joining game with id " + str(chat.id))
try: try:
game = self.chatid_games[chat_id][-1] game = self.chatid_games[chat.id][-1]
except (KeyError, IndexError): except (KeyError, IndexError):
return None raise NoGameInChatError()
if not game.open:
raise LobbyClosedError()
if user.id not in self.userid_players: if user.id not in self.userid_players:
self.userid_players[user.id] = list() self.userid_players[user.id] = list()
@ -61,76 +76,122 @@ class GameManager(object):
players = self.userid_players[user.id] players = self.userid_players[user.id]
# Don not re-add a player and remove the player from previous games in # Don not re-add a player and remove the player from previous games in
# this chat # this chat, if he is in one of them
for player in players: for player in players:
if player in game.players: # Try to pervent someone win or leave then join again.
return False if player in game.players or user.id in game.joined_before:
raise AlreadyJoinedError()
else: else:
self.leave_game(user, chat_id) try:
self.leave_game(user, chat)
except NoGameInChatError:
pass
except NotEnoughPlayersError:
self.end_game(chat, user)
if user.id not in self.userid_players:
self.userid_players[user.id] = list()
players = self.userid_players[user.id]
player = Player(game, user) 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 self.userid_current[user.id] = player
return True
def leave_game(self, user, chat_id): def leave_game(self, user, chat):
""" Remove a player from its current game """ """ Remove a player from its current game """
try:
players = self.userid_players[user.id]
games = self.chatid_games[chat_id]
for player in players: player = self.player_for_user_in_chat(user, chat)
for game in games: players = self.userid_players.get(user.id, list())
if player in game.players:
if player is game.current_player:
game.turn()
player.leave() if not player:
players.remove(player) games = self.chatid_games[chat.id]
for g in games:
for p in g.players:
if p.user.id == user.id:
if p is g.current_player:
g.turn()
# If this is the selected game, switch to another p.leave()
if self.userid_current[user.id] is player: return
if len(players):
self.userid_current[user.id] = players[0]
else:
del self.userid_current[user.id]
return True
else: else:
return False raise NoGameInChatError
except KeyError: game = player.game
return False
def end_game(self, chat_id, user): if len(game.players) < 3:
raise NotEnoughPlayersError()
if player is game.current_player:
game.turn()
player.leave()
players.remove(player)
# If this is the selected game, switch to another
if self.userid_current.get(user.id, None) is player:
if players:
self.userid_current[user.id] = players[0]
else:
del self.userid_current[user.id]
del self.userid_players[user.id]
def end_game(self, user, chat):
""" """
End a game End a game
""" """
self.logger.info("Game in chat " + str(chat_id) + " ended") self.logger.info("Game in chat " + str(chat.id) + " ended")
players = self.userid_players[user.id]
games = self.chatid_games[chat_id]
the_game = None
# Find the correct game instance to end # Find the correct game instance to end
for player in players: player = self.player_for_user_in_chat(user, chat)
for game in games:
if player in game.players:
the_game = game
break
if the_game:
break
else:
return
for player in the_game.players: if not player:
this_users_players = self.userid_players[player.user.id] raise NoGameInChatError
this_users_players.remove(player)
if len(this_users_players) is 0: game = player.game
del self.userid_players[player.user.id]
del self.userid_current[player.user.id] # Clear game
for player_in_game in game.players:
this_users_players = \
self.userid_players.get(player_in_game.user.id, list())
try:
this_users_players.remove(player_in_game)
except ValueError:
pass
if this_users_players:
try:
self.userid_current[player_in_game.user.id] = this_users_players[0]
except KeyError:
pass
else: else:
self.userid_current[player.user.id] = this_users_players[0] try:
del self.userid_players[player_in_game.user.id]
except KeyError:
pass
self.chatid_games[chat_id].remove(the_game) try:
return del self.userid_current[player_in_game.user.id]
except KeyError:
pass
self.chatid_games[chat.id].remove(game)
if not self.chatid_games[chat.id]:
del self.chatid_games[chat.id]
def player_for_user_in_chat(self, user, chat):
players = self.userid_players.get(user.id, list())
for player in players:
if player.game.chat.id == chat.id:
return player
else:
return None

BIN
images/png/option_draw2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
images/png/option_pass2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

171
internationalization.py Normal file
View File

@ -0,0 +1,171 @@
#!/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 gettext
from functools import wraps
from locales import available_locales
from database import db_session
from user_setting import UserSetting
from shared_vars import gm
GETTEXT_DOMAIN = 'unobot'
GETTEXT_DIR = 'locales'
class _Underscore(object):
"""Class to emulate flufl.i18n behaviour, but with plural support"""
def __init__(self):
self.translators = {
locale: gettext.GNUTranslations(
open(gettext.find(
GETTEXT_DOMAIN, GETTEXT_DIR, languages=[locale]
), 'rb')
)
for locale
in available_locales.keys()
if locale != 'en_US' # No translation file for en_US
}
self.locale_stack = list()
def push(self, locale):
self.locale_stack.append(locale)
def pop(self):
if self.locale_stack:
return self.locale_stack.pop()
else:
return None
@property
def code(self):
if self.locale_stack:
return self.locale_stack[-1]
else:
return None
def __call__(self, singular, plural=None, n=1, locale=None):
if not locale:
locale = self.locale_stack[-1]
if locale not in self.translators.keys():
if n is 1:
return singular
else:
return plural
translator = self.translators[locale]
if plural is None:
return translator.gettext(singular)
else:
return translator.ngettext(singular, plural, n)
_ = _Underscore()
def __(singular, plural=None, n=1, multi=False):
"""Translates text into all locales on the stack"""
translations = list()
if not multi and len(set(_.locale_stack)) >= 1:
translations.append(_(singular, plural, n, 'en_US'))
else:
for locale in _.locale_stack:
translation = _(singular, plural, n, locale)
if translation not in translations:
translations.append(translation)
return '\n'.join(translations)
def user_locale(func):
@wraps(func)
@db_session
def wrapped(bot, update, *pargs, **kwargs):
user, chat = _user_chat_from_update(update)
with db_session:
us = UserSetting.get(id=user.id)
if us and us.lang != 'en':
_.push(us.lang)
else:
_.push('en_US')
result = func(bot, update, *pargs, **kwargs)
_.pop()
return result
return wrapped
def game_locales(func):
@wraps(func)
@db_session
def wrapped(bot, update, *pargs, **kwargs):
user, chat = _user_chat_from_update(update)
player = gm.player_for_user_in_chat(user, chat)
locales = list()
if player:
for player in player.game.players:
us = UserSetting.get(id=player.user.id)
if us and us.lang != 'en':
loc = us.lang
else:
loc = 'en_US'
if loc in locales:
continue
_.push(loc)
locales.append(loc)
result = func(bot, update, *pargs, **kwargs)
while _.code:
_.pop()
return result
return wrapped
def _user_chat_from_update(update):
try:
user = update.message.from_user
chat = update.message.chat
except (NameError, AttributeError):
try:
user = update.inline_query.from_user
chat = gm.userid_current[user.id].game.chat
except KeyError:
chat = None
except (NameError, AttributeError):
try:
user = update.chosen_inline_result.from_user
chat = gm.userid_current[user.id].game.chat
except (NameError, AttributeError, KeyError):
chat = None
return user, chat

21
locales/__init__.py Normal file
View File

@ -0,0 +1,21 @@
#!/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/>.
from .available import available_locales

39
locales/available.py Normal file
View File

@ -0,0 +1,39 @@
#!/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/>.
"""Defines a dict of all available locales to the language name"""
OFFSET = 127462 - ord('A')
def flag(code):
return chr(ord(code[0]) + OFFSET) + chr(ord(code[1]) + OFFSET)
available_locales = {'en_US': flag('US') + ' English (US)',
'de_DE': flag('DE') + ' Deutsch (DE)',
'es_ES': flag('ES') + ' Español (ES)',
'id_ID': flag('ID') + ' Bahasa Indonesia',
'it_IT': flag('IT') + ' Italiano',
'pt_BR': flag('BR') + ' Português Brasileiro',
'ru_RU': flag('RU') + ' Русский язык',
'zh_CN': flag('CN') + ' 中文(简体)',
'zh_HK': flag('HK') + ' 廣東話',
'zh_TW': flag('TW') + ' 中文(台灣)'}

View File

@ -0,0 +1,470 @@
# 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/>.
# Jannes Höke <uno@jhoeke.de>, 2016.
#
#: bot.py:224
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-19 22:38+0200\n"
"PO-Revision-Date: 2016-05-21 21:16+0200\n"
"Last-Translator: Jannes Höke <uno@jhoeke.de>\n"
"Language-Team: Deutsch <uno@jhoeke.de>\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.6\n"
#: bot.py:60
msgid "Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Folge den folgenden Schritten:\n"
"\n"
"1. Füge diesen Bot einer Gruppe hinzu\n"
"2. In einer Gruppe kannst du mit /new ein neues Spiel erstellen und mit /"
"join einem bestehenden Spiel beitreten\n"
"3. Nachdem mindestens zwei Spieler beigetreten sind, starte das Spiel mit /"
"start\n"
"4. Gib <code>@unobot</code> in deine Chatbox ein und drücke die "
"<b>Leertaste</b>, oder tippe auf den <code>via @unobot</code>-Text "
"neben oder über den Nachrichten. Du siehst deine Karten (einige in grau), "
"zusätzliche Optionen wie z. B. Ziehen, und ein <b>?</b> um den Infos über "
"das laufende Spiel anzuzeigen. Die <b>grauen Karten</b> kannst du gerade "
"<b>nicht spielen</b>. Tippe eine der Optionen oder Karten an, um diese "
"Aktion auszuführen bzw. die Karte zu spielen. \n"
"Spieler können dem Spiel jederzeit beitreten. Um das Spiel zu verlassen, "
"benutze /leave. Wenn ein Spieler länger als 90 Sekunden braucht, kannst du "
"ihn mit /skip überspringen. "
"Benutze /notify_me, um über ein neues Spiel in dieser Gruppe per privater "
"Nachricht informiert zu werden.\n"
"\n"
"<b>Sprache</b> und andere Einstellungen: /settings\n"
"Weitere Kommandos (nur Spiel-Ersteller):\n"
"/close - Lobby schließen\n"
"/open - Lobby öffnen\n"
"/enable_translations - Übersetze relevante Texte in alle im Spiel gesprochenen"
" Sprachen\n"
"/disable_translations - Verwende Englisch für diese Texte\n"
"\n"
"<b>Experimentell</b>: Spiele in mehreren Gruppen gleichzeitig. Um die "
"Gruppe, in der du deine Karte spielen willst, auszuwählen, tippe auf den "
"<code>Aktuelles Spiel: ...</code>-Button.\n"
"Wenn dir dieser Bot gefällt, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">bewerte ihn</a>, tritt dem <a href=\"https://telegram.me/"
"unobotupdates\">News-Channel</a> bei und kaufe ein UNO Kartenspiel."
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Dieser Bot ist Freie Software und lizenziert unter der AGPL. Der Quellcode "
"ist hier verfügbar:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr ""
"Neues Spiel erstellt! Tritt dem Spiel mit /join bei und starte es mit /start"
#: bot.py
msgid "Send this command in a group to be notified when a new game is started there."
msgstr "Benutze diesen Befehl in einer Gruppe, um über das nächste neu eröffnete "
"Spiel informiert zu werden."
#: bot.py
msgid "A new game has been started in {title}"
msgstr "In der Gruppe {title} wurde gerade ein neues Spiel gestartet"
#: bot.py:152
msgid "The lobby is closed"
msgstr "Die Lobby ist geschlossen"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "Zur Zeit läuft kein Spiel. Erstelle ein neues mit /new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "Du bist dem Spiel bereits beigetreten. Starte es mit /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Spiel beigetreten"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "Du spielst in keinem Spiel in dieser Gruppe."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "Spiel beendet!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Okay. Nächster Spieler: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Spiel nicht gefunden."
#: bot.py:223
msgid "Back to last group"
msgstr "Zurück zur letzten Gruppe"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "Bitte wechsele zu der Gruppe, die du gewählt hast!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Ausgewählte Gruppe: {group}\n"
"<b>Stell sicher, dass du in die richtige Gruppe wechselst!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Entferne {name} aus dem Spiel"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
"In dieser Gruppe gibt es kein laufendes Spiel. Erstelle ein neues mit /new"
#: bot.py:278
msgid "The game has already started"
msgstr "Das Spiel hat bereits begonnen"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr "Es müssen mindestens zwei Spieler dem Spiel beitreten, bevor du es "
"starten kannst"
#: bot.py:297
#, python-format, fuzzy
msgid "First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Erster Spieler: {name}\n"
"Benutze /close, um zu verhindern, dass weitere Spieler beitreten."
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Bitte wähle die Gruppe, in der du spielen willst."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "In dieser Gruppe läuft gerade kein Spiel."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr ""
"Lobby geschlossen. Diesem Spiel können keine weiteren Spieler beitreten."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Dies kann nur der Ersteller des Spiels ({name}) tun."
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "Multi-Übersetzungen aktiviert. Deaktivieren mit /disable_translations"
#: bot.py:377
#, python-format
msgid "Disabled multi-translations. Enable them again with /enable_translations"
msgstr "Multi-Übersetzungen deaktiviert. Aktiviere sie wieder mit "
"/enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "Lobby geöffnet. Neue Spieler können nun beitreten."
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "Du spielst kein Spiel in dieser Gruppe."
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "Bitte warte {time} Sekunde"
msgstr[1] "Bitte warte {time} Sekunden"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] "Die Wartezeit um diesen Spieler zu überspringen wurde auf {time} "
"Sekunde reduziert.\n"
"Nächster Spieler: {name}"
msgstr[1] "Die Wartezeit um diesen Spieler zu überspringen wurde auf {time} "
"Sekunden reduziert.\n"
"Nächster Spieler: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} wurde vier Mal hintereinander übersprungen und daher aus dem Spiel "
"entfernt.\n"
"Nächster Spieler: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name1} wurde vier Mal hintereinander übersprungen und daher aus dem Spiel "
"entfernt.\n"
"Das Spiel wurde beendet."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Alle News hier: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {game}"
msgstr "Aktuelles Spiel: {game}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "{name} hat versucht zu schummeln!"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Nächster Spieler: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "Die Wartezeit für {name} wurde auf 90 Sekunden zurückgesetzt."
#: bot.py:585
msgid "Please choose a color"
msgstr "Bitte wähle eine Farbe"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} hat gewonnen!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "Es sind keine Karten mehr im Deck."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Bluff gecalled! {name} bekommt 4 Karten."
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} hat nicht geblufft! {name2} bekommt 6 Karten."
#: results.py:38
msgid "Choose Color"
msgstr "Wähle Farbe"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "Letzte Karte (tippe für Spielinfo):"
msgstr[1] "Karten (tippe für Spielinfo):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Aktueller Spieler: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Letzte Karte: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "Spieler: {player_list}"
msgstr[1] "Spieler: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} Karte)"
msgstr[1] "{name} ({number} Karten)"
#: results.py:81
msgid "You are not playing"
msgstr "Du spielst gerade nicht"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"Du spielst gerade nicht. Benutze /new um ein neues Spiel zu starten oder /"
"join, um einem bestehenden Spiel beizutreten."
#: results.py:95
msgid "The game wasn't started yet"
msgstr "Das Spiel wurde noch nicht gestartet."
#: results.py:97
msgid "Start the game with /start"
msgstr "Starte das Spiel mit /start"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Ich ziehe {number} Karte"
msgstr[1] "Ich ziehe {number} Karten"
#: results.py:136
msgid "Pass"
msgstr "Passe"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Ich glaube du bluffst!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "Bitte ändere deine Einstellungen in einem privaten Chat mit dem Bot."
#: settings.py:49
msgid "Enable statistics"
msgstr "Statistiken aktivieren"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Alle Statistiken löschen"
#: settings.py:53
msgid "Language"
msgstr "Sprache"
#: settings.py:54
msgid "Settings"
msgstr "Einstellungen"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Statistiken aktiviert!"
#: settings.py:70
msgid "Select locale"
msgstr "Bitte Sprache auswählen"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Alle Statistiken gelöscht und deaktiviert!"
#: settings.py:94
msgid "Set locale!"
msgstr "Sprache gesetzt!"
#: simple_commands.py
msgid "You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."
msgstr "Du hast die Spiel-Statistiken nicht aktiviert. Aktiviere sie, mit dem "
"/settings-Kommando in einem privaten Chat mit dem Bot."
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "{number} gespieltes Spiel"
msgstr[1] "{number} gespielte Spiele"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "{number} mal 1. Platz"
msgstr[1] "{number} mal 1. Platz"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "{number} gespielte Karte"
msgstr[1] "{number} gespielte Karten"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Grün"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Rot"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Blau"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Gelb"

View File

@ -0,0 +1,461 @@
# 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/>.
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-22 17:32-0600\n"
"PO-Revision-Date: 2016-05-22 21:20-0600\n"
"Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: es\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Sigue estos pasos:\n"
"\n"
"1. Añade este bot a un grupo\n"
"2. En el grupo, crea una partida nueva con /new o únete a una iniciada con /"
"join\n"
"3. Después de que al menos dos jugadores se han unido, comienza la partida "
"con /start\n"
"4. Escribe <code>@unobot</code> en la caja de texto y presiona "
"<b>espacio</b> o haz clic en el texto <code>via @unobot</code>junto a "
"los mensajes. Verás tus cartas (algunas de tono grisáceo), cualquier opción "
"adicional como robar y un <b>?</b> para ver el estado actual de la partida. "
"Las <b>cartas grisáceas</b> son aquellas <b>no pueden usarse</b> en el "
"momento. Presiona una opción para ejecutar la acción seleccionada.\n"
"Los jugadores pueden unirse en cualquier momento. Para abandonar una "
"partida, usa /leave. Si un jugador se tarda más de 90 segundos en jugar, "
"puedes usar el /skip para saltar ese jugador.\n"
"\n"
"<b>Idioma</b> y otros ajustes: /settings\n"
"Otros comandos (solo el creador de la partida puede usar):\n"
"/close - Cerrar sala\n"
"/open - Abrir sala\t\n"
"/enable_translations - Traducir mensajes importantes a todos los idiomas "
"disponibles en la partida\n"
"/disable_translations - Usar el idioma por defecto (idioma inglés) \n"
"\n"
"<b>Experimental:</b> Para jugar en múltiples grupos al mismo tiempo. "
"Presiona el botón <code>Current game: ...</code> y selecciona el grupo en "
"el que deseas realizar una jugada.\n"
"Si te gusta el bot <a href=\"https://telegram.me/storebot?start=mau_mau_bot"
"\">rate me</a>, únete al <a href=\"https://telegram.me/unobotupdates\">canal "
"de actualizaciones </a> y compra el juego de cartas UNO."
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Este bot es Software Libre y esta licenciado bajo AGPL. El código esta "
"disponible aquí:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr ""
"¡Partida nueva creada! Únete a la partida con /join y comienza la partida "
"con /start "
#: bot.py:152
msgid "The lobby is closed"
msgstr "La sala esta cerrada"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr ""
"No hay ninguna partida activa por el momento. Crea una partida con /new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "Ya te uniste a la partida. Comienza la partida con /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Te uniste a la partida"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "No estas jugando una partida en este grupo."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "¡Fin de la partida!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Okay. Siguiente Jugador: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Partida no encontrada."
#: bot.py:223
msgid "Back to last group"
msgstr "De vuelta al último grupo"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "¡Por favor ve al grupo seleccionado!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Grupo seleccionado: {group}\n"
"<b>¡Asegúrate de haber cambiado al grupo correcto!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Removiendo a {name} de la partida"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr "No hay ninguna partida en curso en este chat. Crea una nueva con /new"
#: bot.py:278
msgid "The game has already started"
msgstr "La partida ya ha comenzado"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr ""
"Antes de iniciar la partida, al menos dos jugadores deben darle al /join"
#: bot.py:297
#, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Primer Jugador: {name}\n"
"Usa /close para evitar que la gente se una a la partida.\n"
"Habilita multi-traducciones con /enable_translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Elige el grupo en el que deseas jugar."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "No hay ninguna partida ejecutándose en este chat."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr "Sala cerrada. No se pueden unir más jugadores a la partida."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Solo el creador de la partida ({name}) puede hacer eso."
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr ""
"Multi-traducciones habilitadas. Deshabilítalas con /disable_translations"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr ""
"Multi-traducciones deshabilitadas. Habilítalas de nuevo con /"
"enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "Sala abierta. Nuevos jugadores darle al /join."
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "No estás jugando una partida en este chat."
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "Por favor, espere {time} segundo"
msgstr[1] "Por favor, espere {time} segundos"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] ""
"El tiempo de espera para saltar al jugador actual se ha reducido {time} "
"segundo.\n"
"Siguiente jugador: {name}"
msgstr[1] ""
"El tiempo de espera para saltar al jugador actual se ha reducido {time} "
"segundos.\n"
"Siguiente jugador: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} fue saltado cuatro veces consecutivas y ha sido removido de la "
"partida.\n"
"Siguiente Jugador {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name} fue saltado cuatro veces consecutivas y ha sido removido de la "
"partida.\n"
"Partida finalizada."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Todas las noticias aquí: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "Partida actual: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "Intento de trampa por {name}"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Siguiente Jugador: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "El tiempo de espera para {name} se ha reiniciado a 90 segundos"
#: bot.py:585
msgid "Please choose a color"
msgstr "Por favor, selecciona un color"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "¡{name} ganó!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "No hay más cartas en la baraja."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "¡Engaño descubierto! {name} recibe 4 cartas"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "¡{name1} no ha engañado!, {name2} recibe 6 cartas"
#: results.py:38
msgid "Choose Color"
msgstr "Selecciona un color"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "Última carta (presiona para el estado de la partida):"
msgstr[1] "Cartas (presiona para el estado de la partida):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Jugador actual: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Última carta: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "Jugador: {player_list}"
msgstr[1] "Jugadores: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} carta)"
msgstr[1] "{name} ({number} cartas)"
#: results.py:81
msgid "You are not playing"
msgstr "No estás jugando"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"No estas jugando en este momento. Usa /new para comenzar una partida o /"
"join para unirte a la partida actual en este grupo"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "La partida no ha comenzado todavía"
#: results.py:97
msgid "Start the game with /start"
msgstr "Comenzar la partida con /start"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Robando {number} carta"
msgstr[1] "Robando {number} cartas"
#: results.py:136
msgid "Pass"
msgstr "Pasar"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Me estas engañando!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "Por favor, edita tus ajustes en un chat privado con el bot."
#: settings.py:49
msgid "Enable statistics"
msgstr "Habilitar estadísticas"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Borrar estadísticas"
#: settings.py:53
msgid "Language"
msgstr "Idioma"
#: settings.py:54
msgid "Settings"
msgstr "Ajustes"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Estadísticas habilitadas!"
#: settings.py:70
msgid "Select locale"
msgstr "Seleccionar región"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Estadísticas borradas y deshabilitadas! "
#: settings.py:94
msgid "Set locale!"
msgstr "Región seleccionada!"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr ""
"No has habilitado las estadísticas. Usa /settings en un chat privado con el "
"bot para habilitarlas."
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "{number} partida jugada"
msgstr[1] "{number} partidas jugadas"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "{number} primero lugare"
msgstr[1] "{number} primeros lugares"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "{number} carta jugada"
msgstr[1] "{number} cartas jugadas"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Verde"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Rojo"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Azul"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Amarillo"

View File

@ -0,0 +1,454 @@
# 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/>.
# Jannes Höke <uno@jhoeke.de>, 2016.
#
#: bot.py:224
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-19 22:38+0200\n"
"PO-Revision-Date: 2016-05-23 12:43+0200\n"
"Last-Translator: Jannes Höke <uno@jhoeke.de>\n"
"Language-Team: Deutsch <uno@jhoeke.de>\n"
"Language: in_ID\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Generator: Gtranslator 2.91.6\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Ikuti langkah-langkah berikut:\n"
"\n"
"1. Tambahkan grup ini ke dalam grup\n"
"2. Di dalam grup, Membuat permainan baru dengan /new atau bergabung dengan "
"permainan yang sudah berjalan dengan perintah /join\n"
"3.Setelah setidaknya dua pemain bergabung, mulailah permainan dengan "
"perintah /start\n"
"4. Ketik <code>@unobot</code> kedalam chat box dan tekan<b>spasi</b>, "
"atau pilih <code>via @unobot</code> dari daftar pemain. Kamu akan "
"melihat daftar kartumu (yang beberapa tidak dapat dipilih), pilihan lainnya "
"seperti gambar kartu, dan tanda tanya (<b>?</b>) untuk melihat status "
"permainan. Kartu yang <b>berwarna abu-abu</b> adalah kartu yang saat ini "
"<b>tidak dapat dimainkan</b>. Pilih gambar untuk melakukan aksi seperti "
"memilih kartu atau melihat status permainan.\n"
"Pemain dapat bergabung ke dalam permainan kapan saja. Untuk meinggalkan "
"permainan, gunakan /leave.Apabila seorang pemain melebihi 90 detik dalam "
"memilih kartu, kamu bisa menggunakna /skip to melompatipemain tersebut.\n"
"\n"
"<b>Bahasa</b> dan pengaturan lainnya: /settings\n"
"Perintah lainnya (hanya pembuat game):\n"
"/close - Menutup lobby\n"
"/open - Membuka lobby\n"
"/enable_translations - Mengubah tulisan tertulis menjadi semua bahasa pada "
"permainan \n"
"/disable_translations - Menggunakan bahasa inggris sebagai bahasa utama\n"
"\n"
"<b>Eksperimental:</b> Bermain dalam lebih dari satu grup pada waktu yang "
"bersamaan. Tekan <code>Current game: ...</code> dan pilih grup yang ingin "
"kamu mainkan \n"
"Kalau kamu menyukai bot ini, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">beri kami rating</a>, bergabunglah the <a href=\"https://"
"telegram.me/unobotupdates\">update channel</a> dan belilah kartu permainan "
"UNO ."
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Bot ini adalah software gratis dan berlisensi dibawah AGPL. Kode nya "
"tersedia disini: \n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr ""
"Membuat permmainan baru! Ayo bergabung dengan perintah /join dan mulailah "
"permainan tersebut dengan perintah /start"
#: bot.py:152
msgid "The lobby is closed"
msgstr "Lobby ditutup"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr ""
"Tidak ada permainan yang berlangsung. Buat permainan baru dengan perintah /"
"new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr ""
"Kamu sudah bergabung dengan permainan. Mulai permainan dengan perintah /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Tergabung dengan permainan"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "Kamu tidak bermain di grup ini."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "Permainan berakhir!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Baiklah. Pemain berikutnya: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Permainan tidak ditemukan."
#: bot.py:223
msgid "Back to last group"
msgstr "Kembali ke grup sebelumnya"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "Silakan pilih grup!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Grup terpilih: {group}\n"
"<b>Pastikan kamu sudah memilih grup yang benar!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Mengeluarkan {name} dari permainan"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
"Tidak ada permainan yang berlangsung saat ini. Buat permainan baru dengan "
"perintah /new"
#: bot.py:278
msgid "The game has already started"
msgstr "Permainan sudah dimulai."
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr ""
"Minimal dua pemain harus bergabung sebelum kamu bisa memulai game ini. "
"Gunakan perintah /join untuk bergabung"
#: bot.py:297
#, fuzzy, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Pemain pertama: {name}\n"
"Gunakan /close untuk menghentikan pemain baru bergabung pada game ini.\n"
"Aktifkan translasi multi bahasa dengan /enable_translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Silakan pilih pada grup mana kamu akan bermain."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "Tidak ada permainan yang berjalan pada grup chat ini."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr "Lobby ditutup. Tidak ada pemain yang bisa bergabung lagi."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Hanya pembuat permainan: ({name}) yang dapat melakukan itu."
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr ""
"Mengaktifkan translasi multi bahasa. Non-aktifkan dengan /"
"disable_translations"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr ""
"Menon-aktifkan translasi multi bahasa. Nyalakan kembali dengan perintah /"
"enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "Membuka lobby. Pemain baru bisa bergabung dengan perintah /join."
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "Kamu sedang tidak bermain."
#: bot.py:400
#, python-format
msgid "Please wait {time} seconds"
msgstr "Mohon menunggu {time} detik"
#: bot.py:413
#, python-format
msgid ""
"Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr ""
"Waktu tunggu terhadap {name} telah dikurangi menjadi {time} detik.\n"
"Next player: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} telah dilewati dan tidak bermain empat kali berturut-turutdan telah "
"dikeluarkan dari permainan.\n"
"Pemain berikutnya: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name} telah dilewati dan tidak bermain empat kali berturut-turutdan telah "
"dikeluarkan dari permainan.\n"
"Permainan berkahir."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Semua berita ada di sini: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "Permainan saat ini: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "Percobaan curang dilakukan oleh {name}"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Pemain berikutnya: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "Waktu tunggu terhadap {name} telah dikembalikan menjadi 90 detik"
#: bot.py:585
msgid "Please choose a color"
msgstr "Silakan pilih warna"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} menang!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "Tidak ada kartu lagi tersedia."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Ternyata hanya gertakan! Memberikan 4 kartu kepada {name}"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} tidak hanya menggertak! Memberikan 6 kartu kepada {name2}"
#: results.py:38
msgid "Choose Color"
msgstr "Pilih warna"
#: results.py:56
msgid "Cards (tap for game state):"
msgstr "Kartu-kartu (tekan untuk statistik permainan):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Pemain saat ini: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Kartu terakhir: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Players: {player_list}"
msgstr "Pemain: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} cards)"
msgstr "{name} ({number} kartu)"
#: results.py:81
msgid "You are not playing"
msgstr "Kamu sedang tidak bermain"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"Saat ini sedang tidak ada permainan. Gunakan perintah /new untuk memulai "
"permainan atau /join untuk bergabung dengan permainan yang sedang "
"berlangsung di grup ini"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "Permainan belum dimulai"
#: results.py:97
msgid "Start the game with /start"
msgstr "Mulailah permainan dengan perintah /start"
#: results.py:108
#, python-format
msgid "Drawing 1 card"
msgstr "Mengambil satu kartu"
msgid "Drawing {number} cards"
msgstr "Mengambil {number} kartu"
#: results.py:136
msgid "Pass"
msgstr "Lewati"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Saya bilang, kamu hanya menggertak!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "Silakan ubah pengaturan melalui chat pribadi dengan bot."
#: settings.py:49
msgid "Enable statistics"
msgstr "Mengaktifkan statistik"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Menghapus semua statistik"
#: settings.py:53
msgid "Language"
msgstr "Bahasa"
#: settings.py:54
msgid "Settings"
msgstr "Pengaturan"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Mengaktifkan statistik"
#: settings.py:70
msgid "Select locale"
msgstr "Memilih lokasi"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Menghapus dan menonaktifkan statisk"
#: settings.py:94
msgid "Set locale!"
msgstr "Pilih lokasi!"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr ""
"Kamu belum menyalakan statistik. Gunakan /settings melalui chat pribadi "
"kepada bot untuk menyalakannya."
#: simple_commands.py
msgid "{number} games played"
msgstr "{number} permainan dimainkan"
#: simple_commands.py
msgid "{number} first places"
msgstr "{number} diletakkan pertama"
#: simple_commands.py
msgid "{number} cards played"
msgstr "{number} kartu dimainkan"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Hijau"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Merah"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Biru"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Kuning"

View File

@ -0,0 +1,462 @@
# 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/>.
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-22 20:02+0200\n"
"PO-Revision-Date: 2016-05-23 01:39+0200\n"
"Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Language: it_IT\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Segui questi passaggi:\n"
"\n"
"1. Aggiungi questo bot ad un gruppo\n"
"2. Nel gruppo, inizia una nuova partita con /new o unisciti a quella già "
"avviata con /join\n"
"3. Quando almeno due giocatori si sono uniti alla partita, si può iniziare "
"con /start\n"
"4. Digita <code>@unobot</code> nella casella di testo e premi "
"<b>spazio</b>, o clicca sul testo <code>via @unobot</code> vicino ai "
"messaggi. Potrai così vedere le tue carte (alcune in grigio), le opzioni "
"extra come pesca e <b>?</b> per vedere lo stato della partita attuale. Le "
"<b>carte in grigio</b> sono quelle che <b>non puoi giocare</b> al momento. "
"Premi un'opzione per eseguire l'azione selezionata.\n"
"I giocatori possono unirsi alla partita in qualsiasi momento. Per lasciare "
"la partita, usa /leave. Se un giocatore impiega più di 90 secondi a giocare, "
"puoi usare /skip per saltare il turno di quel giocatore.\n"
"\n"
"<b>Lingua</b> e altre opzioni: /settings\n"
"Altri comandi (utilizzabili solo da chi ha creato la partita):\n"
"/close - Chiude la stanza, nessun giocatore può unirsi alla partita dopo che "
"questa è già avviata.\n"
"/open - Apre la stanza, i giocatori possono unirsi alla partita in qualsiasi "
"momento. \v/enable_translations - Traduce i messaggi importanti nelle lingue "
"parlate durante la partita\n"
"/disable_translations - Usa l'inglese (default) per questi messaggi\n"
"\n"
"<b>Sperimentale:</b> Gioca in più gruppi allo stesso tempo. Premi il tasto "
"<code>Partita in corso: ...</code> e scegli il gruppo dove vuoi giocare la "
"carta.\n"
"\n"
"Se ti piace questo bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">votami</a>, segui gli <a href=\"https://telegram.me/"
"unobotupdates\">aggiornamenti</a> e compra il gioco di carte UNO. "
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Questo bot è un software gratuito e distribuito sotto licenza AGPL. Il "
"codice è disponibile qui:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr ""
"È stata creata una nuova partita! Unisciti con /join e inizia a giocare con /"
"start"
#: bot.py:152
msgid "The lobby is closed"
msgstr "La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita."
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "Non c'è nessuna partita aperta al momento. Iniziane una nuova con /new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "Ti sei già unito/a alla partita. Inizia a giocare con /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Si è unito/a alla partita"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "Non stai giocando alcuna partita in questo gruppo."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "La partita è conclusa!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Okay. Prossimo giocatore: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Partita non trovata."
#: bot.py:223
msgid "Back to last group"
msgstr "Vai all'ultimo gruppo."
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "Per favore, vai sul gruppo che hai selezionato!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Gruppo selezionato: {group}\n"
"<b>Assicurati di spostarti nel gruppo giusto!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Sto rimuovendo {name} dalla partita"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
"Non c'è alcuna partita aperta in questa chat. Creane una nuova con /new"
#: bot.py:278
msgid "The game has already started"
msgstr "La partita è già iniziata"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr ""
"Devono partecipare almeno due giocatori per iniziare la partita. Partecipa "
"con /join"
#: bot.py:297
#, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Primo giocatore: {name}\n"
"Usa /close per impedire a nuovi giocatori di unirsi alla partita.\n"
"Abilita la funzione di multi-traduzione con /enable_translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Per favore, seleziona il gruppo dove vuoi giocare."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "Non c'è alcuna partita aperta in questa chat."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr ""
"La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita in corso."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Solo il creatore della partita ({name}) può farlo. "
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "Multi-traduzione abilitata. Disabilitala con /disable_translations"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr "Multi-traduzione disabilitata. Abilitala con /enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr ""
"La stanza è aperta. Nuovi giocatori possono unirsi alla partita con /join"
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "Non stai giocando alcuna partita in questa chat. "
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "Per favore, attendi {time} secondi"
msgstr[1] "Per favore, attendi {time} secondi"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] ""
"Il tempo di attesa per saltare questo giocatore è stato ridotto a {time} "
"secondi.\n"
"Prossimo giocatore: {name}"
msgstr[1] ""
"Il tempo di attesa per saltare questo giocatore è stato ridotto a {time} "
"secondi.\n"
"Prossimo giocatore: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n"
"Prossimo giocatore: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n"
"La partita è conclusa."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Tutte le novità le trovi qui: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "Partita in corso: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "{name} ha tentato di barare!"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Prossimo giocatore: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "Il tempo di attesa per {name} è stato reimpostato a 90 secondi"
#: bot.py:585
msgid "Please choose a color"
msgstr "Per favore, scegli un colore"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} ha vinto!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "Non ci sono più carte sul tavolo."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Il baro è stato scoperto! {name} deve pescare 4 carte!"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} non ha barato! {name2} deve pescare 6 carte!"
#: results.py:38
msgid "Choose Color"
msgstr "Scegli il colore"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "Carte (clicca per vedere lo stato della partita):"
msgstr[1] "Carte (clicca per vedere lo stato della partita):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Giocatore attuale: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Ultima carta: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "Giocatori: {player_list}"
msgstr[1] "Giocatori: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} carta)"
msgstr[1] "{name} ({number} carte)"
#: results.py:81
msgid "You are not playing"
msgstr "Non stai giocando in questa partita."
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"Non stai giocando in questo momento. Usa /new per iniziare una nuova partita "
"o /join per partecipare a quella già avviata in questo gruppo"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "La partita non è ancora iniziata"
#: results.py:97
msgid "Start the game with /start"
msgstr "Inizia la partita con /start"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Sto pescando {number} carta"
msgstr[1] "Sto pescando {number} carte"
#: results.py:136
msgid "Pass"
msgstr "Passo"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Penso che tu stia barando!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr ""
"Per favore, modifica le tue impostazioni in una chat privata con il bot."
#: settings.py:49
msgid "Enable statistics"
msgstr "Abilita le statistiche"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Elimina tutte le statistiche"
#: settings.py:53
msgid "Language"
msgstr "Lingua"
#: settings.py:54
msgid "Settings"
msgstr "Impostazioni"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Statistiche abilitate!"
#: settings.py:70
msgid "Select locale"
msgstr "Seleziona la lingua"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Le statistiche sono state eliminate e disabilitate!"
#: settings.py:94
msgid "Set locale!"
msgstr "Lingua impostata!"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr ""
"Non hai abilitato le statistiche. Usa /settings in una chat privata col bot "
"per abilitarle."
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "{number} partite giocate"
msgstr[1] "{number} partite giocate"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "{number} vittorie"
msgstr[1] "{number} vittorie"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "{number} carta giocate"
msgstr[1] "{number} carte giocate"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Verde"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Rosso"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Blu"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Giallo"

View File

@ -0,0 +1,469 @@
# 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/>.
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-22 18:56-0300\n"
"PO-Revision-Date: 2016-05-22 20:48-0300\n"
"Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"Language: pt_BR\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Siga esses passos:\n"
"1. Adicione o bot ao grupo.\n"
"2. No grupo, crie um jogo com /new ou entre em um jogo já criado com /join.\n"
"3. Após dois ou mais jogadores entrarem, inicie o jogo com /start.\n"
"4. Digite <code>@unobot</code> na janela de conversação e aperte a "
"tecla <b>espaço</b>, ou clique no texto <code>@unobot</code> próximo às "
"mensagens. Você verá suas cartas (algumas apagadas, na cor cinza), e opções "
"extras como sacar, e um <b>?</b> para ver as estatísticas do jogo atual. As "
"<b> cartas acizentadas</b> são as que você <b>não pode jogar</b> no momento. "
"Toque em uma das opções para executar a ação desejada.\n"
"Jogadores podem entrar no jogo a qualquer momento. Para sair do jogo, use /"
"leave. Se um jogador levar mais de 90 segundos para jogar, você pode usar /"
"skip para pular a vez desse jogador."
"Use o /notify_me para receber uma mensagem no privada quando um novo jogo no "
"grupo for iniciado.\n"
"\n"
"<b>Idioma</b> e outras configurações: /settings\n"
"Outros comandos (somente para o criador do jogo):\n"
"/close - Fechar o lobby\n"
"/open - Abrir o lobby\n"
"/enable_translations - Traduz os textos relevantes para todas as linguagens "
"disponíveis no jogo\n"
"/disable_translations - Receber esses textos em inglês\n"
"\n"
"<b>Experimental:</b> Jogue em vários grupos ao mesmo tempo. Toque no botão "
"<code>Jogo atual: ...</code> e selecione o grupo no qual deseja jogar uma "
"carta.\n"
"Se gostou deste bot, <a href=\"https://telegram.me/storebot?start=mau_mau_bot"
"\">avalie-o</a>, entre no <a href=\"https://telegram.me/unobotupdates"
"\">canal de atualizações</a> e compre um jogo de cartas UNO."
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Esse bot é um Software livre, grátis e reconhecido pela AGPL. O código está "
"disponível aqui:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr "Novo jogo criado! Entre no jogo com /join e inicie o jogo com /start"
#: bot.py
msgid "Send this command in a group to be notified when a new game is started there."
msgstr "Envie este comando em um grupo para ser notificado quando um novo jogo for iniciado."
#: bot.py:152
msgid "The lobby is closed"
msgstr "O lobby está fechado"
#: bot.py
msgid "A new game has been started in {title}"
msgstr "Um novo jogo foi iniciado no grupo: {title}"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "Nenhuma partida sendo jogada. Crie um novo jogo com /new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "Você já entrou na partida. Inicie o jogo com /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Entrou na partida"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "Você não está jogando nenhuma partida nesse grupo."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "Fim de jogo!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Ok. Próximo jogador: {name} "
#: bot.py:219
msgid "Game not found."
msgstr "Jogo não encontrado"
#: bot.py:223
msgid "Back to last group"
msgstr "Voltar ao último grupo"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "Por favor, mude para o grupo selecionado!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Grupo selecionado: {group}\n"
"<b>Tenha certeza de que mudou para o grupo certo!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Removendo {name} da partida"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
"Não há uma partida sendo jogada nesta conversa. Crie um novo jogo com /new"
#: bot.py:278
msgid "The game has already started"
msgstr "Essa partida já começou"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr ""
"Pelo menos dois jogadores devem entrar no jogo usando /join para que a "
"partida possa começar"
#: bot.py:297
#, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Primeiro jogador: {name}\n"
"Use /close para impedir que mais pessoas entrem na partida.\n"
"Ative as multi-traduções com /enable_translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Por favor, selecione o grupo em que deseja jogar."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "Não há uma partida sendo jogada nesta conversa."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr ""
"O lobby está fechado. Não é permitida a entrada de novos jogadores nessa "
"partida."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Somente o criador do jogo ({name}) pode fazer isso."
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "Multi-traduções ativadas. Desative com /disable_translations"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr ""
"Multi-traduções desativadas. Ative-as novamente com /enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr ""
"O lobby está aberto. Novos jogadores podem entrar na partida usando /join."
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "Você não está participando de um jogo nesta conversa."
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "Por favor, aguarde {time} segundo"
msgstr[1] "Por favor, aguarde {time} segundos"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] "O tempo de espera para pular a vez deste jogador foi reduzido para {time} segundo\n"
"Próximo jogador: {name}"
msgstr[1] "O tempo de espera para pular a vez deste jogador foi reduzido para {time} segundos\n"
"Próximo jogador: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} teve suas jogadas puladas quatro vezes seguidas e foi removido(a) do "
"jogo.\n"
"Próximo jogador: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name} teve suas jogadas puladas quatro vezes seguidas e foi removido(a) do "
"jogo.\n"
"O jogo acabou."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Todas as novidades aqui: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "Partida atual: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "Tentativa de trapaça por {name}"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Próximo jogador: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "O tempo de espera para {name} é novamente de 90 segundos."
#: bot.py:585
msgid "Please choose a color"
msgstr "Por favor, escolha uma cor"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} venceu!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "Não há mais cartas no deck."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Blefe revelado! Dando 4 cartas para {name}"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} não blefou! Dando 6 cartas para {name2}"
#: results.py:38
msgid "Choose Color"
msgstr "Escolher Cor"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "Última carta (toque para ver as estatísticas do jogo):"
msgstr[1] "Cartas (toque para ver as estatísticas do jogo):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Jogador atual: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Última carta: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "Jogador: {player_list}"
msgstr[1] "Jogadores: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} carta)"
msgstr[1] "{name} ({number} cartas)"
#: results.py:81
msgid "You are not playing"
msgstr "Você não está jogando"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"Você não está jogando. Use /new criar um jogo ou /join para entrar na "
"partida atual da conversa"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "O jogo ainda não começou"
#: results.py:97
msgid "Start the game with /start"
msgstr "Inicie a partida com /start"
#: results.py:108
#, python-format
msgid "Drawing 1 card"
msgstr "Sacando 1 carta"
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Sacando {number} carta"
msgstr[1] "Sacando {number} cartas"
#: results.py:136
msgid "Pass"
msgstr "Passo"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Você está blefando!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr ""
"Por favor, ajuste suas configurações em uma conversa privada com o bot."
#: settings.py:49
msgid "Enable statistics"
msgstr "Habilitar estatísticas"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Deletar todas as estatísticas"
#: settings.py:53
msgid "Language"
msgstr "Idioma"
#: settings.py:54
msgid "Settings"
msgstr "Configurações"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Estatísticas habilitadas!"
#: settings.py:70
msgid "Select locale"
msgstr "Definir linguagem"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Estatísticas deletadas e desabilitadas!"
#: settings.py:94
msgid "Set locale!"
msgstr "Linguagem selecionada!"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr ""
"Você não habilitou as estatísticas. Use /settings em uma conversa privada "
"com o bot para ativá-las."
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "{number} partida jogada"
msgstr[1] "{number} partidas jogadas"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "{number} vez em primeiro lugar"
msgstr[1] "{number} vezes em primeiro lugar"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "{number} carta jogada"
msgstr[1] "{number} cartas jogadas"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Verde"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Vermelho"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Azul"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Amarelo"

View File

@ -0,0 +1,465 @@
# 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/>.
# Jannes Höke <uno@jhoeke.de>, 2016.
#
#: bot.py:224
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-19 22:38+0200\n"
"PO-Revision-Date: 2016-05-21 21:16+0200\n"
"Last-Translator: Jannes Höke <uno@jhoeke.de>\n"
"Language-Team: Deutsch <uno@jhoeke.de>\n"
"Language: ru_RU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.6\n"
#: bot.py:60
msgid "Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"Выполните следующие действия:\n"
"\n"
"1. Добавьте этого бота в свою группу\n"
"2. Создайте новую игру в своей группе с помощью команды /new "
"либо присоединитесь к уже существующей, написав /join\n"
"3. Как только к игре присоединятся по меньшей мере двое игроков, Вы можете начать "
"с помощью команды /start\n"
"4. Напишите <code>@unobot</code> в окне чата и поставьте "
"<b>пробел</b> либо нажмите на текст <code>via @unobot</code> "
"рядом с сообщениями. Вы увидите свои карточки (некоторые из них будут серыми), "
"а также некоторые дополнительные опции и кнопку <b>?</b> для просмотра текущего "
"состояния игры. Вы не можете выбрать <b>серые карточки</b>. "
"Нажмите на доступную кнопку для осуществления выбранного действия. \n "
"Присоединиться к игре можно в любой момент. Выйти из партии можно с помощью "
"команды /leave. Если игрок затратил больше 90 секунд на ход, его ход можно пропустить "
"командой /skip. "
"Используйте /notify_me для получения приватного сообщения о начале новой партии.\n"
"\n"
"<b>Язык</b> и другие настройки: /settings\n"
"Другие команды (только для организаторов партии):\n"
"/close - Закрыть лобби\n"
"/open - Открыть лобби\n"
"/enable_translations - Разрешить вывод текста на языках игроков/n"
"/disable_translations - Выводить текст только на Английском языке\n"
"\n"
"<b>Экспериментальные опции</b>: Одновременная игра в нескольких группах. "
"Нажмите на кнопку"
"<code>Текущая игры: ...</code> и выберите, в какой группе сделать ход.\n"
"Если Вам понравился этот бот, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">оцените его</a> и следите за <a href=\"https://telegram.me/"
"unobotupdates\">новостным каналом</a>, а такщже купите себе карточки UNO."
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"Этот бот является программой с открытым исходным кодом и выпущен под лицензией AGPL. "
"Весь код доступен по адресу:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr ""
"Создана новая игра! Присоединитесь к ней командой /join и начните, написав /start"
#: bot.py
msgid "Send this command in a group to be notified when a new game is started there."
msgstr "Отправьте эту команду в группе, чтобы получать уведомления о новых партиях. "
#: bot.py
msgid "A new game has been started in {title}"
msgstr "В {title} началась новая игра"
#: bot.py:152
msgid "The lobby is closed"
msgstr "Лобби закрыто"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "Нет активных партий в данный момент. Создайте новую, написав /new"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "Вы уже присоединились к этой игре. Начните ее с помощью /start"
#: bot.py:167
msgid "Joined the game"
msgstr "Присоединился к игре"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "Вы не играете в данной группе."
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "Игра окончена!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "Ок. Следующий игрок: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Игры не найдены."
#: bot.py:223
msgid "Back to last group"
msgstr "Вернуться к последней группе"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "Пожалуйста, переключитесь на выбранную группу!"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"Выбранная группа: {group}\n"
"<b>Убедитесь, что Вы переключились на нее!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "Удаляю {name} из игры"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
"Нет ни одной игры в данном чате. Создайте новую командой /new"
#: bot.py:278
msgid "The game has already started"
msgstr "Игра уже началась"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr "Как минимум два человека должны присоединиться, прежде чем Вы сможете "
"начать игру"
#: bot.py:297
#, python-format, fuzzy
msgid "First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"Первый игрок: {name}\n"
"Напишите /close, чтобы запретить присоединяться к этой игре."
"Включите перевод текстов командой /enable-translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "Пожалуйста, выберите группу, в которой хотите играть."
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "Нет ни одной игры в данном чате."
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr ""
"Лобби закрыто. К данной игре нельзя присоединиться."
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "Только создатель партии ({name}) может это сделать."
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "Перевод активирован. Выключите с помощью /disable_translations"
#: bot.py:377
#, python-format
msgid "Disabled multi-translations. Enable them again with /enable_translations"
msgstr "Перевод отключен. Вы можете включить его с помощью "
"/enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "Лобби открыто. Теперь к игре можно присоединиться."
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "Вы не играете ни в одну из партий в данном чате."
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "Пожалуйста, подождите {time} секунды"
msgstr[1] "Пожалуйста, подождите {time} секунд"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] "Время на ход для данного игрока было сокращено на {time} "
"секунды.\n"
"Следюущий игрок: {name}"
msgstr[1] "Время на ход для данного игрока было сокращено на {time} "
"секунд.\n"
"Следующий игрок: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} был пропущен 4 раза подряд и вышел из игры.\n"
"Следующий игрок: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name1} был пропущен 4 раза поряд и вышел из игры.\n"
"Игра окончена."
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "Все новости здесь: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {game}"
msgstr "Текущая игра: {game}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "{name} попытался сжульничать!"
#: bot.py:562
msgid "Next player: {name}"
msgstr "Следующий игрок: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "Время на ход для {name} было сброшено до 90 секунд."
#: bot.py:585
msgid "Please choose a color"
msgstr "Пожалуйста, выберите цвет"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} победил!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "В колоде больше нет карт."
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Это блеф! {name} получает 4 карты."
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} не блефовал! {name2} получает 6 карт."
#: results.py:38
msgid "Choose Color"
msgstr "Выберите цвет"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "Последняя карта (нажмите для просмотра статуса игры):"
msgstr[1] "Карты (нажмите для просмотра статуса игры):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "Текущий игрок: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "Последняя карта: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "Игрок: {player_list}"
msgstr[1] "Игроки: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} карты)"
msgstr[1] "{name} ({number} карт)"
#: results.py:81
msgid "You are not playing"
msgstr "Вы не играете"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
"В данный момент Вы не играете. Используйте /new, чтобы начать новую, или /"
"join, чтобы присоединиться к текущей."
#: results.py:95
msgid "The game wasn't started yet"
msgstr "Игра еще не началась."
#: results.py:97
msgid "Start the game with /start"
msgstr "Начните новую игру с помощью /start"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Забирает {number} карты"
msgstr[1] "Забирает {number} карты"
#: results.py:136
msgid "Pass"
msgstr "Пас"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "Я бросаю тебе вызов!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "Пожалуйста, напишите боту для изменения своих настроек."
#: settings.py:49
msgid "Enable statistics"
msgstr "Включить статистику"
#: settings.py:51
msgid "Delete all statistics"
msgstr "Удалить всю статистику"
#: settings.py:53
msgid "Language"
msgstr "Язык"
#: settings.py:54
msgid "Settings"
msgstr "Настройки"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "Статистика включена!"
#: settings.py:70
msgid "Select locale"
msgstr "Выберите язык"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "Статистика удалена и отключена!"
#: settings.py:94
msgid "Set locale!"
msgstr "Язык установлен!"
#: simple_commands.py
msgid "You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."
msgstr "Вы не включали статистику. Чтобы ее активировать, напишите "
"/settings в приватном чате с ботом."
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "{number} игры сыграно"
msgstr[1] "{number} игр сыграно"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "{number} первое место"
msgstr[1] "{number} первых мест"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "{number} карты сыграно"
msgstr[1] "{number} карты сыграно"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} Зеленый"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} Красный"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} Синий"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} Желтый"

407
locales/unobot.pot Normal file
View File

@ -0,0 +1,407 @@
# 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/>.
#: bot.py:224
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-19 22:38+0200\n"
"PO-Revision-Date: 2016-05-19 22:38+0200\n"
"Last-Translator: Jannes Höke <uno@jhoeke.de>\n"
"Language-Team: en <uno@jhoeke.de>\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: bot.py:60
#, fuzzy
msgid "Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
#: bot.py:88
msgid "This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
#: bot.py:133
msgid "Created a new game! Join the game with /join and start the game with /start"
msgstr ""
#: bot.py
msgid "Send this command in a group to be notified when a new game is started there."
msgstr ""
#: bot.py
msgid "A new game has been started in {title}"
msgstr ""
#: bot.py:152
msgid "The lobby is closed"
msgstr ""
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr ""
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr ""
#: bot.py:167
msgid "Joined the game"
msgstr ""
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr ""
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr ""
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr ""
#: bot.py:219
msgid "Game not found."
msgstr ""
#: bot.py:223
msgid "Back to last group"
msgstr ""
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr ""
#: bot.py:233
#, python-format
msgid "Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr ""
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr ""
#: bot.py:278
msgid "The game has already started"
msgstr ""
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr ""
#: bot.py:297
#, python-format, fuzzy
msgid "First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr ""
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr ""
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr ""
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr ""
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr ""
#: bot.py:377
#, python-format
msgid "Disabled multi-translations. Enable them again with /enable_translations"
msgstr ""
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr ""
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr ""
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] ""
msgstr[1] ""
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] ""
msgstr[1] ""
#: bot.py:424
#, python-format
msgid "{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
#: bot.py:432
#, python-format
msgid "{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr ""
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr ""
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr ""
#: bot.py:562
msgid "Next player: {name}"
msgstr ""
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr ""
#: bot.py:585
msgid "Please choose a color"
msgstr ""
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr ""
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr ""
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr ""
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr ""
#: results.py:38
msgid "Choose Color"
msgstr ""
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] ""
msgstr[1] ""
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr ""
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr ""
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] ""
msgstr[1] ""
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] ""
msgstr[1] ""
#: results.py:81
msgid "You are not playing"
msgstr ""
#: results.py:83
msgid "Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr ""
#: results.py:95
msgid "The game wasn't started yet"
msgstr ""
#: results.py:97
msgid "Start the game with /start"
msgstr ""
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] ""
msgstr[1] ""
#: results.py:136
msgid "Pass"
msgstr ""
#: results.py:148
msgid "I'm calling your bluff!"
msgstr ""
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr ""
#: settings.py:49
msgid "Enable statistics"
msgstr ""
#: settings.py:51
msgid "Delete all statistics"
msgstr ""
#: settings.py:53
msgid "Language"
msgstr ""
#: settings.py:54
msgid "Settings"
msgstr ""
#: settings.py:68
msgid "Enabled statistics!"
msgstr ""
#: settings.py:70
msgid "Select locale"
msgstr ""
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr ""
#: settings.py:94
msgid "Set locale!"
msgstr ""
#: simple_commands.py
msgid "You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."
msgstr ""
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] ""
msgstr[1] ""
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] ""
msgstr[1] ""
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] ""
msgstr[1] ""
#: utils.py
msgid "{emoji} Green"
msgstr ""
#: utils.py
msgid "{emoji} Red"
msgstr ""
#: utils.py
msgid "{emoji} Blue"
msgstr ""
#: utils.py
msgid "{emoji} Yellow"
msgstr ""

View File

@ -0,0 +1,432 @@
# 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/>.
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-23 00:03+0100\n"
"PO-Revision-Date: 2016-05-23 20:02+0800\n"
"Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Language: zh_CN\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"游戏指引:\n"
"\n"
"1. 将这个 Bot 加进一个群\n"
"2. 在这个群中,您可以通过 /new 创建一个新游戏,或者通过 /join 加入一个现有的游戏\n"
"3. 当有最少两名玩家加入后,请通过 /start 开始游戏\n"
"4. 在聊天框中输入 <code>@unobot</code> 并按空格键,或者点击信息旁边的 "
"<code>via @unobot</code> 。你就可以看到你手上的牌,以及一些像抽牌这样的选项, "
"<b>?</b> 选项用来查看当前游戏状态。 <b>灰色的牌</b> 是你当前 <b>不可以</b> 打出的。"
"请选择其中的一个选项。\n"
"玩家随时可以加入游戏,如果想要离开当前的游戏,请输入 /leave 。"
"如果玩家超过 90 秒没有出牌,你可以通过 /skip 跳过这个玩家\n"
"\n"
"<b>语言</b> 和其他设置: /settings \n"
"其他命令(仅限游戏创建者使用)\n"
"/close - 不允许其他人中途加入\n"
"/open - 允许其他人中途加入\n"
"/enable_translations - 翻译文本给游戏中所有使用不同语言的玩家\n"
"/disable_translations - 关闭翻译并使用英文\n"
"\n"
"<b>实验性功能:</b> 玩家可以同时在多个群组中进行游戏。点击 "
"<code>当前游戏: ...</code> 按钮然后选择你想在哪个群组玩。\n"
"如果喜欢这个 Bot 请给机器人 "
"<a href=\"https://telegram.me/storebot?start=mau_mau_bot\">"
"评分</a> ,您可以订阅我们的 "
"<a href=\"https://telegram.me/unobotupdates\"> "
"更新频道</a> 获取最新消息,也可以买一副 UNO 牌玩玩哦!"
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"本机器人是一个在 AGPL 协议下发行的自由软件。源代码可以在这里取得:\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr "创建新游戏成功!请通过 /join 加入游戏,然后通过 /start 开始游戏"
#: bot.py:152
msgid "The lobby is closed"
msgstr "游戏已设置成不允许中途加入"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "这个群组并没有运行中的游戏。通过 /new 新建一个?"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "你已经加入了游戏。请通过 /start 开始游戏"
#: bot.py:167
msgid "Joined the game"
msgstr "游戏加入成功"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "您在这个群中并没有参加游戏。"
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "游戏结束!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "好的,轮到: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "游戏未找到。"
#: bot.py:223
msgid "Back to last group"
msgstr "返回上一个群"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "请切换到您选择的群"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"选择群: {group}\n"
"<b>请确保切换到您选择的群</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "已成功将 {name} 移出游戏"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr "这个群组并没有运行中的游戏。通过 /new 新建一个?"
#: bot.py:278
msgid "The game has already started"
msgstr "游戏已经开始"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr "最少需要两个人通过 /join 加入游戏然后才可以开始游戏"
#: bot.py:297
#, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"第一个出牌的玩家: {name}\n"
"使用 /close 可以阻止别人中途加入游戏。\n"
"使用 /enable_translations 启动游戏翻译功能"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "请选择你要参加游戏的群。"
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "这个群中并没有正在运行的游戏。"
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr "游戏已设置成不允许中途加入,玩家将不允许加入游戏。"
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "只有游戏创建者 ({name}) 可以使用该命令"
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "游戏翻译已启用,通过 /disable_translations 可以停用该功能"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr "游戏翻译已停用,通过 /enable_translations 可以启用该功能"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "游戏已设置成允许中途加入,新玩家现在可以通过 /join 加入游戏。"
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "您并不在游戏中"
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "请等待 {time} 秒"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] ""
"该玩家的等待时间已降至 {time} 秒。\n"
"轮到: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1} 已经被连续跳过了 4 次。\n"
"轮到: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name1} 已经被连续跳过了 4 次。\n"
"游戏结束。"
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "查看机器人的所有更新: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "当前游戏: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "{name} 试图作弊"
#: bot.py:562
msgid "Next player: {name}"
msgstr "轮到: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "{name} 的等待时间已经重置为 90 秒"
#: bot.py:585
msgid "Please choose a color"
msgstr "请选择颜色"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} 赢了!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "已经没有更多的底牌了。"
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "质疑成功!给 {name} 4 张牌"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "质疑 {name1} 失败!给 {name2} 6 张牌"
#: results.py:38
msgid "Choose Color"
msgstr "选择颜色"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "手牌 (点击查看游戏状况)"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "轮到: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "上一张牌: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "玩家: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} 张牌)"
#: results.py:81
msgid "You are not playing"
msgstr "你并不在游戏中"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr "您并不在游戏中。请通过 /new 创建一个新游戏,或者通过 /join 加入一个现有的游戏"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "游戏还没有开始"
#: results.py:97
msgid "Start the game with /start"
msgstr "请先通过 /start 开始游戏"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "抽取 {number} 张牌"
msgid "Drawing {number} cards"
msgstr "抽取 {number} 张牌"
#: results.py:136
msgid "Pass"
msgstr "Pass"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "我要质疑!"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "请给我私聊修改您的设置"
#: settings.py:49
msgid "Enable statistics"
msgstr "启用数据统计"
#: settings.py:51
msgid "Delete all statistics"
msgstr "删除所有统计数据"
#: settings.py:53
msgid "Language"
msgstr "语言"
#: settings.py:54
msgid "Settings"
msgstr "设置"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "数据统计已启用!"
#: settings.py:70
msgid "Select locale"
msgstr "请选择语言"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "统计数据已经被删除并已停用"
#: settings.py:94
msgid "Set locale!"
msgstr "语言设置成功!"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr "您并没有启用数据统计。请给我私聊发送 /settings 进行设置"
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "玩了 {number} 盘"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "赢了 {number} 盘"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "总共出过 {number} 张牌"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} 绿色"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} 红色"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} 蓝色"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} 黄色"

View File

@ -0,0 +1,428 @@
# 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/>.
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-23 00:03+0100\n"
"PO-Revision-Date: 2016-05-23 10:59+0100\n"
"Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7\n"
"Last-Translator: \n"
"Plural-Forms: nplurals=1; plural=0;\n"
"Language: zh_HK\n"
#: bot.py:60
msgid ""
"Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all languages spoken in "
"a game\n"
"/disable_translations - Use English for those texts\n"
"\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr ""
"請跟隨以下指示:\n"
"\n"
"1. Add呢個bot入去一個group度\n"
"2. 輸入/new開展一個新遊戲或者/join加入一個運行緊嘅遊戲\n"
"3. 當有兩個玩家加入, 就可以用/start開始遊戲\n"
"4. 喺你個chatbox打 <code>@unobot</code>然後禁<b>space</b>或者揀隔離個 "
"<code>via @unobot</code>。之後你會見到你嘅手牌或者其他選項例如抽牌, 同埋"
"<b>?</b>睇玩家狀態。但<b>灰咗嘅牌</b>就係<b>你出唔到嘅牌</b>, 請揀選其中一個"
"選項。\n"
"玩家可以喺任何時間加入, 如果想離開, 請打/leave。如果有個玩家90秒內都冇出牌嘅"
"話, 你可以用 /skip skip咗佢\n"
"\n"
"<b>語言</b>同埋其他設定: /settings\n"
"遊戲創始人可以用以下嘅command:\n"
"/close - 關閉 lobby, 其他人就唔可以中途加入\n"
"/open - 開啓 lobby, 令其他人可以中途加入\n"
"/enable_translations - 翻譯指示\n"
"/disable_translations - 用返英文嘅指示\n"
"\n"
"<b>試驗功能:</b> 想喺幾個group度同時玩幾個遊戲嘅話, 請揀 <code>Current "
"game:...</code>然後揀你想喺邊個group玩\n"
"如果你鍾意呢個bot嘅話, 請喺 <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">評分</a>, 然後加入<a href=\"https://telegram.me/unobotupdates"
"\">update channel</a> 再買一副UNO。"
#: bot.py:88
msgid ""
"This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr ""
"呢個bot係一個免費嘅Software, 根據AGPL授權 \n"
"Code可以係呢度搵到\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid ""
"Created a new game! Join the game with /join and start the game with /start"
msgstr "已經開始咗新一盤! 用/join加入同埋/start去開始"
#: bot.py:152
msgid "The lobby is closed"
msgstr "Lobby已經閂咗"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "宜家冇遊戲運行, 用 /new開展新一盤"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "你已經加入咗啦, 用 /start開始呢一盤"
#: bot.py:167
msgid "Joined the game"
msgstr "加入咗"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "你唔喺呢個group玩緊"
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "遊戲結束!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "OK 下一個: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "Game not found."
#: bot.py:223
msgid "Back to last group"
msgstr "去返前一個group"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "請轉去你揀咗果個group"
#: bot.py:233
#, python-format
msgid ""
"Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr ""
"揀咗呢個group: {group}\n"
"<b>記住轉過去正確嘅group</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "{name} 已經比人踢咗"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr "呢個對話入面冇遊戲運行緊, 用/new開始新一盤"
#: bot.py:278
msgid "The game has already started"
msgstr "呢一盤已經開始咗"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr "要有兩個玩家 /join咗先可以開始新一盤"
#: bot.py:297
#, python-format
msgid ""
"First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr ""
"第一個玩家: {name}\n"
"唔想其他人加入遊戲嘅話可以選擇 /close\n"
"用 /enable_translations 啓用翻譯功能"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "你想喺邊個group玩?"
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "呢個對話入面冇嘢玩緊喎"
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr "Lobby已經閂咗, 其他玩家已經冇得加入"
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "只有遊戲創始人先可以做呢個設定"
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "啓用咗其他語言, 可以用 /disable_translations 停用"
#: bot.py:377
#, python-format
msgid ""
"Disabled multi-translations. Enable them again with /enable_translations"
msgstr "已經停用咗其他語言, 想重新嘅話可以揀 /enable_translations"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "開咗個lobby, 宜家可以 /join 呢一盤"
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "你冇喺呢個對話入面玩"
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "請等{time}秒"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] ""
"呢個玩家嘅等待時間已經減少到 {time} 秒\n"
"下個: {name}"
#: bot.py:424
#, python-format
msgid ""
"{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr ""
"{name1}比人連接skip咗4次, 已經踢咗\n"
"下個: {name2}"
#: bot.py:432
#, python-format
msgid ""
"{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr ""
"{name1}比人連接skip咗4次, 已經踢咗\n"
"遊戲結束"
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "所有update都喺晒度: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "宜家玩緊嘅遊戲: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "{name} chok cheat"
#: bot.py:562
msgid "Next player: {name}"
msgstr "下一個: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "Skip {name}嘅時間已經reset咗去90秒"
#: bot.py:585
msgid "Please choose a color"
msgstr "請揀一隻顏色"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} 贏咗!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "檯上面冇哂牌"
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Call咗bluff, {name} draw 4張牌"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1}冇bluff, {name2} draw 6 張牌"
#: results.py:38
msgid "Choose Color"
msgstr "揀顏色"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "手牌 (遊戲status)"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "宜家嘅玩家"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "前一張牌: {card}"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "玩家: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} 張牌)"
#: results.py:81
msgid "You are not playing"
msgstr "你唔係玩緊喎"
#: results.py:83
msgid ""
"Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr "你唔係玩緊喎, 用 /new 開始新一盤或者 /join 加入宜家嘅遊戲"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "呢一盤仲未開始喎"
#: results.py:97
msgid "Start the game with /start"
msgstr "用/start開始呢一盤"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "Draw緊{number}張牌"
#: results.py:136
msgid "Pass"
msgstr "Pass"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "我call你bluff"
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "請pm個bot修改你嘅設定"
#: settings.py:49
msgid "Enable statistics"
msgstr "啓用數據記錄"
#: settings.py:51
msgid "Delete all statistics"
msgstr "刪除所有數據"
#: settings.py:53
msgid "Language"
msgstr "語言"
#: settings.py:54
msgid "Settings"
msgstr "設定"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "已經啓用咗數據記錄!"
#: settings.py:70
msgid "Select locale"
msgstr "請揀個區域"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "已經熄咗同埋delete咗數據記錄"
#: settings.py:94
msgid "Set locale!"
msgstr "Set咗個區域"
#: simple_commands.py
msgid ""
"You did not enable statistics. Use /settings in a private chat with the bot "
"to enable them."
msgstr "你冇啓用數據記錄, pm個bot去啓用"
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "玩咗{number}盤"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "贏咗{number}次"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "已經玩咗{number}張牌"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} 綠色"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} 紅色"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} 藍色"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} 黃色"

View File

@ -0,0 +1,440 @@
# 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/>.
#: bot.py:224
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-19 22:38+0200\n"
"PO-Revision-Date: 2016-05-19 22:38+0200\n"
"Last-Translator: Jim Chen\n"
"Language-Team: en <uno@jhoeke.de>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: bot.py:60
#, fuzzy
msgid "Follow these steps:\n"
"\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already running game "
"with /join\n"
"3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @unobot</code> text next to messages. You will "
"see your cards (some greyed out), any extra options like drawing, and a <b>?"
"</b> to see the current game state. The <b>greyed out cards</b> are those "
"you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a "
"player takes more than 90 seconds to play, you can use /skip to skip that "
"player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n\n"
"<b>Experimental:</b> Play in multiple groups at the same time. Press the "
"<code>Current game: ...</code> button and select the group you want to play "
"a card in.\n"
"If you enjoy this bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">rate me</a>, join the <a href=\"https://telegram.me/"
"unobotupdates\">update channel</a> and buy an UNO card game."
msgstr "請跟隨以下指示:\n"
"\n"
"1. 將這個機器人新增到群組\n"
"2. 輸入 /new 開始一個新遊戲或輸入 /join 加入一個運行中的遊戲\n"
"3. 當有兩個或以上的玩家加入, 就可以用 /start 開始遊戲\n"
"4. 輸入 <code>@unobot</code> 然後按<b>空白鍵</b> 或點一下"
"<code>via @unobot</code>。之後你會看見你手上的牌或者其他選項例如DRAW(抽牌), 和"
"<b>?</b>看其他玩家狀態。但<b>灰色的牌</b>就是<b>你現在不能使用的牌</b>, 選擇其中一個"
"選項來執行對應的操作。\n"
"玩家可以在任何時間加入, 如果想離開, 請打 /leave 。如果玩家90秒後都沒有出牌"
", 你可以用 /skip 跳過他。輸入 /notify_me 以讓我在本群組遊戲開始時私訊你\n"
"\n"
"<b>語言</b>和其他設定: /settings\n"
"遊戲創始人可以用以下的command:\n"
"/close - 關閉 lobby, 其他人不可以中途加入\n"
"/open - 開啓 lobby, 令其他人可以中途加入\n"
"/enable_translations - 使用翻譯的提示\n"
"/disable_translations - 使用英文的提示\n"
"\n"
"<b>試驗功能:</b> 同時在不同的群組中遊玩 請選擇 <code>目前遊戲:...</code>"
"然後選擇你想在哪個群組玩。\n"
"如果你喜歡這個bot, 請 <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">評分</a>, 然後加入 <a href=\"https://telegram."
"me/unobotupdates\">即時更新頻道</a> 並買一副UNO牌。"
#: bot.py:88
msgid "This bot is Free Software and licensed under the AGPL. The code is available "
"here: \n"
"https://github.com/jh0ker/mau_mau_bot"
msgstr "這個bot是一個免費的軟件, 根據AGPL授權 \n"
"源代碼可以在這裡找到\n"
"https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133
msgid "Created a new game! Join the game with /join and start the game with /start"
msgstr "已開始新的遊戲! 用 /join 加入並用 /start 開始遊戲"
#: bot.py
msgid "Send this command in a group to be notified when a new game is started there."
msgstr "在群組中傳送這個指令以讓我在這個群組開始遊戲時私訊你"
#: bot.py
msgid "A new game has been started in {title}"
msgstr "新遊戲已經在 {title} 中開始!"
#: bot.py:152
msgid "The lobby is closed"
msgstr "遊戲大廳已關閉"
#: bot.py:156
msgid "No game is running at the moment. Create a new game with /new"
msgstr "目前沒有進行中的遊戲,輸入 /new 開始新的遊戲"
#: bot.py:162
msgid "You already joined the game. Start the game with /start"
msgstr "您已加入本局遊戲,輸入 /start 來開始遊戲"
#: bot.py:167
msgid "Joined the game"
msgstr "已加入遊戲"
#: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group."
msgstr "你目前沒有在這個群組中遊玩"
#: bot.py:197 bot.py:258 bot.py:595
msgid "Game ended!"
msgstr "遊戲結束!"
#: bot.py:201
msgid "Okay. Next Player: {name}"
msgstr "OK. 下一位: {name}"
#: bot.py:219
msgid "Game not found."
msgstr "找不到遊戲"
#: bot.py:223
msgid "Back to last group"
msgstr "回到上一個群組"
#: bot.py:227
msgid "Please switch to the group you selected!"
msgstr "請切換到你選擇的群組"
#: bot.py:233
#, python-format
msgid "Selected group: {group}\n"
"<b>Make sure that you switch to the correct group!</b>"
msgstr "已選擇的群組: {group}\n"
"<b>請確認你已經切換到目前遊玩中的群組!</b>"
#: bot.py:260
#, python-format
msgid "Removing {name} from the game"
msgstr "將 {name} 從遊戲中踢除"
#: bot.py:273
msgid "There is no game running in this chat. Create a new one with /new"
msgstr "此聊天室目前沒有遊戲進行中,使用 /new 開始新遊戲"
#: bot.py:278
msgid "The game has already started"
msgstr "遊戲已經開始了!"
#: bot.py:281
msgid "At least two players must /join the game before you can start it"
msgstr "至少要有兩個人 /join 才能開始遊戲"
#: bot.py:297
#, python-format, fuzzy
msgid "First player: {name}\n"
"Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations"
msgstr "由 {name} 開始出牌\n"
"輸入 /close 以防止新玩家加入此局遊戲 \n"
"如果你要啟用翻譯的提示請輸入 /enable_translations"
#: bot.py:321
msgid "Please select the group you want to play in."
msgstr "請選擇你要玩的群組"
#: bot.py:335 bot.py:361
msgid "There is no running game in this chat."
msgstr "此聊天室沒有正在進行的遊戲"
#: bot.py:342
msgid "Closed the lobby. No more players can join this game."
msgstr "已關閉大廳,其他人將無法加入遊戲"
#: bot.py:348 bot.py:373
#, python-format
msgid "Only the game creator ({name}) can do that."
msgstr "只有創建遊戲的玩家 ({name}) 可以執行此指令"
#: bot.py:349
#, python-format
msgid "Enabled multi-translations. Disable with /disable_translations"
msgstr "已啟用翻譯提示. 使用 /disable_translations 來停用"
#: bot.py:377
#, python-format
msgid "Disabled multi-translations. Enable them again with /enable_translations"
msgstr "已停用翻譯提示. 使用 /enable_translations 再次啟用"
#: bot.py:368
msgid "Opened the lobby. New players may /join the game."
msgstr "大廳已開啟, 現在可以 /join 本局遊戲"
#: bot.py:386
msgid "You are not playing in a game in this chat."
msgstr "你目前沒有在此聊天室中遊玩"
#: bot.py:400
#, python-format
msgid "Please wait {time} second"
msgid_plural "Please wait {time} seconds"
msgstr[0] "請等待 {time} 秒"
msgstr[1] "請等待 {time} 秒"
#: bot.py:413
#, python-format
msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}"
msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}"
msgstr[0] "此玩家等待時間已經縮短為 {time} 秒\n"
"輪到: {name}"
msgstr[1] "此玩家等待時間已經縮短為 {time} 秒\n"
"輪到: {name}"
#: bot.py:424
#, python-format
msgid "{name1} was skipped four times in a row and has been removed from the game.\n"
"Next player: {name2}"
msgstr "{name1} 已被跳過 4 次,並從此局遊戲中移除\n"
"輪到: {name2}"
#: bot.py:432
#, python-format
msgid "{name} was skipped four times in a row and has been removed from the game.\n"
"The game ended."
msgstr "{name1} 已被跳過 4 次,並從此局遊戲中移除\n"
"遊戲結束!"
#: bot.py:455
msgid "All news here: https://telegram.me/unobotupdates"
msgstr "即時更新頻道: https://telegram.me/unobotupdates"
#: bot.py:513
#, python-format
msgid "Current game: {group}"
msgstr "目前遊戲: {group}"
#: bot.py:545
#, python-format
msgid "Cheat attempt by {name}"
msgstr "提出作弊嫌疑 by {name}"
#: bot.py:562
msgid "Next player: {name}"
msgstr "輪到: {name}"
#: bot.py:572
#, python-format
msgid "Waiting time for {name} has been reset to 90 seconds"
msgstr "{name} 的等待時間已重置到 90 秒"
#: bot.py:585
msgid "Please choose a color"
msgstr "請選擇一個顏色"
#: bot.py:591
#, python-format
msgid "{name} won!"
msgstr "{name} 贏了!"
#: bot.py:613 bot.py:635 bot.py:647
msgid "There are no more cards in the deck."
msgstr "已經沒牌了"
#: bot.py:627
#, python-format
msgid "Bluff called! Giving 4 cards to {name}"
msgstr "已確認為虛張聲勢! 給予 {name} 4 張牌"
#: bot.py:639
#, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} 沒有虛張聲勢! 給予 {name2} 六張牌"
#: results.py:38
msgid "Choose Color"
msgstr "選擇顏色"
#: results.py:56
msgid "Last card (tap for game state):"
msgid_plural "Cards (tap for game state):"
msgstr[0] "最後的牌(點一下以獲得遊戲狀態):"
msgstr[1] "你的手牌(點一下以獲得遊戲狀態):"
#: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}"
msgstr "目前玩家: {name}"
#: results.py:61 results.py:124 results.py:167
msgid "Last card: {card}"
msgstr "上一張牌: {card"
#: results.py:62 results.py:125 results.py:168
msgid "Player: {player_list}"
msgid_plural "Players: {player_list}"
msgstr[0] "目前玩家: {player_list}"
msgstr[1] "目前玩家: {player_list}"
#: results.py:72
#, python-format
msgid "{name} ({number} card)"
msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} (目前有 {number} 張牌)"
msgstr[1] "{name} (目前有 {number} 張牌)"
#: results.py:81
msgid "You are not playing"
msgstr "你沒有在遊戲中"
#: results.py:83
msgid "Not playing right now. Use /new to start a game or /join to join the current "
"game in this group"
msgstr "你目前沒有在遊玩,使用 /new@unobot 開始新的遊戲或使用 /join@unobot 加入目前的遊戲"
#: results.py:95
msgid "The game wasn't started yet"
msgstr "遊戲尚未開始"
#: results.py:97
msgid "Start the game with /start"
msgstr "使用 /start 開始遊戲"
#: results.py:108
#, python-format
msgid "Drawing {number} card"
msgid_plural "Drawing {number} cards"
msgstr[0] "抽 {number} 張牌"
msgstr[1] "抽 {number} 張牌"
#: results.py:136
msgid "Pass"
msgstr "PASS! 下一位!"
#: results.py:148
msgid "I'm calling your bluff!"
msgstr "別騙了,虛張聲勢 = ="
#: settings.py:39
msgid "Please edit your settings in a private chat with the bot."
msgstr "請私訊我來修改你的設定"
#: settings.py:49
msgid "Enable statistics"
msgstr "啟用統計資料"
#: settings.py:51
msgid "Delete all statistics"
msgstr "刪除所有統計資料"
#: settings.py:53
msgid "Language"
msgstr "語言"
#: settings.py:54
msgid "Settings"
msgstr "設置"
#: settings.py:68
msgid "Enabled statistics!"
msgstr "已啟用統計資料"
#: settings.py:70
msgid "Select locale"
msgstr "設置語言"
#: settings.py:81
msgid "Deleted and disabled statistics!"
msgstr "已停用並刪除統計資料"
#: settings.py:94
msgid "Set locale!"
msgstr "語言已設置"
#: simple_commands.py
msgid "You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."
msgstr "您尚未啟用統計資料,請私我"
"<code>/settings</code> 來啟用他"
#: simple_commands.py
msgid "{number} game played"
msgid_plural "{number} games played"
msgstr[0] "已遊玩 {number} 個遊戲"
msgstr[1] "已遊玩 {number} 個遊戲"
#: simple_commands.py
msgid "{number} first place"
msgid_plural "{number} first places"
msgstr[0] "拿了 {number} 次第一名"
msgstr[1] "拿了 {number} 次第一名"
#: simple_commands.py
msgid "{number} card played"
msgid_plural "{number} cards played"
msgstr[0] "已遊玩 {number} 張牌"
msgstr[1] "已遊玩 {number} 張牌"
#: utils.py
msgid "{emoji} Green"
msgstr "{emoji} 綠色 {emoji}"
#: utils.py
msgid "{emoji} Red"
msgstr "{emoji} 紅色 {emoji}"
#: utils.py
msgid "{emoji} Blue"
msgstr "{emoji} 藍色 {emoji}"
#: utils.py
msgid "{emoji} Yellow"
msgstr "{emoji} 黃色 {emoji}"

107
player.py
View File

@ -1,7 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 - 2017 Jannes Höke <uno@jhoeke.de> and Karho Yau
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as # it under the terms of the GNU Affero General Public License as
@ -21,6 +22,7 @@ import logging
from datetime import datetime from datetime import datetime
import card as c import card as c
from errors import DeckEmptyError
class Player(object): class Player(object):
@ -37,6 +39,15 @@ class Player(object):
self.user = user self.user = user
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
try:
for i in range(7):
self.cards.append(self.game.deck.draw())
except DeckEmptyError:
for card in self.cards:
self.game.deck.dismiss(card)
raise
# Check if this player is the first player in this game. # Check if this player is the first player in this game.
if game.current_player: if game.current_player:
self.next = game.current_player self.next = game.current_player
@ -48,17 +59,14 @@ class Player(object):
self._prev = self self._prev = self
game.current_player = self game.current_player = self
for i in range(7):
self.cards.append(self.game.deck.draw())
self.bluffing = False self.bluffing = False
self.drew = False self.drew = False
self.anti_cheat = 0 self.anti_cheat = 0
self.turn_started = datetime.now() self.turn_started = datetime.now()
self.waiting_time = 90 self.waiting_time = 60
def leave(self): def leave(self):
""" Leave the current game """ """Removes player from the game and closes the gap in the list"""
if self.next is self: if self.next is self:
return return
@ -100,8 +108,28 @@ class Player(object):
else: else:
self._next = player self._next = player
def draw(self):
"""Draws 1+ cards from the deck, depending on the draw counter"""
_amount = self.game.draw_counter or 1
try:
for i in range(_amount):
self.cards.append(self.game.deck.draw())
except DeckEmptyError:
raise
finally:
self.game.draw_counter = 0
self.drew = True
def play(self, card):
"""Plays a card and removes it from hand"""
self.cards.remove(card)
self.game.play_card(card)
def playable_cards(self): def playable_cards(self):
""" Returns a list of the cards this player can play right now """ """Returns a list of the cards this player can play right now"""
playable = list() playable = list()
last = self.game.last_card last = self.game.last_card
@ -115,7 +143,7 @@ class Player(object):
# You may only play a +4 if you have no cards of the correct color # You may only play a +4 if you have no cards of the correct color
self.bluffing = False self.bluffing = False
for card in cards: for card in cards:
if self.card_playable(card, playable): if self._card_playable(card):
self.logger.debug("Matching!") self.logger.debug("Matching!")
playable.append(card) playable.append(card)
@ -127,31 +155,56 @@ class Player(object):
return playable return playable
def card_playable(self, card, playable): def _card_playable(self, card):
""" Check a single card if it can be played """ """Check a single card if it can be played"""
is_playable = True is_playable = True
last = self.game.last_card last = self.game.last_card
mode = self.game.mode
self.logger.debug("Checking card " + str(card)) self.logger.debug("Checking card " + str(card))
if (card.color != last.color and card.value != last.value and if mode == 0: # This mode is to apply the original rule
if (card.color != last.color and card.value != last.value and
not card.special): not card.special):
self.logger.debug("Card's color or value doesn't match") self.logger.debug("Card's color or value doesn't match")
is_playable = False is_playable = False
elif last.value == c.DRAW_TWO and not \ elif last.value == c.DRAW_TWO and self.game.draw_counter:
card.value == c.DRAW_TWO and self.game.draw_counter: self.logger.debug("Player has to draw and can't counter")
self.logger.debug("Player has to draw and can't counter") is_playable = False
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: self.logger.debug("Player has to draw and can't counter")
self.logger.debug("Player has to draw and can't counter") is_playable = False
is_playable = False elif (last.special == c.CHOOSE or last.special == c.DRAW_FOUR) and \
elif (last.special == c.CHOOSE or last.special == c.DRAW_FOUR) and \
(card.special == c.CHOOSE or card.special == c.DRAW_FOUR): (card.special == c.CHOOSE or card.special == c.DRAW_FOUR):
self.logger.debug("Can't play colorchooser on another one") self.logger.debug("Can't play colorchooser on another one")
is_playable = False is_playable = False
elif not last.color or card in playable: # Prevent game being locked by choosing colors.
self.logger.debug("Last card has no color or the card was " # When player is going to leave and he doesn't select a color, it causes game lock.
"already added to the list") elif not last.color and (last.special != c.CHOOSE and last.special != c.DRAW_FOUR):
is_playable = False self.logger.debug("Last card has no color")
is_playable = False
elif mode == 1: # This mode is to apply the Progressive UNO rule.
if (card.color != last.color and card.value != last.value and
not card.special):
self.logger.debug("Card's color or value doesn't match")
is_playable = False
elif last.value == c.DRAW_TWO and self.game.draw_counter and not \
card.value == c.DRAW_TWO:
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 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 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
# Prevent game being locked by choosing colors.
# When player is going to leave and he doesn't select a color, it causes game lock.
elif not last.color and (last.special != c.CHOOSE and last.special != c.DRAW_FOUR):
self.logger.debug("Last card has no color")
is_playable = False
return is_playable return is_playable

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
python-telegram-bot==5
pony

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
@ -17,129 +18,137 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Defines helper functions to build the inline result list"""
from uuid import uuid4 from uuid import uuid4
from telegram import InlineQueryResultArticle, InputTextMessageContent, \ from telegram import InlineQueryResultArticle, InputTextMessageContent, \
InlineQueryResultCachedSticker as Sticker InlineQueryResultCachedSticker as Sticker
import card as c import card as c
from utils import * from utils import display_color, display_color_group, display_name
from internationalization import _, __
def add_choose_color(results): def add_choose_color(results, game):
"""Add choose color options"""
for color in c.COLORS: for color in c.COLORS:
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
id=color, id=color,
title="Choose Color", title=_("Choose Color"),
description=display_color(color), description=display_color(color),
input_message_content= input_message_content=
InputTextMessageContent(display_color(color)) InputTextMessageContent(display_color_group(color, game))
) )
) )
def add_other_cards(playable, player, results, game): def add_other_cards(player, results, game):
if not playable: """Add hand cards when choosing colors"""
playable = list()
players = player_list(game)
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
"hand", "hand",
title="Cards (tap for game state):", title=_("Card (tap for game state):",
description=', '.join([repr(card) for card in "Cards (tap for game state):",
list_subtract(player.cards, playable)]), len(player.cards)),
input_message_content=InputTextMessageContent( description=', '.join([repr(card) for card in player.cards]),
"Current player: " + display_name(game.current_player.user) + input_message_content=game_info(game)
"\n" +
"Last card: " + repr(game.last_card) + "\n" +
"Players: " + " -> ".join(players))
) )
) )
def player_list(game): def player_list(game):
players = list() """Generate list of player strings"""
for player in game.players: return [_("{name} ({number} card)",
add_player(player, players) "{name} ({number} cards)",
return players len(player.cards))
.format(name=player.user.first_name, number=len(player.cards))
for player in game.players]
def add_no_game(results): def add_no_game(results):
"""Add text result if user is not playing"""
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
"nogame", "nogame",
title="You are not playing", title=_("You are not playing"),
input_message_content= input_message_content=
InputTextMessageContent('Not playing right now. Use /new to start ' InputTextMessageContent(_('Not playing right now. Use /new to '
'a game or /join to join the current game ' 'start a game or /join to join the '
'in this group') 'current game in this group'))
) )
) )
def add_not_started(results): def add_not_started(results):
"""Add text result if the game has not yet started"""
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
"nogame", "nogame",
title="The game wasn't started yet", title=_("The game wasn't started yet"),
input_message_content= input_message_content=
InputTextMessageContent('Start the game with /start') InputTextMessageContent(_('Start the game with /start'))
) )
) )
def add_draw(player, results): def add_draw(player, results):
"""Add option to draw"""
n = player.game.draw_counter or 1
results.append( results.append(
Sticker( Sticker(
"draw", sticker_file_id=c.STICKERS['option_draw'], "draw", sticker_file_id=c.STICKERS['option_draw'],
input_message_content= input_message_content=
InputTextMessageContent('Drawing %d card(s)' InputTextMessageContent(__('Drawing {number} card',
% (player.game.draw_counter or 1)) 'Drawing {number} cards', n,
multi=player.game.translate)
.format(number=n))
) )
) )
def add_gameinfo(game, results): def add_gameinfo(game, results):
players = player_list(game) """Add option to show game info"""
results.append( results.append(
Sticker( Sticker(
"gameinfo", "gameinfo",
sticker_file_id=c.STICKERS['option_info'], sticker_file_id=c.STICKERS['option_info'],
input_message_content=InputTextMessageContent( input_message_content=game_info(game)
"Current player: " + display_name(game.current_player.user) +
"\n" +
"Last card: " + repr(game.last_card) + "\n" +
"Players: " + " -> ".join(players))
) )
) )
def add_pass(results): def add_pass(results, game):
"""Add option to pass"""
results.append( results.append(
Sticker( Sticker(
"pass", sticker_file_id=c.STICKERS['option_pass'], "pass", sticker_file_id=c.STICKERS['option_pass'],
input_message_content=InputTextMessageContent('Pass') input_message_content=InputTextMessageContent(
__('Pass', multi=game.translate)
)
) )
) )
def add_call_bluff(results): def add_call_bluff(results, game):
"""Add option to call a bluff"""
results.append( results.append(
Sticker( Sticker(
"call_bluff", "call_bluff",
sticker_file_id=c.STICKERS['option_bluff'], sticker_file_id=c.STICKERS['option_bluff'],
input_message_content= input_message_content=
InputTextMessageContent("I'm calling your bluff!") InputTextMessageContent(__("I'm calling your bluff!",
multi=game.translate))
) )
) )
def add_play_card(game, card, results, can_play): def add_card(game, card, results, can_play):
players = player_list(game) """Add an option that represents a card"""
if can_play: if can_play:
results.append( results.append(
@ -148,16 +157,20 @@ def add_play_card(game, card, results, can_play):
else: else:
results.append( results.append(
Sticker(str(uuid4()), sticker_file_id=c.STICKERS_GREY[str(card)], Sticker(str(uuid4()), sticker_file_id=c.STICKERS_GREY[str(card)],
input_message_content=InputTextMessageContent( input_message_content=game_info(game))
"Current player: " + display_name(
game.current_player.user) +
"\n" +
"Last card: " + repr(game.last_card) + "\n" +
"Players: " + " -> ".join(players)))
) )
def add_player(itplayer, players): def game_info(game):
players.append(itplayer.user.first_name + " (%d cards)" players = player_list(game)
% len(itplayer.cards)) return InputTextMessageContent(
_("Current player: {name}")
.format(name=display_name(game.current_player.user)) +
"\n" +
_("Last card: {card}").format(card=repr(game.last_card)) +
"\n" +
_("Player: {player_list}",
"Players: {player_list}",
len(players))
.format(player_list=" -> ".join(players))
)

106
settings.py Normal file
View File

@ -0,0 +1,106 @@
#!/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/>.
from telegram import ReplyKeyboardMarkup, Emoji
from telegram.ext import CommandHandler, RegexHandler
from utils import send_async
from user_setting import UserSetting
from shared_vars import dispatcher
from locales import available_locales
from internationalization import _, user_locale
@user_locale
def show_settings(bot, update):
chat = update.message.chat
if update.message.chat.type != 'private':
send_async(bot, chat.id,
text=_("Please edit your settings in a private chat with "
"the bot."))
return
us = UserSetting.get(id=update.message.from_user.id)
if not us:
us = UserSetting(id=update.message.from_user.id)
if not us.stats:
stats = Emoji.BAR_CHART + ' ' + _("Enable statistics")
else:
stats = Emoji.CROSS_MARK + ' ' + _("Delete all statistics")
kb = [[stats], [Emoji.EARTH_GLOBE_EUROPE_AFRICA + ' ' + _("Language")]]
send_async(bot, chat.id, text=Emoji.WRENCH + ' ' + _("Settings"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))
@user_locale
def kb_select(bot, update, groups):
chat = update.message.chat
user = update.message.from_user
option = groups[0]
if option == Emoji.BAR_CHART:
us = UserSetting.get(id=user.id)
us.stats = True
send_async(bot, chat.id, text=_("Enabled statistics!"))
elif option == Emoji.EARTH_GLOBE_EUROPE_AFRICA:
kb = [[locale + ' - ' + descr]
for locale, descr
in sorted(available_locales.items())]
send_async(bot, chat.id, text=_("Select locale"),
reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True))
elif option == Emoji.CROSS_MARK:
us = UserSetting.get(id=user.id)
us.stats = False
us.first_places = 0
us.games_played = 0
us.cards_played = 0
send_async(bot, chat.id, text=_("Deleted and disabled statistics!"))
@user_locale
def locale_select(bot, update, groups):
chat = update.message.chat
user = update.message.from_user
option = groups[0]
if option in available_locales:
us = UserSetting.get(id=user.id)
us.lang = option
_.push(option)
send_async(bot, chat.id, text=_("Set locale!"))
_.pop()
def register():
dispatcher.add_handler(CommandHandler('settings', show_settings))
dispatcher.add_handler(RegexHandler('^([' + Emoji.BAR_CHART +
Emoji.EARTH_GLOBE_EUROPE_AFRICA +
Emoji.CROSS_MARK + ']) .+$',
kb_select, pass_groups=True))
dispatcher.add_handler(RegexHandler(r'^(\w\w_\w\w) - .*',
locale_select, pass_groups=True))

37
shared_vars.py Normal file
View File

@ -0,0 +1,37 @@
#!/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/>.
from telegram.ext import Updater
from telegram.contrib.botan import Botan
from game_manager import GameManager
from database import db
from credentials import TOKEN, BOTAN_TOKEN
db.bind('sqlite', 'uno.sqlite3', create_db=True)
db.generate_mapping(create_tables=True)
gm = GameManager()
updater = Updater(token=TOKEN, workers=32)
dispatcher = updater.dispatcher
botan = False
if BOTAN_TOKEN:
botan = Botan(BOTAN_TOKEN)

136
simple_commands.py Normal file
View File

@ -0,0 +1,136 @@
#!/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/>.
from telegram import ParseMode
from telegram.ext import CommandHandler
from user_setting import UserSetting
from utils import send_async
from shared_vars import dispatcher
from internationalization import _, user_locale
help_text = ("Follow these steps:\n\n"
"1. Add this bot to a group\n"
"2. In the group, start a new game with /new or join an already"
" running game with /join\n"
"3. After at least two players have joined, start the game with"
" /start\n"
"4. Type <code>@unobot</code> into your chat box and hit "
"<b>space</b>, or click the <code>via @unobot</code> text "
"next to messages. You will see your cards (some greyed out), "
"any extra options like drawing, and a <b>?</b> to see the "
"current game state. The <b>greyed out cards</b> are those you "
"<b>can not play</b> at the moment. Tap an option to execute "
"the selected action.\n"
"Players can join the game at any time. To leave a game, "
"use /leave. If a player takes more than 90 seconds to play, "
"you can use /skip to skip that player. Use /notify_me to "
"receive a private message when a new game is started.\n\n"
"<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n"
"/close - Close lobby\n"
"/open - Open lobby\n"
"/enable_translations - Translate relevant texts into all "
"languages spoken in a game\n"
"/disable_translations - Use English for those texts\n\n"
"<b>Experimental:</b> Play in multiple groups at the same time. "
"Press the <code>Current game: ...</code> button and select the "
"group you want to play a card in.\n"
"If you enjoy this bot, "
"<a href=\"https://telegram.me/storebot?start=mau_mau_bot\">"
"rate me</a>, join the "
"<a href=\"https://telegram.me/unobotupdates\">update channel</a>"
" and buy an UNO card game.")
source_text = ("This bot is Free Software and licensed under the AGPL. "
"The code is available here: \n"
"https://github.com/jh0ker/mau_mau_bot")
attributions = ("Attributions:\n"
'Draw icon by '
'<a href="http://www.faithtoken.com/">Faithtoken</a>\n'
'Pass icon by '
'<a href="http://delapouite.com/">Delapouite</a>\n'
"Originals available on http://game-icons.net\n"
"Icons edited by ɳick")
@user_locale
def help(bot, update):
"""Handler for the /help command"""
send_async(bot, update.message.chat_id, text=_(help_text),
parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@user_locale
def source(bot, update):
"""Handler for the /help command"""
send_async(bot, update.message.chat_id, text=_(source_text) + '\n' +
_(attributions),
parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@user_locale
def news(bot, update):
"""Handler for the /news command"""
send_async(bot, update.message.chat_id,
text=_("All news here: https://telegram.me/unobotupdates"),
disable_web_page_preview=True)
@user_locale
def stats(bot, update):
user = update.message.from_user
us = UserSetting.get(id=user.id)
if not us or not us.stats:
send_async(bot, update.message.chat_id,
text=_("You did not enable statistics. Use /settings in "
"a private chat with the bot to enable them."))
else:
stats_text = list()
n = us.games_played
stats_text.append(
_("{number} game played",
"{number} games played",
n).format(number=n)
)
n = us.first_places
stats_text.append(
_("{number} first place",
"{number} first places",
n).format(number=n)
)
n = us.cards_played
stats_text.append(
_("{number} card played",
"{number} cards played",
n).format(number=n)
)
send_async(bot, update.message.chat_id,
text='\n'.join(stats_text))
def register():
dispatcher.add_handler(CommandHandler('help', help))
dispatcher.add_handler(CommandHandler('source', source))
dispatcher.add_handler(CommandHandler('news', news))
dispatcher.add_handler(CommandHandler('stats', stats))

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>

View File

@ -1,41 +0,0 @@
import unittest
from game import Game
from player import Player
class Test(unittest.TestCase):
game = None
def setUp(self):
self.game = Game()
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)

111
test/test_game_manager.py Normal file
View File

@ -0,0 +1,111 @@
#!/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
from telegram import User, Chat
from game_manager import GameManager
from errors import AlreadyJoinedError, LobbyClosedError, NoGameInChatError, \
NotEnoughPlayersError
class Test(unittest.TestCase):
game = None
def setUp(self):
self.gm = GameManager()
self.chat0 = Chat(0, 'group')
self.chat1 = Chat(1, 'group')
self.chat2 = Chat(2, 'group')
self.user0 = User(0, 'user0')
self.user1 = User(1, 'user1')
self.user2 = User(2, 'user2')
def test_new_game(self):
g0 = self.gm.new_game(self.chat0)
g1 = self.gm.new_game(self.chat1)
self.assertListEqual(self.gm.chatid_games[0], [g0])
self.assertListEqual(self.gm.chatid_games[1], [g1])
def test_join_game(self):
self.assertRaises(NoGameInChatError,
self.gm.join_game,
*(self.user0, self.chat0))
g0 = self.gm.new_game(self.chat0)
self.gm.join_game(self.user0, self.chat0)
self.assertEqual(len(g0.players), 1)
self.gm.join_game(self.user1, self.chat0)
self.assertEqual(len(g0.players), 2)
g0.open = False
self.assertRaises(LobbyClosedError,
self.gm.join_game,
*(self.user2, self.chat0))
g0.open = True
self.assertRaises(AlreadyJoinedError,
self.gm.join_game,
*(self.user1, self.chat0))
def test_leave_game(self):
g0 = self.gm.new_game(self.chat0)
self.gm.join_game(self.user0, self.chat0)
self.gm.join_game(self.user1, self.chat0)
self.assertRaises(NotEnoughPlayersError,
self.gm.leave_game,
*(self.user1, self.chat0))
self.gm.join_game(self.user2, self.chat0)
self.gm.leave_game(self.user0, self.chat0)
self.assertRaises(NoGameInChatError,
self.gm.leave_game,
*(self.user0, self.chat0))
def test_end_game(self):
g0 = self.gm.new_game(self.chat0)
self.gm.join_game(self.user0, self.chat0)
self.gm.join_game(self.user1, self.chat0)
self.assertEqual(len(self.gm.userid_players[0]), 1)
g1 = self.gm.new_game(self.chat0)
self.gm.join_game(self.user2, self.chat0)
self.gm.end_game(self.chat0, self.user0)
self.assertEqual(len(self.gm.chatid_games[0]), 1)
self.gm.end_game(self.chat0, self.user2)
self.assertFalse(0 in self.gm.chatid_games)
self.assertFalse(0 in self.gm.userid_players)
self.assertFalse(1 in self.gm.userid_players)
self.assertFalse(2 in self.gm.userid_players)

164
test/test_player.py Normal file
View File

@ -0,0 +1,164 @@
#!/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
from game import Game
from player import Player
import card as c
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_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 = list()
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)

202
test_player.py Normal file
View 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()

32
user_setting.py Normal file
View File

@ -0,0 +1,32 @@
#!/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/>.
from database import db, Optional, Required, PrimaryKey, db_session
class UserSetting(db.Entity):
id = PrimaryKey(int, auto=False, size=64) # Telegram User ID
lang = Optional(str, default='') # The language setting for this user
stats = Optional(bool, default=False) # Opt-in to keep game statistics
first_places = Optional(int, default=0) # Nr. of games won in first place
games_played = Optional(int, default=0) # Nr. of games completed
cards_played = Optional(int, default=0) # Nr. of cards played total
use_keyboards = Optional(bool, default=False) # Use keyboards (unused)

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# #
# Telegram bot to play UNO in group chats # Telegram bot to play UNO in group chats
# Copyright (c) 2016 Jannes Höke <uno@jhoeke.de> # Copyright (c) 2016 Jannes Höke <uno@jhoeke.de>
@ -17,7 +18,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from telegram import Emoji from telegram import Emoji
from telegram.ext.dispatcher import run_async
from internationalization import _, __
logger = logging.getLogger(__name__)
TIMEOUT = 2.5
def list_subtract(list1, list2): def list_subtract(list1, list2):
@ -41,10 +51,55 @@ def display_name(user):
def display_color(color): def display_color(color):
""" Convert a color code to actual color name """ """ Convert a color code to actual color name """
if color == "r": if color == "r":
return Emoji.HEAVY_BLACK_HEART + " Red" return _("{emoji} Red").format(emoji=Emoji.HEAVY_BLACK_HEART)
if color == "b": if color == "b":
return Emoji.BLUE_HEART + " Blue" return _("{emoji} Blue").format(emoji=Emoji.BLUE_HEART)
if color == "g": if color == "g":
return Emoji.GREEN_HEART + " Green" return _("{emoji} Green").format(emoji=Emoji.GREEN_HEART)
if color == "y": if color == "y":
return Emoji.YELLOW_HEART + " Yellow" return _("{emoji} Yellow").format(emoji=Emoji.YELLOW_HEART)
def display_color_group(color, game):
""" Convert a color code to actual color name """
if color == "r":
return __("{emoji} Red", game.translate).format(
emoji=Emoji.HEAVY_BLACK_HEART)
if color == "b":
return __("{emoji} Blue", game.translate).format(
emoji=Emoji.BLUE_HEART)
if color == "g":
return __("{emoji} Green", game.translate).format(
emoji=Emoji.GREEN_HEART)
if color == "y":
return __("{emoji} Yellow", game.translate).format(
emoji=Emoji.YELLOW_HEART)
def error(bot, update, error):
"""Simple error handler"""
logger.exception(error)
@run_async
def send_async(bot, *args, **kwargs):
"""Send a message asynchronously"""
if 'timeout' not in kwargs:
kwargs['timeout'] = TIMEOUT
try:
bot.sendMessage(*args, **kwargs)
except Exception as e:
error(None, None, e)
@run_async
def answer_async(bot, *args, **kwargs):
"""Answer an inline query asynchronously"""
if 'timeout' not in kwargs:
kwargs['timeout'] = TIMEOUT
try:
bot.answerInlineQuery(*args, **kwargs)
except Exception as e:
error(None, None, e)