code: def frame_step(self, input_actions):
      pygame.event.pump()
  
      reward = 0.1
      terminal = False
  
      if sum(input_actions) != 1:
          raise ValueError("Multiple input actions!")
  
      # input_actions[0] == 1: do nothing
      # input_actions[1] == 1: flap the bird
      if input_actions[1] == 1:
          if self.playery > -2 * PLAYER_HEIGHT:
              self.playerVelY = self.playerFlapAcc
              self.playerFlapped = True
              # SOUNDS['wing'].play()
  
      # check for score
      playerMidPos = self.playerx + PLAYER_WIDTH / 2
      for pipe in self.upperPipes:
          pipeMidPos = pipe["x"] + PIPE_WIDTH / 2
          if pipeMidPos <= playerMidPos < pipeMidPos + 4:
              self.score += 1
              # SOUNDS['point'].play()
              reward = 1
  
      # playerIndex basex change
      if (self.loopIter + 1) % 3 == 0:
          self.playerIndex = next(PLAYER_INDEX_GEN)
      self.loopIter = (self.loopIter + 1) % 30
      self.basex = -((-self.basex + 100) % self.baseShift)
  
      # player's movement
      if (
          self.playerVelY < self.playerMaxVelY
          and not self.playerFlapped
      ):
          self.playerVelY += self.playerAccY
      if self.playerFlapped:
          self.playerFlapped = False
      self.playery += min(
          self.playerVelY, BASEY - self.playery - PLAYER_HEIGHT
      )
      if self.playery < 0:
          self.playery = 0
  
      # move pipes to left
      for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes):
          uPipe["x"] += self.pipeVelX
          lPipe["x"] += self.pipeVelX
  
      # add new pipe when first pipe is about to touch left of screen
      if 0 < self.upperPipes[0]["x"] < 5:
          newPipe = getRandomPipe()
          self.upperPipes.append(newPipe[0])
          self.lowerPipes.append(newPipe[1])
  
      # remove first pipe if its out of the screen
      if self.upperPipes[0]["x"] < -PIPE_WIDTH:
          self.upperPipes.pop(0)
          self.lowerPipes.pop(0)
  
      # check if crash here
      isCrash = checkCrash(
          {
              "x": self.playerx,
              "y": self.playery,
              "index": self.playerIndex,
          },
          self.upperPipes,
          self.lowerPipes,
      )
      if isCrash:
          # SOUNDS['hit'].play()
          # SOUNDS['die'].play()
          terminal = True
          self.__init__()
          reward = -1
  
      # draw sprites
      SCREEN.blit(IMAGES["background"], (0, 0))
  
      for uPipe, lPipe in zip(self.upperPipes, self.lowerPipes):
          SCREEN.blit(IMAGES["pipe"][0], (uPipe["x"], uPipe["y"]))
          SCREEN.blit(IMAGES["pipe"][1], (lPipe["x"], lPipe["y"]))
  
      SCREEN.blit(IMAGES["base"], (self.basex, BASEY))
      # print score so player overlaps the score
      # showScore(self.score)
      SCREEN.blit(
          IMAGES["player"][self.playerIndex],
          (self.playerx, self.playery),
      )
  
      image_data = pygame.surfarray.array3d(
          pygame.display.get_surface()
      )
      pygame.display.update()
      # print ("FPS" , FPSCLOCK.get_fps())
      FPSCLOCK.tick(FPS)
      # print self.upperPipes[0]['y'] + PIPE_HEIGHT - int(BASEY * 0.2)
      return image_data, reward, terminal
  
file_path: CNTK/Examples/ReinforcementLearning/FlappingBirdWithKeras/game/wrapped_flappy_bird.py
imports: import numpy
  import sys
  import random
  from game import flappy_bird_utils
  import pygame
  import pygame.surfarray
  from pygame.locals import *
  from itertools import cycle
label_desc: Use image node_id 2 for calling the GameState obj's underlying member method code with example usage: obj.frame_step(input_actions) and returns: image_data,  reward,  terminal