效果
代码
import pgzrun
TITLE = "井字棋"
WIDTH = 640
HEIGHT = 500
man_machine = False
people_people = False
btn1 = Actor("button")
btn1.left = 230
btn1.top = 200
btn2 = Actor("button")
btn2.left = 230
btn2.top = 300
bg = Actor("chess_bg")
PhotoSize = 120
backgrounds = []
n = 1
for i in range(3):
for j in range(3):
background = Actor("blank")
background.left = 140 + j * PhotoSize;
background.top = 60 + i * PhotoSize;
backgrounds.append(background)
n += 1
chessPieces = []
clicks = 0
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
rightIcon = Actor("smallright")
rightIcon.left = 80
rightIcon.top = 435
wrongIcon = Actor("smallwrong")
wrongIcon.left = 280
wrongIcon.top = 435
rightWin = 0
wrongWin = 0
dogfall = 0
isFinish = False
temp = -1
man_machine_location = -1
flag = 0
one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]
def draw():
if not man_machine and not people_people:
screen.clear()
bg.draw()
btn1.draw()
btn2.draw()
screen.draw.text('人机对战', (250, 210), fontsize=40, fontname='fzshuangqtjw_cu', color="black")
screen.draw.text('人人对战', (250, 310), fontsize=40, fontname='fzshuangqtjw_cu', color="black")
else:
screen.clear()
bg.draw()
for background in backgrounds:
background.draw()
for i in range(4):
screen.draw.line((140, 60 + 120 * i), (500, 60 + 120 * i), 'black')
screen.draw.line((140 + 120 * i, 60), (140 + 120 * i, 420), 'black')
for cp in chessPieces:
cp.draw()
rightIcon.draw()
screen.draw.text("赢:" + str(rightWin), (130, 445), fontsize=30,
fontname='simhei', color=(161, 102, 43))
wrongIcon.draw()
screen.draw.text("赢:" + str(wrongWin), (330, 445), fontsize=30,
fontname='simhei', color=(161, 102, 43))
screen.draw.text("平局:" + str(dogfall), (480, 445), fontsize=30,
fontname='simhei', color=(161, 102, 43))
if isFinish:
screen.draw.text('游戏结束', (200, 200), fontsize=60, fontname='fzshuangqtjw_cu', color="red")
screen.draw.text('再来一次', (100, 350), fontsize=40, fontname='fzshuangqtjw_cu', color="red")
screen.draw.text('回主菜单', (400, 350), fontsize=40, fontname='fzshuangqtjw_cu', color="red")
screen.draw.rect(Rect((90, 350), (180, 50)), "red")
screen.draw.rect(Rect((390, 350), (180, 50)), "red")
def update():
global rightWin, wrongWin, dogfall, isFinish, clicks, man_machine_location, temp
if people_people and not isFinish:
isFinish = whoWin(isClick)
elif man_machine and not isFinish:
if clicks % 2 == 1:
man_machine_location = computermove(isClick)
chessPiecesWhite = Actor("right")
chessPiecesWhite.left = 140 + man_machine_location % 3 * PhotoSize
chessPiecesWhite.top = 60 + man_machine_location // 3 * PhotoSize
chessPieces.append(chessPiecesWhite)
isClick[man_machine_location] = 0
clicks += 1
isFinish = whoWin(isClick)
def on_mouse_down(pos, button):
global PhotoSize, clicks, isClick, isFinish, man_machine, people_people, temp, one_move, flag, rightWin, wrongWin, dogfall
if button == mouse.LEFT and not man_machine and not people_people:
if btn1.collidepoint(pos):
man_machine = True
elif btn2.collidepoint(pos):
people_people = True
if people_people:
if not isFinish and button == mouse.LEFT:
flag += 1
if flag > 1:
for k in range(9):
if backgrounds[k].collidepoint(pos):
if clicks % 2 == 1:
if isClick[k] == -1:
chessPiecesWhite = Actor("right")
isClick[k] = 0
clicks += 1
elif isClick[k] == 1:
chessPiecesWhite = Actor("wrong")
else:
chessPiecesWhite = Actor("right")
elif clicks % 2 == 0:
if isClick[k] == -1:
chessPiecesWhite = Actor("wrong")
isClick[k] = 1
clicks += 1
elif isClick[k] == 0:
chessPiecesWhite = Actor("right")
else:
chessPiecesWhite = Actor("wrong")
chessPiecesWhite.left = 140 + k % 3 * PhotoSize
chessPiecesWhite.top = 60 + k // 3 * PhotoSize
chessPieces.append(chessPiecesWhite)
else:
if button == mouse.LEFT and pos[0] > 90 and pos[0] < 270 and pos[1] > 350 and pos[1] < 400:
chessPieces.clear()
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
flag = 1
clicks = 0
isFinish = False
elif button == mouse.LEFT and pos[0] > 390 and pos[0] < 570 and pos[1] > 350 and pos[1] < 400:
people_people = False
flag = 0
chessPieces.clear()
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
isFinish = False
wrongWin = 0
rightWin = 0
dogfall = 0
clicks = 0
elif man_machine:
if not isFinish and button == mouse.LEFT:
flag += 1
if flag > 1:
for k in range(9):
if backgrounds[k].collidepoint(pos):
temp = k
if clicks % 2 == 0:
if isClick[k] == -1:
chessPiecesWhite = Actor("wrong")
isClick[k] = 1
clicks += 1
elif isClick[k] == 0:
chessPiecesWhite = Actor("right")
else:
chessPiecesWhite = Actor("wrong")
chessPiecesWhite.left = 140 + k % 3 * PhotoSize
chessPiecesWhite.top = 60 + k // 3 * PhotoSize
chessPieces.append(chessPiecesWhite)
isFinish = whoWin(isClick)
for i in range(len(one_move)):
if temp == one_move[i]:
del one_move[i]
break
else:
if button == mouse.LEFT and pos[0] > 90 and pos[0] < 270 and pos[1] > 350 and pos[1] < 400:
chessPieces.clear()
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]
flag = 1
clicks = 0
isFinish = False
elif button == mouse.LEFT and pos[0] > 390 and pos[0] < 570 and pos[1] > 350 and pos[1] < 400:
man_machine = False
flag = 0
chessPieces.clear()
isClick = [-1, -1, -1, -1, -1, -1, -1, -1, -1]
one_move = [4, 0, 2, 6, 8, 1, 3, 5, 7]
isFinish = False
wrongWin = 0
rightWin = 0
dogfall = 0
clicks = 0
def whoWin(board):
global isFinish, rightWin, wrongWin, dogfall
_to_win = {(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)}
for r in _to_win:
if board[r[0]] == board[r[1]] == board[r[2]] != -1:
if board[r[0]] == 0:
print("O赢了")
rightWin += 1
return True
elif board[r[0]] == 1:
print("X赢了")
wrongWin += 1
return True
if -1 not in isClick:
print("平局")
dogfall += 1
return True
def winner(board):
# 判断所给棋子是否获胜
_to_win = {(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)}
for r in _to_win:
if board[r[0]] == board[r[1]] == board[r[2]] != -1:
return True
return False
def computermove(board):
# 核心算法:计算AI的落子位置
boardcopy = board.copy()
# 规则一:判断如果某位置落子可以获胜,则选择这个位置
for i in range(9):
if boardcopy[i] == -1:
boardcopy[i] = 0
if winner(boardcopy):
for j in range(len(one_move) - 1):
if i == one_move[j]:
del one_move[j]
return i
else:
boardcopy[i] = -1
# 规则二:某个位置玩家下一步落子就可以获胜,则选择该位置
for i in range(9):
if boardcopy[i] == -1:
boardcopy[i] = 1
if winner(boardcopy):
for j in range(len(one_move) - 1):
if i == one_move[j]:
del one_move[j]
return i
else:
boardcopy[i] = -1
# 规则三:按照中心、角、边的选择空的位置
for move in one_move:
del one_move[0]
return move
pgzrun.go()
说明
人机模式实现了简单的智能化,但是还是有方法可以赢人机的(暂时不想修改了)。Bug应该也还有但是我暂时还没有发现。嗯,就这样吧