add game report
This commit is contained in:
parent
986300d9fe
commit
e15252bca4
2 changed files with 98 additions and 52 deletions
|
@ -2,6 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from random import randint
|
from random import randint
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
# 0 - 8: means 0-8 mines, not opened
|
# 0 - 8: means 0-8 mines, not opened
|
||||||
# opened block = the value of not opened block + 10
|
# opened block = the value of not opened block + 10
|
||||||
|
@ -42,6 +43,7 @@ class Board():
|
||||||
self.width = width
|
self.width = width
|
||||||
self.mines = mines
|
self.mines = mines
|
||||||
self.map = None
|
self.map = None
|
||||||
|
self.mmap = None
|
||||||
self.moves = list()
|
self.moves = list()
|
||||||
self.state = 0 # 0:not playing, 1:playing, 2:win, 3:dead
|
self.state = 0 # 0:not playing, 1:playing, 2:win, 3:dead
|
||||||
def __gen_map(self, first_move):
|
def __gen_map(self, first_move):
|
||||||
|
@ -72,6 +74,7 @@ class Board():
|
||||||
if nbr_value == IS_MINE:
|
if nbr_value == IS_MINE:
|
||||||
mine_count += 1
|
mine_count += 1
|
||||||
self.map[row][col] = mine_count
|
self.map[row][col] = mine_count
|
||||||
|
self.mmap = deepcopy(self.map)
|
||||||
def __iter_neighbour(self, row, col, return_rc=True):
|
def __iter_neighbour(self, row, col, return_rc=True):
|
||||||
height = self.height
|
height = self.height
|
||||||
width = self.width
|
width = self.width
|
||||||
|
|
141
tgmsbot.py
141
tgmsbot.py
|
@ -4,7 +4,9 @@ from mscore import Board, check_params
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from telegram import InlineKeyboardMarkup, InlineKeyboardButton
|
from telegram import InlineKeyboardMarkup, InlineKeyboardButton
|
||||||
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
|
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler
|
||||||
|
from telegram.error import TimedOut as TimedOutError
|
||||||
from numpy import array_equal
|
from numpy import array_equal
|
||||||
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
@ -21,6 +23,17 @@ UNOPENED_CELL = "\u2588"
|
||||||
FLAGGED_CELL = "\u259a"
|
FLAGGED_CELL = "\u259a"
|
||||||
STEPPED_CELL = "*"
|
STEPPED_CELL = "*"
|
||||||
|
|
||||||
|
WIN_TEXT_TEMPLATE = "哇所有奇怪的地方都被你打开啦…好羞羞\n" \
|
||||||
|
"地图:Op {s_op} / Is {s_is} / 3bv {s_3bv}\n操作总数 {ops_count}\n" \
|
||||||
|
"统计:\n{ops_list}\n{last_player} 你要对人家负责哟/// ///\n\n" \
|
||||||
|
"用时{time}秒,超时{timeouts}次\n\n" \
|
||||||
|
"/mine@{bot_username} 开始新游戏"
|
||||||
|
LOSE_TEXT_TEMPLATE = "一道火光之后,你就在天上飞了呢…好奇怪喵\n" \
|
||||||
|
"地图:Op {s_op} / Is {s_is} / 3bv {s_3bv}\n操作总数 {ops_count}\n" \
|
||||||
|
"统计:\n{ops_list}\n{last_player} 是我们中出的叛徒!\n\n" \
|
||||||
|
"用时{time}秒,超时{timeouts}次\n\n" \
|
||||||
|
"/mine@{bot_username} 开始新游戏"
|
||||||
|
|
||||||
|
|
||||||
def display_username(user, atuser=True, shorten=False, markdown=True):
|
def display_username(user, atuser=True, shorten=False, markdown=True):
|
||||||
"""
|
"""
|
||||||
|
@ -40,43 +53,50 @@ def display_username(user, atuser=True, shorten=False, markdown=True):
|
||||||
return name
|
return name
|
||||||
|
|
||||||
class Game():
|
class Game():
|
||||||
def __init__(self, board, board_hash, group, creators):
|
def __init__(self, board, group, creator):
|
||||||
self.board = board
|
self.board = board
|
||||||
self.board_hash = board_hash
|
|
||||||
self.group = group
|
self.group = group
|
||||||
self.creators = creators
|
self.creator = creator
|
||||||
self.actions = dict()
|
self.actions = dict()
|
||||||
|
self.last_player = None
|
||||||
|
self.start_time = time.time()
|
||||||
|
self.extra = {"timeout": 0}
|
||||||
def save_action(self, user, spot):
|
def save_action(self, user, spot):
|
||||||
'''spot is supposed to be a tuple'''
|
'''spot is supposed to be a tuple'''
|
||||||
|
self.last_player = user
|
||||||
if self.actions.get(user, None):
|
if self.actions.get(user, None):
|
||||||
self.actions[user].append(spot)
|
self.actions[user].append(spot)
|
||||||
else:
|
else:
|
||||||
self.actions[user] = [spot,]
|
self.actions[user] = [spot,]
|
||||||
|
def actions_sum(self):
|
||||||
|
mysum = 0
|
||||||
|
for user in self.actions:
|
||||||
|
count = len(self.actions.get(user, list()))
|
||||||
|
mysum += count
|
||||||
|
return mysum
|
||||||
|
def get_last_player(self):
|
||||||
|
return display_username(self.last_player)
|
||||||
def get_actions(self):
|
def get_actions(self):
|
||||||
'''Convert actions into text'''
|
'''Convert actions into text'''
|
||||||
msg = ""
|
msg = ""
|
||||||
for user in self.actions:
|
for user in self.actions:
|
||||||
count = len(self.actions.get(user, list()))
|
count = len(self.actions.get(user, list()))
|
||||||
msg = "{}{}: {}项操作\n".format(msg, display_username(user), count)
|
msg = "{}{} - {}项操作\n".format(msg, display_username(user), count)
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
class GameManager:
|
class GameManager:
|
||||||
__games = list()
|
__games = dict()
|
||||||
def append(self, board, board_hash, group_id, creator_id):
|
def append(self, board, board_hash, group_id, creator_id):
|
||||||
self.__games.append(Game(board, board_hash, group_id, creator_id))
|
self.__games[board_hash] = Game(board, group_id, creator_id)
|
||||||
def remove(self, board_hash):
|
def remove(self, board_hash):
|
||||||
board = self.get_game_from_hash(board_hash)
|
board = self.get_game_from_hash(board_hash)
|
||||||
if board:
|
if board:
|
||||||
self.__games.remove(board)
|
del self.__games[board_hash]
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
def get_game_from_hash(self, board_hash):
|
def get_game_from_hash(self, board_hash):
|
||||||
for gm in self.__games:
|
return self.__games.get(board_hash, None)
|
||||||
if gm.board_hash == board_hash:
|
|
||||||
return gm
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
def count(self):
|
def count(self):
|
||||||
return len(self.__games)
|
return len(self.__games)
|
||||||
|
|
||||||
|
@ -135,35 +155,8 @@ def send_status(bot, update):
|
||||||
count = game_manager.count()
|
count = game_manager.count()
|
||||||
update.message.reply_text('当前进行的游戏: {}'.format(count))
|
update.message.reply_text('当前进行的游戏: {}'.format(count))
|
||||||
|
|
||||||
def gen_keyboard(board):
|
def update_keyboard(bot, bhash, game, chat_id, message_id):
|
||||||
pass
|
def gen_keyboard(board):
|
||||||
|
|
||||||
def handle_button_click(bot, update):
|
|
||||||
msg = update.callback_query.message
|
|
||||||
user = update.callback_query.from_user
|
|
||||||
chat_id = update.callback_query.message.chat.id
|
|
||||||
data = update.callback_query.data
|
|
||||||
logger.debug('Button clicked by {}, data={}.'.format(user.id, data))
|
|
||||||
bot.answer_callback_query(callback_query_id=update.callback_query.id)
|
|
||||||
try:
|
|
||||||
data = data.split(' ')
|
|
||||||
data = [int(i) for i in data]
|
|
||||||
(bhash, row, col) = data
|
|
||||||
except Exception as err:
|
|
||||||
logger.info('Unknown callback data: {} from user {}'.format(data, user.id))
|
|
||||||
return
|
|
||||||
game = game_manager.get_game_from_hash(bhash)
|
|
||||||
if game is None:
|
|
||||||
logger.info("No game found for hash {}".format(bhash))
|
|
||||||
return
|
|
||||||
board = game.board
|
|
||||||
FIRST_MOVE = False
|
|
||||||
if board.state == 0:
|
|
||||||
FIRST_MOVE = True
|
|
||||||
else:
|
|
||||||
mmap = deepcopy(board.map)
|
|
||||||
board.move((row, col))
|
|
||||||
if FIRST_MOVE or (not array_equal(board.map, mmap)) or board.state == 2:
|
|
||||||
keyboard = list()
|
keyboard = list()
|
||||||
for row in range(board.height):
|
for row in range(board.height):
|
||||||
current_row = list()
|
current_row = list()
|
||||||
|
@ -181,18 +174,68 @@ def handle_button_click(bot, update):
|
||||||
cell = InlineKeyboardButton(text=cell_text, callback_data="{} {} {}".format(bhash, row, col))
|
cell = InlineKeyboardButton(text=cell_text, callback_data="{} {} {}".format(bhash, row, col))
|
||||||
current_row.append(cell)
|
current_row.append(cell)
|
||||||
keyboard.append(current_row)
|
keyboard.append(current_row)
|
||||||
|
return keyboard
|
||||||
|
keyboard = gen_keyboard(game.board)
|
||||||
|
try:
|
||||||
|
bot.edit_message_reply_markup(chat_id=chat_id, message_id=message_id,
|
||||||
|
reply_markup=InlineKeyboardMarkup(keyboard))
|
||||||
|
except TimedOutError:
|
||||||
|
logger.debug('time out in game {}.'.format(bhash))
|
||||||
|
game.extra["timeout"] += 1
|
||||||
|
|
||||||
|
def handle_button_click(bot, update):
|
||||||
|
msg = update.callback_query.message
|
||||||
|
user = update.callback_query.from_user
|
||||||
|
chat_id = update.callback_query.message.chat.id
|
||||||
|
data = update.callback_query.data
|
||||||
|
logger.debug('Button clicked by {}, data={}.'.format(user.id, data))
|
||||||
|
bot.answer_callback_query(callback_query_id=update.callback_query.id)
|
||||||
|
try:
|
||||||
|
data = data.split(' ')
|
||||||
|
data = [int(i) for i in data]
|
||||||
|
(bhash, row, col) = data
|
||||||
|
except Exception as err:
|
||||||
|
logger.info('Unknown callback data: {} from user {}'.format(data, user.id))
|
||||||
|
return
|
||||||
|
game = game_manager.get_game_from_hash(bhash)
|
||||||
|
if game is None:
|
||||||
|
logger.debug("No game found for hash {}".format(bhash))
|
||||||
|
return
|
||||||
|
board = game.board
|
||||||
|
if board.state == 0:
|
||||||
|
mmap = None
|
||||||
|
board.move((row, col))
|
||||||
|
game.save_action(user, (row, col))
|
||||||
|
update_keyboard(bot, bhash, game, chat_id, msg.message_id)
|
||||||
|
else:
|
||||||
|
mmap = deepcopy(board.map)
|
||||||
|
board.move((row, col))
|
||||||
if board.state != 1:
|
if board.state != 1:
|
||||||
|
# if this is the first move, there's no mmap
|
||||||
|
if mmap is not None:
|
||||||
|
game.save_action(user, (row, col))
|
||||||
|
update_keyboard(bot, bhash, game, chat_id, msg.message_id)
|
||||||
|
ops_count = game.actions_sum()
|
||||||
|
ops_list = game.get_actions()
|
||||||
|
last_player = game.get_last_player()
|
||||||
|
bot_username = bot.username
|
||||||
|
time_used = time.time() - game.start_time
|
||||||
|
timeouts = game.extra["timeout"]
|
||||||
if board.state == 2:
|
if board.state == 2:
|
||||||
reply_text = "Win"
|
template = WIN_TEXT_TEMPLATE
|
||||||
game_manager.remove(bhash)
|
else:
|
||||||
elif board.state == 3:
|
template = LOSE_TEXT_TEMPLATE
|
||||||
reply_text = "Lose"
|
myreply = template.format(s_op=0, s_is=0, s_3bv=0, ops_count=ops_count,
|
||||||
|
ops_list=ops_list, last_player=last_player,
|
||||||
|
time=round(time_used, 4), timeouts=timeouts,
|
||||||
|
bot_username=bot_username)
|
||||||
|
msg.reply_text(myreply, parse_mode="Markdown")
|
||||||
game_manager.remove(bhash)
|
game_manager.remove(bhash)
|
||||||
else:
|
else:
|
||||||
reply_text = msg.text_markdown
|
if mmap is not None and (not array_equal(board.map, mmap)):
|
||||||
bot.edit_message_text(chat_id=chat_id, message_id=msg.message_id,
|
game.save_action(user, (row, col))
|
||||||
text=reply_text, parse_mode="Markdown",
|
update_keyboard(bot, bhash, game, chat_id, msg.message_id)
|
||||||
reply_markup=InlineKeyboardMarkup(keyboard))
|
|
||||||
|
|
||||||
|
|
||||||
updater.dispatcher.add_handler(CommandHandler('start', send_help))
|
updater.dispatcher.add_handler(CommandHandler('start', send_help))
|
||||||
|
|
Loading…
Reference in a new issue