我正在尝试通过自己制作的“游戏”进行一些强化学习。
在我的主循环中,当我玩游戏时,如果定期刷新窗口,一切都会正常。
但是,在一集之后,我想训练我的特工,但是如果训练时间太长,则pygame窗口只会显示“控制栏”(带有X的栏用于关闭窗口),并且如果我尝试关闭它,程序只会崩溃。
有没有一种简单的方法可以应对? 其他解决方案告诉我,我应该定期调用一些pygame函数,但是如果我不得不暂停培训以不时进行操作,则代码将变得有些混乱。
答案 0 :(得分:0)
通常在while / for循环中使用围绕环境和代理的包装程序来定义强化学习训练循环。
一种流行的设计是将游戏包装在OpenAI体育馆中,并使用动作作为输入来调用步骤功能,以在该时间步骤中检索下一个状态,奖励,最终状态和其他统计信息:
示例:
import UserNotifications
import FirebaseMessaging
class AppDelegate: UIResponder, MessagingDelegate, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
let dataDict:[String: Bool] = [fcmToken: true]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
DataService.run.saveFCMToken(tokenDict: dataDict, fcmtoken: fcmToken) { (success) in
if success {
print("FCM Token Saved: \(fcmToken)")
DEVICEID_FCMTOKEN = fcmToken
self.connectToFCM()
}//end if
}//end saveFCMToken
}//end func
}
}
我认为您的环境健身室没有包裹,但是这样做很容易。您也可以创建自定义代码,但是应用程序的一般流程应如示例代码所示。
答案 1 :(得分:0)
是的,您必须定期致电pygame.event.get
;否则,事件队列将填满,并且您的窗口将停止响应。
如果您必须在游戏中运行长时间运行的任务,则可以使用以下选项:
如果可以将长时间运行的任务分解为更小的,更快速的步骤,则可以使用协程通过yield来使控件返回主循环:
import pygame
import time
def long_running_task():
i = 0
while i < 300:
time.sleep(0.01)
print(i)
i += 1
yield i
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
rect = pygame.Rect((10, 250, 32, 32))
direction = 1
generator = None
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
generator = long_running_task()
screen.fill(pygame.Color('darkgrey'))
rect.move_ip(5 if direction else -5, 0)
pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
if not screen.get_rect().contains(rect):
direction = not direction
if generator:
try: next(generator)
except StopIteration: generator = None
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
这可能对您不起作用,但是当您有一种算法可以计算结果并且希望在该算法的步骤之间绘制屏幕时,这是一个不错的解决方案。
Python使在另一个进程中运行一个函数变得非常容易。这是一个使用multiprocessing
包的简单示例。
import pygame
import time
import multiprocessing
def long_running_task():
i = 0
while i < 50:
time.sleep(0.1)
print(i)
i += 1
return i
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
rect = pygame.Rect((10, 250, 32, 32))
direction = 1
process = None
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
if process:
process.terminate()
process.join()
return
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
process = multiprocessing.Process(target=long_running_task)
process.start()
screen.fill(pygame.Color('darkgrey'))
rect.move_ip(5 if direction else -5, 0)
pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
if not screen.get_rect().contains(rect):
direction = not direction
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()