Python 连接四子游戏。让电脑下棋

0 投票
4 回答
3297 浏览
提问于 2025-04-17 10:19

我需要一些帮助来完成我的四子棋作业。我的“让电脑下棋”的功能有问题。在这个作业中,我需要用一个列表来表示棋盘。这个列表里面有多个列表,每个列表代表一行。而每个列表里的元素则代表列。

board=[[" "," "," "," "," "],
       [" "," "," "," "," "],
       [" "," "," "," "," "],
       [" "," "," "," "," "],
       [" "," "," "," "," "]]

棋盘有5行5列,所以总共有25个空格可以放棋子。main函数会循环25次,每次都会调用make_computer_move函数。display_board函数不太重要。问题出在make_computer_move上。因为有25个空格,而main循环25次,它应该把整个棋盘都填满。但实际上并没有,棋盘上还留有空白的地方。
而且它也没有打印出它下棋时的坐标。我加了一个打印语句,想让它在每次有效下棋时打印出坐标。但我发现有时候棋盘在循环中保持不变,什么也没有发生。
我真的不知道该怎么办了 :/

def display_board(board):
    col="   "
    for index1 in range(len(board[0])):
        col+=str(index1)+"   "
    print col
    for index2 in range(len(board)):
        print str(index2)+": "+" | ".join(board[index2])+" |"
        print "  "+"---+"*(len(board[0]))
def make_computer_move(board):
    import random
    col=random.randint(0,(len(board[0])-1)) 
    for row in range(len(board)-1,-1,-1): # counts from the bottom of the board and up
        if board[row][col]==" ": #if there is a blank space it will put a "O" and break
            print "The pairing is("+str(row),str(col)+")" #Print the coordinates
            board[row][col] = 'O'
            break
    else: #if the break does not occur this else statement executes
        col=random.randint(0,(len(board[0])-1)) 
def main():
    board=[[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "],[" "," "," "," "," "]]
    for counter in range(25):
        display_board(board)
        make_computer_move(board)
main()

4 个回答

0

首先,你应该检查一下是否有至少一个空格,通常情况下,导入的内容会放在程序的最上面。

import random

定义一个函数来让电脑下棋,函数名叫make_computer_move,参数是棋盘board。这个函数会遍历棋盘的每一行,寻找第一个空格。如果在某一行找到了空格,就会进入一个无限循环。在这个循环里,电脑会随机选择一个列数,然后从棋盘的底部往上检查这一列,看看有没有空格。如果找到了空格,就会打印出这个空格的坐标(行和列),然后在这个位置上放一个'O',表示电脑下了一步棋。最后,函数会返回更新后的棋盘。如果所有的格子都填满了,程序会打印“所有格子都填满了——游戏结束”。

另一种方法是创建一个可用空间的列表,然后随机选择一个

首先,创建一个空的列表available。接着,使用两个循环遍历5行5列的棋盘。如果在某个位置发现是空格,就把这个位置的行和列坐标添加到available列表中。最后,电脑会从available列表中随机选择一个位置作为下棋的地方。

0

这段话的意思是,它会给你一个随机的开放列(或者行,具体看你怎么理解)的索引。

openColumns = [i for i in range(len(board)) if board[i].count(' ') > 0]
if openColumns: ComputerChoice = openColumns[random.randint(0, len(openColumns)]
else: #do something if there are no open columns (i.e. the board is full)
0

上面的代码运行得很好。它让 make_computer_move(board, avail_col) 返回一个列号,当某一列被填满时,这个列号会传回主程序。在主程序中,这个列号会在再次调用 make_computer_board 之前被移除。

import random

def display_board(board):
    col = "   "
    cols = len(board[0])
    for index1 in range(cols):
        col += "%i   " % index1
    print col
    for index2 in range(len(board)):
        print str(index2) + ": " + " | ".join(board[index2]) + " |"
        print "  " + "---+" * cols


def make_computer_move(board, avail_cols):
    col = random.choice(avail_cols) 
    for row in range(len(board)-1, -1, -1):            # counts from bottom of board and up
        if board[row][col] == " ":                      # if there is a blank space, put a "O" and break
            print "The pairing is (%i,%i)" % (row,col)  #Print the coordinates
            board[row][col] = 'O'
            break

    if row == 0:      #arrives to the last row
        return col


def main():
    board = [[" ", " ", " ", " ", " "] for i in range(5)]
    avail_cols = range(len(board[0]))
    display_board(board)
    for counter in range(25):
        filled = make_computer_move(board, avail_cols)
        display_board(board)
        if filled is not None: avail_cols.remove(filled)


main()

注意:

  1. 现在随机数的导入放在了最上面。
  2. 代码经过了一些美化,遵循了 PEP-8 的规范。
  3. 我用列表推导式准备了棋盘。
  4. 调用 display_board(board) 的地方有两个。第一个是绘制开始步骤,第二个被移动到了 make_computer_move 之后,用来在程序结束后绘制最后的图形。
  5. 使用了 % 插值来简化一些代码行。

不过还有一些不够高效的地方。例如,每次调用函数时都在计算 len(board[0]),其实这是不必要的,因为棋盘的大小始终是一样的。

撰写回答