Une vidéo de Google Deepmind qui applique le Deep Q Learning à Break Out d'ATARI pour la capturer est devenue populaire. (La vidéo est ici) J'ai décidé d'essayer cela moi-même et j'ai pensé que ce serait utile plus tard, alors j'ai commencé par fabriquer moi-même un brise-bloc. La raison pour laquelle j'ai utilisé wxPython était parce que je voulais que la bibliothèque Deep Learning soit utilisée plus tard pour être basée sur Python.
Il reste encore un long chemin à parcourir avant le Deep Q Learning, mais j'ai écrit un article dans l'espoir qu'il serait utile pour créer une application d'animation à l'aide de wxPython.
Il nécessite wxPython pour fonctionner. La méthode d'installation est [ici](http://qiita.com/kanlkan/items/5e6f2e63de406f46b3b1#wxpython%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83 Veuillez consulter% 88% E3% 83% BC% E3% 83% AB) et ainsi de suite.
Il est également posté sur GitHub, mais ce n'est pas si long, donc je le posterai ici aussi.
break-wall.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# break-wall.py
#
import wx
import random
import math
gVersion = "0.8.0"
gGameState = ("INIT","PLAYING","END")
gTimerInterval = 5 # [msec]
gFieldWidth = 640
gFieldHeight = 720
gFieldColor = (230,230,160)
gBarIniPos = (300, 640)
gBarSize = (120, 20)
gBarColor = (90, 170, 90)
gBarSpeed = 12
gBallRadius = 8
gBallColor = (0, 0, 255)
gIniBallSpeed = 2
gBlkTop = 120
gBlkVCnt = 8
gBlkHCnt = 3
gBlkSize = (80, 40)
gBlkColor = ((255,0,0),(0,255,0),(0,0,255))
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, 'Break Wall :' + gVersion, \
size=(gFieldWidth + 4, gFieldHeight + 4), \
style=wx.DEFAULT_FRAME_STYLE & ~(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))
self.main_field = FieldPanel(self)
self.Bind(wx.EVT_CLOSE, self.onClose)
self.Bind(wx.EVT_TIMER, self.onTimer)
self.timer = wx.Timer(self)
self.timer.Start(gTimerInterval)
def onClose(self, event):
self.timer.Stop()
self.Destroy()
def onTimer(self, event):
self.main_field.update()
class FieldPanel(wx.Panel):
def __init__(self, parent, pos=(2, 2), size=(gFieldWidth, gFieldHeight)):
wx.Panel.__init__(self, parent, pos=pos, size=size)
self.pos = pos
self.size = size
self.SetBackgroundColour(gFieldColor)
self.SetBackgroundStyle(wx.BG_STYLE_PAINT)
self.bar = Bar(self, gBarIniPos[0], gBarIniPos[1])
self.ball = Ball(self, gBarIniPos[0], (gBarIniPos[1] - gBallRadius))
self.blocks = [[Block(i*gBlkSize[0], gBlkTop+j*gBlkSize[1], \
gBlkColor[(gBlkVCnt*j+i)%gBlkHCnt]) \
for i in range(gBlkVCnt)] for j in range(gBlkHCnt)]
self.block_exist = [[1 for i in range(gBlkVCnt)] for j in range(gBlkHCnt)]
self.state = gGameState[0]
self.Bind(wx.EVT_PAINT, self.onPaint)
self.Bind(wx.EVT_KEY_DOWN, self.onKey)
def update(self):
self.ball.move()
self.Refresh()
def onPaint(self, event):
dc = wx.AutoBufferedPaintDC(self)
dc.Clear()
# Paint Bar
dc.SetPen(wx.Pen(self.bar.color))
dc.SetBrush(wx.Brush(self.bar.color))
dc.DrawRectangle(self.bar.x, self.bar.y, self.bar.size[0], self.bar.size[1])
# Paint Ball
dc.SetPen(wx.Pen(self.ball.color))
dc.SetBrush(wx.Brush(self.ball.color))
dc.DrawCircle(self.ball.x, self.ball.y, self.ball.radius)
# Paint Blovks
for (i, b_list) in enumerate(self.blocks):
for (j, b) in enumerate(b_list):
if self.block_exist[i][j] == 1:
dc.SetPen(wx.Pen(b.color,1))
dc.SetBrush(wx.Brush(b.color))
dc.DrawRectangle(b.x, b.y, b.size[0], b.size[1])
def onKey(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_SPACE:
if self.state == "INIT":
self.ball.shoot()
self.state = gGameState[1]
elif self.state == "END":
self.initialize()
self.state = gGameState[0]
elif (keycode == wx.WXK_LEFT or keycode == ord('H')) and self.state != "END":
self.bar.move(-1)
elif (keycode == wx.WXK_RIGHT or keycode == ord('L')) and self.state != "END":
self.bar.move(1)
def initialize(self):
self.bar.x = gBarIniPos[0]
self.bar.y = gBarIniPos[1]
self.ball.x = self.bar.x
self.ball.y = self.bar.y - self.ball.radius
self.ball.vec = [0, 0]
self.block_exist = [[1 for i in range(gBlkVCnt)] for j in range(gBlkHCnt)]
class Bar(object):
def __init__(self, parent, x, y, size=gBarSize, color=gBarColor, speed=gBarSpeed):
self.parent = parent
self.x = x
self.y = y
self.size = size
self.color = color
self.speed = speed
def move(self, direction):
if direction >= 0:
self.x += self.speed
elif direction < 0:
self.x -= self.speed
if self.x < self.parent.pos[0]:
self.x = self.parent.pos[0]
elif self.x > (self.parent.pos[0] + self.parent.size[0] - self.size[0]):
self.x = self.parent.pos[0] + self.parent.size[0] - self.size[0]
class Ball(object):
def __init__(self, parent, x, y, radius=gBallRadius, vec=[0.0,0.0], \
color=gBallColor, speed=gIniBallSpeed):
self.parent = parent
self.x = x
self.y = y
self.radius = radius
self.vec = vec
self.color = color
self.speed = speed
def shoot(self):
self.parent.state = gGameState[1]
rand_x = random.randrange(1000, 5000)
rand_y = random.randrange(2000, 5000)
self.vec = (-1.0 * float(rand_x)/1000.0, -1.0 * float(rand_y)/1000.0)
pass
def move(self):
if self.parent.state == "INIT":
self.x = self.parent.bar.x
self.y = self.parent.bar.y - self.radius
elif self.parent.state == "END":
pass
else:
unit = self.speed / math.sqrt(pow(self.vec[0],2) + pow(self.vec[1],2))
self.x += (self.vec[0] * unit)
self.y += (self.vec[1] * unit)
self.collision()
def collision(self):
# Game Over
if (self.y + self.radius) >= self.parent.size[1]:
self.parent.state = gGameState[2]
return
# Bound at Bar
if self.x >= self.parent.bar.x and \
self.x <= (self.parent.bar.x + self.parent.bar.size[0]) and \
self.y >= (self.parent.bar.y - self.radius) and \
self.y < (self.parent.bar.y + self.radius) and \
self.vec[1] > 0:
self.vec = [self.vec[0], -1*self.vec[1]]
return
# Bound at Frame
#### left
if self.vec[0] < 0 and \
self.x <= (self.parent.pos[0] + self.radius):
self.vec = [-1*self.vec[0], self.vec[1]]
return
#### right
if self.vec[0] > 0 and \
self.x >= (self.parent.pos[0] + self.parent.size[0] - self.radius):
self.vec = [-1*self.vec[0], self.vec[1]]
return
#### ceiling
if self.y <= (self.parent.pos[1] + self.radius):
self.vec = [self.vec[0], -1*self.vec[1]]
return
# Bound at Blocks
no_block = 1
for (i, b_exist_list) in enumerate(self.parent.block_exist):
for (j, b_exist) in enumerate(b_exist_list):
if b_exist == 1:
no_block = 0
tgt_block = self.parent.blocks[i][j]
# Ball cross the block edge
if self.x > (tgt_block.x - self.radius) and \
self.x < (tgt_block.x + tgt_block.size[0] + self.radius) and \
self.y > (tgt_block.y - self.radius) and \
self.y < (tgt_block.y + tgt_block.size[1] + self.radius):
self.parent.block_exist[i][j] = 0
# update vec
x0 = tgt_block.x + tgt_block.size[0] / 2
y0 = tgt_block.y + tgt_block.size[1] / 2
k = float(tgt_block.size[1]) / float(tgt_block.size[0])
#### top
if (self.vec[1] > 0) and \
(self.x < x0 and \
self.y < (k * (self.x - x0) + y0 - self.radius)) or \
(self.x > x0 and \
self.y < (-1 * k * (self.x - x0) + y0 - self.radius)):
self.vec = [self.vec[0], -1*self.vec[1]]
#### bottom
elif (self.vec[1] < 0) and \
(self.x < x0 and \
self.y > (-1 * k * (self.x - x0) + y0 + self.radius)) or \
(self.x > x0 and \
self.y > (k * (self.x - x0) + y0 + self.radius)):
self.vec = [self.vec[0], -1*self.vec[1]]
#### left
elif (self.vec[0] > 0) and (self.x < x0):
self.vec = [-1*self.vec[0], self.vec[1]]
### right
elif (self.vec[0] < 0) and (self.x > x0):
self.vec = [-1*self.vec[0], self.vec[1]]
return
if no_block == 1:
# Game Clear
self.parent.state = gGameState[2]
class Block(object):
def __init__(self, x, y, color, size=gBlkSize):
self.x = x
self.y = y
self.color = color
self.size = size
if __name__ == "__main__":
app = wx.App()
frame = MainFrame().Show()
app.MainLoop()
Je pense que wxpython fonctionnera également avec 2.8.
Recommended Posts