首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python连接-4

Python连接-4
EN

Code Review用户
提问于 2016-07-12 14:16:31
回答 1查看 27.9K关注 0票数 10

我目前正在使用Python3.5.2创建一个连接四个基本游戏。我的游戏应该为两名球员工作,并告诉你什么时候你已经赢了,无论是水平,垂直或对角线。但是,我不知道如何使我的代码更小或更高效,是否有办法减少,还是我的方法本身就不太有效?

我已经尝试过查找其他各种方法来执行这些代码,唉,我发现它们很难理解。我的代码没有任何错误,虽然我已经完成了我自己设定的任务,但我觉得这不是最好的方法。

如果有人有任何建议的话,我将不胜感激。如果我知道如何在不失去功能的情况下缩短它,我就会这么做。

我希望我的代码将帮助其他人尝试与我的任务相当基本的任务。

代码语言:javascript
复制
import time    

grid1 = [0,0,0,0] # bottom row
grid2 = [0,0,0,0]
grid3 = [0,0,0,0]
grid4 = [0,0,0,0]

grids = [grid1,grid2,grid3,grid4]

check = []

user = 1

class fullSlot_error (Exception):
    pass
def hasWon_def():
    print ("player "+str(user)+" has won")
    time.sleep (1)

def grid_def():
    print ("",grid4,"\n",grid3,"\n",grid2,"\n",grid1)

def user_def():
    global user
    if user < 2:
        user = 2
    else:
        user = 1
    return user

def slotFull_def():
   while True:
        try:
            if grid4[userInput -1] != 0:
                raise fullSlot_error
            else:
                break
        except fullSlot_error:
            print ("slot is full try again")
            confirm_def()

def confirm_def():
    looop= True
    while looop== True:
        try:
            global userInput
            userInput = int(input("\ninput a slot player "+str(user)+"(1,4)\n"))
            if userInput < 5 and 0 < userInput:   
                looop = False
            else:
                print ("invalid int")
        except ValueError:
            print ("invalid input")

def placement_def():
    counter = 0
    for i in range (0,4):
        slotFull_def()
        if (grids[i][userInput -1] == 0):
            grids [i][userInput - 1] = int(user)
            grid_def()
            break


def check_def():
    global loop
    global check
    for i in range(0,4):
        for a in range(0,4):
            check.append(grids[i][a])
        if (check == [1,1,1,1] or check == [2,2,2,2]):
            hasWon_def()
            loop = False
            return loop
            break
        else:
            check = []
    for i in range(0,4):
        for a in range(0,4):
            check.append(grids[a][i])
        if (check == [1,1,1,1] or check == [2,2,2,2]):
            hasWon_def()
            loop = False
            return loop
            break
        else:
            check = []

def checkEmpty_def():
    global check
    for i in range (0,4):
        for a in range (0,4):
            check.append(grids[i][a])
    if 0 not in check:
        print ("full")

def checks_def():
    check_def()
    checkEmpty_def()
    diagcheck_def()

def diagcheck_def():
    global loop
    global check
    check = []
    diag = 0
    for i in range (0,4):
        check.append (grids[diag][diag])
        diag = diag +1
        if (check == [1,1,1,1] or check == [2,2,2,2]):
            hasWon_def()
            loop = False
            return loop
            break
    check = []
    diag = 3
    diag2 = 0
    for i in range (0,4):
        check.append (grids[diag][diag2])
        if (check == [1,1,1,1] or check == [2,2,2,2]):
            hasWon_def()
            loop = False
            return loop
            break


loop = True

while loop == True:
    check_def()
    confirm_def()
    placement_def()
    checks_def()
    if loop == False:
        break
    user_def()
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-07-12 16:36:30

一些建议:

  1. 一般建议对Python代码采用pep8样式。例如,函数名与偏执、lower_case_function_names、逗号后面的空格之间没有空格,等等。
  2. 您可以在单个操作(而不是5 )中定义网格。
  3. 对于print,可以使用*解压缩嵌套列表,然后使用sep='\n'将每一行放在不同的行上。
  4. 最好至少有一个顶级函数,而不是在脚本的根中执行所有的操作。
  5. 不需要全局变量,最好将变量作为参数传递并返回结果。
  6. 对于打印,如果将多个值作为参数,则在参数之间自动插入空格。
  7. 在这里使用自定义异常没有任何好处,只需在您的break测试中使用一个if
  8. 您可以使用一行if测试(称为“三元表达式”)来简化部分代码。
  9. 一个只在一个地方使用的简单的单行函数并没有什么好处。它使事情更难读,并使代码慢了一点点。只是把密码插进去。
  10. 使用哨兵变量(如looop)在特定点将False分配给它是没有多大意义的。只需使用break,如果需要,可以使用continue跳过循环的后面部分。
  11. 最好将绝对最少的代码放在您的try块中,以避免意外捕获错误的异常。
  12. 您可以组合多个比较,例如0 < userInput < 5
  13. 如果您只想在不需要进一步处理的情况下返回结果,则可以使用return而不是break退出while循环。
  14. 您可以使用in来测试一个值是否在列表或其他值序列中,而不是使用and
  15. 您从不在counter中使用placement_def
  16. 0是在range(0, x)中隐含的,所以您可以忽略它。
  17. 与使用range和索引列表不同,直接迭代列表更容易。
  18. 您总是从1中减去userInput。在开始的时候减去一个会更容易。
  19. 与其多次将列表追加到另一个列表,不如使用extend一次追加所有元素。
  20. check不需要是全局的,它的状态从不在函数之间共享。
  21. 您可以使用all简化行或列的检查,使用zip来转换列表。
  22. 您可以使用anyall简化对玩家是否获胜和网格是否已满的检查。
  23. 您可以在某种程度上简化代码,方法是让check函数返回一个布尔值,然后用checks_def打印。
  24. 我不认为placement_def是正确的。每次循环都会得到一个用户输入,而不仅仅是一次,如果它是当前的使用或空的,那么当您只想要覆盖空的时候,就重写这个值。此外,当您想从下到上循环时,您可以从上到上循环。
  25. 您可以对网格大小进行硬编码,但是允许用户指定方格大小是很容易的。

这是我的密码:

代码语言:javascript
复制
def play(n=None):
    if n is None:
        while True:
            try:
                n = int(input('Input the grid size: '))
            except ValueError:
                print('Invalid input')
                continue
            if n <= 0:
                print('Invalid input')
                continue
            break

    grids = [[0]*n for _ in range(n)]
    user = 1
    print('Current board:')
    print(*grids, sep='\n')
    while True:
        user_input = get_input(user, grids, n)
        place_piece(user_input, user, grids)
        print('Current board:')
        print(*grids, sep='\n')

        if (check_won(grids, user, n) or
                check_won(zip(*grids), user, n) or
                diagcheck_won(grids, user, n) or
                diagcheck_won(grids[::-1], user, n)):
            print('Player', user, 'has won')
            return

        if not any(0 in grid for grid in grids):
            return

        user = 2 if user == 1 else 1


def get_input(user, grids, n):
    instr = 'Input a slot player {0} from 1 to {1}: '.format(user, n)
    while True:
        try:
            user_input = int(input(instr))
        except ValueError:
            print('invalid input:', user_input)
            continue
        if 0 > user_input or user_input > n+1:
            print('invalid input:', user_input)
        elif grids[0][user_input-1] != 0:
            print('slot', user_input, 'is full try again')
        else:
            return user_input-1


def place_piece(user_input, user, grids):
    for grid in grids[::-1]:
        if not grid[user_input]:
            grid[user_input] = user
            return


def check_won(grids, user, n):
    return any(all(cell == user for cell in grid) for grid in grids)


def diagcheck_won(grids, user, n):
    return all(grids[x][x] == user for x in range(n))


if __name__ == '__main__':
    play()

请注意,可以使用numpy数组进一步简化这一点,但这更高级。

票数 11
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/134636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档