井字游戏 Tic Tac Toe
西安电子科技大学 Python 上机实验
井字棋(Tic Tac Toe, or noughts and crosses)游戏,又称连三子 棋,OX 棋,是一种供两人玩的纸笔游戏。两个玩家轮流在九个空格中 画上代表自己的 X 或 O ,谁先将自己的符号连成一线(横连、竖连、 斜连皆可),即获得胜利。倘若在游戏过程中,在所有空格都填满的 情况下,双方都没有取得胜利,那么游戏以平局告终。游戏界面类似 我们电脑键盘中的数字小键盘。
上代码!
采用面向对象。
import random
class TicTacToe(object):
"""井字游戏的类:"""
def __init__(self):
# 棋盘:
self.pos = {}
for i in range(1, 10):
self.pos[i] = ' '
self.board = f'{self.pos[7]}|{self.pos[8]}|{self.pos[9]}\n-+-+-\n{self.pos[4]}|{self.pos[5]}|{self.pos[6]}\n-+-+-\n{self.pos[1]}|{self.pos[2]}|{self.pos[3]}'
# 棋子:
self.player, self.computer, self.whoGoFirst = None, None, None
# 检验退出游戏:
self.exit = False
def draw_board(self):
"""绘制棋盘:"""
self.board = f'{self.pos[7]}|{self.pos[8]}|{self.pos[9]}\n-+-+-\n{self.pos[4]}|{self.pos[5]}|{self.pos[6]}\n-+-+-\n{self.pos[1]}|{self.pos[2]}|{self.pos[3]}'
print(self.board)
def go_first(self):
"""谁先走:"""
if random.randint(0, 1) == 0:
self.whoGoFirst = 'computer'
print("这轮计算机先走。")
return None
self.whoGoFirst = 'player'
print("这轮玩家先走。")
def choose(self):
"""选择棋子:"""
player_input = input('你要选 X 还是 O ?:').upper()
while player_input != 'X' and player_input != 'O':
player_input = input('请输入 X 或 O:').upper()
if player_input == 'X':
self.player, self.computer = 'X', 'O'
if player_input == 'O':
self.player, self.computer = 'O', 'X'
def checkWinner(self, letter):
# 检测获胜:
return ((self.pos[7] == letter and self.pos[8] == letter and self.pos[9] == letter) or
(self.pos[4] == letter and self.pos[5] == letter and self.pos[6] == letter) or
(self.pos[1] == letter and self.pos[2] == letter and self.pos[3] == letter) or
(self.pos[7] == letter and self.pos[4] == letter and self.pos[1] == letter) or
(self.pos[8] == letter and self.pos[5] == letter and self.pos[2] == letter) or
(self.pos[9] == letter and self.pos[6] == letter and self.pos[3] == letter) or
(self.pos[7] == letter and self.pos[5] == letter and self.pos[3] == letter) or
(self.pos[9] == letter and self.pos[5] == letter and self.pos[1] == letter))
@staticmethod
def isWinner(boardCopy, letter):
"""模拟胜利条件:"""
return ((boardCopy[7] == letter and boardCopy[8] == letter and boardCopy[9] == letter) or
(boardCopy[4] == letter and boardCopy[5] == letter and boardCopy[6] == letter) or
(boardCopy[1] == letter and boardCopy[2] == letter and boardCopy[3] == letter) or
(boardCopy[7] == letter and boardCopy[4] == letter and boardCopy[1] == letter) or
(boardCopy[8] == letter and boardCopy[5] == letter and boardCopy[2] == letter) or
(boardCopy[9] == letter and boardCopy[6] == letter and boardCopy[3] == letter) or
(boardCopy[7] == letter and boardCopy[5] == letter and boardCopy[3] == letter) or
(boardCopy[9] == letter and boardCopy[5] == letter and boardCopy[1] == letter))
def spaceFree(self, loc):
"""检测空位置:"""
if self.pos[loc] == ' ':
return True
return False
def makeMove(self, loc, boardCopy):
"""让计算机模拟下棋:"""
# 小心能不能改变 boardCopy 这个变量
boardCopy[loc] = self.computer
def player_move(self):
"""让玩家移动:"""
choose = input("你要落子的位置是 (1~9):")
while (eval(choose) not in list(range(1, 10))) or (self.pos[eval(choose)] != ' '):
choose = input("请输入正确的落子位置 (1~9):")
self.pos[eval(choose)] = self.player
self.check_board()
def computer_move(self):
"""让计算机移动:"""
"""第一次运行:"""
if self.whoGoFirst == 'computer':
self.pos[random.randint(1, 9)] = self.computer
self.whoGoFirst = None
return
else:
"""检测有没有能获胜的位置:"""
for i in range(1, 10):
# 对复制字典进行操作:
boardCopy = self.pos.copy()
# 检测空位置:
if self.spaceFree(i):
# 模拟下棋:
self.makeMove(i, boardCopy)
if self.isWinner(boardCopy, self.computer):
# 如果返回的是 True:就在 i 的位置处下棋:
self.pos[i] = self.computer
self.check_board()
return
"""阻止玩家胜利:"""
for i in range(1, 10):
# 复制棋盘:
boardCopy = self.pos.copy()
# 模拟下棋:
if self.spaceFree(i):
self.makeMove(i, boardCopy)
if self.isWinner(boardCopy, self.player):
# 在此处下棋来阻止玩家:
self.pos[i] = self.computer
self.check_board()
return
"""填充四个角:"""
for i in [1, 3, 7, 9]:
if self.pos[i] == ' ':
self.pos[i] = self.computer
return
"""填充中心:"""
if self.pos[5] == ' ':
self.pos[i] = self.computer
return
"""填充四个边:"""
for i in [2, 4, 6, 8]:
if self.pos[i] == ' ':
self.pos[i] = self.computer
return
def boardFill(self):
"""检验棋盘是否已经被充满:"""
for i in range(1, 10):
if self.pos[i] == ' ':
return False
return True
def check_board(self):
"""检验棋盘"""
if self.checkWinner(self.player):
print("玩家获胜!")
self.exit = True
return
if self.checkWinner(self.computer):
print("计算机获胜!")
self.exit = True
return
if self.boardFill():
print("平局!")
self.exit = True
def run_game(self):
"""启动程序:"""
while True:
self.__init__()
self.choose()
self.go_first()
if self.whoGoFirst == 'player':
self.draw_board()
while True:
self.player_move()
self.computer_move()
self.draw_board()
self.check_board()
if self.exit:
break
if self.whoGoFirst == 'computer':
self.computer_move()
self.draw_board()
while True:
self.player_move()
self.computer_move()
self.draw_board()
self.check_board()
if self.exit:
break
"""是否要重新游戏:"""
choice = input("你还要再玩一次吗?(yes or no):").lower()
while choice not in ["yes", "no"]:
choice = input("请输入(yes or no):")
if choice == "no":
print("游戏结束!")
break
if __name__ == '__main__':
my_TicTacToe = TicTacToe()
my_TicTacToe.run_game()