预置环境:python版本2.或3.及以上
numpy库的安装
windows下:
win+R输入cmd打开命令控制行输入:
Linux下:
在linux桌面右键打开terminal终端输入:
sudo pip install numpy
安装完毕即可。
Tic-Tac-Toe井字棋的代码实现
################################################################################
# tictactoe.py - the first of many programs
# uses numpy arrays to represent an internal tictactoe board
# uses four global variables - board_arr, tutorial_arr, user_num, and comp_num
import numpy as np
import random
# Creates blank 3x3 array. Randomizes who goes first.
# TODO: ADD A TUTORIAL PROGRAM
def initialize():
#global board_arr
#global tutorial_arr
# 0's act as o's
# 1's act as x's
# 3's act as placeholders for blank spots
#棋盘
board_arr = np.array([[3, 3, 3],
[3, 3, 3],
[3, 3, 3]])
tutorial_arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
return board_arr, tutorial_arr
def guessfirst(): #猜先手
# Flip a coin to see who goes first with x's
coin_flip = np.random.randint(0, 2)
if coin_flip == 0:
print("Computer goes first. Your letter is o.")
return "AI"
else:
print("You go first. Your letter is x.")
return "P"
# Converts internal numpy array into a visual ASCII board.
def display_board(board_arr):
board_list = []
# loops through flattened board array to scan for 0's, 1's and 3's
# converts them into O's, X's, and blank spots
internal_arr = board_arr.flatten() #降维,返回一个折叠成一维的数组
for i in range(0, 9):
if internal_arr[i] == 0:
board_list.append('o')
elif internal_arr[i] == 1:
board_list.append('x')
elif internal_arr[i] == 3:
board_list.append(' ')
else:
raise Exception("display_board Error")
# inputs O's, X's, and blank spots into an ASCII tictactoe board
print("""
{} | {} | {}
---+---+---
{} | {} | {}
---+---+---
{} | {} | {}
""".format(*board_list))
def return_open_slots(board_arr): #返回可放置棋子的空槽的位置
# Checks for open slots using Boolean arrays.
# Important when checking for winner (if draw) and checking if user's input...
# ...is valid
open_slots = []
bool_arr = (board_arr == 3) #根据board_arr每个位置上的元素是否为3生成一个布尔array
flat_bool_arr = bool_arr.flatten() #变为一维数组进行判断
# is spot taken by 3's? If so, then spot is open.
# appends (i + 1) because inputs are indexed to 1
for i in range(0, len(flat_bool_arr)):
if flat_bool_arr[i] == True:
open_slots.append(i + 1) #将还没有放置棋子的槽的位置放到open_slots列表里
return open_slots
def check_for_winner(board_arr,firstplayer,currentplayer):
#判断当前选手是否获胜
#返回值0:平局,1:赢,2:输,-1:尚未能判断,请继续下子
if return_open_slots(board_arr) == []: #如果已经无处可放,那么就是平局
# Checks if no open slots
return 0
for i in range(0, 3): #判断是否有一行或一列放置同样的棋子
# Checks rows and columns for match
rows_win = (board_arr[i, :] == currentplayer).all() #all()比较两个数组是否所有元素都相等
cols_win = (board_arr[:, i] == currentplayer).all()
if rows_win or cols_win:
return 1
#判断是否有一条斜线上放置同样的棋子
'''
np.fliplr 矩阵左右翻转,在二维的情况下很容易理解 || 按轴1翻转
[ [0,1,2],[3,4,5],[6,7,8] ]翻转后变为
[ [2,1,0],[5,4,3],[8,7,6] ]
flip()
fliplr():按轴1翻转,等价于flip(M,0)
flipud():按轴0翻转,等价于flip(M,0)
[ [0,1,2],[3,4,5],[6,7,8] ] flipud翻转后变为
[ [6,7,8],[3,4,5],[0,1,2]]
'''
diag1_win = (np.diag(board_arr) == currentplayer).all()
diag2_win = (np.diag(np.fliplr(board_arr)) == currentplayer).all()
if diag1_win or diag2_win:
# Checks both diagonals for match
return 1
return -1
def place_letter(board_arr, tutorial_arr, current_num, current_input): #在current_input处放置棋子
# Takes comp_num and comp_choice (or user_num and user_choice)...
# ...and inputs that into the global board_arr
# Current_input is either randomly chosen by computer or input by user
# Current_num is either user_num or comp_num
'''
numpy.where (condition[, x, y])
1. np.where(condition, x, y), 满足条件(condition),输出x,不满足输出y。
2. np.where(condition), 只有条件 (condition),没有x和y,
则输出满足条件元素的坐标 。
这里的坐标以tuple的形式给出,
通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。
'''
index = np.where(tutorial_arr == current_input)
board_arr[index] = current_num #在槽中放置表示人或者机器的数字,即1或0
# TODO: LIST OPEN SLOTS ON ASCII BOARD
def choose_randomly(board_arr, avail):
possible_moves = []
slot = return_open_slots(board_arr)
for i in avail:
if i in slot:
possible_moves.append(i)
if len(possible_moves) != 0:
return random.choice(possible_moves)
else:
return None
def get_P_moves(board_arr):
move = 0
slot = return_open_slots(board_arr)
while move not in slot:
move = int(input("Pick an open slot: "))
return move
def user_turn(board_arr,tutorial_arr, firstplayer, user_num):
#display_board(board_arr)
user_input = get_P_moves(board_arr)
place_letter(board_arr, tutorial_arr, user_num, user_input)
return check_for_winner(board_arr, firstplayer, user_num)
def get_AI_moves(board_arr, tutorial_arr, firstplayer, comp_num):
#check if AI can win in the next move
for i in range(1, 10):
copy = board_arr.copy() #获得副本
slot = return_open_slots(copy)
#print("in get_AI_moves, slot = :", slot)
if i not in slot:
continue
place_letter(copy, tutorial_arr, comp_num, i)
re = check_for_winner(copy, firstplayer, comp_num)
if re == 1:
return i
#else check if P can win in the next move and block the first found move
for i in range(1, 10):
copy = board_arr.copy() #获得副本
slot = return_open_slots(copy)
if i not in slot:
continue
place_letter(copy, tutorial_arr, 1-comp_num, i)
re = check_for_winner(copy, firstplayer, 1-comp_num)
if re == 1:
return i
#The key to win is to occupy the corners, so move there if available
move = choose_randomly(board_arr, [1, 3, 7, 9])
#print(move)
if move != None:
return move
#of second priority is the center element
move = choose_randomly(board_arr, [5])
#print(move)
if move != None:
return move
#Then the rest
return choose_randomly(board_arr, [2, 4, 6, 8])
def comp_turn(board_arr, tutorial_arr, firstplayer, comp_num):
#display_board(board_arr)
AI_input = get_AI_moves(board_arr, tutorial_arr, firstplayer, comp_num)
place_letter(board_arr, tutorial_arr, comp_num, AI_input)
return check_for_winner(board_arr, firstplayer, comp_num)
#===========================
while True:
board_arr, tutorial_arr = initialize()
who = guessfirst()
print("{0} will go first".format(who))
if who == "P":
user_num = 1
comp_num = 0
else:
user_num = 0
comp_num = 1
GameOn = True
while GameOn:
if who == 'P':
re = user_turn(board_arr, tutorial_arr, who, user_num)
display_board(board_arr)
if re == 1:
print("GameOver You've Won!")
GameOn = False
elif re == 0:
print("Tie")
GameOn = False
else:
who = 'AI'
else:
re = comp_turn(board_arr, tutorial_arr, who, comp_num)
display_board(board_arr)
if re == 1:
print("GameOver AI've Won!")
GameOn = False
elif re == 0:
print("Tie")
GameOn = False
else:
who = 'P'
again_choice = input("Play again?(Y or N).")
if again_choice == "N" or again_choice == "n":
break