Python 连接四子游戏。让电脑下棋
我需要一些帮助来完成我的四子棋作业。我的“让电脑下棋”的功能有问题。在这个作业中,我需要用一个列表来表示棋盘。这个列表里面有多个列表,每个列表代表一行。而每个列表里的元素则代表列。
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 个回答
首先,你应该检查一下是否有至少一个空格,通常情况下,导入的内容会放在程序的最上面。
import random
定义一个函数来让电脑下棋,函数名叫make_computer_move,参数是棋盘board。这个函数会遍历棋盘的每一行,寻找第一个空格。如果在某一行找到了空格,就会进入一个无限循环。在这个循环里,电脑会随机选择一个列数,然后从棋盘的底部往上检查这一列,看看有没有空格。如果找到了空格,就会打印出这个空格的坐标(行和列),然后在这个位置上放一个'O',表示电脑下了一步棋。最后,函数会返回更新后的棋盘。如果所有的格子都填满了,程序会打印“所有格子都填满了——游戏结束”。
另一种方法是创建一个可用空间的列表,然后随机选择一个
首先,创建一个空的列表available。接着,使用两个循环遍历5行5列的棋盘。如果在某个位置发现是空格,就把这个位置的行和列坐标添加到available列表中。最后,电脑会从available列表中随机选择一个位置作为下棋的地方。
这段话的意思是,它会给你一个随机的开放列(或者行,具体看你怎么理解)的索引。
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)
上面的代码运行得很好。它让 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()
注意:
- 现在随机数的导入放在了最上面。
- 代码经过了一些美化,遵循了 PEP-8 的规范。
- 我用列表推导式准备了棋盘。
- 调用
display_board(board)
的地方有两个。第一个是绘制开始步骤,第二个被移动到了make_computer_move
之后,用来在程序结束后绘制最后的图形。 - 使用了 % 插值来简化一些代码行。
不过还有一些不够高效的地方。例如,每次调用函数时都在计算 len(board[0])
,其实这是不必要的,因为棋盘的大小始终是一样的。