我正在用minimax算法编写井字游戏。当玩家失败时,我已经添加了topWindow,但是我找不到使程序显示Draw消息的方法。在这种情况下我该怎么办?
from tkinter import *
from tkinter.font import Font
from copy import deepcopy
class Board:
def __init__(self, other=None):
self.player = 'X'
self.opponent = 'O'
self.empty = ''
self.size = 3
self.fields = {}
for y in range(self.size):
for x in range(self.size):
self.fields[x, y] = self.empty
# copy constructor
if other:
self.__dict__ = deepcopy(other.__dict__)
def move(self, x, y):
board = Board(self)
board.fields[x, y] = board.player
(board.player, board.opponent) = (board.opponent, board.player)
return board
def __minimax(self, player):
if self.won():
if player:
return (-1, None)
else:
return (+1, None)
elif self.tied():
return (0, None)
elif player:
best = (-2, None)
for x, y in self.fields:
if self.fields[x, y] == self.empty:
value = self.move(x, y).__minimax(not player)[0]
if value > best[0]:
best = (value, (x, y))
return best
else:
best = (+2, None)
for x, y in self.fields:
if self.fields[x, y] == self.empty:
value = self.move(x, y).__minimax(not player)[0]
if value < best[0]:
best = (value, (x, y))
return best
def best(self):
return self.__minimax(True)[1]
def tied(self):
for (x, y) in self.fields:
if self.fields[x, y] == self.empty:
return False
return True
def won(self):
# horizontal
for y in range(self.size):
winning = []
for x in range(self.size):
if self.fields[x, y] == self.opponent:
winning.append((x, y))
if len(winning) == self.size:
return winning
# vertical
for x in range(self.size):
winning = []
for y in range(self.size):
if self.fields[x, y] == self.opponent:
winning.append((x, y))
if len(winning) == self.size:
return winning
# diagonal
winning = []
for y in range(self.size):
x = y
if self.fields[x, y] == self.opponent:
winning.append((x, y))
if len(winning) == self.size:
return winning
# other diagonal
winning = []
for y in range(self.size):
x = self.size - 1 - y
if self.fields[x, y] == self.opponent:
winning.append((x, y))
if len(winning) == self.size:
return winning
# default
return None
def __str__(self):
string = ''
for y in range(self.size):
for x in range(self.size):
string += self.fields[x, y]
string += "\n"
return string
class GUI:
def __init__(self):
self.app = Tk()
self.app.title('Tic-Tac-Toe')
self.app.resizable(width=False, height=False)
self.board = Board()
self.font = Font(family="Helvetica", size=32)
self.buttons = {}
for x, y in self.board.fields:
handler = lambda x=x, y=y: self.move(x, y)
button = Button(self.app, command=handler, font=self.font, width=2, height=1)
button.grid(row=y, column=x)
self.buttons[x, y] = button
handler = lambda: self.reset()
button = Button(self.app, text='Restart', command=handler)
button.grid(row=self.board.size + 1, column=0, columnspan=self.board.size, sticky="WE")
self.update()
def reset(self):
self.board = Board()
self.update()
self.top.destroy()
def move(self, x, y):
self.app.config(cursor="watch")
self.app.update()
self.board = self.board.move(x, y)
self.update()
move = self.board.best()
if move:
self.board = self.board.move(*move)
self.update()
self.app.config(cursor="")
def topMessage(self):
"""Congratulation message pops up"""
self.top = Toplevel()
self.top.title("Congratulations!")
self.top.minsize(300, 150)
# top.geometry("200x150")
self.topText = Label(self.top, text="O is the winner!", font=("Helvetica", 20), pady=20)
self.topButton = Button(self.top, text="Restart", width=10, height=2, command=lambda: self.reset())
self.topText.pack(fill=X)
self.topButton.pack()
def update(self):
for (x, y) in self.board.fields:
text = self.board.fields[x, y]
self.buttons[x, y]['text'] = text
self.buttons[x, y]['disabledforeground'] = 'black'
if text == self.board.empty:
self.buttons[x, y]['state'] = 'normal'
else:
self.buttons[x, y]['state'] = 'disabled'
winning = self.board.won()
if winning:
for x, y in winning:
self.buttons[x, y]['disabledforeground'] = 'red'
for x, y in self.buttons:
self.buttons[x, y]['state'] = 'disabled'
self.topMessage()
for (x, y) in self.board.fields:
self.buttons[x, y].update()
def mainloop(self):
self.app.mainloop()
if __name__ == '__main__':
GUI().mainloop()
............................................... ................................................... ................................................... ................................................... ................................................... ................................................... .......................
答案 0 :(得分:0)
我对boolean
不熟悉。但是根据您的代码,当export class Product implements IProduct {
[key: string]: number | boolean;
b: number;
c: boolean;
}
中的变量export class Product implements IProduct {
b: number;
c: boolean;
a: string /* Gives erorr, since string is not allowed index type */
}
为import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
import 'dart:math';
const BOX_COLOR = Colors.cyan;
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Spring Box",
theme: ThemeData(
primaryColor: Colors.red,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Padding(
child: PhysicsBox(),
padding: EdgeInsets.only(
left: 20.0,
right: 20.0,
top: 20.0,
bottom: 20.0,
),
),
));
}
}
class PhysicsBox extends StatefulWidget {
@override
BoxState createState() => BoxState();
}
class BoxState extends State<PhysicsBox> with TickerProviderStateMixin {
AnimationController controller;
AnimationController controller2;
Animation<double> animation;
SpringSimulation simulation;
double _position;
@override
void initState() {
super.initState();
simulation = SpringSimulation(
SpringDescription(
mass: 1.0,
stiffness: 100.0,
damping: 5.0,
),
400.0,
208.0,
-4000.0,
);
controller2 = AnimationController(vsync: this,duration: Duration(milliseconds: 70));
animation = Tween(begin: 200.0, end: 400.0).animate(controller2)
..addListener((){
if(controller2.status == AnimationStatus.completed){controller.reset();}
setState(() {
_position = animation.value;
});
});
controller = AnimationController(vsync: this,duration: Duration(milliseconds: 700))..forward()
..addListener(() {
if(controller.status == AnimationStatus.completed){controller2.reset();}
setState(() {
_position = simulation.x(controller.value);
});
print('${simulation.x(controller.value)}');
});
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
width:500.0,
height:500.0,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Positioned(
top: _position,
child: GestureDetector(
onTap: (){
if (controller.status == AnimationStatus.completed) {
controller2.forward();//controller.reset();
}else{
controller.forward();}
},
child: Container(
width: 100.0,
height: 100.0,
color: Colors.red,
),
),
)
],
)
);
}
}
(由minimax algorithm
产生)时,游戏结束。但是,游戏结束后,您的代码不会返回游戏结果。
建议修改move
以返回游戏结果:
None
还要修改self.board.best()
以适应上述更改,并在游戏结束时显示GUI.move()
或Board.best()
消息:
def best(self):
return self.__minimax(True) # return the game result as well, not just the move
最后修改GUI.move()
以接受另一个参数,即游戏结果:
tie
请注意,lose
中存在一个问题:在游戏中单击def move(self, x, y):
self.app.config(cursor="watch")
self.app.update()
self.board = self.board.move(x, y)
self.update()
result, move = self.board.best() # get the result of game as well
if move:
self.board = self.board.move(*move)
self.update()
else:
# tie or lose game
self.topMessage('tie' if result == 0 else 'lose')
self.app.config(cursor="")
按钮时,变量topMessage()
尚未定义,并且引发异常。因此,只有在定义def topMessage(self, result='win'):
"""Congratulation message pops up"""
self.top = Toplevel()
self.top.title("Congratulations!")
self.top.minsize(300, 150)
# top.geometry("200x150")
if result == 'win':
message = "O is the winner!"
elif result == 'lose':
message = "X is the winner!"
else:
message = "No winner!"
self.topText = Label(self.top, text=message, font=("Helvetica", 20), pady=20)
self.topButton = Button(self.top, text="Restart", width=10, height=2, command=lambda: self.reset())
self.topText.pack(fill=X)
self.topButton.pack()
时,才能销毁它:
GUI.reset()