skip to Main Content

I am looking forward to make some kind of telegram chess bot. So it`s based on inline keyboard. User should press on ilnlineButton to pick a chessman and than the presses button where to put chessman. I don’t know how to pick a free cell on “board” in inlineKeyboard after picking a, only for now, pawn. I tried to do bot.register_next_step_handler but he doesn’t give what I expected.

@bot.callback_query_handler(func=lambda call: True)
def callback_inline(call):
    try:
        if call.message:
            if call.data == "suck":
                bot.send_message(call.message.chat.id, "Just wait a bit, OK?")
            elif call.data == "frick":
                bot.send_message(call.message.chat.id, "No, frick you")
            elif call.data == "sad":
                bot.send_message(call.message.chat.id, "Well, shit happens")
            elif call.data == "good":
                bot.send_message(call.message.chat.id, "I am soulless robot. How do      you think I can feel?")
            elif call.data.partition('pawn')[1] == "pawn":
                bot.register_next_step_handler(call.data, process_move_step)

else:
                bot.send_message(call.message.chat.id, call.data)
                bot.edit_message_text(chat_id=call.message.chat.id, message_id=call.message.message_id, text=
                                                                                                      "some_text",reply_markup=None)

    except Exception as e:
        print(repr(e))


def process_move_step(call):
    try:
        if call.message:
            if call.data.partition('empty')[1] == "empty":
                next_move = new_board.get_chessman(call.data)
                new_board.move(call, next_move.X, next_move.Y)
                bot.send_message(call.message.chat.id, "Moved to "+str(next_move.X+str(next_move.Y)))
                print(new_board)

    except Exception as e:
        print(repr(e))

so I hoped process jumps to process_move_step and waits for new callback and checks it there, but after getting “pawn” callback and than getting “empty” callback I got result from else: part instead of getting in that if

if call.data.partition('empty')[1] == "empty":

So how can I get “pawn” cell then “empty” cell from callbacks and then complete functions. For “empty” stands object EmptyCell and it has attributes X and Y, so I can move pawn in exact place in Board obj and edit inline keyboard. I have seen something similar in @TrueMafiaBot. When police officer is asked if he want to check or shoot somebody and then he picks a player to make chosen action.

2

Answers


  1. It doesn’t work as you expected. Every request always passes to your main function (callback_inline). So if you try to catch the next step after pawn selection you should save the current status of a user. If the user selects pawn then his status sets is_pawn_selected = true. After this, you can add some logic for processing this status. In your case, it should be something like this:

     if (users.get(user_ID).is_pawn_selected) { 
        user.is_pawn_selected = false
        process_move_step 
    }
    
    Login or Signup to reply.
  2. The most straightforward way is to hold some state when running a bot and perform if-else checks on callback query answer. For example, you can do something like:

    from enum import Enum
    from dataclasses import dataclass
    
    
    class Color(Enum):
        WHITE = 0
        BLACK = 1
    
    
    @dataclass
    class GameState:
        chat_id: int
        turn: Color
        holding_chessman: Chessman
        # ...another useful data for game flow
    
    
    # data is your callback data received from users
    # gamestate is local instanse of GameState on server (or database)
    
    # inside callback answer handling:
    if gamestate.turn != data.user.color:
        return error('Not your turn, hold on!')
    if gamestate.holding_chessman is None:
        gamestate.holding_chessman = data.pressed_figure
        return info('Now press a button where to move a chessman.')
    else:
        perform_chessman_move()
        switch_turn()
        return info('You moved a chessman, now another user must turn')
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search