Ejemplo n.º 1
0
class Map(QtGui.QFrame):
	
	msg2Statusbar = QtCore.pyqtSignal(str)
	changedStatus = QtCore.pyqtSignal(bool)
	
	MapWidth = 1024
	MapHeight = 640
	Speed = 100
	
	NoAction = 0
	PlaceBlockAction = 1
	PlaceRobotAction = 2
	PlaceTargetAction = 3
	
	
	def __init__(self, parent):
		super(Map, self).__init__(parent)
	
		self.parent = parent
	
		self.initMap()
	
	
	def initMap(self):
		QtCore.qDebug('sim_map.Map.initMap')
		
		self.timer = QtCore.QBasicTimer()
		self.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
		
		self.objects = []
		self.setFocusPolicy(QtCore.Qt.StrongFocus)
		self.setFixedSize(Map.MapWidth, Map.MapHeight)
		self.isStarted = False
		self.isPaused = False
		self.clearMap()
		
		self.dragXstart = -1
		self.dragYstart = -1
		self.dragXend = -1
		self.dragYend = -1
		self.dragObject = None
	
		self.mouseActionType = Map.NoAction
		self.saveToImage = True
		
		self.mapChanged = False
		self.robot = None
		self.target = None
		self.vbox = QtGui.QVBoxLayout()
		self.setLayout(self.vbox)
		self.simStats = SimStats(self)
	
	
	def load(self, fname):
		print("[sim_map.Map.load]")
		
		with open(fname) as fp:
			
			fp.readline()
			
			line = fp.readline().strip().split()
			Map.MapWidth = int(line[0])
			Map.MapHeight = int(line[1])
			Map.Speed = int(line[2])
			
			fp.readline()
			
			line = fp.readline().strip()
			nObjects = int(line)
			
			fp.readline()
			
			for i in range(nObjects):
				line = fp.readline().strip().split()
				
				x = int(line[0])
				y = int(line[1])
				w = int(line[2])
				h = int(line[3])
				
				print(line)
				self.objects.append(Rectangle(x, y, w, h))
	
			self.setFixedSize(Map.MapWidth, Map.MapHeight)
			self.repaint()
		
	
	def save(self, fname):
		print("[sim_map.Map.save]")
		
		self.setChanged(False)
		
		with open(fname, 'w') as fp:
			fp.write('# MapWidth MapHeight Speed\n') 
			fp.write(str(Map.MapWidth) + ' ' + str(Map.MapHeight) + ' ' + str(Map.Speed) + '\n')
			
			fp.write('# Number of objects\n')
			fp.write(str(len(self.objects)) + '\n')
			
			fp.write('# x y width height\n')
			for obj in self.objects:
				fp.write(str(obj) + '\n')
	
	
	def start(self):
		QtCore.qDebug('sim_map.Map.start')
		
		if self.isPaused:
			return
		
		self.isStarted = True
		
		self.clearMap()
		
		self.msg2Statusbar.emit(str(0))
		
		
		self.timer.start(Map.Speed, self)
	
	
	def pause(self):
		QtCore.qDebug('sim_map.Map.pause')
		
		if not self.isStarted:
			return
		
		self.isPaused = not self.isPaused
		
		if self.isPaused:
			self.timer.stop()
			self.msg2Statusbar.emit("paused")
			
		else:
			self.timer.start(Map.Speed, self)
			self.msg2Statusbar.emit(str(0))
		
		self.update()
	
	
	def mousePressEvent(self, QMouseEvent):
		
		x = QMouseEvent.x()
		y = QMouseEvent.y()
		
		if self.mouseActionType == Map.NoAction:
			
			self.dragXstart = x
			self.dragYstart = y
		
			self.dragObject = Rectangle()
			self.dragObject.updateDrag(self.dragXstart,
					self.dragYstart, self.dragXstart, self.dragYstart)
		
			self.mouseActionType = Map.PlaceBlockAction
		
			#TODO cleanup
			#print(QMouseEvent.pos())
		
		elif self.mouseActionType == Map.PlaceRobotAction:
			
			self.robot = Robot(x, y, 0)
			self.setStatsWidget()
			
	
	def mouseMoveEvent(self, QMouseEvent):
		x = QMouseEvent.x()
		y = QMouseEvent.y()
		
		if self.mouseActionType == Map.PlaceBlockAction:
			
			self.dragXend = x
			self.dragYend = y
		
			self.dragObject.updateDrag(self.dragXstart,
					self.dragYstart, self.dragXend, self.dragYend)
		
			#TODO cleanup
			#print(QMouseEvent.pos())
			self.repaint()
	
		elif self.mouseActionType == Map.PlaceRobotAction:
			
			ab = x - self.robot.posX
			mb = math.sqrt(math.pow(x - self.robot.posX, 2) + math.pow(y - self.robot.posY, 2))
			if mb == 0:
				newTheta = 0
			else:
				newTheta = math.acos(ab / mb)
				
				if y < self.robot.posY:
					newTheta = math.pi - newTheta + math.pi
				
			print('theta: %f' % newTheta)
			self.robot.setOrientation(newTheta)
			
			if self.target is not None:
				
				# I am computing the angle relative to Ox ax.
				x = self.target.x - self.robot.posX
				y = self.target.y - self.robot.posY
				
				ab = x
				mb = math.sqrt(x * x + y * y)
			
				if mb == 0:
					theta = 0
				else:
					theta = math.acos(ab / mb)
				
				if self.target.y < self.robot.posY:
					theta = math.pi - theta + math.pi
				
				theta = theta - newTheta
				if theta < 0:
					theta = theta + 2 * math.pi
				
				self.robot.setTargetDirection(theta)
			
			self.repaint()
	
		
	def mouseReleaseEvent(self, QMouseEvent):
		
		x = QMouseEvent.x()
		y = QMouseEvent.y()
		
		if self.mouseActionType == Map.PlaceRobotAction:

			self.mouseActionType = Map.NoAction
			
			self.simStats.btPlaceRobot.setEnabled(False)
			
			ab = x - self.robot.posX
			mb = math.sqrt(math.pow(x - self.robot.posX, 2) + math.pow(y - self.robot.posY, 2))
			if mb == 0:
				newTheta = 0
			else:
				newTheta = math.acos(ab / mb)
			
			if y < self.robot.posY:
				newTheta = math.pi - newTheta + math.pi
			
			self.robot.setOrientation(newTheta)
			
			if self.target is not None:
				
				# I am computing the angle relative to Ox ax.
				x = self.target.x - self.robot.posX
				y = self.target.y - self.robot.posY
				
				ab = x
				mb = math.sqrt(x * x + y * y)
			
				if mb == 0:
					theta = 0
				else:
					theta = math.acos(ab / mb)
				
				if self.target.y < self.robot.posY:
					theta = math.pi - theta + math.pi
				
				theta = theta - newTheta
				if theta < 0:
					theta = theta + 2 * math.pi
				
				self.robot.setTargetDirection(theta)
			
			self.repaint()
			
		elif self.mouseActionType == Map.PlaceTargetAction:
			
			self.target = Target(x, y)
			self.mouseActionType = Map.NoAction
			
			self.simStats.btPlaceTarget.setEnabled(False)
			self.simStats.btPlaceRobot.setEnabled(True)
			
			self.repaint()
			
		elif self.mouseActionType == Map.PlaceBlockAction:
			
			self.dragXend = x
			self.dragYend = y
			
			self.dragObject.updateDrag(self.dragXstart, self.dragYstart,
					self.dragXend, self.dragYend)
		
			self.objects.append(self.dragObject)
			self.dragObject = None
		
			self.saveToImage = True
			self.setChanged(True)
		
			self.mouseActionType = Map.NoAction
			#TODO
			#print(QMouseEvent.pos())
			self.repaint()
	
	
	def paintEvent(self, event):
		rect = self.contentsRect()
		
		if self.saveToImage == True:
			
			ImageMap.image = QtGui.QImage(rect.right(), rect.bottom(), QtGui.QImage.Format_RGB32)
			imagePainter = QtGui.QPainter(ImageMap.image)
			
			self.draw(imagePainter)
			
			ImageMap.image.save('image.jpg')
			
			self.saveToImage = False
	
		painter = QtGui.QPainter(self)
		self.draw(painter)
	
	
	def draw(self, painter):
		
		rect = self.contentsRect()
		
		painter.setPen(QtGui.QColor(0xff0000))
		#TODO
		#QtCore.qDebug('[sim_map.Map.paintEvent] %d %d %d %d' % (rect.top(), rect.left(), rect.bottom(), rect.right())) 
		painter.fillRect(0, 0, rect.right(), rect.bottom(), QtGui.QColor(0xffffff))
		
		for obj in self.objects:
			obj.draw(painter)
		
		if not self.dragObject is None:
			self.dragObject.draw(painter)
			
		if self.robot is not None and self.saveToImage != True:
			self.robot.draw(painter)
		
		if self.target is not None and self.saveToImage != True:
			self.target.draw(painter)
	
	
	def keyPressEvent(self, event):
		
		key = event.key()
		
		if key == QtCore.Qt.Key_S:
			self.start()
			return
		
		if not self.isStarted:
			super(Map, self).keyPressEvent(event)
			return
		
		if key == QtCore.Qt.Key_P:
			self.pause()
			return
		
		if self.isPaused:
			return
		
		elif key == QtCore.Qt.Key_Q:
			self.robot.increaseLeftMotorSpeed(10)
		
		elif key == QtCore.Qt.Key_A:
			self.robot.increaseLeftMotorSpeed(-10)
		
		elif key == QtCore.Qt.Key_E:
			self.robot.increaseRightMotorSpeed(10)
		
		elif key == QtCore.Qt.Key_D:
			self.robot.increaseRightMotorSpeed(-10)
		
		else:
			super(Map, self).keyPressEvent(event)
	
	
	def timerEvent(self, event):
		
		if event.timerId() == self.timer.timerId():
			
			if self.robot is not None:
				self.robot.move()
				self.repaint()
		
		else:
			super(Map, self).timerEvent(event)
	
	
	def clearMap(self):
		self.objects = []


	def changed(self):
		return self.mapChanged


	def setChanged(self, mapChanged):
		self.mapChanged = mapChanged
		self.changedStatus.emit(bool(self.mapChanged))
	
	
	def getStatsWidget(self):
		
		widgets = []
		
		widgets.append(self.simStats)
		
		if self.robot is not None:
			widgets.append(self.robot.getStatsWidget())
	
		return widgets
	
	
	def setStatsWidget(self):
		
		widgets = []
		
		widgets.append(self.simStats)
		
		if self.robot is not None:
			widgets.append(self.robot.getStatsWidget())
		
		self.parent.setStatsWidgets(widgets)


	def placeRobot(self):
		self.mouseActionType = Map.PlaceRobotAction
		
		
	def placeTarget(self):
		self.mouseActionType = Map.PlaceTargetAction
Ejemplo n.º 2
0
class Env:
    SIZE = 500
    RETURN_IMAGES = False
    MOVE_PENALTY = 1
    ENEMY_PENALTY = 300
    FOOD_REWARD = 50
    #OBSERVATION_SPACE_VALUES = 8
    ACTION_SPACE_SIZE = 5

    def reset(self):
        self.player = Ballon("ballon", 50, 50, 1,1, 100, 1)
        self.food = Target(100,100,[100,100])
        self.food.instantiate()
        while self.food.check(self.player.x, self.player.y):
            self.food.instantiate()

        self.startdpos = [self.player.loc[0] - self.food.x, self.player.loc[1] - self.food.y]
        self.startdis = np.sqrt((self.food.x- self.player.loc[0])**2 + (self.food.y-self.player.loc[1])**2)

        self.episode_step = 0

        if self.RETURN_IMAGES:
            observation = np.array(self.get_image())
        else:
            self.dposold = [self.food.x- self.player.loc[0], self.food.y-self.player.loc[1]]
            observation = [self.dposold[0]/1920, self.dposold[1]/1080,  self.player.vel[0]/153, self.player.vel[1]/153, self.player.angvel/2.5, self.player.rot/(2*3.1415926535897932384623383)]

        return observation

    def step(self, action):
        self.episode_step += 1
        self.player.action(action)


        self.player.setVelocity()
        self.player.move()
        self.player.boundries(1920, 1080)
        if self.RETURN_IMAGES:
            new_observation = np.array(self.get_image())
        else:
            self.dpos = [self.food.x- self.player.loc[0], self.food.y-self.player.loc[1]]
            new_observation = [self.dposold[0]/1920, self.dposold[1]/1080,  self.player.vel[0]/153, self.player.vel[1]/153, self.player.angvel/2.5, self.player.rot/(2*3.1415926535897932384623383)]


        if self.food.check(self.player.loc[0], self.player.loc[1]):
            reward = self.FOOD_REWARD
        elif self.episode_step >= 2500:
            reward = 100 - (np.sqrt((self.food.x - self.player.loc[0])**2 + (self.food.y-self.player.loc[1])**2)/self.startdis)*100
        else:
            reward =  -self.MOVE_PENALTY +(np.abs(self.dposold[0])-np.abs(self.dpos[0])) + (np.abs(self.dposold[1])-np.abs(self.dpos[1]))

        done = False

        if reward == self.FOOD_REWARD or self.episode_step >= 2500:
            done = True

        self.dposold[0] = self.dpos[0]
        self.dposold[1] = self.dpos[1]

        return new_observation, reward, done

    def render(self, screen):
        self.player.draw(screen)
        self.food.draw(screen)
Ejemplo n.º 3
0
                force_left = .2
            if event.key == pygame.K_a:
                force_left = .1
            if event.key == pygame.K_z:
                force_left = -.1
        else:
            force_right = 0
            force_left = 0
    screen.fill((200, 200, 200))
    if (force_left >= 0 and force_right >= 0) or (force_left < 0
                                                  and force_right < 0):
        force_front = force_left + force_right - abs(force_left - force_right)
    elif (force_left < 0 and force_right == 0) or (force_right < 0
                                                   and force_left == 0):
        force_front = 0
    else:
        force_front = force_left + force_right  #+ abs(force_left - force_right)

    force_rot = force_left - force_right
    object.setVelocity()
    object.applyForce(input.calculateforward(object.rot, force_front),
                      force_rot)
    object.move()
    object.boundries(1920, 1080)
    target.draw(screen)
    object.draw(screen)
    clock.tick(60)
    pygame.display.update()

pygame.quit()
Ejemplo n.º 4
0
class Box():
    def __init__(self, w, h):
        pygame.init()
        self.width = w
        self.height = h
        self.target = None
        self.font = pygame.font.SysFont('comicsansms', FONT_SIZE)
        self.font_intro = pygame.font.SysFont('comicsansms', 40)
        self.bg = pygame.image.load("img/bg.jpg")  # 背景画像の取得
        self.rect_bg = self.bg.get_rect()
        self.title = pygame.image.load("img/title.png")
        self.rect_title = self.title.get_rect()
        self.tutorial = pygame.image.load("img/tutorial.png")
        self.rect_tutorial = self.tutorial.get_rect()
        self.star_guide_image = pygame.image.load("img/fukidashi.png")
        self.cutin_image = []  # 百裂肉球
        for i in range(25):
            cutin = pygame.image.load(
                "img/cutin/frame_{:02}_delay-0.1s.gif".format(i))
            self.cutin_image.append(cutin)
        self.cutin_index = 0
        self.deg = 0

    def set(self):  # 初期設定を一括して行う
        self.stage = STAGE_START
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("Cat Fighter Z")
        self.clock = pygame.time.Clock()  # 時計オブジェクト
        self.player = Player(self.screen, PLAYER_X, PLAYER_Y, 0, 0,
                             STATE_STANDING)
        self.target = Target(self.screen, TARGET_X, TARGET_Y, 0, 0,
                             STATE_STANDING)
        self.show_score()

    def show_score(self):

        h_scale = 2
        self.screen.blit(self.font.render("HP", True, WHITE),
                         [BOX_WIDTH - 40, 20])
        show_health_bar(self.screen, self.player.hp / h_scale,
                        PLAYER_MAX_HP / h_scale, (BOX_WIDTH - 150, 20))
        self.screen.blit(self.font.render("MP", True, WHITE),
                         [BOX_WIDTH - 40, 40])
        show_magic_point(self.screen, int(self.player.mp), PLAYER_MAX_MP,
                         (BOX_WIDTH - 130, 50))

        self.screen.blit(self.font.render("HP", True, WHITE), [20, 20])
        show_health_bar(self.screen, self.target.hp / h_scale,
                        ENEMY_MAX_HP / h_scale, (50, 20))
        self.screen.blit(self.font.render("MP", True, WHITE), [20, 40])
        show_magic_point(self.screen, int(self.target.mp), ENEMY_MAX_MP,
                         (70, 50))

    def run(self):
        while (self.stage != STAGE_QUIT):
            if self.stage == STAGE_START:
                self.show_intro_screen()
            elif self.stage == STAGE_TUTORIAL:
                self.show_tutorial_screen()
            elif self.stage == STAGE_RUN:
                self.show_battle_screen()
            elif self.stage == STAGE_CLEAR:
                self.show_clear_screen()
            elif self.stage == STAGE_OVER:
                self.show_gameover_screen()
            elif self.stage == STAGE_CUTIN:
                self.show_cutin_screen()

    def intro_message(self):
        text = self.font_intro.render("PRESS SPACE", True, (0, 0, 0))
        position = text.get_rect()
        position.center = (WIDTH / 2, 250)
        alpha = (math.cos(float(self.deg) / 180 * math.pi) + 1) / 2 * 255
        text.set_alpha(alpha)
        self.screen.blit(text, position)
        self.deg = (self.deg + 5) % 360

    def show_intro_screen(self):
        self.stage = STAGE_INTRO
        while (self.stage == STAGE_INTRO):
            for event in pygame.event.get():
                if event.type == pygame.QUIT: self.stage = STAGE_QUIT
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        self.stage = STAGE_TUTORIAL

            self.clock.tick(FPS)  # 毎秒の呼び出し回数に合わせて遅延
            self.intro_message()
            pygame.display.flip()
            self.screen.fill((0, 0, 0))
            self.screen.blit(self.title, self.rect_title)

    def show_tutorial_screen(self):
        while (self.stage == STAGE_TUTORIAL):
            for event in pygame.event.get():
                if event.type == pygame.QUIT: self.stage = STAGE_QUIT
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        self.stage = STAGE_RUN
                        self.clock.tick(FPS)  # 毎秒の呼び出し回数に合わせて遅延
            pygame.display.flip()
            self.screen.fill((0, 0, 0))
            self.screen.blit(self.tutorial, self.rect_tutorial)

    def show_battle_screen(self):
        while (self.stage == STAGE_RUN):  # メインループ
            if self.target.hp <= 0:
                # プレイヤーが勝った
                self.player.win()
                self.target.lose()
                self.stage = STAGE_CLEAR
                sleep(1)
                return
            if self.player.hp <= 0:
                # 敵が勝った
                self.player.lose()
                self.target.lose()
                self.stage = STAGE_OVER
                sleep(1)
                return
            enemy_direction = 1 if self.player.x < self.target.x else -1
            for event in pygame.event.get():
                # 「閉じる」ボタンを処理する
                if event.type == pygame.QUIT:
                    print("finish animation")
                    pygame.quit()
                    return

                if event.type == pygame.KEYDOWN:  # aキーで攻撃
                    if event.key == pygame.K_a:
                        self.player.shot(enemy_direction)
                    if event.key == pygame.K_s:
                        self.player.punch(enemy_direction)

            self.clock.tick(FPS)  # 毎秒の呼び出し回数に合わせて遅延

            pressed_keys = pygame.key.get_pressed()  # キー情報を取得
            if pressed_keys[pygame.K_UP]:  # 上でジャンプ
                self.player.jump(0, -15)
            if pressed_keys[pygame.K_RIGHT]:
                self.player.right()
            if pressed_keys[pygame.K_LEFT]:
                self.player.left()
            if self.player.mp == PLAYER_MAX_MP:  # 百裂肉球を表示する
                position = self.star_guide_image.get_rect()
                position.center = (WIDTH / 4 * 3 + 20, 40)
                alpha = (math.cos(float(self.deg) / 180 * math.pi) + 1) * 255
                self.star_guide_image.set_alpha(alpha)
                self.screen.blit(self.star_guide_image, position)
                self.deg = (self.deg + 3) % 360
                if pressed_keys[pygame.K_z]:  # 百裂肉球
                    self.player.mp = 0
                    self.target.hp -= 50
                    for i in range(4):
                        surface = pygame.image.load("img/explosion_small.png")
                        rect = surface.get_rect()
                        rect.center = (random.randrange(BOX_WIDTH),
                                       random.randrange(BOX_HEIGHT))
                        effect = Effect(surface, rect, 100)
                        self.player.effects.add(effect)

                        surface = pygame.image.load("img/explosion_big.png")
                        rect = surface.get_rect()
                        rect.center = (random.randrange(BOX_WIDTH),
                                       random.randrange(BOX_HEIGHT))
                        effect = Effect(surface, rect, 100)
                        self.player.effects.add(effect)
                    self.stage = STAGE_CUTIN

            # 肉球の衝突判定
            collided = pygame.sprite.spritecollideany(self.target,
                                                      self.player.bullets)
            if collided != None:
                self.target.get_attacked('SHOT')
                self.player.bullets.remove(collided)
            # 近接猫パンチとターゲットの衝突判定
            if self.player.nikukyu != None and pygame.sprite.collide_rect(
                    self.target, self.player.nikukyu):
                self.target.get_attacked('PUNCH')

            # お互いの情報を伝え合う
            self.player.set_enemy(self.target)
            self.target.set_player(self.player)

            # オブジェクトのアップデート
            self.player.update()
            self.target.update()

            # 表示の更新
            self.show_score()
            self.target.draw()
            self.player.draw()
            self.player.bullets.draw(self.screen)
            pygame.display.flip()  # パドルとボールの描画を画面に反映
            self.screen.blit(self.bg, self.rect_bg)  # 背景画像
            # self.screen.fill((0, 0, 0))  # 塗潰し:次の flip まで反映されない

    def show_cutin_screen(self):
        repeat_num = 2
        fps_scale = 3
        self.clock.tick(FPS)
        print(self.cutin_index)
        self.screen.blit(
            self.cutin_image[(self.cutin_index % (25 * fps_scale)) //
                             fps_scale],
            self.cutin_image[(self.cutin_index % (25 * fps_scale)) //
                             fps_scale].get_rect())
        self.cutin_index += 1
        pygame.display.flip()

        if self.cutin_index == 25 * fps_scale * repeat_num:
            self.cutin_index = 0
            self.stage = STAGE_RUN

    def show_clear_screen(self):
        self.clock.tick(FPS)
        pygame.display.flip()
        self.screen.fill((0, 0, 0))
        text = self.font_intro.render("CLEARED!!", True, (255, 255, 255))
        position = text.get_rect()
        position.center = (WIDTH / 2, HEIGHT / 2)
        self.screen.blit(text, position)

    def show_gameover_screen(self):
        self.clock.tick(FPS)
        pygame.display.flip()
        self.screen.fill((0, 0, 0))
        text = self.font_intro.render("GAME OVER!!", True, (255, 255, 255))
        position = text.get_rect()
        position.center = (WIDTH / 2, HEIGHT / 2)
        self.screen.blit(text, position)
Ejemplo n.º 5
0
class Trainer(object):

    def __init__(self):

        ###############
        # load config #
        ###############
        with open('trainer_config.yaml') as f:
            CONFIG = yaml.load(f)
        self.exp_type = CONFIG['experiment-type']
        self.playback_bool = CONFIG['playback-enabled']
        self.subj_id = CONFIG['subject-id']
        self.subj_dir = 'datasets/' + self.subj_id
        if self.exp_type == 'timed':
            fu.write_all_headers_timed(self)
        elif self.exp_type == 'block':
            fu.write_all_headers_block(self)

        #################
        # set constants #
        #################
        self.FRAME_RATE = 30
        self.SCREEN_WIDTH, self.SCREEN_HEIGHT = 1024, 768
        self.BG_COLOR_REG = 70,70,70
        self.BG_COLOR_REG_2 = 110,110,110
        self.BG_COLOR_REG_3 = 40,40,40
        self.SUCCESS_COLOR = 70,170,70
        self.INDICATOR_COLOR = 40,60,40
        self.INDICATOR_COLOR_2 = 30,100,30
        self.GOOD_MSG_COLOR = 160,255,160
        self.BAD_MSG_COLOR = 255,160,160
        self.A_MSG_COLOR = 160,160,255
        self.B_MSG_COLOR = 230,230,160
        self.SENSOR_INPUT_OFFSET = np.array([0.5*self.SCREEN_WIDTH,
                                             0.5*self.SCREEN_HEIGHT])
        self.NEWTONS_2_PIXEL = 200
        self.BLOCK_TIME = CONFIG['block-length']
        self.RESET_HOLD_TIME = 0.5
        self.REACH_SUCCESS_TIME = 2.
        self.NOISE_VAR_GOOD = 0.025
        if not self.playback_bool:
            self.NOISE_VAR_BAD = 10*self.NOISE_VAR_GOOD
        else:
            self.NOISE_VAR_BAD = self.NOISE_VAR_GOOD
        self.SAMPLE_PERIOD = 2.
        self.SAMPLE_FRAMES = self.SAMPLE_PERIOD*self.FRAME_RATE
        self.TRS_SHOW_UPDATE_RATE = 2
        self.TR_LIST = (0.125, .25, 0.5, 1., 2., 4.)
        self.TRS_SAMPLES_DICT = dict((tr, tr/self.SAMPLE_PERIOD)
                                     for tr in self.TR_LIST)
        self.TRS_SUCCESS_DICT = dict((tr, self.REACH_SUCCESS_TIME/tr)
                                     for tr in self.TR_LIST)
        self.BUFFER_DIST = 0.075*self.SCREEN_HEIGHT
        self.START_DIST = self.BUFFER_DIST
        self.GAME_ORIGIN = (0.5*self.SCREEN_WIDTH-0.5*self.SCREEN_HEIGHT,
                            self.SCREEN_HEIGHT)
        self.START_COORDS = np.array([self.GAME_ORIGIN[0]+self.BUFFER_DIST,
                                      self.GAME_ORIGIN[1]-self.BUFFER_DIST])
        self.TARGET_DIST = (0.3*self.SCREEN_HEIGHT,
                            0.8*self.SCREEN_HEIGHT)
        self.ERROR_CUTOFF = self.TARGET_DIST[0] - self.START_DIST
        self.MIN_ERROR_METRIC = 0.1
        self.SS_ERROR_METRIC = 0.9
        self.MIN_SUCCESS_SCORE = 0.7
        self.TARGET_RAD = (self.ERROR_CUTOFF*
                           (1-(self.MIN_SUCCESS_SCORE-self.MIN_ERROR_METRIC)
                            /(self.SS_ERROR_METRIC-self.MIN_ERROR_METRIC)))
        if SENSOR_ACTIVE:
            self.daq = Pydaq('Dev1/ai0:1', self.FRAME_RATE)
        self.VISIBLE_TRIALS = CONFIG['visible-trials']
        self.INVISIBLE_TRIALS = CONFIG['invisible-trials']
        self.NUM_TRIALS = self.VISIBLE_TRIALS
        self.TRIAL_TYPES = 8

        ####################################################
        # start pygame and initialize default game objects #
        ####################################################
        pygame.init()
        pygame.mouse.set_visible(not pygame.mouse.set_visible)
        self.clock = pygame.time.Clock()
        if CONFIG['fullscreen']:
            self.screen = pygame.display.set_mode(
                            (self.SCREEN_WIDTH, self.SCREEN_HEIGHT),
                             pygame.FULLSCREEN)
        else:
            self.screen = pygame.display.set_mode(
                            (self.SCREEN_WIDTH, self.SCREEN_HEIGHT))

        ##################################
        # initialize custom game objects #
        ##################################
        self.cursor = Cursor(self.screen)


        self.target = Target(self.screen,
                             self.FRAME_RATE,
                             self.TARGET_RAD,
                             self.ERROR_CUTOFF,
                             self.MIN_ERROR_METRIC,
                             self.SS_ERROR_METRIC,
                             self.MIN_SUCCESS_SCORE,
                             self.START_COORDS,
                             self.TARGET_DIST)

        self.therm = Thermometer(self.screen,
                                 self.MIN_ERROR_METRIC,
                                 self.MIN_SUCCESS_SCORE,
                                 self.SS_ERROR_METRIC)

        self.INDIC_RAD_MAX = self.START_DIST-self.cursor.RAD-2
        self.target.target_lims = self.TARGET_DIST
        self.timers = {}
        self.init_timers()
        self.set_tr(2.)
        self.trial_count = 0
        self.trial_type_count = 1
        self.next_dof = 1
        self.set_dof(self.next_dof)
        self.next_ir = 'impulse'
        self.next_visible = True
        self.set_trial()

        ######################
        # set game variables #
        ######################
        self.screen_mid = np.array([0.5*self.screen.get_width(),
                                    0.5*self.screen.get_height()])
        self.bg_color = self.BG_COLOR_REG
        self.bg_color_alt = self.BG_COLOR_REG_2
        self.bg_color_alt_2 = self.BG_COLOR_REG_3
        self.indicator_color = self.INDICATOR_COLOR
        self.indicator_rad = 0*self.START_DIST
        self.success_color = self.SUCCESS_COLOR
        self.input_mode = 'mouse'
        self.input_pos = np.array([0.0,0.0])
        self.training_mode = True

        #######################
        # set block variables #
        #######################
        self.NUM_BLOCK_TRIALS = CONFIG['num-block-trials'] 
        self.next_target = 'new'
        self.first_feedback = CONFIG['first-trial-feedback'] 
        self.first_noise = CONFIG['first-trial-noise']
        self.next_feedback = self.first_feedback
        self.next_noise = self.first_noise
        self.set_noise()
        self.BLOCK_TRS = self.BLOCK_TIME/self.tr
        self.block_nfb_buffer = np.zeros(self.BLOCK_TRS)
        self.block_tr_count = 0
        self.total_block_count = 0
        self.trial_block_count = 0

        ##########################
        # set playback variables #
        ##########################
        self.TIME_SHIFT = 6
        self.PLAYBACK_TRS = self.BLOCK_TRS + self.TIME_SHIFT/self.tr
        self.EXTRA_TRS = 2
        self.playback_buffer_length = (self.BLOCK_TIME
                                       + self.EXTRA_TRS)*self.FRAME_RATE
        self.move_counter = 0
        self.reset_playback_buffers()

    def reset_playback_buffers(self):
        self.playback_counter = 0
        self.playback_time_buffer = np.zeros(self.playback_buffer_length)
        self.playback_pos_buffer = np.zeros((2,self.playback_buffer_length))
        self.playback_nfb_buffer = np.zeros(self.playback_buffer_length)
        self.playback_nfb_points = np.zeros(self.PLAYBACK_TRS)


    def get_pos(self):
        if self.input_mode=='mouse' or not(SENSOR_ACTIVE):
            return pygame.mouse.get_pos()
        else:
            f_out = self.daq.get_force()
            return (self.SENSOR_INPUT_OFFSET[0]+self.NEWTONS_2_PIXEL*f_out[0], 
                    self.SENSOR_INPUT_OFFSET[1]+self.NEWTONS_2_PIXEL*f_out[1])


    def set_trial(self):
        self.set_dof(self.next_dof)
        self.target.set_fb_mode(self.next_ir)
        self.set_training_mode(self.next_visible)


    def set_noise(self):
        if self.next_noise == 'good':
            self.noise_var = self.NOISE_VAR_GOOD
        elif self.next_noise == 'bad':
            self.noise_var = self.NOISE_VAR_BAD


    def set_training_mode(self, bool_arg):
        self.training_mode = bool_arg


    def set_tr(self, tr):
        if tr == 0.125:
            self.tr = 0.125
            self.timers['tr'] = self.timers['tr_8hz']
        elif tr == 0.25:
            self.tr = 0.25
            self.timers['tr'] = self.timers['tr_4hz']
        elif tr == 0.5:
            self.tr = 0.5
            self.timers['tr'] = self.timers['tr_2hz']
        elif tr == 1:
            self.tr = 1.
            self.timers['tr'] = self.timers['tr_1hz']
        elif tr == 2:
            self.tr = 2.
            self.timers['tr'] = self.timers['tr_p5hz']
        elif tr == 4:
            self.tr = 4.
            self.timers['tr'] = self.timers['tr_p25hz']


    def init_timers(self):
        self.timers['signal'] = Timer(self.SAMPLE_PERIOD)
        self.timers['tr_8hz'] = Timer(self.TR_LIST[0])
        self.timers['tr_4hz'] = Timer(self.TR_LIST[1])
        self.timers['tr_2hz'] = Timer(self.TR_LIST[2])
        self.timers['tr_1hz'] = Timer(self.TR_LIST[3])
        self.timers['tr_p5hz'] = Timer(self.TR_LIST[4])
        self.timers['tr_p25hz'] = Timer(self.TR_LIST[5])
        self.timers['tr'] = self.timers['tr_2hz']
        self.timers['reach'] = Timer(0)
        self.timers['reach_hold'] = Timer(self.REACH_SUCCESS_TIME)
        self.timers['block'] = Timer(self.BLOCK_TIME)
        self.timers['reset_hold'] = Timer(self.RESET_HOLD_TIME)


    def reset_all_timers(self):
        for k,t in self.timers.iteritems():
            t.reset()


    def check_input(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.quit()
                elif event.key == pygame.K_0:
                    self.daq.set_volts_zero()
                elif event.key == pygame.K_f:
                    if self.dof == 1:
                        self.set_dof(2)
                    elif self.dof == 2:
                        self.set_dof(1)
                elif event.key == pygame.K_b:
                    self.target.set_new_target()
                elif event.key == pygame.K_v:
                    self.training_mode = not(self.training_mode)
                elif event.key == pygame.K_c:
                    self.target.set_fb_mode('hrf')
                elif event.key == pygame.K_x:
                    self.target.set_fb_mode('impulse')
                elif event.key == pygame.K_m:
                    if self.input_mode == 'mouse':
                        self.input_mode = 'sensor'
                    elif self.input_mode == 'sensor':
                        self.input_mode = 'mouse'

    def run_timed(self):
        ###########################################
        # main loop for time-to-target experiment #
        ###########################################
        while True:
            time_passed = self.clock.tick_busy_loop(self.FRAME_RATE)
            self.check_input()
            self.input_pos = self.get_pos()
            self.cursor.update(self.input_pos)
            self.target.update(self.cursor.pos)


            if not(self.timers['reset_hold'].time_limit_hit):
                gr.check_in_start(self, time_passed)
                self.target.draw_bool = True
            elif not(self.cursor.has_left):
                gr.check_if_left(self)
                self.target.draw_bool = False
            elif self.training_mode:
                self.target.draw_bool = True
            else:
                self.target.draw_bool = False

            if self.cursor.has_left:
                gr.frame_based_updates_timed(self)
                self.timers['signal'].update(time_passed)
                self.timers['tr'].update(time_passed)
                if self.timers['signal'].time_limit_hit:
                    gr.signal_based_updates(self)
                    if self.timers['tr'].time_limit_hit:
                        gr.tr_based_updates(self)

            self.draw_background()
            self.therm.draw(self.cursor.has_left,
                            self.target.error_metric)
            self.target.draw()
            if (self.trial_count == 0
                    and not self.cursor.has_left):
                self.draw_instructions_timed()
            self.cursor.draw()
            pygame.display.flip()

    def run_block(self):
        ###########################################
        # main loop for block feedback experiment #
        ###########################################
        self.target.draw_bool = False 
        if self.playback_bool:
            self.set_dof(2)
        else:
            self.set_dof(1)
        self.target.set_fb_mode('hrf')

        while True:
            time_passed = self.clock.tick_busy_loop(self.FRAME_RATE)
            self.check_input()
            self.input_pos = self.get_pos()
            self.cursor.update(self.input_pos)
            self.target.update(self.cursor.pos)


            if not(self.timers['reset_hold'].time_limit_hit):
                gr.check_in_start(self, time_passed)
                if self.next_target == 'new':
                    self.target.draw_bool = True
            elif not(self.cursor.has_left):
                gr.check_if_left(self)
                self.target.draw_bool = False
            # debugging
            # self.target.draw_bool = True

            if self.cursor.has_left:
                gr.frame_based_updates_block(self)
                self.timers['signal'].update(time_passed)
                self.timers['tr'].update(time_passed)
                self.timers['block'].update(time_passed)
                if self.timers['signal'].time_limit_hit:
                    gr.signal_based_updates(self)
                    if self.timers['tr'].time_limit_hit:
                        gr.tr_based_updates(self)
                        if self.timers['block'].time_limit_hit:
                            gr.block_based_updates(self)

            self.draw_background()
            therm_draw_bool = ((self.cursor.has_left and
                                self.next_feedback == 'continuous')
                               or (self.total_block_count > 0 
                                   and not self.cursor.has_left))
            score = self.target.error_metric
            self.therm.draw(therm_draw_bool,
                            score)
            self.target.draw()
            if not self.cursor.has_left:
                self.draw_instructions_block()
            else:
                self.therm.set_score_color('norm')
            self.cursor.draw()
            pygame.display.flip()

    def run_playback(self):
        while self.move_counter > 0:
            time_passed = self.clock.tick_busy_loop(self.FRAME_RATE)
            self.check_input()
            self.cursor.update(self.playback_pos_buffer[:,
                                                        self.playback_counter])
            self.indicator_rad = int(self.INDIC_RAD_MAX*(
                                     self.playback_time_buffer[self.playback_counter]
                                     /float(self.timers['block'].MAX_TIME)))
            self.draw_background()
            self.therm.draw(True,
                            self.playback_nfb_buffer[self.playback_counter])
            # debugging
            # self.target.draw()
            self.cursor.draw()
            pygame.display.flip()
            self.move_counter -= 1
            self.playback_counter += 1

    def set_dof(self, dof):
        self.dof = dof
        self.cursor.set_dof(dof)
        self.target.set_dof(dof)

    def draw_background(self):
        self.screen.fill(self.bg_color_alt_2)
        gr.cap_indicator_rad(self)
        self.draw_play_area()
        if self.indicator_rad > 0:
            self.draw_indicator()

    def draw_instructions_block(self):
        if self.next_target == 'new':
            top_msg = 'New target'
            top_color = self.GOOD_MSG_COLOR
        else:
            top_msg = 'Same target'
            top_color = self.BAD_MSG_COLOR

        if self.next_feedback == 'continuous':
            mid_msg = 'Continuous feedback'
            mid_color = self.A_MSG_COLOR
        else:
            mid_msg = 'Intermittent feedback'
            mid_color = self.B_MSG_COLOR

        if self.next_noise == 'good':
            btm_msg = 'Good signal'
            btm_color = self.A_MSG_COLOR
        else:
            btm_msg = 'Bad signal'
            btm_color = self.B_MSG_COLOR

        gg.draw_msg(self.screen, top_msg,
                    color=top_color,
                    center=(self.screen_mid[0],
                            self.screen_mid[1]-75))
        gg.draw_msg(self.screen, mid_msg,
                    color=mid_color,
                    center=(self.screen_mid[0],
                            self.screen_mid[1]))
        if not self.playback_bool:
            gg.draw_msg(self.screen, btm_msg,
                        color=btm_color,
                        center=(self.screen_mid[0],
                                self.screen_mid[1]+75))

    def draw_instructions_timed(self):
        if self.next_visible:
            top_msg = 'Target visible'
            top_color = self.GOOD_MSG_COLOR
        else:
            top_msg = 'Target invisible'
            top_color = self.BAD_MSG_COLOR
        if self.next_ir == 'impulse':
            btm_msg = 'Instant feedback'
            btm_color = self.GOOD_MSG_COLOR
        else:
            btm_msg = 'Delayed feedback'
            btm_color = self.BAD_MSG_COLOR
        gg.draw_msg(self.screen, top_msg,
                    color=top_color,
                    center=(self.screen_mid[0],
                            self.screen_mid[1]-50))
        gg.draw_msg(self.screen, btm_msg,
                    color=btm_color,
                    center=(self.screen_mid[0],
                            self.screen_mid[1]+50))

    def draw_play_area(self):
        if self.dof == 1:
            gg.draw_center_rect(self.screen,
                                self.SCREEN_HEIGHT, self.SCREEN_HEIGHT,
                                self.bg_color,
                                self.screen_mid[0], self.screen_mid[1])

            gg.draw_center_rect(self.screen, 
                                self.TARGET_DIST[1]-self.TARGET_DIST[0],
                                self.SCREEN_HEIGHT,
                                self.bg_color_alt,
                                (self.TARGET_DIST[0]
                                 +0.5*(self.TARGET_DIST[1]
                                       -self.TARGET_DIST[0])
                                 + self.START_COORDS[0]),
                                self.screen_mid[1])

            gg.draw_center_rect(self.screen,
                                2*(self.START_DIST-self.cursor.RAD),
                                self.SCREEN_HEIGHT,
                                self.bg_color_alt_2,
                                self.START_COORDS[0],  self.screen_mid[1])

        elif self.dof == 2:
            gg.draw_center_rect(self.screen,
                                self.SCREEN_HEIGHT, self.SCREEN_HEIGHT,
                                self.bg_color,
                                self.screen_mid[0], self.screen_mid[1])

            gg.draw_filled_aacircle(self.screen,
                                    self.TARGET_DIST[1],
                                    self.bg_color_alt,
                                    self.START_COORDS[0], self.START_COORDS[1])

            gg.draw_filled_aacircle(self.screen,
                                    self.TARGET_DIST[0],
                                    self.bg_color,
                                    self.START_COORDS[0], self.START_COORDS[1])

            gg.draw_center_rect(self.screen,
                                self.SCREEN_HEIGHT, 2*self.BUFFER_DIST,
                                self.bg_color,
                                self.screen_mid[0], self.GAME_ORIGIN[1])
            gg.draw_center_rect(self.screen,
                                2*self.BUFFER_DIST, self.SCREEN_HEIGHT,
                                self.bg_color,
                                self.GAME_ORIGIN[0], self.screen_mid[1])

            gg.draw_filled_aacircle(self.screen,
                                    self.START_DIST-self.cursor.RAD,
                                    self.bg_color_alt_2,
                                    self.START_COORDS[0], self.START_COORDS[1])

    def draw_indicator(self):
        if self.dof == 1:
            gg.draw_center_rect(self.screen,
                                2*self.indicator_rad, self.SCREEN_HEIGHT,
                                self.indicator_color,
                                self.START_COORDS[0], self.screen_mid[1])
        elif self.dof == 2:
            gg.draw_filled_aacircle(self.screen,
                                    self.indicator_rad,
                                    self.indicator_color,
                                    self.START_COORDS[0], self.START_COORDS[1])


    def quit(self):
        sys.exit()
Ejemplo n.º 6
0
    # Creature wins if it is closest to target
    for i in range(len(creatures)):
        distance = math.sqrt(abs(creatures[i].get_loc()[1] - target.get_loc()[1]) ** 2 +
                             abs(creatures[i].get_loc()[0] - target.get_loc()[0]) ** 2)
        if distance < best_distance:
            best_distance = distance
            best = i

    # Breed
    for i in range(len(creatures)):
        if i != best:
            creatures[i].breedwith(creatures[best])

    # Draw the target
    target.draw()

    dislpay_instructions()

    # Update and draw creature
    for i in range(len(creatures)):
        creatures[i].update()

    # show only the winner or the entire population
    if show_best:
        creatures[best].draw()
    else:
        for i in range(len(creatures)):
            creatures[i].draw()

    # Event handling