在 Python 中获取单个字符作为输入,无需按 Enter 键(类似于 C++ 中的 getch)

Sak*_*han 5 python user-input menu getchar python-3.x

首先,我对Python完全陌生,刚刚开始学习它。我知道很多关于 C++ 的东西,但我只是尝试用 Python 实现其中一些。

我已经对其进行了大量搜索,但找不到任何符合我要求的解决方案。请看下面的代码,

import os

class _Getch:
    """Gets a single character from standard input.  Does not echo to the
screen."""
    def __init__(self):
    try:
        self.impl = _GetchWindows()
    except:
        print("Error!")
    def __call__(self): return self.impl()

class _GetchWindows:
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()



def mainfun():
    check = fh = True
    while check:
        fh = True
        arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
        print ("Welcome to Tic Tac Toe Game!!!\n\n")
        print("Enter 1 to Start Game")
        print("Enter 2 to Exit Game")
        a = _Getch()
        if a == "1":
            while fh:
                os.system("cls")
                drawboard()
                playermove()
                fh = checkresult()
        elif a == "2":
            break
       
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我在这里尝试做的是要求用户按 1 和 2 中的一个数字,然后将该数字存储在“a”中,然后将其用于我的要求。

现在,我第一次尝试使用这个,

    input('').split(" ")[0]
Run Code Online (Sandbox Code Playgroud)

但这没有用。它要求我在输入 1 或 2 后始终按 Enter 键。所以,这不起作用。

然后我找到了Getch这个类并实现了它。长话短说,它让我陷入了一个永无休止的循环,我的结果现在是这样的,

Welcome to Tic Tac Toe Game!!!


Enter 1 to Start Game
Enter 2 to Exit Game

Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!


Enter 1 to Start Game
Enter 2 to Exit Game

Press Enter to Continue....
Welcome to Tic Tac Toe Game!!!


Enter 1 to Start Game
Enter 2 to Exit Game

Press Enter to Continue....
Run Code Online (Sandbox Code Playgroud)

这是一个永无休止的循环......即使我按“1”或“2”等任何键,它仍然不会停止并继续执行此操作并且不输入任何功能。

我想要的是类似这样的功能,

  1. 它应该在PYCHARM控制台上工作(我正在练习,我不想在终端上练习。我习惯使用我正在使用的IDE的控制台)
  2. 它暂停并等待用户输入任何输入(就像输入一样)
  3. 它接受用户输入的第一个键并将其存储到变量中。就像在本例中一样,如果用户按“1”,那么它应该将该字符存储在“a”中,然后继续前进。您不必按“ENTER”即可继续。
  4. 如果用户按下任何其他按钮,例如“a”或“b”或类似的任何按钮,它不会执行任何操作并继续要求输入,直到输入所需的数字“1”或“2”(我认为可以很容易地在这个 while 循环中处理)

换句话说,我只想在Python中替代C++的getch()命令。我已经尝试了很多方法来找到它,但我找不到。请向我提出一个问题,该问题提供了该确切问题的解决方案或在此处提供解决方案。谢谢。

编辑:请注意这不是完整的代码。我只提供了相关的代码。如果有人需要查看整个代码,我也很乐意分享。

完整代码如下,

import os
import keyboard
def getch():
    alphabet =  list(map(chr, range(97, 123)))
    while True:
        for letter in alphabet: # detect when a letter is pressed
            if keyboard.is_pressed(letter):
                return letter
        for num in range(10): # detect numbers 0-9
            if keyboard.is_pressed(str(num)):
                return str(num)

arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
playerturn = 1
def drawboard():
    global playerturn
    print("Player 1 (X) - Player 2 (O)\n")
    print("Turn: Player " + str(playerturn))
    print("\n")
    for i in range(3):
        print (" ", end='')
        for j in range(3):
            print(arr[i][j], end='')
            if j == 2:
                continue
            print("  | ", end='')
        if i == 2:
            continue
        print("")
        print("____|____|____")
        print("    |    |    ")

def playermove():
    global playerturn
    row = col = 0
    correctmove = False
    print("\n\nMake your Move!\n")
    while not correctmove:
        row = int(input("Enter Row: "))
        col = int(input("Enter Col: "))
        if (3 > row > -1) and (-1 < col < 3):
            for i in range(3):
                for j in range(3):
                    if arr[row][col] == 0:
                        correctmove = True
                        if playerturn == 1:
                            arr[row][col] = 1
                        else:
                            arr[row][col] = 2
                        playerturn += 1
                        if playerturn > 2:
                            playerturn = 1


        if not correctmove:
            print ("Wrong Inputs, please enter again, ")

def checkwin():
    for player in range(1, 3):
        for i in range(3):
            if arr[i][0] == player and arr[i][1] == player and arr[i][2] == player: return player
            if arr[0][i] == player and arr[1][i] == player and arr[2][i] == player: return player
        if arr[0][0] == player and arr[1][1] == player and arr[2][2] == player: return player
        if arr[0][2] == player and arr[1][1] == player and arr[2][0] == player: return player
    return -1

def checkdraw():
    for i in range(3):
        for j in range(3):
            if arr[i][j] == 0:
                return False
    return True



def checkresult():
    check = checkwin()
    if check == 1:
        os.system('cls')
        drawboard()
        print("\n\nPlayer 1 has won the game!!\n")
    elif check == 2:
        os.system('cls')
        drawboard()
        print("\n\nPlayer 2 has won the game!!\n")
    elif check == 3:
        os.system('cls')
        drawboard()
        print("\n\nThe game has been drawn!!\n")
    else:
        return True
    return False

def mainfun():
    check = fh = True
    while check:
        os.system("cls")
        fh = True
        arr = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
        print ("Welcome to Tic Tac Toe Game!!!\n\n")
        print("Enter 1 to Start Game")
        print("Enter 2 to Exit Game")
        a = getch()
        if a == "1":
            while fh:
                os.system("cls")
                drawboard()
                playermove()
                fh = checkresult()
        elif a == "2":
            break
        print ("Press any key to continue...")
        getch()

mainfun()
Run Code Online (Sandbox Code Playgroud)

EDIT2:通过使用键盘模块解决了问题...这里的下一个问题是如何在调用 getch() 函数后删除存储在输入缓冲区中的数据?因为缓冲区中的数据将显示在下一个输入上(当我接收行和列时),而我不希望发生这种情况。我找到了适用于 Linux 的解决方案,但不适用于 Windows(或 Pycharm)

Wya*_*lue 4

看起来这个功能并不在标准 python 库中,但你可以重新创建它。

首先,安装模块“键盘”

 $ pip3 install keyboard
Run Code Online (Sandbox Code Playgroud)

然后你可以使用keyboard.is_pressed()来查看是否有任何一个字符被按下。

 $ pip3 install keyboard
Run Code Online (Sandbox Code Playgroud)

编辑:对于 unix,您需要使用 sudo 运行脚本。这段代码在 Windows 上应该可以正常工作。