90 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
33 changed files with 4173 additions and 391 deletions

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.1.1 - 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

View File

@ -3,8 +3,14 @@
The following awesome people contributed to this project by translating it: The following awesome people contributed to this project by translating it:
| Locale | Translators | | Locale | Translators |
|--------|--------------------------------------------------------| |--------|----------------------------------------------------------------------|
| de_DE | [Jannes Höke](https://github.com/jh0ker) | | de_DE | [Jannes Höke](https://github.com/jh0ker) |
| it_IT | Carola Mariano, nick | | 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. Please add yourself here alphabetically when you submit your first translation.

218
bot.py
View File

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- 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
@ -23,9 +23,9 @@ from datetime import datetime
from random import randint from random import randint
from telegram import ParseMode, Message, Chat, InlineKeyboardMarkup, \ from telegram import ParseMode, Message, Chat, InlineKeyboardMarkup, \
InlineKeyboardButton InlineKeyboardButton, ReplyKeyboardMarkup, Emoji
from telegram.ext import InlineQueryHandler, ChosenInlineResultHandler, \ from telegram.ext import InlineQueryHandler, ChosenInlineResultHandler, \
CommandHandler, MessageHandler, Filters, CallbackQueryHandler CommandHandler, MessageHandler, Filters, CallbackQueryHandler, RegexHandler
from telegram.ext.dispatcher import run_async from telegram.ext.dispatcher import run_async
from start_bot import start_bot from start_bot import start_bot
@ -36,35 +36,68 @@ from user_setting import UserSetting
from utils import display_name from utils import display_name
import card as c import card as c
from errors import (NoGameInChatError, LobbyClosedError, AlreadyJoinedError, from errors import (NoGameInChatError, LobbyClosedError, AlreadyJoinedError,
NotEnoughPlayersError, DeckEmptyError) NotEnoughPlayersError, DeckEmptyError, PlayerLeftError)
from utils import _, __, send_async, answer_async, user_locale, game_locales, \ from utils import send_async, answer_async, error, TIMEOUT
error, TIMEOUT
from shared_vars import botan, gm, updater, dispatcher from shared_vars import botan, gm, updater, dispatcher
from internationalization import _, __, user_locale, game_locales
import simple_commands
import settings
import simple_commands, settings
from simple_commands import help from simple_commands import help
logging.basicConfig( logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.DEBUG) level=logging.INFO)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@user_locale
def notify_me(bot, update):
"""Handler for /notify_me command, pm people for next game"""
chat_id = update.message.chat.id
if update.message.chat.type == 'private':
send_async(bot,
chat_id,
text=_("Send this command in a group to be notified "
"when a new game is started there."))
else:
try:
gm.remind_dict[chat_id].add(update.message.from_user.id)
send_async(bot,
chat_id,
text=_("You will be notified "
"when a new game is started in {title}.").format(
title=update.message.chat.title))
except KeyError:
gm.remind_dict[chat_id] = {update.message.from_user.id}
@user_locale @user_locale
def new_game(bot, update): def new_game(bot, update):
"""Handler for the /new command""" """Handler for the /new command"""
chat_id = update.message.chat_id chat_id = update.message.chat.id
if update.message.chat.type == 'private': if update.message.chat.type == 'private':
help(bot, update) help(bot, update)
else: else:
if update.message.chat_id in gm.remind_dict:
for user in gm.remind_dict[chat_id]:
send_async(bot,
user,
text=_("A new game has been started in {title}.").format(
title=update.message.chat.title))
del gm.remind_dict[chat_id]
game = gm.new_game(update.message.chat) game = gm.new_game(update.message.chat)
game.owner = update.message.from_user game.owner = update.message.from_user
send_async(bot, chat_id, send_async(bot, chat_id,
text=_("Created a new game! Join the game with /join " text=_("Created a new game! Wait for your friends "
"and start the game with /start")) "and start the game with /start"))
gm.join_game(update.message.from_user, update.message.chat)
if botan: if botan:
botan.track(update.message, 'New games') botan.track(update.message, 'New games')
@ -135,17 +168,17 @@ def leave_game(bot, update):
reply_to_message_id=update.message.message_id) reply_to_message_id=update.message.message_id)
except NotEnoughPlayersError: except NotEnoughPlayersError:
gm.end_game(chat, user) gm.end_game(user, chat)
send_async(bot, chat.id, text=__("Game ended!", game.translate)) send_async(bot, chat.id, text=__("Game ended!", multi=game.translate))
else: else:
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Okay. Next Player: {name}", game.translate).format( text=__("Okay. Next Player: {name}",
multi=game.translate).format(
name=display_name(game.current_player.user)), name=display_name(game.current_player.user)),
reply_to_message_id=update.message.message_id) reply_to_message_id=update.message.message_id)
@run_async
def select_game(bot, update): def select_game(bot, update):
"""Handler for callback queries to select the current game""" """Handler for callback queries to select the current game"""
@ -157,14 +190,15 @@ def select_game(bot, update):
gm.userid_current[user_id] = player gm.userid_current[user_id] = player
break break
else: else:
bot.sendMessage(update.callback_query.message.chat_id, send_async(bot,
text=_("Game not found."), update.callback_query.message.chat_id,
timeout=TIMEOUT) text=_("Game not found."))
return return
@run_async
def selected(bot):
back = [[InlineKeyboardButton(text=_("Back to last group"), back = [[InlineKeyboardButton(text=_("Back to last group"),
switch_inline_query='')]] switch_inline_query='')]]
bot.answerCallbackQuery(update.callback_query.id, bot.answerCallbackQuery(update.callback_query.id,
text=_("Please switch to the group you selected!"), text=_("Please switch to the group you selected!"),
show_alert=False, show_alert=False,
@ -180,6 +214,8 @@ def select_game(bot, update):
parse_mode=ParseMode.HTML, parse_mode=ParseMode.HTML,
timeout=TIMEOUT) timeout=TIMEOUT)
selected(bot)
@game_locales @game_locales
def status_update(bot, update): def status_update(bot, update):
@ -196,11 +232,12 @@ def status_update(bot, update):
except NoGameInChatError: except NoGameInChatError:
pass pass
except NotEnoughPlayersError: except NotEnoughPlayersError:
gm.end_game(chat, user) gm.end_game(user, chat)
send_async(bot, chat.id, text=__("Game ended!", game.translate)) send_async(bot, chat.id, text=__("Game ended!",
multi=game.translate))
else: else:
send_async(bot, chat.id, text=__("Removing {name} from the game", send_async(bot, chat.id, text=__("Removing {name} from the game",
game.translate) multi=game.translate)
.format(name=display_name(user))) .format(name=display_name(user)))
@ -236,7 +273,7 @@ def start_game(bot, update, args):
__("First player: {name}\n" __("First player: {name}\n"
"Use /close to stop people from joining the game.\n" "Use /close to stop people from joining the game.\n"
"Enable multi-translations with /enable_translations", "Enable multi-translations with /enable_translations",
game.translate) multi=game.translate)
.format(name=display_name(game.current_player.user))) .format(name=display_name(game.current_player.user)))
@run_async @run_async
@ -298,7 +335,7 @@ def close_game(bot, update):
else: else:
send_async(bot, chat.id, send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that") text=_("Only the game creator ({name}) can do that.")
.format(name=game.owner.first_name), .format(name=game.owner.first_name),
reply_to_message_id=update.message.message_id) reply_to_message_id=update.message.message_id)
return return
@ -388,6 +425,47 @@ def disable_translations(bot, update):
return return
@game_locales
@user_locale
def mode(bot, update):
"""Handler for the /mode command"""
chat = update.message.chat
user = update.message.from_user
games = gm.chatid_games.get(chat.id)
if not games:
send_async(bot, chat.id,
text=__("There is no running game in this chat."))
return
game = games[-1]
if chat.type == 'private':
send_async(bot, chat.id,
text=_("Please change the group mode in the public game group with "
"the bot."))
return
if game.owner.id == user.id and not games.started:
kb = [["🎻 " + _("Original"), "🚴 " + _("Progressive UNO")]]
markup = ReplyKeyboardMarkup(kb, resize_keyboard=True, one_time_keyboard=True)
choice = send_async(bot, chat.id, text=_("Choose the game mode:"), reply_markup = markup)
if choice[0] == "🎻":
game.mode = 0
send_async(bot, chat.id, text=_("Original rules will be used."))
else if choice[0] == "🚴":
game.mode = 1
send_async(bot, chat.id, text=_("Progressive UNO rules will be used."))
return
else:
send_async(bot, chat.id,
text=_("Only the game creator ({name}) can do that when the game does not start")
.format(name=game.owner.first_name),
reply_to_message_id=update.message.message_id)
return
@game_locales @game_locales
@user_locale @user_locale
def skip_player(bot, update): def skip_player(bot, update):
@ -410,9 +488,12 @@ def skip_player(bot, update):
delta = (now - started).seconds delta = (now - started).seconds
if delta < skipped_player.waiting_time: if delta < skipped_player.waiting_time:
n = skipped_player.waiting_time - delta
send_async(bot, chat.id, send_async(bot, chat.id,
text=_("Please wait {time} seconds") text=_("Please wait {time} second",
.format(time=(skipped_player.waiting_time - delta)), "Please wait {time} seconds",
n)
.format(time=n),
reply_to_message_id=update.message.message_id) reply_to_message_id=update.message.message_id)
elif skipped_player.waiting_time > 0: elif skipped_player.waiting_time > 0:
@ -423,11 +504,17 @@ def skip_player(bot, update):
except DeckEmptyError: except DeckEmptyError:
pass pass
n = skipped_player.waiting_time
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Waiting time to skip this player has " text=__("Waiting time to skip this player has "
"been reduced to {time} second.\n"
"Next player: {name}",
"Waiting time to skip this player has "
"been reduced to {time} seconds.\n" "been reduced to {time} seconds.\n"
"Next player: {name}", game.translate) "Next player: {name}",
.format(time=skipped_player.waiting_time, n,
multi=game.translate)
.format(time=n,
name=display_name(next_player.user))) name=display_name(next_player.user)))
game.turn() game.turn()
@ -435,20 +522,25 @@ def skip_player(bot, update):
try: try:
gm.leave_game(skipped_player.user, chat) gm.leave_game(skipped_player.user, chat)
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("{name1} was skipped four times in a row " text=__("{name1} was skipped three times in a row "
"and has been removed from the game.\n" "and has been removed from the game.\n"
"Next player: {name2}", game.translate) "Next player: {name2}", multi=game.translate)
.format(name1=display_name(skipped_player.user), .format(name1=display_name(skipped_player.user),
name2=display_name(next_player.user))) name2=display_name(next_player.user)))
except NotEnoughPlayersError: except NotEnoughPlayersError:
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("{name} was skipped four times in a row " text=__("{name} was skipped three times in a row "
"and has been removed from the game.\n" "and has been removed from the game.\n"
"The game ended.", game.translate) "The game ended.", multi=game.translate)
.format(name=display_name(skipped_player.user))) .format(name=display_name(skipped_player.user)))
gm.end_game(chat.id, skipped_player.user) us2 = UserSetting.get(id=skipped_player.user.id)
if us2 and us2.stats:
us2.games_played += 1
gm.end_game(skipped_player.user, chat)
@game_locales @game_locales
@ -459,7 +551,6 @@ def reply_to_query(bot, update):
Builds the result list for inline queries and answers to the client. Builds the result list for inline queries and answers to the client.
""" """
results = list() results = list()
playable = list()
switch = None switch = None
try: try:
@ -476,7 +567,7 @@ def reply_to_query(bot, update):
elif user_id == game.current_player.user.id: elif user_id == game.current_player.user.id:
if game.choosing_color: if game.choosing_color:
add_choose_color(results, game) add_choose_color(results, game)
add_other_cards(playable, player, results, game) add_other_cards(player, results, game)
else: else:
if not player.drew: if not player.drew:
add_draw(player, results) add_draw(player, results)
@ -496,6 +587,8 @@ def reply_to_query(bot, update):
str(card) not in added_ids)) str(card) not in added_ids))
added_ids.append(str(card)) added_ids.append(str(card))
add_gameinfo(game, results)
elif user_id != game.current_player.user.id or not game.started: elif user_id != game.current_player.user.id or not game.started:
for card in sorted(player.cards): for card in sorted(player.cards):
add_card(game, card, results, can_play=False) add_card(game, card, results, can_play=False)
@ -526,7 +619,7 @@ def process_result(bot, update):
game = player.game game = player.game
result_id = update.chosen_inline_result.result_id result_id = update.chosen_inline_result.result_id
chat = game.chat chat = game.chat
except KeyError: except (KeyError, AttributeError):
return return
logger.debug("Selected result: " + result_id) logger.debug("Selected result: " + result_id)
@ -541,7 +634,7 @@ def process_result(bot, update):
return return
elif int(anti_cheat) != last_anti_cheat: elif int(anti_cheat) != last_anti_cheat:
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Cheat attempt by {name}", game.translate) text=__("Cheat attempt by {name}", multi=game.translate)
.format(name=display_name(player.user))) .format(name=display_name(player.user)))
return return
elif result_id == 'call_bluff': elif result_id == 'call_bluff':
@ -553,14 +646,20 @@ def process_result(bot, update):
elif result_id == 'pass': elif result_id == 'pass':
game.turn() game.turn()
elif result_id in c.COLORS: elif result_id in c.COLORS:
try:
game.choose_color(result_id) game.choose_color(result_id)
except PlayerLeftError:
send_async(bot, chat.id,
text=__("There are errors in choosing color. "
"Color is now unchanged.", multi=game.translate))
game.turn()
else: else:
reset_waiting_time(bot, player) reset_waiting_time(bot, player)
do_play_card(bot, player, result_id) do_play_card(bot, player, result_id)
if game in gm.chatid_games.get(chat.id, list()): if game in gm.chatid_games.get(chat.id, list()):
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Next player: {name}", game.translate) text=__("Next player: {name}", multi=game.translate)
.format(name=display_name(game.current_player.user))) .format(name=display_name(game.current_player.user)))
@ -568,11 +667,11 @@ def reset_waiting_time(bot, player):
"""Resets waiting time for a player and sends a notice to the group""" """Resets waiting time for a player and sends a notice to the group"""
chat = player.game.chat chat = player.game.chat
if player.waiting_time < 90: if player.waiting_time < 60:
player.waiting_time = 90 player.waiting_time = 60
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Waiting time for {name} has been reset to 90 " text=__("Waiting time for {name} has been reset to 60 "
"seconds", player.game.translate) "seconds", multi=player.game.translate)
.format(name=display_name(player.user))) .format(name=display_name(player.user)))
@ -588,6 +687,7 @@ def do_play_card(bot, player, result_id):
if not us: if not us:
us = UserSetting(id=user.id) us = UserSetting(id=user.id)
if us.stats:
us.cards_played += 1 us.cards_played += 1
if game.choosing_color: if game.choosing_color:
@ -598,7 +698,7 @@ def do_play_card(bot, player, result_id):
if len(player.cards) == 0: if len(player.cards) == 0:
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("{name} won!", game.translate) text=__("{name} won!", multi=game.translate)
.format(name=user.first_name)) .format(name=user.first_name))
if us.stats: if us.stats:
@ -607,16 +707,19 @@ def do_play_card(bot, player, result_id):
if game.players_won is 0: if game.players_won is 0:
us.first_places += 1 us.first_places += 1
game.players_won += 1
try: try:
gm.leave_game(user, chat) gm.leave_game(user, chat)
except NotEnoughPlayersError: except NotEnoughPlayersError:
send_async(bot, chat.id, text=__("Game ended!", game.translate)) send_async(bot, chat.id,
text=__("Game ended!", multi=game.translate))
us2 = UserSetting.get(id=game.current_player.next.user.id) us2 = UserSetting.get(id=game.current_player.user.id)
if us2 and us2.stats: if us2 and us2.stats:
us2.games_played += 1 us2.games_played += 1
gm.end_game(chat, user) gm.end_game(user, chat)
if botan: if botan:
botan.track(Message(randint(1, 1000000000), user, datetime.now(), botan.track(Message(randint(1, 1000000000), user, datetime.now(),
@ -634,7 +737,7 @@ def do_draw(bot, player):
except DeckEmptyError: except DeckEmptyError:
send_async(bot, player.game.chat.id, send_async(bot, player.game.chat.id,
text=__("There are no more cards in the deck.", text=__("There are no more cards in the deck.",
game.translate)) multi=game.translate))
if (game.last_card.value == c.DRAW_TWO or if (game.last_card.value == c.DRAW_TWO or
game.last_card.special == c.DRAW_FOUR) and \ game.last_card.special == c.DRAW_FOUR) and \
@ -649,30 +752,32 @@ def do_call_bluff(bot, player):
if player.prev.bluffing: if player.prev.bluffing:
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("Bluff called! Giving 4 cards to {name}", text=__("Bluff called! Giving {numbers} cards to {name}",
game.translate) multi=game.translate)
.format(name=player.prev.user.first_name)) .format(name=player.prev.user.first_name,
numbers=game.draw_counter))
try: try:
player.prev.draw() player.prev.draw()
except DeckEmptyError: except DeckEmptyError:
send_async(bot, player.game.chat.id, send_async(bot, player.game.chat.id,
text=__("There are no more cards in the deck.", text=__("There are no more cards in the deck.",
game.translate)) multi=game.translate))
else: else:
game.draw_counter += 2 game.draw_counter += 2
send_async(bot, chat.id, send_async(bot, chat.id,
text=__("{name1} didn't bluff! Giving 6 cards to {name2}", text=__("{name1} didn't bluff! Giving {numbers} cards to {name2}",
game.translate) multi=game.translate)
.format(name1=player.prev.user.first_name, .format(name1=player.prev.user.first_name,
name2=player.user.first_name)) name2=player.user.first_name,
numbers=game.draw_counter))
try: try:
player.draw() player.draw()
except DeckEmptyError: except DeckEmptyError:
send_async(bot, player.game.chat.id, send_async(bot, player.game.chat.id,
text=__("There are no more cards in the deck.", text=__("There are no more cards in the deck.",
game.translate)) multi=game.translate))
game.turn() game.turn()
@ -692,6 +797,11 @@ dispatcher.add_handler(CommandHandler('enable_translations',
dispatcher.add_handler(CommandHandler('disable_translations', dispatcher.add_handler(CommandHandler('disable_translations',
disable_translations)) disable_translations))
dispatcher.add_handler(CommandHandler('skip', skip_player)) dispatcher.add_handler(CommandHandler('skip', skip_player))
dispatcher.add_handler(CommandHandler('notify_me', notify_me))
dispatcher.add_handler(CommandHandler('mode', mode))
dispatcher.add_handler(RegexHandler('^(Original|Progressive UNO)$', mode, pass_groups=True))
simple_commands.register()
settings.register()
dispatcher.add_handler(MessageHandler([Filters.status_update], status_update)) dispatcher.add_handler(MessageHandler([Filters.status_update], status_update))
dispatcher.add_error_handler(error) dispatcher.add_error_handler(error)

View File

@ -116,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'
} }

View File

@ -36,3 +36,7 @@ class NotEnoughPlayersError(Exception):
class DeckEmptyError(Exception): class DeckEmptyError(Exception):
pass pass
class PlayerLeftError(Exception):
pass

View File

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- 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
@ -36,10 +36,12 @@ class Game(object):
open = True open = True
translate = False translate = False
players_won = 0 players_won = 0
mode = 0
def __init__(self, chat): def __init__(self, chat):
self.chat = chat self.chat = chat
self.last_card = None self.last_card = None
self.joined_before = set()
while not self.last_card or self.last_card.special: while not self.last_card or self.last_card.special:
self.deck = Deck() self.deck = Deck()

View File

@ -19,6 +19,7 @@
import logging import logging
import random
from game import Game from game import Game
from player import Player from player import Player
@ -33,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):
@ -47,6 +50,11 @@ class GameManager(object):
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
@ -70,7 +78,8 @@ class GameManager(object):
# 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, if he is in one of them # 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.
if player in game.players or user.id in game.joined_before:
raise AlreadyJoinedError() raise AlreadyJoinedError()
else: else:
try: try:
@ -80,9 +89,20 @@ class GameManager(object):
except NotEnoughPlayersError: except NotEnoughPlayersError:
self.end_game(chat, user) 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)
# Randomize player position.
game.joined_before.append(user.id)
if len(players) > 2:
players.insert(random.randrange(len(players)), player)
else:
players.append(player) players.append(player)
self.userid_current[user.id] = player self.userid_current[user.id] = player
def leave_game(self, user, chat): def leave_game(self, user, chat):
@ -92,6 +112,16 @@ class GameManager(object):
players = self.userid_players.get(user.id, list()) players = self.userid_players.get(user.id, list())
if not player: if not 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()
p.leave()
return
else:
raise NoGameInChatError raise NoGameInChatError
game = player.game game = player.game
@ -113,7 +143,7 @@ class GameManager(object):
del self.userid_current[user.id] del self.userid_current[user.id]
del self.userid_players[user.id] del self.userid_players[user.id]
def end_game(self, chat, user): def end_game(self, user, chat):
""" """
End a game End a game
""" """
@ -130,14 +160,29 @@ class GameManager(object):
# Clear game # Clear game
for player_in_game in game.players: for player_in_game in game.players:
this_users_players = self.userid_players[player_in_game.user.id] this_users_players = \
self.userid_players.get(player_in_game.user.id, list())
try:
this_users_players.remove(player_in_game) this_users_players.remove(player_in_game)
except ValueError:
pass
if this_users_players: if this_users_players:
self.userid_current[player.user.id] = this_users_players[0] try:
self.userid_current[player_in_game.user.id] = this_users_players[0]
except KeyError:
pass
else: else:
try:
del self.userid_players[player_in_game.user.id] del self.userid_players[player_in_game.user.id]
except KeyError:
pass
try:
del self.userid_current[player_in_game.user.id] del self.userid_current[player_in_game.user.id]
except KeyError:
pass
self.chatid_games[chat.id].remove(game) self.chatid_games[chat.id].remove(game)
if not self.chatid_games[chat.id]: if not self.chatid_games[chat.id]:

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

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

@ -16,6 +16,7 @@
# Jannes Höke <uno@jhoeke.de>, 2016. # Jannes Höke <uno@jhoeke.de>, 2016.
# #
#: bot.py:224 #: bot.py:224
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: uno_bot 0.1\n" "Project-Id-Version: uno_bot 0.1\n"
@ -26,9 +27,9 @@ msgstr ""
"Language-Team: Deutsch <uno@jhoeke.de>\n" "Language-Team: Deutsch <uno@jhoeke.de>\n"
"Language: de_DE\n" "Language: de_DE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Gtranslator 2.91.6\n" "X-Generator: Gtranslator 2.91.6\n"
#: bot.py:60 #: bot.py:60
@ -38,15 +39,16 @@ msgid "Follow these steps:\n"
"2. In the group, start a new game with /new or join an already running game " "2. In the group, start a new game with /new or join an already running game "
"with /join\n" "with /join\n"
"3. After at least two players have joined, start the game with /start\n" "3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@mau_mau_bot</code> into your chat box and hit <b>space</b>, " "4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @mau_mau_bot</code> text next to messages. You will " "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>?" "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 " "</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 " "you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n" "action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a " "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 takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n" "player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n" "\n"
"<b>Language</b> and other settings: /settings\n" "<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n" "Other commands (only game creator):\n"
@ -70,8 +72,8 @@ msgstr ""
"join einem bestehenden Spiel beitreten\n" "join einem bestehenden Spiel beitreten\n"
"3. Nachdem mindestens zwei Spieler beigetreten sind, starte das Spiel mit /" "3. Nachdem mindestens zwei Spieler beigetreten sind, starte das Spiel mit /"
"start\n" "start\n"
"3. Gib <code>@mau_mau_bot</code> in deine Chatbox ein und drücke die " "4. Gib <code>@unobot</code> in deine Chatbox ein und drücke die "
"<b>Leertaste</b>, oder tippe auf den <code>via @mau_mau_bot</code>-Text " "<b>Leertaste</b>, oder tippe auf den <code>via @unobot</code>-Text "
"neben oder über den Nachrichten. Du siehst deine Karten (einige in grau), " "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 " "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 " "das laufende Spiel anzuzeigen. Die <b>grauen Karten</b> kannst du gerade "
@ -79,7 +81,9 @@ msgstr ""
"Aktion auszuführen bzw. die Karte zu spielen. \n" "Aktion auszuführen bzw. die Karte zu spielen. \n"
"Spieler können dem Spiel jederzeit beitreten. Um das Spiel zu verlassen, " "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 " "benutze /leave. Wenn ein Spieler länger als 90 Sekunden braucht, kannst du "
"ihn mit /skip überspringen.\n" "ihn mit /skip überspringen. "
"Benutze /notify_me, um über ein neues Spiel in dieser Gruppe per privater "
"Nachricht informiert zu werden.\n"
"\n" "\n"
"<b>Sprache</b> und andere Einstellungen: /settings\n" "<b>Sprache</b> und andere Einstellungen: /settings\n"
"Weitere Kommandos (nur Spiel-Ersteller):\n" "Weitere Kommandos (nur Spiel-Ersteller):\n"
@ -112,6 +116,15 @@ msgid ""
msgstr "" msgstr ""
"Neues Spiel erstellt! Tritt dem Spiel mit /join bei und starte es mit /start" "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 #: bot.py:152
msgid "The lobby is closed" msgid "The lobby is closed"
msgstr "Die Lobby ist geschlossen" msgstr "Die Lobby ist geschlossen"
@ -228,17 +241,22 @@ msgstr "Du spielst kein Spiel in dieser Gruppe."
#: bot.py:400 #: bot.py:400
#, python-format #, python-format
msgid "Please wait {time} seconds" msgid "Please wait {time} second"
msgstr "Bitte warte {time} Sekunden" msgid_plural "Please wait {time} seconds"
msgstr[0] "Bitte warte {time} Sekunde"
msgstr[1] "Bitte warte {time} Sekunden"
#: bot.py:413 #: bot.py:413
#, python-format #, python-format
msgid "" msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}" "Next player: {name}"
msgstr "" msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Die Wartezeit um diesen Spieler zu überspringen wurde auf {time} Sekunden " "Next player: {name}"
"reduziert.\n" 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}" "Nächster Spieler: {name}"
#: bot.py:424 #: bot.py:424
@ -267,12 +285,12 @@ msgstr "Alle News hier: https://telegram.me/unobotupdates"
#: bot.py:513 #: bot.py:513
#, python-format #, python-format
msgid "Current game: %s" msgid "Current game: {game}"
msgstr "Aktuelles Spiel: {game}" msgstr "Aktuelles Spiel: {game}"
#: bot.py:545 #: bot.py:545
#, python-format #, python-format
msgid "Cheat attempt by %s" msgid "Cheat attempt by {name}"
msgstr "{name} hat versucht zu schummeln!" msgstr "{name} hat versucht zu schummeln!"
#: bot.py:562 #: bot.py:562
@ -312,8 +330,10 @@ msgid "Choose Color"
msgstr "Wähle Farbe" msgstr "Wähle Farbe"
#: results.py:56 #: results.py:56
msgid "Cards (tap for game state):" msgid "Last card (tap for game state):"
msgstr "Karten (tippe für Spielinfo):" 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 #: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}" msgid "Current player: {name}"
@ -324,13 +344,17 @@ msgid "Last card: {card}"
msgstr "Letzte Karte: {card}" msgstr "Letzte Karte: {card}"
#: results.py:62 results.py:125 results.py:168 #: results.py:62 results.py:125 results.py:168
msgid "Players: {player_list}" msgid "Player: {player_list}"
msgstr "Spieler: {player_list}" msgid_plural "Players: {player_list}"
msgstr[0] "Spieler: {player_list}"
msgstr[1] "Spieler: {player_list}"
#: results.py:72 #: results.py:72
#, python-format #, python-format
msgid "{name} ({number} cards)" msgid "{name} ({number} card)"
msgstr "{name} ({number} Karten)" msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} Karte)"
msgstr[1] "{name} ({number} Karten)"
#: results.py:81 #: results.py:81
msgid "You are not playing" msgid "You are not playing"
@ -354,11 +378,10 @@ msgstr "Starte das Spiel mit /start"
#: results.py:108 #: results.py:108
#, python-format #, python-format
msgid "Drawing 1 card" msgid "Drawing {number} card"
msgstr "Zieht 1 Karte" msgid_plural "Drawing {number} cards"
msgstr[0] "Ich ziehe {number} Karte"
msgid "Drawing {number} cards" msgstr[1] "Ich ziehe {number} Karten"
msgstr "Zieht {number} Karten"
#: results.py:136 #: results.py:136
msgid "Pass" msgid "Pass"
@ -412,16 +435,22 @@ msgstr "Du hast die Spiel-Statistiken nicht aktiviert. Aktiviere sie, mit dem "
"/settings-Kommando in einem privaten Chat mit dem Bot." "/settings-Kommando in einem privaten Chat mit dem Bot."
#: simple_commands.py #: simple_commands.py
msgid "{number} games played" msgid "{number} game played"
msgstr "{number} gespielte Spiele" msgid_plural "{number} games played"
msgstr[0] "{number} gespieltes Spiel"
msgstr[1] "{number} gespielte Spiele"
#: simple_commands.py #: simple_commands.py
msgid "{number} first places" msgid "{number} first place"
msgstr "{number}x 1. Platz" msgid_plural "{number} first places"
msgstr[0] "{number} mal 1. Platz"
msgstr[1] "{number} mal 1. Platz"
#: simple_commands.py #: simple_commands.py
msgid "{number} cards played" msgid "{number} card played"
msgstr "{number} gespielte Karten" msgid_plural "{number} cards played"
msgstr[0] "{number} gespielte Karte"
msgstr[1] "{number} gespielte Karten"
#: utils.py #: utils.py
@ -439,4 +468,3 @@ msgstr "{emoji} Blau"
#: utils.py #: utils.py
msgid "{emoji} Yellow" msgid "{emoji} Yellow"
msgstr "{emoji} Gelb" 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

@ -18,7 +18,7 @@ msgstr ""
"Project-Id-Version: uno_bot 0.1\n" "Project-Id-Version: uno_bot 0.1\n"
"Report-Msgid-Bugs-To: uno@jhoeke.de\n" "Report-Msgid-Bugs-To: uno@jhoeke.de\n"
"POT-Creation-Date: 2016-05-22 20:02+0200\n" "POT-Creation-Date: 2016-05-22 20:02+0200\n"
"PO-Revision-Date: 2016-05-22 21:27+0200\n" "PO-Revision-Date: 2016-05-23 01:39+0200\n"
"Language-Team: en <uno@jhoeke.de>\n" "Language-Team: en <uno@jhoeke.de>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -36,8 +36,8 @@ msgid ""
"2. In the group, start a new game with /new or join an already running game " "2. In the group, start a new game with /new or join an already running game "
"with /join\n" "with /join\n"
"3. After at least two players have joined, start the game with /start\n" "3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@mau_mau_bot</code> into your chat box and hit <b>space</b>, " "4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @mau_mau_bot</code> text next to messages. You will " "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>?" "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 " "</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 " "you <b>can not play</b> at the moment. Tap an option to execute the selected "
@ -64,12 +64,12 @@ msgstr ""
"Segui questi passaggi:\n" "Segui questi passaggi:\n"
"\n" "\n"
"1. Aggiungi questo bot ad un gruppo\n" "1. Aggiungi questo bot ad un gruppo\n"
"2. Nel gruppo, inizia un nuovo gioco con /new o unisciti ad una partita già " "2. Nel gruppo, inizia una nuova partita con /new o unisciti a quella già "
"avviata con /join\n" "avviata con /join\n"
"3. Quando almeno due giocatori si sono uniti alla partita, si può iniziare " "3. Quando almeno due giocatori si sono uniti alla partita, si può iniziare "
"con /start\n" "con /start\n"
"4. Digita <code>@mau_mau_bot</code> nella casella di testo e premi " "4. Digita <code>@unobot</code> nella casella di testo e premi "
"<b>spazio</b>, o clicca sul testo <code>via @mau_mau_bot</code> vicino ai " "<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 " "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 " "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. " "<b>carte in grigio</b> sono quelle che <b>non puoi giocare</b> al momento. "
@ -80,17 +80,17 @@ msgstr ""
"\n" "\n"
"<b>Lingua</b> e altre opzioni: /settings\n" "<b>Lingua</b> e altre opzioni: /settings\n"
"Altri comandi (utilizzabili solo da chi ha creato la partita):\n" "Altri comandi (utilizzabili solo da chi ha creato la partita):\n"
"/close - Chiude la lobby, nessun giocatore può unirsi al gioco dopo che " "/close - Chiude la stanza, nessun giocatore può unirsi alla partita dopo che "
"questo è già avviato.\n" "questa è già avviata.\n"
"/open - Apre la lobby, i giocatori possono unirsi al gioco in qualsiasi " "/open - Apre la stanza, i giocatori possono unirsi alla partita in qualsiasi "
"momento. \n" "momento. \v/enable_translations - Traduce i messaggi importanti nelle lingue "
"/enable_translations - Traduce i messaggi importanti nelle lingue parlate " "parlate durante la partita\n"
"in gioco\n" "/disable_translations - Usa l'inglese (default) per questi messaggi\n"
"/disable_translations - Usa l'inglese per questi messaggi\n"
"\n" "\n"
"<b>Sperimentale:</b> Gioca in più gruppi allo stesso tempo. Premi il tasto " "<b>Sperimentale:</b> Gioca in più gruppi allo stesso tempo. Premi il tasto "
"<code>Partita corrente: ...</code> e scegli il gruppo dove vuoi giocare la " "<code>Partita in corso: ...</code> e scegli il gruppo dove vuoi giocare la "
"carta.\n" "carta.\n"
"\n"
"Se ti piace questo bot, <a href=\"https://telegram.me/storebot?" "Se ti piace questo bot, <a href=\"https://telegram.me/storebot?"
"start=mau_mau_bot\">votami</a>, segui gli <a href=\"https://telegram.me/" "start=mau_mau_bot\">votami</a>, segui gli <a href=\"https://telegram.me/"
"unobotupdates\">aggiornamenti</a> e compra il gioco di carte UNO. " "unobotupdates\">aggiornamenti</a> e compra il gioco di carte UNO. "
@ -101,33 +101,32 @@ msgid ""
"here: \n" "here: \n"
"https://github.com/jh0ker/mau_mau_bot" "https://github.com/jh0ker/mau_mau_bot"
msgstr "" msgstr ""
"Questo bot è Free Software e certificato con AGPL. Il codice è disponibile " "Questo bot è un software gratuito e distribuito sotto licenza AGPL. Il "
"qui:\n" "codice è disponibile qui:\n"
"https://github.com/jh0ker/mau_mau_bot" "https://github.com/jh0ker/mau_mau_bot"
#: bot.py:133 #: bot.py:133
msgid "" msgid ""
"Created a new game! Join the game with /join and start the game with /start" "Created a new game! Join the game with /join and start the game with /start"
msgstr "" msgstr ""
"È stato creato un nuovo gioco! Unisciti con /join e inizia la partita con /" "È stata creata una nuova partita! Unisciti con /join e inizia a giocare con /"
"start" "start"
#: bot.py:152 #: bot.py:152
msgid "The lobby is closed" msgid "The lobby is closed"
msgstr "La lobby è chiusa. Nessuno nuovo giocatore può unirsi alla partita." msgstr "La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita."
#: bot.py:156 #: bot.py:156
msgid "No game is running at the moment. Create a new game with /new" msgid "No game is running at the moment. Create a new game with /new"
msgstr "" msgstr "Non c'è nessuna partita aperta al momento. Iniziane una nuova con /new"
"Non c'è nessuna partita aperta al momento. Inizia un nuovo gioco con /new"
#: bot.py:162 #: bot.py:162
msgid "You already joined the game. Start the game with /start" msgid "You already joined the game. Start the game with /start"
msgstr "Ti sei già unito al gioco. Inizia la partita con /start" msgstr "Ti sei già unito/a alla partita. Inizia a giocare con /start"
#: bot.py:167 #: bot.py:167
msgid "Joined the game" msgid "Joined the game"
msgstr "Si è unito al gioco" msgstr "Si è unito/a alla partita"
#: bot.py:179 bot.py:191 #: bot.py:179 bot.py:191
msgid "You are not playing in a game in this group." msgid "You are not playing in a game in this group."
@ -151,7 +150,7 @@ msgstr "Vai all'ultimo gruppo. "
#: bot.py:227 #: bot.py:227
msgid "Please switch to the group you selected!" msgid "Please switch to the group you selected!"
msgstr "Per favore, spostati sul gruppo che hai selezionato!" msgstr "Per favore, vai sul gruppo che hai selezionato!"
#: bot.py:233 #: bot.py:233
#, python-format #, python-format
@ -179,8 +178,8 @@ msgstr "La partita è già iniziata"
#: bot.py:281 #: bot.py:281
msgid "At least two players must /join the game before you can start it" msgid "At least two players must /join the game before you can start it"
msgstr "" msgstr ""
"Ci devono essere almeno due giocatori che hanno cliccato /join per iniziare " "Devono partecipare almeno due giocatori per iniziare la partita. Partecipa "
"la partita" "con /join"
#: bot.py:297 #: bot.py:297
#, python-format #, python-format
@ -204,12 +203,12 @@ msgstr "Non c'è alcuna partita aperta in questa chat."
#: bot.py:342 #: bot.py:342
msgid "Closed the lobby. No more players can join this game." msgid "Closed the lobby. No more players can join this game."
msgstr "" msgstr ""
"La lobby è chiusa. Nessun nuovo giocatore può unirsi alla partita corrente." "La stanza è chiusa. Nessun nuovo giocatore può unirsi alla partita in corso."
#: bot.py:348 bot.py:373 #: bot.py:348 bot.py:373
#, python-format #, python-format
msgid "Only the game creator ({name}) can do that." msgid "Only the game creator ({name}) can do that."
msgstr "Solo il creatore del gioco ({name}) può farlo. " msgstr "Solo il creatore della partita ({name}) può farlo. "
#: bot.py:349 #: bot.py:349
#, python-format #, python-format
@ -225,7 +224,7 @@ msgstr "Multi-traduzione disabilitata. Abilitala con /enable_translations"
#: bot.py:368 #: bot.py:368
msgid "Opened the lobby. New players may /join the game." msgid "Opened the lobby. New players may /join the game."
msgstr "" msgstr ""
"La lobby è aperta. Nuovi giocatori possono unirsi alla partita con /join" "La stanza è aperta. Nuovi giocatori possono unirsi alla partita con /join"
#: bot.py:386 #: bot.py:386
msgid "You are not playing in a game in this chat." msgid "You are not playing in a game in this chat."
@ -233,16 +232,23 @@ msgstr "Non stai giocando alcuna partita in questa chat. "
#: bot.py:400 #: bot.py:400
#, python-format #, python-format
msgid "Please wait {time} seconds" msgid "Please wait {time} second"
msgstr "Per favore, attendi {time} secondi" msgid_plural "Please wait {time} seconds"
msgstr[0] "Per favore, attendi {time} secondi"
msgstr[1] "Per favore, attendi {time} secondi"
#: bot.py:413 #: bot.py:413
#, python-format #, python-format
msgid "" msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Waiting time to skip this player has been reduced to {time} seconds.\n"
"Next player: {name}" "Next player: {name}"
msgstr "" msgid_plural "Waiting time to skip this player has been reduced to {time} seconds.\n"
"Il tempo di attesa per saltare questo giocatore è stata ridotta a {time} " "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" "secondi.\n"
"Prossimo giocatore: {name}" "Prossimo giocatore: {name}"
@ -253,7 +259,6 @@ msgid ""
"Next player: {name2}" "Next player: {name2}"
msgstr "" msgstr ""
"{name1} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n" "{name1} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n"
" \n"
"Prossimo giocatore: {name2}" "Prossimo giocatore: {name2}"
#: bot.py:432 #: bot.py:432
@ -263,7 +268,6 @@ msgid ""
"The game ended." "The game ended."
msgstr "" msgstr ""
"{name} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n" "{name} è stato saltato per quattro turni ed è stato rimosso dalla partita.\n"
" \n"
"La partita è conclusa." "La partita è conclusa."
#: bot.py:455 #: bot.py:455
@ -273,7 +277,7 @@ msgstr "Tutte le novità le trovi qui: https://telegram.me/unobotupdates"
#: bot.py:513 #: bot.py:513
#, python-format #, python-format
msgid "Current game: {group}" msgid "Current game: {group}"
msgstr "Partita corrente: {group}" msgstr "Partita in corso: {group}"
#: bot.py:545 #: bot.py:545
#, python-format #, python-format
@ -305,20 +309,22 @@ msgstr "Non ci sono più carte sul tavolo."
#: bot.py:627 #: bot.py:627
#, python-format #, python-format
msgid "Bluff called! Giving 4 cards to {name}" msgid "Bluff called! Giving 4 cards to {name}"
msgstr "Il baro è stato scoperto! Sto dando 4 carte a {name}" msgstr "Il baro è stato scoperto! {name} deve pescare 4 carte!"
#: bot.py:639 #: bot.py:639
#, python-format #, python-format
msgid "{name1} didn't bluff! Giving 6 cards to {name2}" msgid "{name1} didn't bluff! Giving 6 cards to {name2}"
msgstr "{name1} non ha barato! Sto dando 6 carte a {name2}" msgstr "{name1} non ha barato! {name2} deve pescare 6 carte!"
#: results.py:38 #: results.py:38
msgid "Choose Color" msgid "Choose Color"
msgstr "Scegli il colore" msgstr "Scegli il colore"
#: results.py:56 #: results.py:56
msgid "Cards (tap for game state):" msgid "Last card (tap for game state):"
msgstr "Carte (clicca per vedere lo stato della partita):" 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 #: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}" msgid "Current player: {name}"
@ -329,13 +335,17 @@ msgid "Last card: {card}"
msgstr "Ultima carta: {card}" msgstr "Ultima carta: {card}"
#: results.py:62 results.py:125 results.py:168 #: results.py:62 results.py:125 results.py:168
msgid "Players: {player_list}" msgid "Player: {player_list}"
msgstr "Giocatori: {player_list}" msgid_plural "Players: {player_list}"
msgstr[0] "Giocatori: {player_list}"
msgstr[1] "Giocatori: {player_list}"
#: results.py:72 #: results.py:72
#, python-format #, python-format
msgid "{name} ({number} cards)" msgid "{name} ({number} card)"
msgstr "{name} ({number} carte)" msgid_plural "{name} ({number} cards)"
msgstr[0] "{name} ({number} carta)"
msgstr[1] "{name} ({number} carte)"
#: results.py:81 #: results.py:81
msgid "You are not playing" msgid "You are not playing"
@ -346,28 +356,27 @@ msgid ""
"Not playing right now. Use /new to start a game or /join to join the current " "Not playing right now. Use /new to start a game or /join to join the current "
"game in this group" "game in this group"
msgstr "" msgstr ""
"Non stai giocando in questo momento. Usa /new per iniziare un nuovo gioco o /" "Non stai giocando in questo momento. Usa /new per iniziare una nuova partita "
"join per partecipare alla partita avviata in questo gruppo" "o /join per partecipare a quella già avviata in questo gruppo"
#: results.py:95 #: results.py:95
msgid "The game wasn't started yet" msgid "The game wasn't started yet"
msgstr "Il gioco non è ancora iniziato" msgstr "La partita non è ancora iniziata"
#: results.py:97 #: results.py:97
msgid "Start the game with /start" msgid "Start the game with /start"
msgstr "Inizia il gioco con /start" msgstr "Inizia la partita con /start"
#: results.py:108 #: results.py:108
#, python-format #, python-format
msgid "Drawing 1 card" msgid "Drawing {number} card"
msgstr "Pesca 1 carta" msgid_plural "Drawing {number} cards"
msgstr[0] "Sto pescando {number} carta"
msgid "Drawing {number} cards" msgstr[1] "Sto pescando {number} carte"
msgstr "Pesca {number} carte"
#: results.py:136 #: results.py:136
msgid "Pass" msgid "Pass"
msgstr "Passa" msgstr "Passo"
#: results.py:148 #: results.py:148
msgid "I'm calling your bluff!" msgid "I'm calling your bluff!"
@ -400,7 +409,7 @@ msgstr "Statistiche abilitate!"
#: settings.py:70 #: settings.py:70
msgid "Select locale" msgid "Select locale"
msgstr "Seleziona locale" msgstr "Seleziona la lingua"
#: settings.py:81 #: settings.py:81
msgid "Deleted and disabled statistics!" msgid "Deleted and disabled statistics!"
@ -408,7 +417,7 @@ msgstr "Le statistiche sono state eliminate e disabilitate!"
#: settings.py:94 #: settings.py:94
msgid "Set locale!" msgid "Set locale!"
msgstr "Imposta locale!" msgstr "Lingua impostata!"
#: simple_commands.py #: simple_commands.py
msgid "" msgid ""
@ -419,16 +428,22 @@ msgstr ""
"per abilitarle." "per abilitarle."
#: simple_commands.py #: simple_commands.py
msgid "{number} games played" msgid "{number} game played"
msgstr "{number} partite giocate" msgid_plural "{number} games played"
msgstr[0] "{number} partite giocate"
msgstr[1] "{number} partite giocate"
#: simple_commands.py #: simple_commands.py
msgid "{number} first places" msgid "{number} first place"
msgstr "{number} primi posti" msgid_plural "{number} first places"
msgstr[0] "{number} vittorie"
msgstr[1] "{number} vittorie"
#: simple_commands.py #: simple_commands.py
msgid "{number} cards played" msgid "{number} card played"
msgstr "{number} carte giocate" msgid_plural "{number} cards played"
msgstr[0] "{number} carta giocate"
msgstr[1] "{number} carte giocate"
#: utils.py #: utils.py
msgid "{emoji} Green" msgid "{emoji} Green"

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} Желтый"

View File

@ -29,6 +29,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: utf-8\n" "Content-Transfer-Encoding: utf-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: bot.py:60 #: bot.py:60
@ -39,15 +40,16 @@ msgid "Follow these steps:\n"
"2. In the group, start a new game with /new or join an already running game " "2. In the group, start a new game with /new or join an already running game "
"with /join\n" "with /join\n"
"3. After at least two players have joined, start the game with /start\n" "3. After at least two players have joined, start the game with /start\n"
"4. Type <code>@mau_mau_bot</code> into your chat box and hit <b>space</b>, " "4. Type <code>@unobot</code> into your chat box and hit <b>space</b>, "
"or click the <code>via @mau_mau_bot</code> text next to messages. You will " "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>?" "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 " "</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 " "you <b>can not play</b> at the moment. Tap an option to execute the selected "
"action.\n" "action.\n"
"Players can join the game at any time. To leave a game, use /leave. If a " "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 takes more than 90 seconds to play, you can use /skip to skip that "
"player.\n" "player. "
"Use /notify_me to receive a private message when a new game is started.\n"
"\n" "\n"
"<b>Language</b> and other settings: /settings\n" "<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n" "Other commands (only game creator):\n"
@ -74,6 +76,14 @@ msgstr ""
msgid "Created a new game! Join the game with /join and start the game with /start" msgid "Created a new game! Join the game with /join and start the game with /start"
msgstr "" 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 #: bot.py:152
msgid "The lobby is closed" msgid "The lobby is closed"
msgstr "" msgstr ""
@ -184,14 +194,19 @@ msgstr ""
#: bot.py:400 #: bot.py:400
#, python-format #, python-format
msgid "Please wait {time} seconds" msgid "Please wait {time} second"
msgstr "" msgid_plural "Please wait {time} seconds"
msgstr[0] ""
msgstr[1] ""
#: bot.py:413 #: bot.py:413
#, python-format #, python-format
msgid "Waiting time to skip this player has been reduced to {time} seconds.\n" msgid "Waiting time to skip this player has been reduced to {time} second.\n"
"Next player: {name}" "Next player: {name}"
msgstr "" 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 #: bot.py:424
#, python-format #, python-format
@ -256,8 +271,10 @@ msgid "Choose Color"
msgstr "" msgstr ""
#: results.py:56 #: results.py:56
msgid "Cards (tap for game state):" msgid "Last card (tap for game state):"
msgstr "" msgid_plural "Cards (tap for game state):"
msgstr[0] ""
msgstr[1] ""
#: results.py:60 results.py:123 results.py:165 #: results.py:60 results.py:123 results.py:165
msgid "Current player: {name}" msgid "Current player: {name}"
@ -268,13 +285,17 @@ msgid "Last card: {card}"
msgstr "" msgstr ""
#: results.py:62 results.py:125 results.py:168 #: results.py:62 results.py:125 results.py:168
msgid "Players: {player_list}" msgid "Player: {player_list}"
msgstr "" msgid_plural "Players: {player_list}"
msgstr[0] ""
msgstr[1] ""
#: results.py:72 #: results.py:72
#, python-format #, python-format
msgid "{name} ({number} cards)" msgid "{name} ({number} card)"
msgstr "" msgid_plural "{name} ({number} cards)"
msgstr[0] ""
msgstr[1] ""
#: results.py:81 #: results.py:81
msgid "You are not playing" msgid "You are not playing"
@ -295,11 +316,10 @@ msgstr ""
#: results.py:108 #: results.py:108
#, python-format #, python-format
msgid "Drawing 1 card" msgid "Drawing {number} card"
msgstr "" msgid_plural "Drawing {number} cards"
msgstr[0] ""
msgid "Drawing {number} cards" msgstr[1] ""
msgstr ""
#: results.py:136 #: results.py:136
msgid "Pass" msgid "Pass"
@ -352,16 +372,22 @@ msgid "You did not enable statistics. Use /settings in "
msgstr "" msgstr ""
#: simple_commands.py #: simple_commands.py
msgid "{number} games played" msgid "{number} game played"
msgstr "" msgid_plural "{number} games played"
msgstr[0] ""
msgstr[1] ""
#: simple_commands.py #: simple_commands.py
msgid "{number} first places" msgid "{number} first place"
msgstr "" msgid_plural "{number} first places"
msgstr[0] ""
msgstr[1] ""
#: simple_commands.py #: simple_commands.py
msgid "{number} cards played" msgid "{number} card played"
msgstr "" msgid_plural "{number} cards played"
msgstr[0] ""
msgstr[1] ""
#: utils.py #: utils.py
@ -379,4 +405,3 @@ msgstr ""
#: utils.py #: utils.py
msgid "{emoji} Yellow" msgid "{emoji} Yellow"
msgstr "" 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}"

View File

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- 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
@ -63,7 +63,7 @@ class Player(object):
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):
"""Removes player from the game and closes the gap in the list""" """Removes player from the game and closes the gap in the list"""
@ -160,14 +160,15 @@ class Player(object):
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 mode == 0: # This mode is to apply the original rule
if (card.color != last.color and card.value != last.value and 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:
@ -177,7 +178,32 @@ class Player(object):
(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: # 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
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") self.logger.debug("Last card has no color")
is_playable = False is_playable = False

2
requirements.txt Normal file
View File

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

View File

@ -26,8 +26,8 @@ from telegram import InlineQueryResultArticle, InputTextMessageContent, \
InlineQueryResultCachedSticker as Sticker InlineQueryResultCachedSticker as Sticker
import card as c import card as c
from utils import display_color, display_color_group, display_name, \ from utils import display_color, display_color_group, display_name
list_subtract, _, __ from internationalization import _, __
def add_choose_color(results, game): def add_choose_color(results, game):
@ -44,17 +44,16 @@ def add_choose_color(results, game):
) )
def add_other_cards(playable, player, results, game): def add_other_cards(player, results, game):
"""Add hand cards when choosing colors""" """Add hand cards when choosing colors"""
if not playable:
playable = list()
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)),
description=', '.join([repr(card) for card in player.cards]),
input_message_content=game_info(game) input_message_content=game_info(game)
) )
) )
@ -62,7 +61,9 @@ def add_other_cards(playable, player, results, game):
def player_list(game): def player_list(game):
"""Generate list of player strings""" """Generate list of player strings"""
return [_("{name} ({number} cards)") return [_("{name} ({number} card)",
"{name} ({number} cards)",
len(player.cards))
.format(name=player.user.first_name, number=len(player.cards)) .format(name=player.user.first_name, number=len(player.cards))
for player in game.players] for player in game.players]
@ -101,10 +102,9 @@ def add_draw(player, results):
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 1 card', player.game.translate) InputTextMessageContent(__('Drawing {number} card',
if n == 1 else 'Drawing {number} cards', n,
__('Drawing {number} cards', multi=player.game.translate)
player.game.translate)
.format(number=n)) .format(number=n))
) )
) )
@ -127,8 +127,9 @@ def add_pass(results, game):
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(
game.translate)) __('Pass', multi=game.translate)
)
) )
) )
@ -141,7 +142,7 @@ def add_call_bluff(results, game):
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!",
game.translate)) multi=game.translate))
) )
) )
@ -168,6 +169,8 @@ def game_info(game):
"\n" + "\n" +
_("Last card: {card}").format(card=repr(game.last_card)) + _("Last card: {card}").format(card=repr(game.last_card)) +
"\n" + "\n" +
_("Players: {player_list}") _("Player: {player_list}",
"Players: {player_list}",
len(players))
.format(player_list=" -> ".join(players)) .format(player_list=" -> ".join(players))
) )

View File

@ -18,18 +18,14 @@
# 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 ReplyKeyboardMarkup, Emoji from telegram import ReplyKeyboardMarkup, Emoji
from telegram.ext import CommandHandler, RegexHandler from telegram.ext import CommandHandler, RegexHandler
from utils import send_async from utils import send_async
from user_setting import UserSetting from user_setting import UserSetting
from utils import _, user_locale
from shared_vars import dispatcher from shared_vars import dispatcher
from locales import available_locales
available_locales = [['en_US', 'de_DE'], from internationalization import _, user_locale
['it_IT']]
@user_locale @user_locale
@ -70,8 +66,11 @@ def kb_select(bot, update, groups):
send_async(bot, chat.id, text=_("Enabled statistics!")) send_async(bot, chat.id, text=_("Enabled statistics!"))
elif option == Emoji.EARTH_GLOBE_EUROPE_AFRICA: 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"), send_async(bot, chat.id, text=_("Select locale"),
reply_markup=ReplyKeyboardMarkup(keyboard=available_locales, reply_markup=ReplyKeyboardMarkup(keyboard=kb,
one_time_keyboard=True)) one_time_keyboard=True))
elif option == Emoji.CROSS_MARK: elif option == Emoji.CROSS_MARK:
@ -89,7 +88,7 @@ def locale_select(bot, update, groups):
user = update.message.from_user user = update.message.from_user
option = groups[0] option = groups[0]
if option in [locale for row in available_locales for locale in row]: if option in available_locales:
us = UserSetting.get(id=user.id) us = UserSetting.get(id=user.id)
us.lang = option us.lang = option
_.push(option) _.push(option)
@ -97,10 +96,11 @@ def locale_select(bot, update, groups):
_.pop() _.pop()
def register():
dispatcher.add_handler(CommandHandler('settings', show_settings)) dispatcher.add_handler(CommandHandler('settings', show_settings))
dispatcher.add_handler(RegexHandler('^([' + Emoji.BAR_CHART + dispatcher.add_handler(RegexHandler('^([' + Emoji.BAR_CHART +
Emoji.EARTH_GLOBE_EUROPE_AFRICA + Emoji.EARTH_GLOBE_EUROPE_AFRICA +
Emoji.CROSS_MARK + ']) .+$', Emoji.CROSS_MARK + ']) .+$',
kb_select, pass_groups=True)) kb_select, pass_groups=True))
dispatcher.add_handler(RegexHandler(r'^(\w\w_\w\w)$', dispatcher.add_handler(RegexHandler(r'^(\w\w_\w\w) - .*',
locale_select, pass_groups=True)) locale_select, pass_groups=True))

View File

@ -19,7 +19,7 @@
from telegram.ext import Updater from telegram.ext import Updater
from telegram.utils.botan import Botan from telegram.contrib.botan import Botan
from game_manager import GameManager from game_manager import GameManager
from database import db from database import db

View File

@ -21,8 +21,9 @@ from telegram import ParseMode
from telegram.ext import CommandHandler from telegram.ext import CommandHandler
from user_setting import UserSetting from user_setting import UserSetting
from utils import _, send_async, user_locale from utils import send_async
from shared_vars import dispatcher from shared_vars import dispatcher
from internationalization import _, user_locale
help_text = ("Follow these steps:\n\n" help_text = ("Follow these steps:\n\n"
"1. Add this bot to a group\n" "1. Add this bot to a group\n"
@ -30,8 +31,8 @@ help_text = ("Follow these steps:\n\n"
" running game with /join\n" " running game with /join\n"
"3. After at least two players have joined, start the game with" "3. After at least two players have joined, start the game with"
" /start\n" " /start\n"
"4. Type <code>@mau_mau_bot</code> into your chat box and hit " "4. Type <code>@unobot</code> into your chat box and hit "
"<b>space</b>, or click the <code>via @mau_mau_bot</code> text " "<b>space</b>, or click the <code>via @unobot</code> text "
"next to messages. You will see your cards (some greyed out), " "next to messages. You will see your cards (some greyed out), "
"any extra options like drawing, and a <b>?</b> to see the " "any extra options like drawing, and a <b>?</b> to see the "
"current game state. The <b>greyed out cards</b> are those you " "current game state. The <b>greyed out cards</b> are those you "
@ -39,7 +40,8 @@ help_text = ("Follow these steps:\n\n"
"the selected action.\n" "the selected action.\n"
"Players can join the game at any time. To leave a game, " "Players can join the game at any time. To leave a game, "
"use /leave. If a player takes more than 90 seconds to play, " "use /leave. If a player takes more than 90 seconds to play, "
"you can use /skip to skip that player.\n\n" "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" "<b>Language</b> and other settings: /settings\n"
"Other commands (only game creator):\n" "Other commands (only game creator):\n"
"/close - Close lobby\n" "/close - Close lobby\n"
@ -59,6 +61,13 @@ help_text = ("Follow these steps:\n\n"
source_text = ("This bot is Free Software and licensed under the AGPL. " source_text = ("This bot is Free Software and licensed under the AGPL. "
"The code is available here: \n" "The code is available here: \n"
"https://github.com/jh0ker/mau_mau_bot") "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 @user_locale
@ -71,7 +80,8 @@ def help(bot, update):
@user_locale @user_locale
def source(bot, update): def source(bot, update):
"""Handler for the /help command""" """Handler for the /help command"""
send_async(bot, update.message.chat_id, text=_(source_text), send_async(bot, update.message.chat_id, text=_(source_text) + '\n' +
_(attributions),
parse_mode=ParseMode.HTML, disable_web_page_preview=True) parse_mode=ParseMode.HTML, disable_web_page_preview=True)
@ -93,17 +103,33 @@ def stats(bot, update):
"a private chat with the bot to enable them.")) "a private chat with the bot to enable them."))
else: else:
stats_text = list() stats_text = list()
n = us.games_played
stats_text.append( stats_text.append(
_("{number} games played").format(number=us.games_played)) _("{number} game played",
"{number} games played",
n).format(number=n)
)
n = us.first_places
stats_text.append( stats_text.append(
_("{number} first places").format(number=us.first_places)) _("{number} first place",
"{number} first places",
n).format(number=n)
)
n = us.cards_played
stats_text.append( stats_text.append(
_("{number} cards played").format(number=us.cards_played)) _("{number} card played",
"{number} cards played",
n).format(number=n)
)
send_async(bot, update.message.chat_id, send_async(bot, update.message.chat_id,
text='\n'.join(stats_text)) text='\n'.join(stats_text))
def register():
dispatcher.add_handler(CommandHandler('help', help)) dispatcher.add_handler(CommandHandler('help', help))
dispatcher.add_handler(CommandHandler('source', source)) dispatcher.add_handler(CommandHandler('source', source))
dispatcher.add_handler(CommandHandler('news', news)) dispatcher.add_handler(CommandHandler('news', news))

View File

@ -138,6 +138,7 @@ class Test(unittest.TestCase):
def test_bluffing(self): def test_bluffing(self):
p = Player(self.game, "Player 0") p = Player(self.game, "Player 0")
Player(self.game, "Player 01")
self.game.last_card = c.Card(c.RED, '1') self.game.last_card = c.Card(c.RED, '1')
@ -156,4 +157,8 @@ class Test(unittest.TestCase):
c.Card(None, None, c.CHOOSE)] c.Card(None, None, c.CHOOSE)]
p.playable_cards() p.playable_cards()
self.assertFalse(p.bluffing)
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()

View File

@ -24,7 +24,7 @@ from database import db, Optional, Required, PrimaryKey, db_session
class UserSetting(db.Entity): class UserSetting(db.Entity):
id = PrimaryKey(int, auto=False, size=64) # Telegram User ID id = PrimaryKey(int, auto=False, size=64) # Telegram User ID
lang = Optional(str, default='en') # The language setting for this user lang = Optional(str, default='') # The language setting for this user
stats = Optional(bool, default=False) # Opt-in to keep game statistics stats = Optional(bool, default=False) # Opt-in to keep game statistics
first_places = Optional(int, default=0) # Nr. of games won in first place first_places = Optional(int, default=0) # Nr. of games won in first place
games_played = Optional(int, default=0) # Nr. of games completed games_played = Optional(int, default=0) # Nr. of games completed

111
utils.py
View File

@ -19,52 +19,17 @@
import logging import logging
from functools import wraps
from flufl.i18n import registry
from flufl.i18n import PackageStrategy
from telegram import Emoji from telegram import Emoji
from telegram.ext.dispatcher import run_async from telegram.ext.dispatcher import run_async
import locales
from database import db_session
from user_setting import UserSetting
from shared_vars import gm
strategy = PackageStrategy('unobot', locales) from internationalization import _, __
application = registry.register(strategy)
_ = application._
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
TIMEOUT = 2.5 TIMEOUT = 2.5
def __(string, multi_translate):
"""Translates text into all locales on the stack"""
translations = list()
locales = list()
if not multi_translate:
_.push('en_US')
translations.append(_(string))
_.pop()
else:
while _.code:
translation = _(string)
if translation not in translations:
translations.append(translation)
locales.append(_.code)
_.pop()
for l in reversed(locales):
_.push(l)
return '\n'.join(translations)
def list_subtract(list1, list2): def list_subtract(list1, list2):
""" Helper function to subtract two lists and return the sorted result """ """ Helper function to subtract two lists and return the sorted result """
list1 = list1.copy() list1 = list1.copy()
@ -138,75 +103,3 @@ def answer_async(bot, *args, **kwargs):
bot.answerInlineQuery(*args, **kwargs) bot.answerInlineQuery(*args, **kwargs)
except Exception as e: except Exception as e:
error(None, None, e) error(None, None, e)
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:
_.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:
loc = us.lang
else:
loc = 'en_US'
if loc in locales:
continue
_.push(loc)
locales.append(loc)
result = func(bot, update, *pargs, **kwargs)
for i in locales:
_.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):
chat = None
return user, chat