parent
b0b372c95d
commit
243f7bbe5d
|
@ -14,7 +14,7 @@ from .constants import EMPTY_BOARD
|
|||
|
||||
|
||||
class MerelsStorage():
|
||||
def __init__(self, storage):
|
||||
def __init__(self, topic_name, storage):
|
||||
"""Instantiate storage field.
|
||||
|
||||
The current database has this form:
|
||||
|
@ -30,29 +30,6 @@ class MerelsStorage():
|
|||
"""
|
||||
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,
|
||||
take_mode):
|
||||
""" Updates the current status of the game to the database.
|
||||
|
|
|
@ -7,13 +7,13 @@ freely import another modules.
|
|||
|
||||
import re
|
||||
|
||||
from zulip_bots.game_handler import BadMoveException
|
||||
|
||||
from . import database
|
||||
from . import mechanics
|
||||
|
||||
COMMAND_PATTERN = re.compile(
|
||||
"^(\\w*).*(\\d,\\d).*(\\d,\\d)|^(\\w+).*(\\d,\\d)")
|
||||
|
||||
|
||||
def getInfo():
|
||||
""" 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 " \
|
||||
"in that topic. "
|
||||
|
||||
|
||||
def getHelp():
|
||||
""" Gets the help message
|
||||
|
||||
|
@ -30,8 +29,6 @@ def getHelp():
|
|||
"""
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -39,76 +36,65 @@ take (v,h): Take an opponent's man from the grid in phase 2/3
|
|||
v: vertical position of grid
|
||||
h: horizontal position of grid"""
|
||||
|
||||
|
||||
def unknown_command():
|
||||
"""Returns an unknown command info
|
||||
|
||||
: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)"
|
||||
raise BadMoveException(message)
|
||||
|
||||
|
||||
# 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
|
||||
|
||||
:param message: User's message
|
||||
:param topic_name: User's current topic
|
||||
:param merels_storage: Merels' storage
|
||||
:return: A response string to reply to that topic, if any. If not, it
|
||||
returns an empty string
|
||||
:return: a tuple of response string and message, non-empty string
|
||||
we want to keep the turn of the same played,
|
||||
an empty string otherwise.
|
||||
"""
|
||||
|
||||
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."
|
||||
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
match = COMMAND_PATTERN.match(message)
|
||||
same_player_move = "" # message indicating move of the same player
|
||||
|
||||
if match is None:
|
||||
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(
|
||||
2) is not None and match.group(3) is not None:
|
||||
responses = ""
|
||||
|
||||
responses = ""
|
||||
command = match.group(1)
|
||||
|
||||
if command.lower() == "move":
|
||||
|
||||
p1 = [int(x) for x in match.group(2).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:
|
||||
responses += "Take is required to proceed. Please try " \
|
||||
"again.\n"
|
||||
else:
|
||||
|
||||
raise BadMoveException("Take is required to proceed."
|
||||
" Please try again.\n")
|
||||
|
||||
responses += mechanics.move_man(topic_name, p1, p2,
|
||||
merels_storage) + "\n"
|
||||
responses += after_event_checkup(responses, topic_name,
|
||||
merels_storage)
|
||||
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
||||
|
||||
mechanics.update_hill_uid(topic_name, merels_storage)
|
||||
else:
|
||||
responses += unknown_command()
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
command = match.group(4)
|
||||
p1 = [int(x) for x in match.group(5).split(",")]
|
||||
|
@ -118,46 +104,43 @@ def beat(message, topic_name, merels_storage):
|
|||
responses = ""
|
||||
|
||||
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
||||
responses += "Take is required to proceed. Please try " \
|
||||
"again.\n"
|
||||
else:
|
||||
raise BadMoveException("Take is required to proceed."
|
||||
" Please try again.\n")
|
||||
responses += mechanics.put_man(topic_name, p1[0], p1[1],
|
||||
merels_storage) + "\n"
|
||||
responses += after_event_checkup(responses, topic_name,
|
||||
merels_storage)
|
||||
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
||||
|
||||
mechanics.update_hill_uid(topic_name, merels_storage)
|
||||
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
|
||||
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
|
||||
elif command == "take":
|
||||
responses = ""
|
||||
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
||||
responses += mechanics.take_man(topic_name, p1[0], p1[1],
|
||||
merels_storage) + "\n"
|
||||
if not ("Failed" in responses):
|
||||
mechanics.update_toggle_take_mode(topic_name,
|
||||
merels_storage)
|
||||
mechanics.update_change_turn(topic_name,
|
||||
merels_storage)
|
||||
if "Failed" in responses:
|
||||
raise BadMoveException(responses)
|
||||
mechanics.update_toggle_take_mode(topic_name, merels_storage)
|
||||
no_moves = after_event_checkup(responses, 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:
|
||||
return "Taking is not possible."
|
||||
raise BadMoveException("Taking is not possible.")
|
||||
else:
|
||||
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):
|
||||
"""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:
|
||||
mechanics.update_change_turn(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
|
||||
player
|
||||
|
@ -191,7 +173,6 @@ def check_any_moves(topic_name, merels_storage):
|
|||
|
||||
return ""
|
||||
|
||||
|
||||
def after_event_checkup(response, topic_name, merels_storage):
|
||||
"""After doing certain moves in the game, it will check for take mode
|
||||
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)
|
||||
return check_any_moves(topic_name, merels_storage)
|
||||
|
||||
|
||||
def check_win(topic_name, merels_storage):
|
||||
"""Checks whether the current grid has a winner, if it does, finish the
|
||||
game and remove it from the database
|
||||
|
@ -214,7 +194,7 @@ def check_win(topic_name, merels_storage):
|
|||
:param merels_storage: Merels' storage
|
||||
:return:
|
||||
"""
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
|
||||
win = mechanics.who_won(topic_name, merels_storage)
|
||||
if win != "None":
|
||||
|
|
|
@ -11,7 +11,7 @@ from .interface import construct_grid
|
|||
|
||||
class GameData():
|
||||
def __init__(self, game_data=(
|
||||
'test', 'X', 0, 0, 'NNNNNNNNNNNNNNNNNNNNNNNN', '', 0)):
|
||||
'merels', 'X', 0, 0, 'NNNNNNNNNNNNNNNNNNNNNNNN', '', 0)):
|
||||
self.topic_name = game_data[0]
|
||||
self.turn = game_data[1]
|
||||
self.x_taken = game_data[2]
|
||||
|
@ -41,7 +41,7 @@ class GameData():
|
|||
"""
|
||||
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
|
||||
put yet on the grid
|
||||
|
||||
|
@ -49,7 +49,7 @@ class GameData():
|
|||
"""
|
||||
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
|
||||
put yet on the grid
|
||||
|
||||
|
@ -64,8 +64,8 @@ class GameData():
|
|||
:return: A phase number (1, 2, or 3)
|
||||
"""
|
||||
return mechanics.get_phase_number(self.grid(), self.turn,
|
||||
self.get_x_piece_possesed_not_on_grid(),
|
||||
self.get_o_piece_possesed_not_on_grid())
|
||||
self.get_x_piece_possessed_not_on_grid(),
|
||||
self.get_o_piece_possessed_not_on_grid())
|
||||
|
||||
def switch_turn(self):
|
||||
"""Switches turn between X and O
|
||||
|
|
|
@ -10,7 +10,7 @@ from . import constants
|
|||
from . import database
|
||||
from . import game_data
|
||||
from . import interface
|
||||
|
||||
from zulip_bots.game_handler import BadMoveException
|
||||
|
||||
def is_in_grid(vertical_pos, horizontal_pos):
|
||||
"""Checks whether the cell actually exists or not
|
||||
|
@ -228,7 +228,7 @@ def who_won(topic_name, merels_storage):
|
|||
is winning
|
||||
"""
|
||||
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
data = game_data.GameData(merels.get_game_data(topic_name))
|
||||
|
||||
if data.get_phase() > 1:
|
||||
|
@ -275,7 +275,7 @@ def create_room(topic_name, merels_storage):
|
|||
:param merels_storage: Merels' storage
|
||||
:return: A response string
|
||||
"""
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
|
||||
if merels.create_new_game(topic_name):
|
||||
response = ""
|
||||
|
@ -297,7 +297,7 @@ def display_game(topic_name, merels_storage):
|
|||
:param merels_storage: Merels' storage
|
||||
: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))
|
||||
|
||||
|
@ -309,9 +309,9 @@ def display_game(topic_name, merels_storage):
|
|||
take = "No"
|
||||
|
||||
response += interface.graph_grid(data.grid()) + "\n"
|
||||
response += """Phase {}, {}'s turn. Take mode: {}.
|
||||
response += """Phase {}. Take mode: {}.
|
||||
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
|
||||
|
||||
|
@ -323,7 +323,7 @@ def reset_game(topic_name, merels_storage):
|
|||
:param merels_storage: Merels' storage
|
||||
:return: A response string
|
||||
"""
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
|
||||
merels.remove_game(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
|
||||
: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))
|
||||
|
||||
# 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(
|
||||
p1[0], p1[1], p2[0], p2[1], data.turn)
|
||||
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):
|
||||
"""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
|
||||
: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))
|
||||
|
||||
# Get the grid
|
||||
|
@ -393,7 +392,7 @@ def put_man(topic_name, v, h, merels_storage):
|
|||
data.take_mode)
|
||||
return "Put a man to ({0}, {1}) for {2}.".format(v, h, data.turn)
|
||||
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):
|
||||
|
@ -405,7 +404,7 @@ def take_man(topic_name, v, h, merels_storage):
|
|||
:param merels_storage: Merels' storage
|
||||
: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))
|
||||
|
||||
# Get the grid
|
||||
|
@ -431,7 +430,7 @@ def take_man(topic_name, v, h, merels_storage):
|
|||
data.take_mode)
|
||||
return "Taken a man from ({0}, {1}) for {2}.".format(v, h, data.turn)
|
||||
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):
|
||||
|
@ -442,7 +441,7 @@ def update_hill_uid(topic_name, merels_storage):
|
|||
: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.hill_uid = get_hills_numbers(data.grid())
|
||||
|
@ -460,7 +459,7 @@ def update_change_turn(topic_name, merels_storage):
|
|||
: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.switch_turn()
|
||||
|
@ -478,7 +477,7 @@ def update_toggle_take_mode(topic_name, merels_storage):
|
|||
: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.toggle_take_mode()
|
||||
|
@ -496,7 +495,7 @@ def get_take_status(topic_name, merels_storage):
|
|||
: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))
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
data = game_data.GameData(merels.get_game_data(topic_name))
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
merels = database.MerelsStorage(merels_storage)
|
||||
merels = database.MerelsStorage(topic_name, merels_storage)
|
||||
data = game_data.GameData(merels.get_game_data(topic_name))
|
||||
|
||||
if data.get_phase() != 1:
|
||||
|
|
|
@ -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):
|
||||
"""
|
||||
Simulate the merels game to the chat
|
||||
"""
|
||||
def __init__(self, topic_name):
|
||||
self.data[topic_name] = '["X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0]'
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def put(self, topic_name, value: str):
|
||||
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()
|
||||
|
||||
def handle_message(self, message, bot_handler):
|
||||
room_name = self.compose_room_name(message)
|
||||
content = message['content']
|
||||
def __init__(self) -> None:
|
||||
game_name = 'Merels'
|
||||
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)
|
||||
|
||||
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
|
||||
handler_class = MerelsHandler
|
||||
|
|
|
@ -17,61 +17,12 @@ class TestFollowUpBot(zulip_bots.test_lib.BotTestCase):
|
|||
message = dict(
|
||||
content='magic',
|
||||
type='stream',
|
||||
sender_email="boo@email.com",
|
||||
sender_full_name="boo"
|
||||
)
|
||||
|
||||
res = self.get_response(message)
|
||||
|
||||
self.assertEqual(res['content'],
|
||||
'Unknown command. Available commands: create, '
|
||||
'reset, help, put (v,h), take (v,h), move (v,'
|
||||
'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 ''')
|
||||
'You are not in a game at the moment.'
|
||||
' Type `help` for help.')
|
||||
|
|
Loading…
Reference in a new issue