Port merels to game_handler.

Fixes #305
This commit is contained in:
amanagr 2018-02-17 11:44:50 +05:30 committed by showell
parent b0b372c95d
commit 243f7bbe5d
6 changed files with 203 additions and 236 deletions

View file

@ -14,7 +14,7 @@ from .constants import EMPTY_BOARD
class MerelsStorage(): class MerelsStorage():
def __init__(self, storage): def __init__(self, topic_name, storage):
"""Instantiate storage field. """Instantiate storage field.
The current database has this form: The current database has this form:
@ -30,29 +30,6 @@ class MerelsStorage():
""" """
self.storage = storage self.storage = storage
def create_new_game(self, topic_name):
""" Creates a new merels game if it doesn't exists yet.
:param topic_name: Name of the topic
:return: True, if the game is successfully created, False if otherwise.
"""
parameters = ("X", 0, 0, EMPTY_BOARD, "", 0)
# Checks whether the game exists yet
# If it exists
try:
if not self.storage.contains(topic_name) or self.storage.get(
topic_name) == "":
self.storage.put(topic_name, json.dumps(parameters))
return True
else:
return False
except KeyError:
self.storage.put(topic_name, json.dumps(parameters))
return True
def update_game(self, topic_name, turn, x_taken, o_taken, board, hill_uid, def update_game(self, topic_name, turn, x_taken, o_taken, board, hill_uid,
take_mode): take_mode):
""" Updates the current status of the game to the database. """ Updates the current status of the game to the database.

View file

@ -7,13 +7,13 @@ freely import another modules.
import re import re
from zulip_bots.game_handler import BadMoveException
from . import database from . import database
from . import mechanics from . import mechanics
COMMAND_PATTERN = re.compile( COMMAND_PATTERN = re.compile(
"^(\\w*).*(\\d,\\d).*(\\d,\\d)|^(\\w+).*(\\d,\\d)") "^(\\w*).*(\\d,\\d).*(\\d,\\d)|^(\\w+).*(\\d,\\d)")
def getInfo(): def getInfo():
""" Gets the info on starting the game """ Gets the info on starting the game
@ -22,7 +22,6 @@ def getInfo():
return "To start a game, mention me and add `create`. A game will start " \ return "To start a game, mention me and add `create`. A game will start " \
"in that topic. " "in that topic. "
def getHelp(): def getHelp():
""" Gets the help message """ Gets the help message
@ -30,8 +29,6 @@ def getHelp():
""" """
return """Commands: return """Commands:
create: Create a new game if it doesn't exist
reset: Reset a current game
put (v,h): Put a man into the grid in phase 1 put (v,h): Put a man into the grid in phase 1
move (v,h) -> (v,h): Moves a man from one point to -> another point move (v,h) -> (v,h): Moves a man from one point to -> another point
take (v,h): Take an opponent's man from the grid in phase 2/3 take (v,h): Take an opponent's man from the grid in phase 2/3
@ -39,76 +36,65 @@ take (v,h): Take an opponent's man from the grid in phase 2/3
v: vertical position of grid v: vertical position of grid
h: horizontal position of grid""" h: horizontal position of grid"""
def unknown_command(): def unknown_command():
"""Returns an unknown command info """Returns an unknown command info
:return: A string containing info about available commands :return: A string containing info about available commands
""" """
return "Unknown command. Available commands: create, reset, help, " \ message = "Unknown command. Available commands: " \
"put (v,h), take (v,h), move (v,h) -> (v,h)" "put (v,h), take (v,h), move (v,h) -> (v,h)"
raise BadMoveException(message)
# def beat(message, topic_name, merels_storage):
def beat(message, topic_name, merels_storage): def beat(message, topic_name, merels_storage):
""" This gets triggered every time a user send a message in any topic """ This gets triggered every time a user send a message in any topic
:param message: User's message :param message: User's message
:param topic_name: User's current topic :param topic_name: User's current topic
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string to reply to that topic, if any. If not, it :return: a tuple of response string and message, non-empty string
returns an empty string we want to keep the turn of the same played,
an empty string otherwise.
""" """
merels = database.MerelsStorage(topic_name, merels_storage)
merels = database.MerelsStorage(merels_storage)
if "create" in message.lower():
return mechanics.create_room(topic_name, merels_storage)
if "help" in message.lower():
return getHelp()
if "reset" in message.lower():
if merels.get_game_data(topic_name) is not None:
return mechanics.reset_game(topic_name, merels_storage)
else:
return "No game created yet."
match = COMMAND_PATTERN.match(message) match = COMMAND_PATTERN.match(message)
same_player_move = "" # message indicating move of the same player
if match is None: if match is None:
return unknown_command() return unknown_command()
# Matches when user types the command in format of: "command v,h -> v,
# h" or something similar that has three arguments
if merels.get_game_data(topic_name) is not None:
if match.group(1) is not None and match.group( if match.group(1) is not None and match.group(
2) is not None and match.group(3) is not None: 2) is not None and match.group(3) is not None:
responses = ""
responses = ""
command = match.group(1) command = match.group(1)
if command.lower() == "move": if command.lower() == "move":
p1 = [int(x) for x in match.group(2).split(",")] p1 = [int(x) for x in match.group(2).split(",")]
p2 = [int(x) for x in match.group(3).split(",")] p2 = [int(x) for x in match.group(3).split(",")]
# Note that it doesn't have to be "move 1,1 -> 1,2".
# It can also just be "move 1,1 1,2"
if mechanics.get_take_status(topic_name, merels_storage) == 1: if mechanics.get_take_status(topic_name, merels_storage) == 1:
responses += "Take is required to proceed. Please try " \
"again.\n" raise BadMoveException("Take is required to proceed."
else: " Please try again.\n")
responses += mechanics.move_man(topic_name, p1, p2, responses += mechanics.move_man(topic_name, p1, p2,
merels_storage) + "\n" merels_storage) + "\n"
responses += after_event_checkup(responses, topic_name, no_moves = after_event_checkup(responses, topic_name, merels_storage)
merels_storage)
mechanics.update_hill_uid(topic_name, merels_storage) mechanics.update_hill_uid(topic_name, merels_storage)
else:
responses += unknown_command()
responses += mechanics.display_game(topic_name, responses += mechanics.display_game(topic_name, merels_storage) + "\n"
merels_storage) + "\n"
return responses if no_moves != "":
same_player_move = no_moves
else:
return unknown_command()
if mechanics.get_take_status(topic_name, merels_storage) == 1:
same_player_move = "Take is required to proceed.\n"
return responses, same_player_move
elif match.group(4) is not None and match.group(5) is not None: elif match.group(4) is not None and match.group(5) is not None:
command = match.group(4) command = match.group(4)
p1 = [int(x) for x in match.group(5).split(",")] p1 = [int(x) for x in match.group(5).split(",")]
@ -118,46 +104,43 @@ def beat(message, topic_name, merels_storage):
responses = "" responses = ""
if mechanics.get_take_status(topic_name, merels_storage) == 1: if mechanics.get_take_status(topic_name, merels_storage) == 1:
responses += "Take is required to proceed. Please try " \ raise BadMoveException("Take is required to proceed."
"again.\n" " Please try again.\n")
else:
responses += mechanics.put_man(topic_name, p1[0], p1[1], responses += mechanics.put_man(topic_name, p1[0], p1[1],
merels_storage) + "\n" merels_storage) + "\n"
responses += after_event_checkup(responses, topic_name, no_moves = after_event_checkup(responses, topic_name, merels_storage)
merels_storage)
mechanics.update_hill_uid(topic_name, merels_storage) mechanics.update_hill_uid(topic_name, merels_storage)
responses += mechanics.display_game(topic_name,
merels_storage) + "\n" responses += mechanics.display_game(topic_name, merels_storage) + "\n"
return responses
if no_moves != "":
same_player_move = no_moves
if mechanics.get_take_status(topic_name, merels_storage) == 1:
same_player_move = "Take is required to proceed.\n"
return responses, same_player_move
# take 5,3 # take 5,3
elif command == "take": elif command == "take":
responses = "" responses = ""
if mechanics.get_take_status(topic_name, merels_storage) == 1: if mechanics.get_take_status(topic_name, merels_storage) == 1:
responses += mechanics.take_man(topic_name, p1[0], p1[1], responses += mechanics.take_man(topic_name, p1[0], p1[1],
merels_storage) + "\n" merels_storage) + "\n"
if not ("Failed" in responses): if "Failed" in responses:
mechanics.update_toggle_take_mode(topic_name, raise BadMoveException(responses)
merels_storage) mechanics.update_toggle_take_mode(topic_name, merels_storage)
mechanics.update_change_turn(topic_name, no_moves = after_event_checkup(responses, topic_name, merels_storage)
merels_storage)
mechanics.update_hill_uid(topic_name, merels_storage) mechanics.update_hill_uid(topic_name, merels_storage)
responses += check_win(topic_name, merels_storage)
if not ("win" in responses.lower()):
responses += mechanics.display_game(topic_name,
merels_storage) \
+ "\n"
return responses responses += mechanics.display_game(topic_name, merels_storage) + "\n"
if no_moves != "":
same_player_move = no_moves
return responses, same_player_move
else: else:
return "Taking is not possible." raise BadMoveException("Taking is not possible.")
else: else:
return unknown_command() return unknown_command()
else:
return "No game created yet. You cannot do any of the game commands." \
" Create the game first."
def check_take_mode(response, topic_name, merels_storage): def check_take_mode(response, topic_name, merels_storage):
"""This checks whether the previous action can result in a take mode for """This checks whether the previous action can result in a take mode for
@ -175,7 +158,6 @@ def check_take_mode(response, topic_name, merels_storage):
else: else:
mechanics.update_change_turn(topic_name, merels_storage) mechanics.update_change_turn(topic_name, merels_storage)
def check_any_moves(topic_name, merels_storage): def check_any_moves(topic_name, merels_storage):
"""Check whether the player can make any moves, if can't switch to another """Check whether the player can make any moves, if can't switch to another
player player
@ -191,7 +173,6 @@ def check_any_moves(topic_name, merels_storage):
return "" return ""
def after_event_checkup(response, topic_name, merels_storage): def after_event_checkup(response, topic_name, merels_storage):
"""After doing certain moves in the game, it will check for take mode """After doing certain moves in the game, it will check for take mode
availability and check for any possible moves availability and check for any possible moves
@ -205,7 +186,6 @@ def after_event_checkup(response, topic_name, merels_storage):
check_take_mode(response, topic_name, merels_storage) check_take_mode(response, topic_name, merels_storage)
return check_any_moves(topic_name, merels_storage) return check_any_moves(topic_name, merels_storage)
def check_win(topic_name, merels_storage): def check_win(topic_name, merels_storage):
"""Checks whether the current grid has a winner, if it does, finish the """Checks whether the current grid has a winner, if it does, finish the
game and remove it from the database game and remove it from the database
@ -214,7 +194,7 @@ def check_win(topic_name, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: :return:
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
win = mechanics.who_won(topic_name, merels_storage) win = mechanics.who_won(topic_name, merels_storage)
if win != "None": if win != "None":

View file

@ -11,7 +11,7 @@ from .interface import construct_grid
class GameData(): class GameData():
def __init__(self, game_data=( def __init__(self, game_data=(
'test', 'X', 0, 0, 'NNNNNNNNNNNNNNNNNNNNNNNN', '', 0)): 'merels', 'X', 0, 0, 'NNNNNNNNNNNNNNNNNNNNNNNN', '', 0)):
self.topic_name = game_data[0] self.topic_name = game_data[0]
self.turn = game_data[1] self.turn = game_data[1]
self.x_taken = game_data[2] self.x_taken = game_data[2]
@ -41,7 +41,7 @@ class GameData():
""" """
return construct_grid(self.board) return construct_grid(self.board)
def get_x_piece_possesed_not_on_grid(self): def get_x_piece_possessed_not_on_grid(self):
"""Gets the amount of X pieces that the player X still have, but not """Gets the amount of X pieces that the player X still have, but not
put yet on the grid put yet on the grid
@ -49,7 +49,7 @@ class GameData():
""" """
return 9 - self.x_taken - mechanics.get_piece("X", self.grid()) return 9 - self.x_taken - mechanics.get_piece("X", self.grid())
def get_o_piece_possesed_not_on_grid(self): def get_o_piece_possessed_not_on_grid(self):
"""Gets the amount of X pieces that the player O still have, but not """Gets the amount of X pieces that the player O still have, but not
put yet on the grid put yet on the grid
@ -64,8 +64,8 @@ class GameData():
:return: A phase number (1, 2, or 3) :return: A phase number (1, 2, or 3)
""" """
return mechanics.get_phase_number(self.grid(), self.turn, return mechanics.get_phase_number(self.grid(), self.turn,
self.get_x_piece_possesed_not_on_grid(), self.get_x_piece_possessed_not_on_grid(),
self.get_o_piece_possesed_not_on_grid()) self.get_o_piece_possessed_not_on_grid())
def switch_turn(self): def switch_turn(self):
"""Switches turn between X and O """Switches turn between X and O

View file

@ -10,7 +10,7 @@ from . import constants
from . import database from . import database
from . import game_data from . import game_data
from . import interface from . import interface
from zulip_bots.game_handler import BadMoveException
def is_in_grid(vertical_pos, horizontal_pos): def is_in_grid(vertical_pos, horizontal_pos):
"""Checks whether the cell actually exists or not """Checks whether the cell actually exists or not
@ -228,7 +228,7 @@ def who_won(topic_name, merels_storage):
is winning is winning
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
if data.get_phase() > 1: if data.get_phase() > 1:
@ -275,7 +275,7 @@ def create_room(topic_name, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
if merels.create_new_game(topic_name): if merels.create_new_game(topic_name):
response = "" response = ""
@ -297,7 +297,7 @@ def display_game(topic_name, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
@ -309,9 +309,9 @@ def display_game(topic_name, merels_storage):
take = "No" take = "No"
response += interface.graph_grid(data.grid()) + "\n" response += interface.graph_grid(data.grid()) + "\n"
response += """Phase {}, {}'s turn. Take mode: {}. response += """Phase {}. Take mode: {}.
X taken: {}, O taken: {}. X taken: {}, O taken: {}.
""".format(data.get_phase(), data.turn, take, data.x_taken, data.o_taken) """.format(data.get_phase(), take, data.x_taken, data.o_taken)
return response return response
@ -323,7 +323,7 @@ def reset_game(topic_name, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
merels.remove_game(topic_name) merels.remove_game(topic_name)
return "Game removed.\n" + create_room(topic_name, return "Game removed.\n" + create_room(topic_name,
@ -339,7 +339,7 @@ def move_man(topic_name, p1, p2, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
# Get the grid # Get the grid
@ -361,8 +361,7 @@ def move_man(topic_name, p1, p2, merels_storage):
return "Moved a man from ({0}, {1}) -> ({2}, {3}) for {4}.".format( return "Moved a man from ({0}, {1}) -> ({2}, {3}) for {4}.".format(
p1[0], p1[1], p2[0], p2[1], data.turn) p1[0], p1[1], p2[0], p2[1], data.turn)
else: else:
return "Failed: That's not a legal move. Please try again." raise BadMoveException("Failed: That's not a legal move. Please try again.")
def put_man(topic_name, v, h, merels_storage): def put_man(topic_name, v, h, merels_storage):
"""Puts a man into the specified cell in topic_name """Puts a man into the specified cell in topic_name
@ -373,7 +372,7 @@ def put_man(topic_name, v, h, merels_storage):
:param merels_storage: MerelsDatabase object :param merels_storage: MerelsDatabase object
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
# Get the grid # Get the grid
@ -393,7 +392,7 @@ def put_man(topic_name, v, h, merels_storage):
data.take_mode) data.take_mode)
return "Put a man to ({0}, {1}) for {2}.".format(v, h, data.turn) return "Put a man to ({0}, {1}) for {2}.".format(v, h, data.turn)
else: else:
return "Failed: That's not a legal put. Please try again." raise BadMoveException("Failed: That's not a legal put. Please try again.")
def take_man(topic_name, v, h, merels_storage): def take_man(topic_name, v, h, merels_storage):
@ -405,7 +404,7 @@ def take_man(topic_name, v, h, merels_storage):
:param merels_storage: Merels' storage :param merels_storage: Merels' storage
:return: A response string :return: A response string
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
# Get the grid # Get the grid
@ -431,7 +430,7 @@ def take_man(topic_name, v, h, merels_storage):
data.take_mode) data.take_mode)
return "Taken a man from ({0}, {1}) for {2}.".format(v, h, data.turn) return "Taken a man from ({0}, {1}) for {2}.".format(v, h, data.turn)
else: else:
return "Failed: That's not a legal take. Please try again." raise BadMoveException("Failed: That's not a legal take. Please try again.")
def update_hill_uid(topic_name, merels_storage): def update_hill_uid(topic_name, merels_storage):
@ -442,7 +441,7 @@ def update_hill_uid(topic_name, merels_storage):
:return: None :return: None
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
data.hill_uid = get_hills_numbers(data.grid()) data.hill_uid = get_hills_numbers(data.grid())
@ -460,7 +459,7 @@ def update_change_turn(topic_name, merels_storage):
:return: None :return: None
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
data.switch_turn() data.switch_turn()
@ -478,7 +477,7 @@ def update_toggle_take_mode(topic_name, merels_storage):
:return: None :return: None
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
data.toggle_take_mode() data.toggle_take_mode()
@ -496,7 +495,7 @@ def get_take_status(topic_name, merels_storage):
:return: 1 or 0 :return: 1 or 0
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
return data.take_mode return data.take_mode
@ -528,7 +527,7 @@ def can_take_mode(topic_name, merels_storage):
:return: True if this turn can trigger take mode, False if otherwise :return: True if this turn can trigger take mode, False if otherwise
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
current_hill_uid = data.hill_uid current_hill_uid = data.hill_uid
@ -570,7 +569,7 @@ def can_make_any_move(topic_name, merels_storage):
:return: True if the player has a way, False if there isn't :return: True if the player has a way, False if there isn't
""" """
merels = database.MerelsStorage(merels_storage) merels = database.MerelsStorage(topic_name, merels_storage)
data = game_data.GameData(merels.get_game_data(topic_name)) data = game_data.GameData(merels.get_game_data(topic_name))
if data.get_phase() != 1: if data.get_phase() != 1:

View file

@ -1,42 +1,102 @@
from zulip_bots.bots.merels.libraries import game from typing import List, Any
from zulip_bots.bots.merels.libraries import (
game,
mechanics,
database,
game_data
)
from zulip_bots.game_handler import GameAdapter, SamePlayerMove
class Storage(object):
data = {}
class MerelsBot(object): def __init__(self, topic_name):
""" self.data[topic_name] = '["X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]'
Simulate the merels game to the chat
"""
def __init__(self): def put(self, topic_name, value: str):
pass self.data[topic_name] = value
def usage(self): def get(self, topic_name):
return self.data[topic_name]
class MerelsModel(object):
def __init__(self, board: Any=None) -> None:
self.topic = "merels"
self.storage = Storage(self.topic)
self.current_board = mechanics.display_game(self.topic, self.storage)
self.token = ['O', 'X']
def determine_game_over(self, players: List[str]) -> str:
if self.contains_winning_move(self.current_board):
return 'current turn'
return ''
def contains_winning_move(self, board: Any) -> bool:
merels = database.MerelsStorage(self.topic, self.storage)
data = game_data.GameData(merels.get_game_data(self.topic))
if data.get_phase() > 1:
if (mechanics.get_piece("X", data.grid()) <= 2) or\
(mechanics.get_piece("O", data.grid()) <= 2):
return True
return False
def make_move(self, move: str, player_number: int, computer_move: bool=False) -> Any:
if self.storage.get(self.topic) == '["X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]':
self.storage.put(
self.topic,
'["{}", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]'.format(
self.token[player_number]
))
self.current_board, same_player_move = game.beat(move, self.topic, self.storage)
if same_player_move != "":
raise SamePlayerMove(same_player_move)
return self.current_board
class MerelsMessageHandler(object):
tokens = [':o_button:', ':cross_mark_button:']
def parse_board(self, board: Any) -> str:
return board
def get_player_color(self, turn: int) -> str:
return self.tokens[turn]
def alert_move_message(self, original_player: str, move_info: str) -> str:
return original_player + " :"
def game_start_message(self) -> str:
return game.getHelp()
class MerelsHandler(GameAdapter):
'''
You can play merels! Make sure your message starts with
"@mention-bot".
'''
META = {
'name': 'merels',
'description': 'Lets you play merels against any player.',
}
def usage(self) -> str:
return game.getInfo() return game.getInfo()
def handle_message(self, message, bot_handler): def __init__(self) -> None:
room_name = self.compose_room_name(message) game_name = 'Merels'
content = message['content'] bot_name = 'merels'
move_help_message = ""
move_regex = '.*'
model = MerelsModel
gameMessageHandler = MerelsMessageHandler
super(MerelsHandler, self).__init__(
game_name,
bot_name,
move_help_message,
move_regex,
model,
gameMessageHandler,
supports_computer=False
)
response = game.beat(content, room_name, bot_handler.storage) handler_class = MerelsHandler
bot_handler.send_reply(message, response)
def compose_room_name(self, message):
room_name = "test"
if "type" in message:
if message['type'] == "stream":
if 'subject' in message:
realm = message['sender_realm_str']
stream = message['display_recipient']
topic = message['subject']
room_name = "{}-{}-{}".format(realm, stream, topic)
else:
# type == "private"
realm = message['sender_realm_str']
users_list = [recipient['email'] for recipient in message[
'display_recipient']]
users = "-".join(sorted(users_list))
room_name = "{}-{}".format(realm, users)
return room_name
handler_class = MerelsBot

View file

@ -17,61 +17,12 @@ class TestFollowUpBot(zulip_bots.test_lib.BotTestCase):
message = dict( message = dict(
content='magic', content='magic',
type='stream', type='stream',
sender_email="boo@email.com",
sender_full_name="boo"
) )
res = self.get_response(message) res = self.get_response(message)
self.assertEqual(res['content'], self.assertEqual(res['content'],
'Unknown command. Available commands: create, ' 'You are not in a game at the moment.'
'reset, help, put (v,h), take (v,h), move (v,' ' Type `help` for help.')
'h) -> (v,h)')
def test_help_command(self):
message = dict(
content='help',
type='stream',
)
res = self.get_response(message)
self.assertEqual(res['content'], "Commands:\ncreate: Create a new "
"game if it doesn't exist\nreset: "
"Reset a current game\nput (v,"
"h): Put a man into the grid in "
"phase 1\nmove (v,h) -> (v,"
"h): Moves a man from one point to "
"-> another point\ntake (v,h): Take "
"an opponent's man from the grid in "
"phase 2/3\n\nv: vertical position "
"of grid\nh: horizontal position of "
"grid")
def test_create_new_game(self):
message = dict(
content='create',
type='stream',
subject='test'
)
with mock.patch.object(zulip_bots.bots.merels.merels.MerelsBot,
'compose_room_name',
return_value="test"):
res = self.get_response(message)
self.assertEqual(res['content'], '''A room has been created in test. Starting game now.
` 0 1 2 3 4 5 6
0 [ ]---------------[ ]---------------[ ]
| | |
1 | [ ]---------[ ]---------[ ] |
| | | | |
2 | | [ ]---[ ]---[ ] | |
| | | | | |
3 [ ]---[ ]---[ ] [ ]---[ ]---[ ]
| | | | | |
4 | | [ ]---[ ]---[ ] | |
| | | | |
5 | [ ]---------[ ]---------[ ] |
| | |
6 [ ]---------------[ ]---------------[ ]`
Phase 1, X's turn. Take mode: No.
X taken: 0, O taken: 0.\n ''')