Example #1
0
def ml_loop():
    """
    The main loop for the ml process
    """

    # === The execution order of the loop === #
    # 1. Put the initialization code here

    # 2. Inform the game process that the ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1 Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2 If the game is over
        if scene_info["status"] == "GAME_OVER":
            # 3.2.1 Do some reset works if needed.

            # 3.2.2 Inform the game process that ml process
            #       is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Process the information received here

        # 3.4 Generate a command for this game information and
        #     send to the game process.
        comm.send_to_game({"frame": scene_info["frame"], "command": "RIGHT"})
Example #2
0
def ml_loop(side: str):
    init_pygame()

    print("Invisible joystick is used. "
          "Press Enter to start the {} ml process.".format(side))
    while wait_enter_key():
        pass

    comm.ml_ready()

    while True:
        scene_info = comm.recv_from_game()

        if scene_info["status"] != "GAME_ALIVE":
            comm.ml_ready()
            continue

        key_pressed_list = pygame.key.get_pressed()
        if key_pressed_list[pygame.K_LEFT]:
            cmd = "MOVE_LEFT"
        elif key_pressed_list[pygame.K_RIGHT]:
            cmd = "MOVE_RIGHT"
        elif key_pressed_list[pygame.K_PERIOD]:
            cmd = "SERVE_TO_LEFT"
        elif key_pressed_list[pygame.K_SLASH]:
            cmd = "SERVE_TO_RIGHT"
        else:
            cmd = "NONE"

        comm.send_to_game({"frame": scene_info["frame"], "command": cmd})

        pygame.event.pump()
Example #3
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process

    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```

    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "MOVE_LEFT"
            })
Example #4
0
def ml_loop():
    """
    The main loop of the machine learning process

    This loop is run in a separate process, and communicates with the game process.

    Note that the game process won't wait for the ml process to generate the
    GameInstruction. It is possible that the frame of the GameInstruction
    is behind of the current frame in the game process. Try to decrease the fps
    to avoid this situation.
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here.
    ball_served = False

    # 2. Inform the game process that ml process is ready before start the loop.
    comm.ml_ready()

    # 3. Start an endless loop.
    while True:
        # 3.1. Receive the scene information sent from the game process.
        scene_info = comm.recv_from_game()

        # 3.2. If the game is over or passed, the game process will reset
        #      the scene and wait for ml process doing resetting job.
        if (scene_info["status"] == "GAME_OVER"
                or scene_info["status"] == "GAME_PASS"):
            # Do some stuff if needed
            ball_served = False

            # 3.2.1. Inform the game process that ml process is ready
            comm.ml_ready()
            continue

        # 3.3. Put the code here to handle the scene information

        # 3.4. Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "MOVE_LEFT"
            })
Example #5
0
def ml_loop(side: str):
    print("For {}".format(side))
    comm.ml_ready()

    while True:
        scene_info = comm.recv_from_game()

        if (scene_info["status"] == "GAME_1P_WIN"
                or scene_info["status"] == "GAME_2P_WIN"):
            comm.ml_ready()
            continue

        comm.send_to_game({
            "frame": scene_info["frame"],
            "command": "MOVE_LEFT"
        })
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """
    H = 200
    D = 8
    resume = False # resume from previous checkpoint?

    if resume:
        model = pickle.load(open('save.p', 'rb'))
    else:
        model = {}
        model['W1'] = np.random.randn(H,D) / np.sqrt(D) # "Xavier" initialization
        model['W2'] = np.random.randn(H) / np.sqrt(H)

    grad_buffer = { k : np.zeros_like(v) for k,v in model.items() } # update buffers that add up gradients over a batch
    rmsprop_cache = { k : np.zeros_like(v) for k,v in model.items() } # rmsprop memory

    xs,hs,dlogps,drs = [],[],[],[]
    running_reward = None
    reward_sum = 0
    episode_number = 0

    batch_size = 10 # every how many episodes to do a param update?
    learning_rate = 1e-4
    gamma = 0.99 # discount factor for reward
    decay_rate = 0.99 # decay factor for RMSProp leaky sum of grad^2

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def sigmoid(x): 
        return 1.0 / (1.0 + np.exp(-x)) # sigmoid "squashing" function to interval [0,1]

    def getObs(player):
        observation = []
        observation.append(scene_info['ball'][0])
        observation.append(scene_info['ball'][1])
        observation.append(scene_info['ball_speed'][0])
        observation.append(scene_info['ball_speed'][1])
        observation.append(scene_info['blocker'][0])
        observation.append(scene_info['blocker'][1])
        if player == '1P':
            observation.append(scene_info['platform_1P'][0])
            observation.append(scene_info['platform_1P'][1])
        if player == '2P':
            observation.append(scene_info['platform_2P'][0])
            observation.append(scene_info['platform_2P'][1])
        observation = np.array(observation)
        return observation

    def discount_rewards(r):
        """ take 1D float array of rewards and compute discounted reward """
        discounted_r = np.zeros_like(r)
        running_add = 0
        for t in reversed(range(0, r.size)):
            if r[t] != 0: running_add = 0 # reset the sum, since this was a game boundary (pong specific!)
            #print(r[t])
            running_add = running_add * gamma + r[t]

            discounted_r[t] = running_add
        return discounted_r

    def policy_backward(eph, epdlogp):
        """ backward pass. (eph is array of intermediate hidden states) """
        dW2 = np.dot(eph.T, epdlogp).ravel()
        dh = np.outer(epdlogp, model['W2'])
        dh[eph <= 0] = 0 # backpro prelu
        dW1 = np.dot(dh.T, epx)
        return {'W1':dW1, 'W2':dW2}

    def rl(player):
        observation = getObs(player)
        aprob, h = policy_forward(observation)
        action = 2 if np.random.uniform() < aprob else 3
        # record various intermediates (needed later for backprop)
        xs.append(x) # observation
        hs.append(h) # hidden state
        y = 1 if action == 2 else 0 # a "fake label"
        dlogps.append(y - aprob) # grad that encourages the action that was taken to be taken (see http://cs231n.github.io/neural-networks-2/#losses if confused)
        
        if scene_info['status'] == 'GAME_ALIVE':
            reward = 0
            done = False
        elif scene_info['status'] == 'GAME_1P_WIN':
            reward = 2
            done = True
        elif scene_info['status'] == 'GAME_DRAW':
            reward = 1
            done = True
        else:
            reward = -1
            done = True

        reward_sum += reward
        drs.append(reward)

        if done: # an episode finished
            episode_number += 1

            # stack together all inputs, hidden states, action gradients, and rewards for this episode
            epx = np.vstack(xs)
            eph = np.vstack(hs)
            epdlogp = np.vstack(dlogps)
            epr = np.vstack(drs)
            xs,hs,dlogps,drs = [],[],[],[] # reset array memory

            # compute the discounted reward backwards through time
            discounted_epr = discount_rewards(epr)
            # standardize the rewards to be unit normal (helps control the gradient estimator variance)
            discounted_epr -= np.mean(discounted_epr)
            discounted_epr /= np.std(discounted_epr)

            epdlogp *= discounted_epr # modulate the gradient with advantage (PG magic happens right here.)
            grad = policy_backward(eph, epdlogp)
            for k in model: grad_buffer[k] += grad[k] # accumulate grad over batch
            # perform rmsprop parameter update every batch_size episodes
            if episode_number % batch_size == 0:
                for k,v in model.items():
                    g = grad_buffer[k] # gradient
                    rmsprop_cache[k] = decay_rate * rmsprop_cache[k] + (1 - decay_rate) * g**2
                    model[k] += learning_rate * g / (np.sqrt(rmsprop_cache[k]) + 1e-5)
                    grad_buffer[k] = np.zeros_like(v) # reset batch gradient buffer

            # boring book-keeping
            running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01
            #print('resetting env. episode reward total was %f. running mean: %f' % (reward_sum, running_reward))
            if episode_number % 100 == 0: pickle.dump(model, open('save.p', 'wb'))
            reward_sum = 0

        #if reward != 0: # Pong has either +1 or -1 reward exactly when game ends.
            #print(('ep %d: game finished, reward: %f' % (episode_number, reward)) + ('' if reward == -1 else ' !!!!!!!!'))

        

        
    def policy_forward(x):
        h = np.dot(model['W1'], x)
        h[h<0] = 0 # ReLU nonlinearity
        logp = np.dot(model['W2'], h)
        p = sigmoid(logp)
        return p, h # return probability of taking action 2, and hidden state
    

    def move_to(player, pred) : #move platform to predicted position to catch ball 
        if player == '1P':
            if scene_info["platform_1P"][0]+20  > (pred-10) and scene_info["platform_1P"][0]+20 < (pred+10): return 0 # NONE
            elif scene_info["platform_1P"][0]+20 <= (pred-10) : return 1 # goes right
            else : return 2 # goes left
        else :
            if scene_info["platform_2P"][0]+20  > (pred-10) and scene_info["platform_2P"][0]+20 < (pred+10): return 0 # NONE
            elif scene_info["platform_2P"][0]+20 <= (pred-10) : return 1 # goes right
            else : return 2 # goes left

    def ml_loop_for_1P(): 
        if scene_info['status'] == 'GAME_ALIVE':
            reward = 0
        elif scene_info['status'] == 'GAME_1P_WIN':
            reward = 2
        elif scene_info['status'] == 'GAME_DRAW':
            reward = 1
        else:
            reward = -1
        
        #print(reward)

        if scene_info["ball_speed"][1] > 0 : # 球正在向下 # ball goes down
            x = ( scene_info["platform_1P"][1]-scene_info["ball"][1] ) // scene_info["ball_speed"][1] # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x)  # 預測最終位置 # pred means predict ball landing site 
            bound = pred // 200 # Determine if it is beyond the boundary
            if (bound > 0): # pred > 200 # fix landing position
                if (bound%2 == 0) : 
                    pred = pred - bound*200                    
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) : # pred < 0
                if (bound%2 ==1) :
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '1P',pred = pred)
        else : # 球正在向上 # ball goes up
            return move_to(player = '1P',pred = 100)



    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0 : 
            return move_to(player = '2P',pred = 100)
        else : 
            x = ( scene_info["platform_2P"][1]+30-scene_info["ball"][1] ) // scene_info["ball_speed"][1] 
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x) 
            bound = pred // 200 
            if (bound > 0):
                if (bound%2 == 0):
                    pred = pred - bound*200 
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) :
                if bound%2 ==1:
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '2P',pred = pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    count = 0
    _score = [0,0]
    _game_over_score = 11
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.


        # 3.3 Put the code here to handle the scene information
        
        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({"frame": scene_info["frame"], "command": "SERVE_TO_LEFT"})
            ball_served = True
        else:
            if side == "1P":
                observation = getObs("1P")
                aprob, h = policy_forward(observation)
                action = 2 if np.random.uniform() < aprob else 3

                #print('action' + str(action))
                #print('aprob' + str(aprob))
                #print('a' + str(np.random.uniform()))

                
                if action == 2:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                else:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})


                # record various intermediates (needed later for backprop)
                xs.append(observation) # observation
                hs.append(h) # hidden state
                y = 1 if action == 2 else 0 # a "fake label"
                dlogps.append(y - aprob) # grad that encourages the action that was taken to be taken (see http://cs231n.github.io/neural-networks-2/#losses if confused)
                
                if scene_info['status'] == 'GAME_ALIVE':
                    reward = 0
                    done = False
                elif scene_info['status'] == 'GAME_1P_WIN':
                    reward = 2
                    _score[0] += 1
                elif scene_info['status'] == 'GAME_DRAW':
                    reward = 1
                    _score[0] += 1
                    _score[1] += 1
                else:
                    reward = -1
                    _score[1] += 1
  
                if _score[0] == _game_over_score or _score[1] == _game_over_score:
                    done = True
                else:
                    done = False

                reward_sum += reward
                drs.append(reward)

                if done: # an episode finished
                    episode_number += 1
                    _score = [0,0]
                    # stack together all inputs, hidden states, action gradients, and rewards for this episode
                    epx = np.vstack(xs)
                    eph = np.vstack(hs)
                    epdlogp = np.vstack(dlogps)
                    epr = np.vstack(drs)
                    xs,hs,dlogps,drs = [],[],[],[] # reset array memory


                    # compute the discounted reward backwards through time
                    discounted_epr = discount_rewards(epr)
                    discounted_epr = discounted_epr.astype('float')
                    # standardize the rewards to be unit normal (helps control the gradient estimator variance)
                    
                    discounted_epr -= np.mean(discounted_epr).astype('float')
                    discounted_epr /= np.std(discounted_epr).astype('float')

                    epdlogp *= discounted_epr # modulate the gradient with advantage (PG magic happens right here.)
                    grad = policy_backward(eph, epdlogp)
                    for k in model: grad_buffer[k] += grad[k] # accumulate grad over batch
                    # perform rmsprop parameter update every batch_size episodes
                    if episode_number % batch_size == 0:
                        for k,v in model.items():
                            g = grad_buffer[k] # gradient
                            rmsprop_cache[k] = decay_rate * rmsprop_cache[k] + (1 - decay_rate) * g**2
                            model[k] += learning_rate * g / (np.sqrt(rmsprop_cache[k]) + 1e-5)
                            grad_buffer[k] = np.zeros_like(v) # reset batch gradient buffer

                    # boring book-keeping
                    running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01
                    print('resetting env. episode reward total was %f. running mean: %f' % (reward_sum, running_reward))
                    if episode_number % 100 == 0: pickle.dump(model, open('save.p', 'wb'))
                    reward_sum = 0

                if reward != 0: # Pong has either +1 or -1 reward exactly when game ends.
                    print(('ep %d: game finished, reward: %f' % (episode_number, reward)) + ('' if reward == -1 else ' !!!!!!!!'))
                #command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()
                if command == 0:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "NONE"})
                elif command == 1:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                else :
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})
            


        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue
Example #7
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process

    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```

    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        cur = [0, 0]  # a,b
        cur = list(scene_info["ball"])
        vel = list(scene_info["ball_speed"])
        plat1 = list(scene_info["platform_1P"])
        plat2 = list(scene_info["platform_2P"])
        #block = list(scene_info["blocker"])

        if (vel[0] == 0):
            m = 1
        else:
            m = vel[1] / vel[0]  #斜率(vy/vx)

        point1 = cur[0] + ((420 - cur[1]) / m)  #1P的落點
        point2 = cur[0] - ((cur[1] - 80) / m)  #2P的落點
        #point1c = [100,260]
        #point2c = [100,240]

        #print(cur)
        #print(vel)

        if (vel[1] > 0 and cur[1] > 110):
            point1 = point1_down(point1)
        elif (vel[1] < 0 and cur[1] > 260):
            point1 = point1_up(cur, m)
        elif (vel[1] < 0 and cur[1] < 260):
            point1 = 100

        print(point1)

        #ml_loop_for_1P(plat1, point1)

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            #comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})
            if (vel[1] == 0):
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            else:
                if (plat1[0] + 20 > point1):
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_LEFT"
                    })
                elif (plat1[0] + 20 < point1):
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_RIGHT"
                    })
                else:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "NONE"
                    })
Example #8
0
def ml_loop(side: str):

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    filename = path.join(path.dirname(__file__), 'save', 'NORMAL_model.pickle')
    with open(filename, 'rb') as file:
        clf = pickle.load(file)

    def get_direction(speed_x, speed_y):
        if (speed_x >= 0 and speed_y >= 0):
            return 0
        elif (speed_x > 0 and speed_y < 0):
            return 1
        elif (speed_x < 0 and speed_y > 0):
            return 2
        elif (speed_x < 0 and speed_y < 0):
            return 3
    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        feature=[]
        feature.append(scene_info["ball"][0])
        feature.append(scene_info["ball"][1])
        feature.append(scene_info["platform_1P"][0]+20)

        feature.append(scene_info["ball_speed"][0])
        feature.append(scene_info["ball_speed"][1])

        feature.append(get_direction(feature[3],feature[4]))


        feature=np.array(feature)
        feature = feature.reshape((-1,6))
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] !="GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False
            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            #comm.send_instruction(scene_info.frame, PlatformAction.SERVE_TO_LEFT)
            ball_served = True
        else:
            y = clf.predict(feature)
            if y == 0:
                comm.send_to_game({"frame": scene_info["frame"], "command": "NONE"})
                print('NONE')
            elif y ==1:
                comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})
                print('LEFT')
            elif y ==2:
                comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                print('RIGHT')
Example #9
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process

    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```

    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    c = 0
    X = []
    Y = []

    dis = 100
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        mid = scene_info["platform_1P"][0] + 20
        if c == 0:
            filename = path.join(path.dirname(__file__), 'Predict.pickle')
            with open(filename, "rb") as f:
                knn = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T0.pickle')
            with open(filename, "rb") as f:
                knn0 = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T1.pickle')
            with open(filename, "rb") as f:
                knn1 = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T2.pickle')
            with open(filename, "rb") as f:
                knn2 = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T3.pickle')
            with open(filename, "rb") as f:
                knn3 = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T4.pickle')
            with open(filename, "rb") as f:
                knn4 = pickle.load(f)
            filename = path.join(path.dirname(__file__), 'T5.pickle')
            with open(filename, "rb") as f:
                knn5 = pickle.load(f)
            box_px = -1
            c = 1
        box_x = scene_info["blocker"][0]
        if scene_info["frame"] > 2:
            if box_x > box_px:
                s = 1
            if box_x < box_px:
                s = -1

            feature = []
            feature.append(scene_info["ball"][0])
            feature.append(scene_info["ball"][1])
            feature.append(scene_info["ball_speed"][0])
            feature.append(scene_info["ball_speed"][1])
            feature.append(scene_info["blocker"][0])
            feature.append(s)
            feature = np.array(feature)
            feature = feature.reshape((-1, 6))
            t = knn.predict(feature)

            feature1 = []
            feature1.append(scene_info["ball"][0])
            feature1.append(scene_info["ball"][1])
            feature1.append(scene_info["ball_speed"][0])
            feature1.append(scene_info["ball_speed"][1])
            feature1 = np.array(feature1)
            feature1 = feature1.reshape((-1, 4))
            if t == 0:
                dis = knn0.predict(feature1)
            if t == 1:
                dis = knn1.predict(feature)
            if t == 2:
                dis = knn2.predict(feature)
            if t == 3:
                dis = knn3.predict(feature)
            if t == 4:
                dis = knn4.predict(feature)
            if t == 5:
                dis = knn5.predict(feature1)
            if dis < 20:
                dis = 20
            if dis > 180:
                dis = 180
        box_px = box_x
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if dis < mid - 7:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
            elif dis > mid + 7:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
Example #10
0
def ml_loop(side: str
            ):  #呼叫此程式的程式中,助教已有設定好1P的板子side會設1P,所以def裡的程式直接依判別side值為何來決定該如何動作
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    flag = 0
    blocker_pre = 0

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if (player == '1P'):
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 5) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                       5):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 5):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P(blocker_dir):  #預測1P該在的位置
        global flag
        if (scene_info["ball"][1] <= 260 and scene_info["ball"][1] >= 240):
            print("ball_x", scene_info["ball"][1], scene_info["ball"][0])
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            ball_x = scene_info["ball"][0]
            ball_y = scene_info["ball"][1]
            ball_speed_x = scene_info["ball_speed"][0]
            ball_speed_y = scene_info["ball_speed"][1]

            #判斷2P回球是否會打到blocker側邊
            if (scene_info["ball"][1] <= 240):
                #               print()
                # x_top = (240-scene_info["ball"][1] ) / scene_info["ball_speed"][1]
                # x_bottom = (260-scene_info["ball"][1] ) / scene_info["ball_speed"][1]
                block_x = (240 -
                           scene_info["ball"][1]) / scene_info["ball_speed"][1]
                #                print(x)
                #print("x_top, x_bottom:", x_top, x_bottom)
                slope = abs(scene_info["ball_speed"][0] /
                            scene_info["ball_speed"][1])
                conflict_pred = scene_info["ball"][0] + (
                    scene_info["ball_speed"][0] * block_x)

                bound = conflict_pred // 200  # Determine if it is beyond the boundary
                if (bound > 0):  # pred > 200 # fix landing position #超出右邊邊界
                    if (bound % 2 == 0):
                        conflict_pred = conflict_pred - bound * 200
                        flag = 1  #flag 1 表撞到blocker時往右
                    else:
                        conflict_pred = 200 - (conflict_pred - 200 * bound)
                        flag = 2  #flag 2 表撞到blocker時往左
                elif (bound < 0):  # pred < 0 超出左邊邊界
                    if (bound % 2 == 1):
                        conflict_pred = abs(conflict_pred - (bound + 1) * 200)
                        flag = 1
                    else:
                        conflict_pred = conflict_pred + (abs(bound) * 200)
                        flag = 2

                #bias = 20//abs(scene_info["ball_speed"][1])
                blocker_pos_pred = scene_info["blocker"][0] + (blocker_dir *
                                                               block_x)
                if (blocker_pos_pred > 170):
                    blocker_pos_pred = 170 - (blocker_pos_pred - 170)  #-5*bias
                elif (blocker_pos_pred < 0):
                    blocker_pos_pred = abs(blocker_pos_pred)  #+5*bias
                # else:
                #     if(blocker_dir>0):
                #         blocker_pos_pred += 5*bias
                #     else:
                #         blocker_pos_pred -= 5*bias
                #確定球會撞到blocker左邊反彈
                # print(flag)
                # print("speed:", ball_speed_x, ball_speed_y)
                print("conflict_pred", conflict_pred)
                print("blocker:", scene_info["blocker"][0])
                print("blocker_pos_pred", blocker_pos_pred,
                      blocker_pos_pred + 30)
                if (flag == 1 and conflict_pred < (blocker_pos_pred + 15)
                        and conflict_pred > (blocker_pos_pred - 20 * slope)):
                    print("會撞到左邊")
                    ball_x = blocker_pos_pred
                    ball_y = 240 + ((blocker_pos_pred - conflict_pred) / slope)
                    ball_speed_x = -abs(scene_info["ball_speed"][0])
                #確定球會撞到blocker右邊反彈
#                print(blocker_pos_pred+30, blocker_pos_pred+30+20*slope)
                if (flag == 2 and conflict_pred > (blocker_pos_pred + 15)
                        and conflict_pred <
                    (blocker_pos_pred + 30 + 20 * slope)):
                    print("會撞到右邊")
                    ball_x = blocker_pos_pred + 30
                    ball_y = 240 + ((conflict_pred -
                                     (blocker_pos_pred + 30)) / slope)
                    ball_speed_x = abs(scene_info["ball_speed"][0])

            x = (
                scene_info["platform_1P"][1] - ball_y
            ) // ball_speed_y  # 幾個frame以後會需要接(y距離/ball y速度)  # x means how many frames before catch the ball
            pred = ball_x + (ball_speed_x * x
                             )  # 預測最終位置 # pred means predict ball landing site
            bound = pred // 200  # Determine if it is beyond the boundary
            if (bound > 0):  # pred > 200 # fix landing position #超出右邊邊界
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):  # pred < 0 超出左邊邊界
                if (bound % 2 == 1):
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            #對回球瞬間做判斷,決定怎麼回會最好
            if (x <= 1):
                #print("pred:",pred)
                #print("1p platform", scene_info["platform_1P"][0],scene_info["platform_1P"][0]+40)
                if (pred < 15):
                    return 2
                elif (pred > 185):
                    return 1

                dist = (160 + (420 - scene_info["ball"][1])
                        ) / scene_info["ball_speed"][1]
                #計算球彈到blocker時的位置
                ball_blocker_pred = scene_info["ball"][0] + (
                    (scene_info["ball_speed"][0]) * dist)
                ball_blocker_cut_pred = scene_info["ball"][0] + (
                    (scene_info["ball_speed"][0]) * dist)
                if (abs(scene_info["ball_speed"][0]) -
                        scene_info["ball_speed"][1] == 0):
                    if (scene_info["ball_speed"][0] < 0):
                        ball_blocker_cut_pred = scene_info["ball"][0] + (
                            (scene_info["ball_speed"][0] - 3) * dist)
                    else:
                        ball_blocker_cut_pred = scene_info["ball"][0] + (
                            (scene_info["ball_speed"][0] + 3) * dist)

                ball_blocker_bound = ball_blocker_pred // 200
                ball_blocker_cut_bound = ball_blocker_cut_pred // 200
                #假設一般
                if (ball_blocker_bound > 0):
                    if (ball_blocker_bound % 2 == 0):
                        ball_blocker_pred = ball_blocker_pred - ball_blocker_bound * 200
                    else:
                        ball_blocker_pred = 200 - (ball_blocker_pred -
                                                   200 * ball_blocker_bound)
                elif (ball_blocker_bound < 0):
                    if (ball_blocker_bound % 2 == 1):
                        ball_blocker_pred = abs(ball_blocker_pred -
                                                (ball_blocker_bound + 1) * 200)
                    else:
                        ball_blocker_pred = ball_blocker_pred + (
                            abs(ball_blocker_bound) * 200)
                #假設切球
                if (ball_blocker_cut_bound > 0):
                    if (ball_blocker_cut_bound % 2 == 0):
                        ball_blocker_cut_pred = ball_blocker_cut_pred - ball_blocker_cut_bound * 200
                    else:
                        ball_blocker_cut_pred = 200 - (
                            ball_blocker_cut_pred -
                            200 * ball_blocker_cut_bound)
                elif (ball_blocker_cut_bound < 0):
                    if (ball_blocker_cut_bound % 2 == 1):
                        ball_blocker_cut_pred = abs(
                            ball_blocker_cut_pred -
                            (ball_blocker_cut_bound + 1) * 200)
                    else:
                        ball_blocker_cut_pred = ball_blocker_cut_pred + (
                            abs(ball_blocker_cut_bound) * 200)
                #計算球到blocker y座標時,blocker此時位置
                blocker_pos_pred = scene_info["blocker"][0] + (blocker_dir *
                                                               dist)
                if (blocker_pos_pred > 170):
                    blocker_pos_pred = 170 - (blocker_pos_pred - 170)
                if (blocker_pos_pred < 0):
                    blocker_pos_pred = abs(blocker_pos_pred)
                #如果預測切球之後會使得球打到障礙物,則選擇反向反彈,但當反彈或切球都會撞到障礙物時則無法避免
                #print("ball_blocker_pred:" ,ball_blocker_pred, "blocker_pos_pred:", blocker_pos_pred, blocker_pos_pred+30)
                #print("ball_blocker_cut_pred:" ,ball_blocker_cut_pred, "blocker_pos_pred:", blocker_pos_pred, blocker_pos_pred+30)
                if (pred >= scene_info["platform_1P"][0] + 40):
                    #print("右")
                    return 1
                elif (pred <= scene_info["platform_1P"][0]):
                    #print("左")
                    return 2
                #blocker預測範圍加15增加容錯率
                elif (ball_blocker_cut_pred < blocker_pos_pred - 12
                      or ball_blocker_cut_pred > blocker_pos_pred + 42):
                    #print("accelerate")
                    if (scene_info["ball_speed"][0] < 0
                            and not (scene_info["platform_1P"][0] + 40 - 5 <
                                     pred)):
                        return 2
                    elif (scene_info["ball_speed"][0] > 0
                          and not (scene_info["platform_1P"][0] + 5 > pred)):
                        return 1
                elif (ball_blocker_pred < blocker_pos_pred - 12
                      or ball_blocker_pred > blocker_pos_pred + 42):
                    #print("NONE")
                    return 0
                else:
                    #print("reverse")
                    if (scene_info["ball_speed"][0] < 0
                            and not (scene_info["platform_1P"][0] + 5 > pred)):
                        return 1
                    elif (scene_info["ball_speed"][0] > 0 and
                          not (scene_info["platform_1P"][0] + 40 - 5 < pred)):
                        return 2

                    # print("random")
                    # if (rand < 0.33):
                    #     return 1
                    # elif (rand>=0.33 and rand<0.66):
                    #     return 2
                    # else:
                    #     return 0
            else:
                #print("normal")
                return move_to(player='1P', pred=pred)

        else:  # 球正在向上 # ball goes up
            flag = 0
            return move_to(player='1P', pred=100)

    def ml_loop_for_2P(blocker_dir):  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            rand = random.random()
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            if (x <= 1):
                if (pred >= scene_info["platform_2P"][0] + 25):
                    return 1
                elif (pred <= scene_info["platform_2P"][0] + 15):
                    return 2
                else:
                    if (rand < 0.33):
                        return 1
                    elif (rand >= 0.33 and rand < 0.66):
                        return 2
                    else:
                        return 0
            else:
                return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        blocker_dir = scene_info["blocker"][0] - blocker_pre
        blocker_pre = scene_info["blocker"][0]

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })  #以dict形式傳入,內有兩個參數
            ball_served = True
        else:
            #if(scene_info["ball"][0]<=scene_info["blocker"][0]+30 and scene_info["ball"][0]>=scene_info["blocker"][0] and scene_info["ball"][1]>=scene_info["blocker"][1] and scene_info["ball"][1]<=scene_info["blocker"][1]+20):
            #print("ball pos:",scene_info["ball"][0], scene_info["ball"][1])

            if side == "1P":
                command = ml_loop_for_1P(blocker_dir)
            else:
                command = ml_loop_for_2P(blocker_dir)

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #11
0
def ml_loop(side: str):

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    check = False
    p1 = False

    p2 = False
    person = False
    dead = True
    Pdirect = rd.randint(0, 1)

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > pred: return 2  # goes left
            elif scene_info["platform_1P"][0] + 20 < pred:
                return 1  # goes right
            else:
                return 0  # NONE
        else:
            if scene_info["platform_2P"][0] + 20 > pred: return 2  # goes left
            elif scene_info["platform_2P"][0] + 20 < pred:
                return 1  # goes right
            else:
                return 0  # NONE

    def cut_the_ball():
        tmp = rd.randint(0, 2)
        if tmp == 2: return 2  # goes left
        elif tmp == 1: return 1  # goes right
        else: return 1  # NONE

    def ml_loop_for_1P():
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            abs_speedX = abs(scene_info["ball_speed"][0])  #將speed設為正
            now_direct = 0
            yseg = math.ceil(
                (scene_info["platform_1P"][1] - scene_info["ball"][1] - 5) /
                scene_info["ball_speed"][1]
            )  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            if scene_info["ball_speed"][0] > 0:  #球往右邊跑,等等由左邊開始計算
                xseg = math.ceil((195 - scene_info["ball"][0]) / abs_speedX)
                now_direct = 1
            else:  #球往左邊跑,等等由右邊開始計算
                xseg = math.ceil(scene_info["ball"][0] / abs_speedX)  # 目前的xreg
                now_direct = 0
            x_range_seg = math.ceil(195 / abs_speedX)  #現在速度的xrangeseg
            last_reg = abs(int(yseg - xseg) % int(x_range_seg))  #最後的reg
            bound = abs(int((yseg - xseg) // x_range_seg + now_direct) % 2)

            pred = abs(195 * bound - last_reg * abs_speedX)
            if yseg < xseg:
                pred = scene_info["ball"][
                    0] + yseg * scene_info["ball_speed"][0]
            # print(scene_info["ball_speed"],pred,now_direct,yseg,xseg,last_reg,x_range_seg,bound,scene_info["ball"],scene_info["platform_2P"],scene_info["platform_1P"])
            if scene_info["ball"][1] + scene_info["ball_speed"][1] >= 415:
                # print(scene_info["frame"],scene_info["blocker"],scene_info["ball_speed"],scene_info["ball"],scene_info["platform_1P"],scene_info["platform_2P"])
                return cut_the_ball()
            else:

                return move_to(player='1P', pred=pred)
        else:  # 球正在向上 # ball goes up
            # if scene_info["ball"][1]==415:
            #     # print(scene_info["frame"],scene_info["blocker"],scene_info["ball_speed"],scene_info["ball"],scene_info["platform_1P"],scene_info["platform_2P"])
            # global p1test
            # if scene_info["ball"][1]==415:
            #     if scene_info["ball_speed"][0]>0:
            #         p1test=195-scene_info["ball"][0]/2
            #     else:
            #         p1test=scene_info["ball"][0]/2
            return move_to(player='1P', pred=100)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] < 0:
            abs_speedX = abs(scene_info["ball_speed"][0])  #將speed設為正
            now_direct = 0
            yseg = math.ceil(
                (scene_info["platform_2P"][1] + 30 - scene_info["ball"][1]) /
                scene_info["ball_speed"][1]
            )  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            if scene_info["ball_speed"][0] > 0:  #球往右邊跑,等等由左邊開始計算
                xseg = math.ceil((195 - scene_info["ball"][0]) / abs_speedX)
                now_direct = 1
            else:  #球往左邊跑,等等由右邊開始計算
                xseg = math.ceil(scene_info["ball"][0] / abs_speedX)  # 目前的xreg
                now_direct = 0
            x_range_seg = math.ceil(195 / abs_speedX)  #現在速度的xrangeseg
            last_reg = abs(int(yseg - xseg) % int(x_range_seg))  #最後的reg
            bound = abs(int((yseg - xseg) // x_range_seg + now_direct) % 2)

            pred = abs(195 * bound - last_reg * abs_speedX)
            if yseg < xseg:
                pred = scene_info["ball"][
                    0] + yseg * scene_info["ball_speed"][0]
            # print(pred,now_direct,yseg,xseg,last_reg,x_range_seg,bound,scene_info["ball"])
            if scene_info["ball"][1] - scene_info["ball_speed"][1] <= 80:
                print(scene_info["frame"], scene_info["ball_speed"],
                      scene_info["ball"], scene_info["platform_1P"],
                      scene_info["platform_2P"])
                return cut_the_ball()
            else:
                return move_to(player='2P', pred=pred)
        else:

            return move_to(player='2P', pred=100)

    start_frame = rd.randint(0, 20)
    print(start_frame, "ooooooooo")
    test = 0
    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:

        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        # print(scene_info["blocker"])
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False
            if dead == True:
                start_frame = rd.randint(0, 20)
                dead = False
                print(start_frame, "pppppppppp")
            Pdirect = rd.randint(0, 1)
            person = True
            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue
        # 3.4 Send the instruction for this frame to the game process
        if not ball_served and scene_info["frame"] >= start_frame:
            direct = rd.randint(0, 1)
            if direct == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "SERVE_TO_LEFT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "SERVE_TO_RIGHT"
                })
            ball_served = True
            continue
        elif scene_info["frame"] < start_frame:
            person = True
            if scene_info["ball"][1] > 150:
                preson = True
            else:
                preson = False
            if person == True and side == "1P" or person == False and side == "2P":
                if Pdirect == 0:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_LEFT"
                    })
                else:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_RIGHT"
                    })
        else:
            dead = True
            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """
    H = 200
    D = 8
    resume = False # resume from previous checkpoint?

    RIGHT_ACTION = 2
    LEFT_ACTION = 3

    if resume:
        model = pickle.load(open('save.p', 'rb'))
    else:
        model = Sequential()
        model.add(Dense(units=200,input_dim=80*80, activation='relu', kernel_initializer='glorot_uniform'))
        model.add(Dense(units=1, activation='sigmoid', kernel_initializer='RandomNormal'))
        model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

    gamma = 0.99 # discount factor for reward
    decay_rate = 0.99 # decay factor for RMSProp leaky sum of grad^2

    # initialization of variables used in the main loop
    x_train, y_train, rewards = [],[],[]
    reward_sum = 0
    episode_nb = 0

    # initialize variables
    resume = True
    running_reward = None
    epochs_before_saving = 10
    log_dir = './log' + datetime.now().strftime("%Y%m%d-%H%M%S") + "/"

    # load pre-trained model if exist
    if (resume and os.path.isfile('my_model_weights.h5')):
        print("loading previous weights")
        model.load_weights('my_model_weights.h5')
        
    # add a callback tensorboard object to visualize learning
    tbCallBack = callbacks.TensorBoard(log_dir=log_dir, histogram_freq=0,  
            write_graph=True, write_images=True)

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False


    def getObs(player):
        observation = []
        observation.append(scene_info['ball'][0])
        observation.append(scene_info['ball'][1])
        observation.append(scene_info['ball_speed'][0])
        observation.append(scene_info['ball_speed'][1])
        observation.append(scene_info['blocker'][0])
        observation.append(scene_info['blocker'][1])
        if player == '1P':
            observation.append(scene_info['platform_1P'][0])
            observation.append(scene_info['platform_1P'][1])
        if player == '2P':
            observation.append(scene_info['platform_2P'][0])
            observation.append(scene_info['platform_2P'][1])
        observation = np.array(observation)
        return observation

    def move_to(player, pred) : #move platform to predicted position to catch ball 
        if player == '1P':
            if scene_info["platform_1P"][0]+20  > (pred-10) and scene_info["platform_1P"][0]+20 < (pred+10): return 0 # NONE
            elif scene_info["platform_1P"][0]+20 <= (pred-10) : return 1 # goes right
            else : return 2 # goes left
        else :
            if scene_info["platform_2P"][0]+20  > (pred-10) and scene_info["platform_2P"][0]+20 < (pred+10): return 0 # NONE
            elif scene_info["platform_2P"][0]+20 <= (pred-10) : return 1 # goes right
            else : return 2 # goes left

    def ml_loop_for_1P(): 
        if scene_info['status'] == 'GAME_ALIVE':
            reward = 0
        elif scene_info['status'] == 'GAME_1P_WIN':
            reward = 2
        elif scene_info['status'] == 'GAME_DRAW':
            reward = 1
        else:
            reward = -1
        
        #print(reward)

        if scene_info["ball_speed"][1] > 0 : # 球正在向下 # ball goes down
            x = ( scene_info["platform_1P"][1]-scene_info["ball"][1] ) // scene_info["ball_speed"][1] # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x)  # 預測最終位置 # pred means predict ball landing site 
            bound = pred // 200 # Determine if it is beyond the boundary
            if (bound > 0): # pred > 200 # fix landing position
                if (bound%2 == 0) : 
                    pred = pred - bound*200                    
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) : # pred < 0
                if (bound%2 ==1) :
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '1P',pred = pred)
        else : # 球正在向上 # ball goes up
            return move_to(player = '1P',pred = 100)



    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0 : 
            return move_to(player = '2P',pred = 100)
        else : 
            x = ( scene_info["platform_2P"][1]+30-scene_info["ball"][1] ) // scene_info["ball_speed"][1] 
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x) 
            bound = pred // 200 
            if (bound > 0):
                if (bound%2 == 0):
                    pred = pred - bound*200 
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) :
                if bound%2 ==1:
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '2P',pred = pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    _score = [0,0]
    _game_over_score = 11
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.


        # 3.3 Put the code here to handle the scene information
        
        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({"frame": scene_info["frame"], "command": "SERVE_TO_LEFT"})
            ball_served = True
        else:
            if side == "1P":
                observation = getObs("1P")
                proba = model.predict(np.expand_dims(observation, axis=1).T)
                action = RIGHT_ACTION if np.random.uniform() < proba else LEFT_ACTION
                y = 1 if action == 2 else 0 # 0 and 1 are our labels

                #print('action' + str(action))
                #print('aprob' + str(aprob))
                #print('a' + str(np.random.uniform()))
                
                if action == 2:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                else:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})


                # record various intermediates (needed later for backprop)
                x_train.append(observation)
                y_train.append(y)          

                if scene_info['status'] == 'GAME_ALIVE':
                    reward = 0
                    done = False
                elif scene_info['status'] == 'GAME_1P_WIN':
                    reward = 2
                    _score[0] += 1
                elif scene_info['status'] == 'GAME_DRAW':
                    reward = 1
                    _score[0] += 1
                    _score[1] += 1
                else:
                    reward = -1
                    _score[1] += 1
  
                if _score[0] == _game_over_score or _score[1] == _game_over_score:
                    done = True
                else:
                    done = False

                rewards.append(reward)
                reward_sum += reward      

                if done: # an episode finished
                    print('At the end of episode', episode_nb, 'the total reward was :', reward_sum)
        
                    # increment episode number
                    episode_nb += 1
                    
                    # training
                    model.fit(x=np.vstack(x_train), y=np.vstack(y_train), verbose=1, callbacks=[tbCallBack], sample_weight=discount_rewards(rewards, gamma))
                    
                    # Saving the weights used by our model
                    if episode_nb % epochs_before_saving == 0:    
                        model.save_weights('my_model_weights' + datetime.now().strftime("%Y%m%d-%H%M%S") + '.h5')
                    
                    # Log the reward
                    running_reward = reward_sum if running_reward is None else running_reward * 0.99 + reward_sum * 0.01
                    tflog('running_reward', running_reward, custom_dir=log_dir)
                    
                    # Reinitialization
                    x_train, y_train, rewards = [],[],[]
                    reward_sum = 0
            else:
                command = ml_loop_for_2P()
                if command == 0:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "NONE"})
                elif command == 1:
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                else :
                    comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})
            


        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue
Example #13
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    hit_range = 10
    pred_range = 3

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - pred_range
            ) and scene_info["platform_1P"][0] + 20 < (pred + pred_range):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - pred_range):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - pred_range
            ) and scene_info["platform_2P"][0] + 20 < (pred + pred_range):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - pred_range):
                return 1  # goes right
            else:
                return 2  # goes left

    def get_blocker_direction(bkx, pre_bkx):
        if bkx > pre_bkx:
            return 1
        elif bkx < pre_bkx:
            return -1
        else:
            return 0

    def ml_loop_for_1P(bkx, bkxdir):
        if scene_info["ball_speed"][1] > 0 and scene_info["ball"][
                1] < scene_info["blocker"][
                    1]:  #ball goes down and over blocker for 1P
            hit_blocker_frames = (
                scene_info["blocker"][1] + 10 - scene_info["ball"][1]
            ) // scene_info["ball_speed"][1]  #frames of hit blocker
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                            hit_blocker_frames)
            turn_head = 0
            turn_rear = 0
            if pred > 200:
                pred = 400 - pred
                turn_rear = 1
            elif pred < 0:
                pred = 0 - pred
                turn_head = 1
            if scene_info["ball_speed"][
                    0] > 0 and turn_rear == 0:  #ball goes right and not hit wall
                pred_1P = scene_info["ball"][0] + (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5
                    if predic_bkx > 170: predic_bkx = 340 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5
                    if predic_bkx < 0: predic_bkx = 0 - predic_bkx
            elif scene_info["ball_speed"][
                    0] > 0 and turn_rear == 1:  #ball goes right and hit wall
                pred_1P = scene_info["ball"][0] + (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx > 200: predic_bkx = 400 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx < 30: predic_bkx = 30 + (30 - predic_bkx)
            elif scene_info["ball_speed"][
                    0] < 0 and turn_head == 0:  #ball goes left and not hit wall
                pred_1P = scene_info["ball"][0] - (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx > 200: predic_bkx = 400 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx < 30: predic_bkx = 30 + (30 - predic_bkx)
            elif scene_info["ball_speed"][
                    0] < 0 and turn_head == 1:  #ball goes left and hit wall
                pred_1P = scene_info["ball"][0] - (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5
                    if predic_bkx > 170: predic_bkx = 340 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5
                    if predic_bkx < 0: predic_bkx = 0 - predic_bkx
            if abs(predic_bkx - pred) < hit_range:  # hit blocker situation
                if scene_info["ball_speed"][0] > 0 and turn_rear == 0:
                    pred_1P = predic_bkx - 170
                elif scene_info["ball_speed"][0] > 0 and turn_rear == 1:
                    pred_1P = predic_bkx + 170
                elif scene_info["ball_speed"][0] < 0 and turn_head == 0:
                    pred_1P = predic_bkx + 170
                elif scene_info["ball_speed"][0] < 0 and turn_head == 1:
                    pred_1P = predic_bkx - 170
        elif scene_info["ball_speed"][1] > 0:  #ball goes down for 1P
            if scene_info["ball_speed"][0] > 0:  #ball goes right
                pred_1P = scene_info["ball"][0] + (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
            else:  #ball goes left
                pred_1P = scene_info["ball"][0] - (
                    scene_info["platform_1P"][1] - scene_info["ball"][1])
        elif scene_info["ball_speed"][1] < 0 and scene_info["ball"][
                1] > scene_info["blocker"][
                    1] + 20:  #ball goes up and below blocker for 1P
            if scene_info["ball_speed"][0] > 0:  #ball goes right
                px = scene_info["ball"][0] - (scene_info["platform_1P"][1] -
                                              scene_info["ball"][1])
                if px < -80:
                    pred_1P = 160
                elif px < 80:
                    pred_1P = 80 - px
                else:
                    pred_1P = px - 80
            else:  #ball goes left
                px = scene_info["ball"][0] + (scene_info["platform_1P"][1] -
                                              scene_info["ball"][1])
                if px > 300:
                    pred_1P = 20
                elif px > 120:
                    pred_1P = 320 - px
                else:
                    pred_1P = px + 80
        else:
            pred_1P = 80

        bound = pred_1P // 200  # Determine if it is beyond the boundary
        if (bound > 0):  # pred > 200 # fix landing position
            if (bound % 2 == 0):
                pred_1P = pred_1P - bound * 200
            else:
                pred_1P = 200 - (pred_1P - 200 * bound)
        elif (bound < 0):  # pred < 0
            if (bound % 2 == 1):
                pred_1P = abs(pred_1P - (bound + 1) * 200)
            else:
                pred_1P = pred_1P + (abs(bound) * 200)
        return move_to(player='1P', pred=pred_1P)

    def ml_loop_for_2P(bkx, bkxdir):
        if scene_info["ball_speed"][1] < 0 and scene_info["ball"][
                1] > scene_info["blocker"][
                    1] + 20:  #ball goes down and over blocker for 2P
            hit_blocker_frames = (
                scene_info["blocker"][1] + 10 - scene_info["ball"][1]
            ) // scene_info["ball_speed"][1]  #frames of hit blocker
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                            hit_blocker_frames)
            turn_head = 0
            turn_rear = 0
            if pred > 200:
                pred = 400 - pred
                turn_rear = 1
            elif pred < 0:
                pred = 0 - pred
                turn_head = 1
            if scene_info["ball_speed"][
                    0] > 0 and turn_rear == 0:  #ball goes right and not hit wall
                pred_2P = scene_info["ball"][0] + (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5
                    if predic_bkx > 170: predic_bkx = 340 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5
                    if predic_bkx < 0: predic_bkx = 0 - predic_bkx
            elif scene_info["ball_speed"][
                    0] > 0 and turn_rear == 1:  #ball goes right and hit wall
                pred_2P = scene_info["ball"][0] + (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx > 200: predic_bkx = 400 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx < 30: predic_bkx = 30 + (30 - predic_bkx)
            elif scene_info["ball_speed"][
                    0] < 0 and turn_head == 0:  #ball goes left and not hit wall
                pred_2P = scene_info["ball"][0] - (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx > 200: predic_bkx = 400 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5 + 30
                    if predic_bkx < 30: predic_bkx = 30 + (30 - predic_bkx)
            elif scene_info["ball_speed"][
                    0] < 0 and turn_head == 1:  #ball goes left and hit wall
                pred_2P = scene_info["ball"][0] - (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if bkxdir == 1:
                    predic_bkx = bkx + hit_blocker_frames // 2 * 5
                    if predic_bkx > 170: predic_bkx = 340 - predic_bkx
                elif bkxdir == -1:
                    predic_bkx = bkx - hit_blocker_frames // 2 * 5
                    if predic_bkx < 0: predic_bkx = 0 - predic_bkx
            if abs(predic_bkx - pred) < hit_range:  # hit blocker situation
                if scene_info["ball_speed"][0] > 0 and turn_rear == 0:
                    pred_2P = predic_bkx - 170
                elif scene_info["ball_speed"][0] > 0 and turn_rear == 1:
                    pred_2P = predic_bkx + 170
                elif scene_info["ball_speed"][0] < 0 and turn_head == 0:
                    pred_2P = predic_bkx + 170
                elif scene_info["ball_speed"][0] < 0 and turn_head == 1:
                    pred_2P = predic_bkx - 170
        elif scene_info["ball_speed"][1] < 0:  #ball goes down for 2P
            if scene_info["ball_speed"][0] > 0:  #ball goes right
                pred_2P = scene_info["ball"][0] + (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
            else:  #ball goes left
                pred_2P = scene_info["ball"][0] - (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
        elif scene_info["ball_speed"][1] > 0 and scene_info["ball"][
                1] < scene_info["blocker"][
                    1]:  #ball goes up and below blocker for 2P
            if scene_info["ball_speed"][0] > 0:  #ball goes right
                px = scene_info["ball"][0] - (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if px < -80:
                    pred_2P = 160
                elif px < 80:
                    pred_2P = 80 - px
                else:
                    pred_2P = px - 80
            else:  #ball goes left
                px = scene_info["ball"][0] + (
                    scene_info["ball"][1] - scene_info["platform_2P"][1] - 30)
                if px > 300:
                    pred_2P = 20
                elif px > 120:
                    pred_2P = 320 - px
                else:
                    pred_2P = px + 80
        else:
            pred_2P = 80

        bound = pred_2P // 200
        if (bound > 0):
            if (bound % 2 == 0):
                pred_2P = pred_2P - bound * 200
            else:
                pred_2P = 200 - (pred_2P - 200 * bound)
        elif (bound < 0):
            if bound % 2 == 1:
                pred_2P = abs(pred_2P - (bound + 1) * 200)
            else:
                pred_2P = pred_2P + (abs(bound) * 200)
        return move_to(player='2P', pred=pred_2P)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    pre_bkx = 80
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        bkx = scene_info["blocker"][0]

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if (random.randint(0, 10) >= 5):
                r1 = 2
            else:
                r1 = 0

            if side == "1P":
                pd1 = get_blocker_direction(bkx, pre_bkx)
                if pd1 == 0: pd1 = ppd1
                command = ml_loop_for_1P(bkx, pd1)
                pre_bkx = bkx
                ppd1 = pd1
                if command == 0:
                    if abs(scene_info["ball"][1] -
                           scene_info["platform_1P"][1]) < 7 and r1 == 0:
                        if scene_info["ball_speed"][0] > 0:
                            comm.send_to_game({
                                "frame": scene_info["frame"],
                                "command": "MOVE_RIGHT"
                            })
                        else:
                            comm.send_to_game({
                                "frame": scene_info["frame"],
                                "command": "MOVE_LEFT"
                            })
                    else:
                        comm.send_to_game({
                            "frame": scene_info["frame"],
                            "command": "NONE"
                        })
                elif command == 1:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_RIGHT"
                    })
                else:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_LEFT"
                    })

            else:
                pd2 = get_blocker_direction(bkx, pre_bkx)
                if pd2 == 0: pd2 = ppd2
                command = ml_loop_for_2P(bkx, pd2)
                pre_bkx = bkx
                ppd2 = pd2
                if command == 0:
                    if abs(scene_info["ball"][1] -
                           scene_info["platform_2P"][1]) < 7 and r1 == 2:
                        if scene_info["ball_speed"][0] > 0:
                            comm.send_to_game({
                                "frame": scene_info["frame"],
                                "command": "MOVE_RIGHT"
                            })
                        else:
                            comm.send_to_game({
                                "frame": scene_info["frame"],
                                "command": "MOVE_LEFT"
                            })
                    else:
                        comm.send_to_game({
                            "frame": scene_info["frame"],
                            "command": "NONE"
                        })
                elif command == 1:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_RIGHT"
                    })
                else:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_LEFT"
                    })
Example #14
0
def ml_ready():
    """
    Inform the game process that ml process is ready
    """
    comm.ml_ready()
Example #15
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 5) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                       5):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 5):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 5) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                       5):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 5):
                return 1  # goes right
            else:
                return 2  # goes left

    before_blocker_x = 0

    def ml_loop_for_1P():
        """        
        if scene_info["ball_speed"][1] > 0 : # 球正在向下 # ball goes down
            x = ( scene_info["platform_1P"][1]-scene_info["ball"][1] ) // scene_info["ball_speed"][1] # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x)  # 預測最終位置 # pred means predict ball landing site 
            bound = pred // 200 # Determine if it is beyond the boundary
            if (bound > 0): # pred > 200 # fix landing position
                if (bound%2 == 0) : 
                    pred = pred - bound*200                    
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) : # pred < 0
                if (bound%2 ==1) :
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '1P',pred = pred)
        else : # 球正在向上 # ball goes up
            return move_to(player = '1P',pred = 100)
        """

        ball_x = scene_info["ball"][0]
        ball_y = scene_info["ball"][1]

        platform_x = scene_info["platform_1P"][0]
        platform_y = scene_info["platform_1P"][1]

        blocker_x = scene_info["blocker"][0]
        blocker_y = scene_info["blocker"][1]

        ball_speed_x = scene_info["ball_speed"][0]
        ball_speed_y = vector_y_down = scene_info["ball_speed"][1]
        blocker_x = scene_info["blocker"][0]

        if 240 < scene_info["ball"][1] < 260 and scene_info["ball"][
                0] != 0 and scene_info["ball"][
                    0] != 195 and ball_x_speed != before_ball_x_speed:
            scene_info["blocker"][0], "block_y:", scene_info["blocker"][1]

        now_ball_x = ball_x
        now_ball_y = ball_y

        vector_x_right = True if ball_speed_x > 0 else False
        vector_y_down = True if ball_speed_y > 0 else False

        hit_y = 0

        while hit_y < 415:
            if vector_x_right:
                hit_x = 195
            else:
                hit_x = 0

            if vector_y_down:
                hit_y = 415
            else:
                hit_y = 80

            if abs(now_ball_x - hit_x) < abs(now_ball_y - hit_y):
                if vector_y_down:
                    hit_y = (
                        (abs(now_ball_x - hit_x) - 1) // abs(ball_speed_x) +
                        1) * abs(ball_speed_y) + now_ball_y
                    if hit_y > 415:
                        hit_y = (
                            (abs(now_ball_x - hit_x)) /
                            abs(ball_speed_x)) * abs(ball_speed_y) + now_ball_y
                else:
                    hit_y = -(
                        (abs(now_ball_x - hit_x) - 1) // abs(ball_speed_x) +
                        1) * abs(ball_speed_y) + now_ball_y
                    if hit_y < 0:
                        hit_y = -(
                            (abs(now_ball_x - hit_x)) /
                            abs(ball_speed_x)) * abs(ball_speed_y) + now_ball_y

                vector_x_right = not vector_x_right
            else:
                #這邊可能會切球
                if vector_x_right:
                    hit_x = (
                        (abs(now_ball_y - hit_y)) /
                        abs(ball_speed_x)) * abs(ball_speed_x) + now_ball_x
                else:
                    hit_x = -(
                        (abs(now_ball_y - hit_y)) /
                        abs(ball_speed_y)) * abs(ball_speed_x) + now_ball_x
                vector_y_down = not vector_y_down

            now_ball_x = hit_x
            now_ball_y = hit_y

        should_x2 = hit_x
        return move_to(player='1P', pred=should_x2)

    def ml_loop_for_2P():  # as same as 1P
        ball_x = scene_info["ball"][0]
        ball_y = scene_info["ball"][1]

        platform_x = scene_info["platform_1P"][0]
        platform_y = scene_info["platform_1P"][1]

        ball_speed_x = scene_info["ball_speed"][0]
        ball_speed_y = vector_y_down = scene_info["ball_speed"][1]

        now_ball_x = ball_x
        now_ball_y = ball_y

        vector_x_right = True if ball_speed_x > 0 else False
        vector_y_down = True if ball_speed_y > 0 else False

        hit_y = 500

        while hit_y > 80:
            if vector_x_right:
                hit_x = 195
            else:
                hit_x = 0

            if vector_y_down:
                hit_y = 415
            else:
                hit_y = 80

            if abs(now_ball_x - hit_x) < abs(now_ball_y - hit_y):
                if vector_y_down:
                    hit_y = (
                        (abs(now_ball_x - hit_x) - 1) // abs(ball_speed_x) +
                        1) * abs(ball_speed_y) + now_ball_y
                    if hit_y > 415:
                        hit_y = (
                            (abs(now_ball_x - hit_x)) /
                            abs(ball_speed_x)) * abs(ball_speed_y) + now_ball_y
                else:
                    hit_y = -(
                        (abs(now_ball_x - hit_x) - 1) // abs(ball_speed_x) +
                        1) * abs(ball_speed_y) + now_ball_y
                    if hit_y < 0:
                        hit_y = -(
                            (abs(now_ball_x - hit_x)) /
                            abs(ball_speed_x)) * abs(ball_speed_y) + now_ball_y

                vector_x_right = not vector_x_right
            else:
                #這邊可能會切球
                if vector_x_right:
                    hit_x = (
                        (abs(now_ball_y - hit_y)) /
                        abs(ball_speed_x)) * abs(ball_speed_x) + now_ball_x
                else:
                    hit_x = -(
                        (abs(now_ball_y - hit_y)) /
                        abs(ball_speed_y)) * abs(ball_speed_x) + now_ball_x
                vector_y_down = not vector_y_down

            now_ball_x = hit_x
            now_ball_y = hit_y

        should_x = hit_x
        return move_to(player='2P', pred=should_x)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    i = 0

    ball_x_speed = 100
    ball_y_speed = 10

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information
        # 3.4 Send the instruction for this frame to the game process
        if not ball_served and i < 1:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "MOVE_RIGHT"
            })
            i = i + 1
        elif not ball_served and i == 1:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True

        else:

            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
                #print("right")
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
                #print("left")
            """
            if scene_info["ball"][0]==195 or scene_info["ball"][0]==0:
                print("########x:",scene_info["ball"][0],"y:",scene_info["ball"][1])
            """

            #if scene_info["ball"][1]==80 or scene_info["ball"][1]==415:
            #if scene_info["ball"][1]==415:
            #   print("******x:",scene_info["ball"][0],"y:",scene_info["ball"][1],"PLATFORM_x:",scene_info["platform_1P"][0],"PLATFORM_y:",scene_info["platform_1P"][1])
            #print("x:",scene_info["ball"][0],"y:",scene_info["ball"][1],"ball_speed_x:",scene_info["ball_speed"][0],"ball_speed_y:",scene_info["ball_speed"][1],"PLATFORM_x:",scene_info["platform_1P"][0],"PLATFORM_y:",scene_info["platform_1P"][1])
            #print("block_x:",scene_info["blocker"][0],"block_y:",scene_info["blocker"][1])
            #print("x:",scene_info["ball"][0],"y:",scene_info["ball"][1],"ball_speed_x:","block_x:",scene_info["blocker"][0],"block_y:",scene_info["blocker"][1],scene_info["ball_speed"][0],"ball_speed_y:",scene_info["ball_speed"][1],"PLATFORM_x:",scene_info["platform_1P"][0],"PLATFORM_y:",scene_info["platform_1P"][1])

            before_ball_x_speed = ball_x_speed
            before_ball_y_speed = ball_y_speed

            ball_x_speed = scene_info["ball_speed"][0]
            ball_y_speed = scene_info["ball_speed"][1]

            if 240 < scene_info["ball"][1] < 260 and scene_info["ball"][
                    0] != 0 and scene_info["ball"][
                        0] != 195 and ball_x_speed != before_ball_x_speed:
                print("x:", scene_info["ball"][0], "y:", scene_info["ball"][1],
                      "ball_speed_x:", scene_info["ball_speed"][0], "block_x:",
                      scene_info["blocker"][0], "block_y:",
                      scene_info["blocker"][1], "ball_speed_y:",
                      scene_info["ball_speed"][1], "PLATFORM_x:",
                      scene_info["platform_1P"][0], "PLATFORM_y:",
                      scene_info["platform_1P"][1])
Example #16
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P():
        slope = 1
        blocker_pred = 0
        if (scene_info["ball_speed"][0] != 0):
            slope = (scene_info["ball_speed"][1] / scene_info["ball_speed"][0])
        if (scene_info["ball_speed"][1] < 0):
            if (scene_info["ball"][1] > 270):
                blocker_pred = (270 - scene_info["ball"][1]
                                ) / slope + scene_info["ball"][0]
                while blocker_pred < 0 or blocker_pred > 195:
                    if blocker_pred > 195:
                        blocker_pred = 390 - blocker_pred
                    elif blocker_pred < 0:
                        blocker_pred = -blocker_pred
                pred = 150 / slope + blocker_pred
                while pred < 0 or pred > 195:
                    if pred > 195:
                        pred = 390 - pred
                    elif pred < 0:
                        pred = -pred
                return move_to(player='1P', pred=pred)
            else:
                pred = 100
                return move_to(player='1P', pred=pred)
        elif slope != 0:
            pred = (420 -
                    scene_info["ball"][1]) / slope + scene_info["ball"][0]
        while pred < 0 or pred > 195:
            if pred > 195:
                pred = 390 - pred
            elif pred < 0:
                pred = -pred
        return move_to(player='1P', pred=pred)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #17
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """
    ball_served = False

    filename = path.join(path.dirname(__file__), 'save', 'RANF blocker.pickle')
    with open(filename, 'rb') as file:  # read binary
        clf = pickle.load(file)

    ball_prev = [80, 415]  # ball's initial point

    def get_dir(vector_x, vector_y):
        if (vector_x >= 0 and vector_y >= 0):
            return [0, 0, 0, 1]
        elif (vector_x > 0 and vector_y < 0):
            return [0, 0, 1, 0]
        elif (vector_x < 0 and vector_y > 0):
            return [0, 1, 0, 0]
        else:
            return [1, 0, 0, 0]
        # elif(vector_x < 0 and vector_y < 0):
        #     return [1, 0, 0, 0]

    def move_to(player,
                pred):  # move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        scene_info = comm.recv_from_game()

        feature = []
        feature.append(scene_info["ball"][0])
        feature.append(scene_info["ball"][1])
        feature.append(scene_info["blocker"][0])

        arr = get_dir(scene_info["ball"][0] - ball_prev[0],
                      scene_info["ball"][1] - ball_prev[1])
        feature.append(arr[0])
        feature.append(arr[1])
        feature.append(arr[2])
        feature.append(arr[3])
        # if side == "1P":
        #     feature.append(1)
        # else:
        #     feature.append(2)

        ball_prev = [scene_info["ball"][0], scene_info["ball"][1]]
        feature = np.array(feature)
        feature = feature.reshape((-1, 7))  # reshape array into 7 column
        # print(feature)

        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            comm.ml_ready()
            continue

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = move_to(player="1P", pred=clf.predict(feature))
            else:
                command = move_to(player="2P", pred=clf.predict(feature))

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #18
0
def ml_loop(side: str):

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here.
    ball_served = False
    filename = path.join(path.dirname(__file__), "random_forest.pickle")
    with open(filename, 'rb') as file:
        clf = pickle.load(file)
    # 2. Inform the game process that ml process is ready before start the loop.
    comm.ml_ready()

    s = [93, 93]

    def get_direction(ball_x, ball_y, ball_pre_x, ball_pre_y):
        VectorX = ball_x - ball_pre_x
        VectorY = ball_y - ball_pre_y
        if (VectorX > 0 and VectorY > 0):
            return 0
        elif (VectorX > 0 and VectorY < 0):
            return 1
        elif (VectorX < 0 and VectorY > 0):
            return 2
        elif (VectorX < 0 and VectorY < 0):
            return 3
        else:
            return 4

    # 3. Start an endless loop.
    while True:
        # 3.1. Receive the scene information sent from the game process.
        scene_info = comm.recv_from_game()
        #Data = [Commands, Balls, Ball_speed, PlatformPos, Blocker, vectors, direction]
        #Feature = [Balls, Ball_speed, PlatformPos, Blocker, direction]
        feature = []
        for i in range(0, 2):
            # feature.append(scene_info["ball"][i])
            # feature.append(scene_info["ball_speed"][i])
            feature.append(scene_info["platform_1P"][i])
            feature.append(scene_info["blocker"][i])
        feature.append(feature[0] - s[0])
        feature.append(feature[1] - s[1])
        feature.append(get_direction(feature[0], feature[1], s[0], s[1]))
        s = [feature[0], feature[1]]
        # print(feature)
        feature = np.array(feature)
        feature = feature.reshape((-2, 7))

        # 3.2. If the game is over or passed, the game process will reset
        #      the scene and wait for ml process doing resetting job.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some stuff if needed
            ball_served = False

            # 3.2.1. Inform the game process that ml process is ready
            comm.ml_ready()
            continue

        # 3.3. Put the code here to handle the scene information

        # 3.4. Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            y = clf.predict(feature)
            if y == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
                print('NONE')
            elif y == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
                print('LEFT')
            elif y == 2:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
                print('RIGHT')
Example #19
0
def ml_ready():
    comm.ml_ready()
Example #20
0
def ml_loop(side: "1P"):
    """
    The main loop of the machine learning process

    This loop is run in a separate process, and communicates with the game process.

    Note that the game process won't wait for the ml process to generate the
    GameInstruction. It is possible that the frame of the GameInstruction
    is behind of the current frame in the game process. Try to decrease the fps
    to avoid this situation.
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here.
    ball_served = False
    filename = path.join(path.dirname(__file__), "save/KNN.pickle")
    #filename = "C:\\Users\\HsuanPu_Chang\\Desktop\\ML_Game_File\\ML_Game_MidtermTwo\\MLGame-beta6.0\\clf_SVMClassification_VectorsAndDirection.pickle"
    with open(filename, 'rb') as file:
        clf = pickle.load(file)

    # 2. Inform the game process that ml process is ready before start the loop.
    comm.ml_ready()
    """
    s = [93,93]
    def get_direction(ball_x,ball_y,ball_pre_x,ball_pre_y):
        VectorX = ball_x - ball_pre_x
        VectorY = ball_y - ball_pre_y
        if(VectorX>=0 and VectorY>=0):
            return 0
        elif(VectorX>0 and VectorY<0):
            return 1
        elif(VectorX<0 and VectorY>0):
            return 2
        elif(VectorX<0 and VectorY<0):
            return 3
        """

    # 3. Start an endless loop.
    while True:
        scene_info = comm.recv_from_game()
        # 3.1. Receive the scene information sent from the game process.
        feature = []
        feature.append(scene_info["ball"])
        feature.append(scene_info["ball_speed"])
        feature.append(scene_info["blocker"])
        feature.append(scene_info["platform_1P"])
        feature = np.array(feature)
        feature = feature.reshape((-1, 8))
        print(feature)

        #feature.append(get_direction(feature[0],feature[1],s[0],s[1]))
        #s = [feature[0], feature[1]]
        #feature = np.array(feature)
        #feature = feature.reshape((-1,4))
        # 3.2. If the game is over or passed, the game process will reset
        #      the scene and wait for ml process doing resetting job.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3. Put the code here to handle the scene information

        # 3.4. Send the instruction for this frame to the game process
        if scene_info["frame"] > 1500:
            if not ball_served:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "SERVE_TO_LEFT"
                })
                ball_served = True
            else:

                y = clf.predict(feature)

                if y <= 0.5:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "NONE"
                    })
                    print('NONE')
                elif y > 0.5 and y <= 1.5:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_LEFT"
                    })
                    print('LEFT')
                elif y > 1.5:
                    comm.send_to_game({
                        "frame": scene_info["frame"],
                        "command": "MOVE_RIGHT"
                    })
                    print('RIGHT')
Example #21
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
   
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P() """
    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    """
    if side == "1P":
        filename = path.join(path.dirname(__file__),'save', 'player1.pickle')
        #filename = "MLGame-master\games\pingpong\save\player1.pickle"
        with open(filename, 'rb') as file:
            clf = pickle.load(file)
    else:
        
        filename = path.join(path.dirname(__file__),'save', 'player2.pickle')
        #filename = "MLGame-master\games\pingpong\save\player2.pickle"
        with open(filename, 'rb') as file:
            clf = pickle.load(file)
    """

    filename = path.join(path.dirname(__file__), 'save', 'player1_5.pickle')
    #filename = "MLGame-master\games\pingpong\save\player1.pickle"
    with open(filename, 'rb') as file:
        clf = pickle.load(file)
    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    s = [85, 250]

    def get_direction(VectorX, VectorY):

        if (VectorX >= 0 and VectorY >= 0):
            return 0
        elif (VectorX > 0 and VectorY < 0):
            return 1
        elif (VectorX < 0 and VectorY > 0):
            return 2
        else:
            return 3

    def get_Vx(ball_x, ball_y, ball_pre_x, ball_pre_y):
        VectorX = ball_x - ball_pre_x
        return VectorX

    def get_Vy(ball_x, ball_y, ball_pre_x, ball_pre_y):
        VectorY = ball_y - ball_pre_y
        return VectorY

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        feature = []
        vector = []
        vector.append(scene_info['ball_speed'][0])
        vector.append(scene_info['ball_speed'][1])

        feature.append(scene_info['ball'][0])
        feature.append(scene_info['ball'][1])
        feature.append(scene_info['platform_1P'][0])
        #feature.append(vector[0])
        #feature.append(vector[1])
        feature.append(get_direction(vector[0], vector[1]))

        s = [vector[0], vector[1]]
        feature = np.array(feature)
        feature = feature.reshape((-1, 4))
        #print(feature)
        #print(feature)
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            y = clf.predict(feature)
            #print(y)
            if y == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            #    comm.send_instruction(scene_info.frame, PlatformAction.NONE)
            # print('NONE')
            elif y == 1:
                #    comm.send_instruction(scene_info.frame, PlatformAction.MOVE_LEFT)
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
                #print('LEFT')
            elif y == 2:
                #    comm.send_instruction(scene_info.frame, PlatformAction.MOVE_RIGHT)
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
Example #22
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """
    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    filename = path.join(path.dirname(__file__), 'save', 'forest_reg.pickle')
    with open(filename, 'rb') as file:  # read binary
        clf = pickle.load(file)
    ball_prev = [93, 395]  # ball's initial point

    def get_dir(vector_x, vector_y):
        if (vector_x >= 0 and vector_y >= 0):
            return 0
        elif (vector_x > 0 and vector_y < 0):
            return 1
        elif (vector_x < 0 and vector_y > 0):
            return 2
        elif (vector_x < 0 and vector_y < 0):
            return 3

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 1) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                       1):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 1):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 1) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                       1):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 1):
                return 1  # goes right
            else:
                return 2  # goes left

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        if side == "1P":
            feature = []
            # feature.append(scene_info["platform_1P"][0])
            feature.append(scene_info["ball"][0])
            feature.append(scene_info["ball"][1])
            x = get_dir(scene_info['ball_speed'][0],
                        scene_info['ball_speed'][1])
            feature.append(1)
            for i in range(4):
                if i == x:
                    feature.append(1)
                else:
                    feature.append(0)
            print(feature)
            feature = np.array(feature)
            feature = feature.reshape((-1, 7))  # reshape array into 4 column
        else:
            feature = []
            # feature.append(scene_info["platform_1P"][0])
            feature.append(scene_info["ball"][0])
            feature.append(scene_info["ball"][1])
            x = get_dir(scene_info['ball_speed'][0],
                        scene_info['ball_speed'][1])
            feature.append(2)
            for i in range(4):
                if i == x:
                    feature.append(1)
                else:
                    feature.append(0)
            # print(feature)
            feature = np.array(feature)
            feature = feature.reshape((-1, 7))  # reshape array into 4 column
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False
            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue
        # 3.3 Put the code here to handle the scene information
        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = move_to(player="1P", pred=clf.predict(feature))
            else:
                command = move_to(player="2P", pred=clf.predict(feature))
            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P():
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            x = (
                scene_info["platform_1P"][1] - scene_info["ball"][1]
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x
            )  # 預測最終位置 # pred means predict ball landing site
            bound = pred // 200  # Determine if it is beyond the boundary
            print("1P predict " + str(pred))
            print("1P bound " + str(bound))
            if (bound > 0):  # pred > 200 # fix landing position
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):  # pred < 0
                if (bound % 2 == 1):
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            print("result " + str(pred))
            return move_to(player='1P', pred=pred)
        else:  # 球正在向上 # ball goes up
            return move_to(player='1P', pred=100)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
def ml_loop(side: str):
    """
    The main loop for the machine learning process

    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```

    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    model = tf.keras.models.load_model('saved_model/myModel')

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({"frame": scene_info["frame"], "command": "SERVE_TO_RIGHT"})
            ball_served = True
        else:
            ballX = scene_info["ball"][0]
            ballY = scene_info["ball"][1]
            ball_speed_X = scene_info["ball_speed"][0]
            ball_speed_Y = scene_info["ball_speed"][1]
            platform_1P_X = scene_info["platform_1P"][0]
            blocker_X = scene_info["blocker"][0]
            features = [[ballX, ballY, ball_speed_X, ball_speed_Y, platform_1P_X, blocker_X]]
            probabilityModel = tf.keras.Sequential([model, tf.keras.layers.Softmax()])
            prediction = probabilityModel.predict(features)
            awaitCommand = np.argmax(prediction[0])
            print(awaitCommand)
            if awaitCommand == 1:
                comm.send_to_game({"frame": scene_info["frame"], "command": "NONE"})
                print('NONE')
            elif awaitCommand == 2:
                comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_RIGHT"})
                print('RIGHT')
            elif awaitCommand == 0:
                comm.send_to_game({"frame": scene_info["frame"], "command": "MOVE_LEFT"})
                print('LEFT')
Example #25
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    s = 100

    def get_block_direction(block_x, block_pre_x):
        VectorX = block_x - block_pre_x
        if (VectorX >= 0):
            return 1  #障礙物往右
        else:
            return 0  #障礙物往左

    def wall_correction(pred, limit_up, limit_down):
        if (pred > limit_up):
            x = (limit_up -
                 scene_info["ball"][0]) // scene_info["ball_speed"][0]
            ball_wall_x = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x)
            correction = ball_wall_x + scene_info["ball_speed"][0] - limit_up
            pred -= correction
            pred = limit_up - (pred - limit_up)
            if pred >= limit_down:
                return pred
            else:
                return wall_correction(pred, limit_up, limit_down)

        elif (pred < limit_down):
            x = (limit_down -
                 scene_info["ball"][0]) // scene_info["ball_speed"][0]
            ball_wall_x = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x)
            correction = ball_wall_x + scene_info["ball_speed"][0] - limit_down
            pred -= correction
            pred = abs(pred)
            if pred <= limit_up:
                return pred
            else:
                return wall_correction(pred, limit_up, limit_down)
        else:
            return pred

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P():
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            x = (
                scene_info["platform_1P"][1] - 5 - scene_info["ball"][1]
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] *
                (x + 1))  # 預測最終位置 # pred means predict ball landing site
            pred = wall_correction(pred, 195, 0)
            #print(pred, scene_info["ball"], scene_info["frame"]%100)
            if scene_info["ball"][1] <= 235:
                pred = hit_blocker_side(pred)
            return move_to(player='1P', pred=pred)
        else:  # 球正在向上 # ball goes up
            pred = 100
            if scene_info["ball"][1] >= 260:
                pred = hit_blocker_down()
            print(pred, scene_info["ball"], scene_info["frame"])
            return move_to(player='1P', pred=pred)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            pred = 100
            if scene_info["ball"][1] <= 235:
                pred = hit_blocker_up()
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                            (x + 1))
            pred = wall_correction(pred, 195, 0)
            if scene_info["ball"][1] >= 260:
                pred = hit_blocker_side2(pred)
            return move_to(player='2P', pred=pred)

    def hit_blocker_side(pred):
        x = 100 - (scene_info["frame"] % 100)
        block_frame = (scene_info["blocker"][1] - 5 -
                       scene_info["ball"][1]) // (scene_info["ball_speed"][1])
        pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] * x)
        flag = 0
        speed = scene_info["ball_speed"]
        if pred_y >= 235:
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              block_frame)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              block_frame)
        else:
            if scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, 1])
            elif scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, -1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, 1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, -1])
            y = (scene_info["blocker"][1] - 5 - pred_y) // (
                speed[1])  # 幾個frame以後會到障礙物的位置(
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              x) + (speed[0] * y)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              x) + (speed[1] * y)
            block_frame = x + y
            flag = 1

        block_direction = get_block_direction(scene_info["blocker"][0], s)
        if block_direction == 1:
            block_x = scene_info["blocker"][0] + 3 * block_frame
        else:
            block_x = scene_info["blocker"][0] - 3 * block_frame
        bound_block = block_x // 170
        if bound_block > 0:
            if bound_block % 2 == 0:
                block_x = block_x - (bound_block * 170)
            else:
                block_x = 170 - (block_x - 170 * bound_block)
                block_direction = 0
        elif bound_block < 0:
            if (bound_block % 2 == 1):
                block_x = abs(block_x - (bound_block + 1) * 170)
                block_direction = 1
            else:
                block_x = block_x + (abs(bound_block) * 170)

        if block_direction == 1:
            block_x_next = block_x + 3
        else:
            block_x_next = block_x - 3
        if flag:
            pred_x_next = pred_x + speed[0]
            pred_y_next = pred_y + speed[1]
        else:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = pred_y + scene_info["ball_speed"][1]
        flag2 = 1
        for i in range(3):
            if pred_x_next < 0 or pred_x_next > 200:
                flag2 = -1
            pred_x_next2 = wall_correction(pred_x_next, 195, 0)
            pred = hit_side(pred_x_next2, pred_y_next, flag, block_direction,
                            pred, block_x_next, speed)
            if block_direction == 1:
                block_x_next = block_x_next + 3
            else:
                block_x_next = block_x_next - 3
            if flag:
                pred_x_next = pred_x_next + speed[0]
                pred_y_next = pred_y_next + speed[1]
            else:
                pred_x_next = pred_x_next + scene_info["ball_speed"][0]
                pred_y_next = pred_y_next + scene_info["ball_speed"][1]
        return pred

    def hit_side(pred_x_next, pred_y_next, flag, block_direction, pred,
                 block_x_next, speed):
        #print(pred_x_next, pred_y_next, scene_info["ball"], block_x_next, scene_info["blocker"])
        if pred_x_next > block_x_next - 5 and pred_x_next < block_x_next + 30 and pred_y_next >= 235 and pred_y_next <= 260:
            if block_direction == 1:
                pred_x_next = block_x_next - 5
            else:
                pred_x_next = block_x_next
            if not flag:
                pred_y_next = pred_y_next + scene_info["ball_speed"][1]
                frame = (scene_info["platform_1P"][1] - 5 -
                         pred_y_next) // (scene_info["ball_speed"][1])
                pred2 = pred_x_next + scene_info["ball_speed"][0] * (frame + 1)
            else:
                pred_y_next = pred_y_next + speed[1]
                frame = (scene_info["platform_1P"][1] - 5 -
                         pred_y_next) // (speed[1])
                pred2 = pred_x_next + speed[0] * (frame + 1)
            pred2 = wall_correction(pred, 195, 0)
            return pred2
        else:
            return pred

    def hit_blocker_side2(pred):
        x = 100 - (scene_info["frame"] % 100)
        block_frame = (scene_info["blocker"][1] + 20 -
                       scene_info["ball"][1]) // (scene_info["ball_speed"][1])
        pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] * x)
        flag = 0
        speed = scene_info["ball_speed"]
        if pred_y <= 260:
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              block_frame)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              block_frame)
        else:
            if scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, 1])
            elif scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, -1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, 1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, -1])
            y = (scene_info["blocker"][1] + 20 - pred_y) // (
                speed[1])  # 幾個frame以後會到障礙物的位置(
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              x) + (speed[0] * y)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              x) + (speed[1] * y)
            block_frame = x + y
            flag = 1

        block_direction = get_block_direction(scene_info["blocker"][0], s)
        if block_direction == 1:
            block_x = scene_info["blocker"][0] + 3 * block_frame
        else:
            block_x = scene_info["blocker"][0] - 3 * block_frame
        bound_block = block_x // 170
        if bound_block > 0:
            if bound_block % 2 == 0:
                block_x = block_x - (bound_block * 170)
            else:
                block_x = 170 - (block_x - 170 * bound_block)
                block_direction = 0
        elif bound_block < 0:
            if (bound_block % 2 == 1):
                block_x = abs(block_x - (bound_block + 1) * 170)
                block_direction = 1
            else:
                block_x = block_x + (abs(bound_block) * 170)

        if block_direction == 1:
            block_x_next = block_x + 3
        else:
            block_x_next = block_x - 3
        if flag:
            pred_x_next = pred_x + speed[0]
            pred_y_next = pred_y + speed[1]
        else:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = pred_y + scene_info["ball_speed"][1]
        flag2 = 1
        for i in range(3):
            if pred_x_next < 0 or pred_x_next > 200:
                flag2 = -1
            pred_x_next2 = wall_correction(pred_x_next, 195, 0)
            pred = hit_side2(pred_x_next2, pred_y_next, flag, block_direction,
                             pred, block_x_next, speed)
            if block_direction == 1:
                block_x_next = block_x_next + 3
            else:
                block_x_next = block_x_next - 3
            if flag:
                pred_x_next = pred_x_next + speed[0]
                pred_y_next = pred_y_next + speed[1]
            else:
                pred_x_next = pred_x_next + scene_info["ball_speed"][0]
                pred_y_next = pred_y_next + scene_info["ball_speed"][1]
        return pred

    def hit_side2(pred_x_next, pred_y_next, flag, block_direction, pred,
                  block_x_next, speed):
        #print(pred_x_next, pred_y_next, scene_info["ball"], block_x_next, scene_info["blocker"])
        if pred_x_next > block_x_next - 5 and pred_x_next < block_x_next + 30 and pred_y_next >= 235 and pred_y_next <= 260:
            if block_direction == 1:
                pred_x_next = block_x_next - 5
            else:
                pred_x_next = block_x_next
            if not flag:
                pred_y_next = pred_y_next + scene_info["ball_speed"][1]
                frame = (scene_info["platform_2P"][1] + 30 -
                         pred_y_next) // (scene_info["ball_speed"][1])
                pred2 = pred_x_next + scene_info["ball_speed"][0] * (frame + 1)
            else:
                pred_y_next = pred_y_next + speed[1]
                frame = (scene_info["platform_2P"][1] + 30 -
                         pred_y_next) // (speed[1])
                pred2 = pred_x_next + speed[0] * (frame + 1)
            pred2 = wall_correction(pred, 195, 0)
            return pred2
        else:
            return pred

    def hit_blocker_up():
        x = 100 - (scene_info["frame"] % 100)
        block_frame = (scene_info["blocker"][1] -
                       scene_info["ball"][1]) // (scene_info["ball_speed"][1])
        pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] * x)
        flag = 0
        speed = scene_info["ball_speed"]
        if pred_y >= 235:
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              block_frame)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              block_frame)
        else:
            if scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, 1])
            elif scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, -1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, 1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, -1])
            y = (scene_info["blocker"][1] + 20 - pred_y) // (speed[1])
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              x) + (speed[0] * y)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              x) + (speed[1] * y)
            block_frame = x + y
            flag = 1

        block_direction = get_block_direction(scene_info["blocker"][0], s)
        if block_direction == 1:
            block_x = scene_info["blocker"][0] + 3 * block_frame
        else:
            block_x = scene_info["blocker"][0] - 3 * block_frame
        block_x = wall_correction(block_x, 170, 0)

        if block_direction == 1:
            block_x_next = block_x + 3
        else:
            block_x_next = block_x - 3

        if flag:
            pred_x_next = pred_x + speed[0]
            pred_y_next = pred_y + speed[1]
        else:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = pred_y + scene_info["ball_speed"][1]

        pred_x_next = wall_correction(pred_x_next, 195, 0)
        block_x_next = wall_correction(block_x_next, 170, 0)
        if pred_x_next > block_x_next - 5 and pred_x_next < block_x_next + 30:
            pred = hit_up(pred_x, speed, flag)
            pred = wall_correction(pred, 195, 0)
            return pred

        else:
            return 80

    def hit_up(pred_x, speed, flag):
        if not flag:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = 235
            frame = (scene_info["platform_1P"][1] - 5 -
                     260) // (-scene_info["ball_speed"][1])
            pred = pred_x_next + scene_info["ball_speed"][0] * (frame + 1)
        else:
            pred_x_next = pred_x + speed[0]
            pred_y_next = 235
            frame = (scene_info["platform_1P"][1] - 5 - 260) // (-speed[1])
            pred = pred_x_next + speed[0] * (frame + 1)
        return pred

    def hit_blocker_down():
        x = 100 - (scene_info["frame"] % 100)
        block_frame = (scene_info["blocker"][1] + 20 -
                       scene_info["ball"][1]) // (scene_info["ball_speed"][1])
        pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] * x)
        flag = 0
        speed = scene_info["ball_speed"]
        if pred_y <= 260:
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              block_frame)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              block_frame)
        else:
            if scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, 1])
            elif scene_info["ball_speed"][0] > 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [1, -1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] > 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, 1])
            elif scene_info["ball_speed"][0] < 0 and scene_info["ball_speed"][
                    1] < 0:
                speed = tuple(list(scene_info["ball_speed"]) + [-1, -1])
            y = (scene_info["blocker"][1] + 20 - pred_y) // (speed[1])
            pred_x = scene_info["ball"][0] + (scene_info["ball_speed"][0] *
                                              x) + (speed[0] * y)
            pred_y = scene_info["ball"][1] + (scene_info["ball_speed"][1] *
                                              x) + (speed[1] * y)
            block_frame = x + y
            flag = 1

        block_direction = get_block_direction(scene_info["blocker"][0], s)
        if block_direction == 1:
            block_x = scene_info["blocker"][0] + 3 * block_frame
        else:
            block_x = scene_info["blocker"][0] - 3 * block_frame
        block_x = wall_correction(block_x, 170, 0)

        if block_direction == 1:
            block_x_next = block_x + 3
        else:
            block_x_next = block_x - 3
        if flag:
            pred_x_next = pred_x + speed[0]
            pred_y_next = pred_y + speed[1]
        else:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = pred_y + scene_info["ball_speed"][1]

        pred_x_next = wall_correction(pred_x_next, 195, 0)
        block_x_next = wall_correction(block_x_next, 170, 0)

        if pred_x_next > block_x_next - 5 and pred_x_next < block_x_next + 30:
            pred = hit_down(pred_x, speed, flag)
            pred = wall_correction(pred, 195, 0)
            return pred

        else:
            return 80

    def hit_down(pred_x, speed, flag):
        if not flag:
            pred_x_next = pred_x + scene_info["ball_speed"][0]
            pred_y_next = 260
            frame = (scene_info["platform_1P"][1] - 5 -
                     260) // (-scene_info["ball_speed"][1])
            pred = pred_x_next + scene_info["ball_speed"][0] * (frame + 1)
        else:
            pred_x_next = pred_x + speed[0]
            pred_y_next = 260
            frame = (scene_info["platform_1P"][1] - 5 - 260) // (-speed[1])
            pred = pred_x_next + speed[0] * (frame + 1)
        return pred

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()
            s = scene_info['blocker'][0]

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #26
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    last_blocker_pos = (-1, -1)
    p_blocker = 0
    p_frame = -1
    ball_served = False

    def cut_to(player, speedx, way):
        if player == '1P':
            if way == 'same':
                print("same cut")
                if speedx > 0:
                    return 1
                else:
                    return 2
            elif way == 'reverse':
                print("reserve cut")
                if speedx > 0:
                    return 2
                else:
                    return 1

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P(blocker_dir):
        p_blocker = 0
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            x = (
                scene_info["platform_1P"][1] - scene_info["ball"][1]
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x
            )  # 預測最終位置 # pred means predict ball landing site
            bound = pred // 200  # Determine if it is beyond the boundary
            if (bound > 0):  # pred > 200 # fix landing position
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):  # pred < 0
                if (bound % 2 == 1):
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            if abs(
                    scene_info["ball"][1] + 5 - scene_info["platform_1P"][1]
            ) < scene_info["ball_speed"][
                    1]:  #scene_info["ball_speed"][1] > abs(scene_info["platform_1P"][1]-scene_info["ball"][1]-5)
                print("close to 1p plat")
                print("frame: ", scene_info["frame"])
                f = (160) // abs(scene_info["ball_speed"][1])
                print(f)
                speed_range = scene_info["frame"] // 100
                p_blocker = f
                if (scene_info["frame"] + f) // 100 > speed_range:
                    f_n = (160 -
                           ((speed_range + 1) * 100 - scene_info["frame"]) *
                           abs(scene_info["ball_speed"][1])) // (
                               abs(scene_info["ball_speed"][1]) + 1)
                    f = (speed_range + 1) * 100 - scene_info["frame"] + f_n
                    p_blocker = f
                    print("new f", f)
                blocker_pred = scene_info["blocker"][0] + (5 * blocker_dir * f)
                blocker_bound = blocker_pred // 200  # Determine if it is beyond the boundary
                if (blocker_bound > 0):  # pred > 200 # fix landing position
                    if (blocker_bound % 2 == 0):
                        blocker_pred = blocker_pred - blocker_bound * 200
                    else:
                        blocker_pred = 200 - (blocker_pred -
                                              200 * blocker_bound)
                elif (blocker_bound < 0):  # pred < 0
                    if (blocker_bound % 2 == 1):
                        blocker_pred = abs(blocker_pred -
                                           (blocker_bound + 1) * 200)
                    else:
                        blocker_pred = blocker_pred + (abs(blocker_bound) *
                                                       200)
                print("blocker now: ", scene_info["blocker"][0])
                print("blocker pred: ", blocker_pred)
                print("ball now: ", scene_info["ball"])
                print("ball speed now: ", abs(scene_info["ball_speed"][1]))
                cut_r = False
                cut_s = False

                if scene_info["ball_speed"][0] > 0:
                    ball_pred = scene_info["ball"][0] + abs(
                        scene_info["ball"][1] + 5 -
                        scene_info["platform_1P"][1]) + (
                            (scene_info["ball_speed"][0] + 3) * f)
                else:
                    ball_pred = scene_info["ball"][0] - abs(
                        scene_info["ball"][1] + 5 -
                        scene_info["platform_1P"][1]) + (
                            (scene_info["ball_speed"][0] - 3) * f)
                ball_bound = ball_pred // 200  # Determine if it is beyond the boundary
                if (ball_bound > 0):  # pred > 200 # fix landing position
                    if (ball_bound % 2 == 0):
                        ball_pred = ball_pred - ball_bound * 200
                    else:
                        ball_pred = 200 - (ball_pred - 200 * ball_bound)
                elif (ball_bound < 0):  # pred < 0
                    if (ball_bound % 2 == 1):
                        ball_pred = abs(ball_pred - (ball_bound + 1) * 200)
                    else:
                        ball_pred = ball_pred + (abs(ball_bound) * 200)
                cut_svalue = 0
                if (ball_pred + 5 < blocker_pred - 15
                        or ball_pred > blocker_pred + 45):
                    cut_s = True
                    if ball_pred + 5 < blocker_pred - 10:
                        cut_svalue = blocker_pred - ball_pred + 5
                    else:
                        cut_svalue = ball_pred - blocker_pred + 30
                print("cut s ball pred: ", ball_pred)

                if scene_info["ball_speed"][0] > 0:
                    ball_pred = scene_info["ball"][0] + abs(
                        scene_info["ball"][1] + 5 -
                        scene_info["platform_1P"][1]) + (
                            -scene_info["ball_speed"][0] * f)
                else:
                    ball_pred = scene_info["ball"][0] - abs(
                        scene_info["ball"][1] + 5 -
                        scene_info["platform_1P"][1]) + (
                            -scene_info["ball_speed"][0] * f)
                ball_bound = ball_pred // 200  # Determine if it is beyond the boundary
                if (ball_bound > 0):  # pred > 200 # fix landing position
                    if (ball_bound % 2 == 0):
                        ball_pred = ball_pred - ball_bound * 200
                    else:
                        ball_pred = 200 - (ball_pred - 200 * ball_bound)
                elif (ball_bound < 0):  # pred < 0
                    if (ball_bound % 2 == 1):
                        ball_pred = abs(ball_pred - (ball_bound + 1) * 200)
                    else:
                        ball_pred = ball_pred + (abs(ball_bound) * 200)

                cut_rvalue = 0
                if (ball_pred + 5 < blocker_pred - 15
                        or ball_pred > blocker_pred + 45):
                    cut_r = True
                    if ball_pred + 5 < blocker_pred - 10:
                        cut_rvalue = blocker_pred - ball_pred + 5
                    else:
                        cut_rvalue = ball_pred - blocker_pred + 30
                print("cut r ball pred: ", ball_pred)
                if cut_r and cut_s:
                    if cut_rvalue >= cut_svalue:
                        return cut_to(player='1P',
                                      speedx=scene_info["ball_speed"][0],
                                      way='reverse'), p_blocker
                    else:
                        return cut_to(player='1P',
                                      speedx=scene_info["ball_speed"][0],
                                      way='same'), p_blocker
                elif cut_r:
                    return cut_to(player='1P',
                                  speedx=scene_info["ball_speed"][0],
                                  way='reverse'), p_blocker
                elif cut_s:
                    return cut_to(player='1P',
                                  speedx=scene_info["ball_speed"][0],
                                  way='same'), p_blocker
                else:
                    return move_to(player='1P', pred=pred), p_blocker
            else:
                if pred > 180:
                    return move_to(player='1P', pred=185), 0
                elif pred < 20:
                    return move_to(player='1P', pred=15), 0
                else:
                    return move_to(player='1P', pred=pred), 0
        else:  # 球正在向上 # ball goes up
            return move_to(player='1P', pred=100), 0

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    t1 = 0
    t2 = 0
    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        if (scene_info["ball"][0]+5 >= scene_info["blocker"][0] and scene_info["ball"][0] < scene_info["blocker"][0]+30) and \
            abs(scene_info["ball"][1]-(scene_info["blocker"][1]+20)) < abs(scene_info["ball_speed"][1]) and scene_info["ball_speed"][1]<0:
            print("crush frame", scene_info["frame"], ": ball x: ",
                  scene_info["ball"], " blocker: ", scene_info["blocker"])
            print("ball speed now: ", abs(scene_info["ball_speed"][1]))
            print("crush!!!")
        if scene_info["frame"] == 0:
            t1 = time.monotonic()
        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False
            last_blocker_pos = (-1, -1)
            p_blocker = 0
            p_frame = -1
            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            t2 = time.monotonic()
            print("game time: {:8.3f}seconds".format(t2 - t1))
            print("final speed: " + str(abs(scene_info["ball_speed"][1])))
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            blocker_direct = 0
            if last_blocker_pos[0] - scene_info["blocker"][0] > 0:
                blocker_direct = 1
            else:
                blocker_direct = -1
            #print("blocker speed",abs(last_blocker_pos[0] - scene_info["blocker"][0]))
            print("current frame :", scene_info["frame"], " ball: ",
                  scene_info["ball"], " blocker: ", scene_info["blocker"])
            last_blocker_pos = scene_info["blocker"]

            if p_frame != -1 and scene_info["frame"] == p_frame:
                print("close frame", scene_info["frame"], ": ball x: ",
                      scene_info["ball"], " blocker: ", scene_info["blocker"])
                p_frame = -1
            if side == "1P":
                command, p_blocker = ml_loop_for_1P(-blocker_direct)
                if p_blocker != 0:
                    p_frame = scene_info["frame"] + p_blocker
                    print("p frame: ", p_frame)
                    p_blocker = 0
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #27
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def transformCommand(command):
        if 'RIGHT' in str(command):
            return 2
        elif 'LEFT' in str(command):
            return 1
        else:
            return 0
        pass

    def get_ArkanoidData(filename):
        Frames = []
        Balls = []
        Commands = []
        PlatformPos = []
        log = pickle.load((open(filename, 'rb')))
        for sceneInfo in log:
            Frames.append(sceneInfo.frame)
            Balls.append([sceneInfo.ball[0], sceneInfo.ball[1]])
            PlatformPos.append(sceneInfo.platform)
            Commands.append(transformCommand(sceneInfo.command))

        commands_ary = np.array([Commands])
        commands_ary = commands_ary.reshape((len(Commands), 1))
        frame_ary = np.array(Frames)
        frame_ary = frame_ary.reshape((len(Frames), 1))
        data = np.hstack((frame_ary, Balls, PlatformPos, commands_ary))
        return data

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def cut_ball(cut_dirc):
        """
        0加速 1原路徑 2向右 3向左

        """
        if cut_dirc == 0:  #切球反方向
            if scene_info["ball_speed"][0] > 0:
                return 1
            else:
                return 2
        elif cut_dirc == 1:
            if scene_info["ball_speed"][0] > 0:
                return 2
            else:
                return 1
        elif cut_dirc == 2:
            return 1
        else:
            return 2

    def pred_block_1P():

        if scene_info["ball_speed"][1] > 0 and scene_info["ball"][
                1] > 420 and scene_info["ball"][1] < 240:
            x = (
                scene_info["ball"][1] - scene_info["blocker"][1] + 180
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會遇到block  # x means how many frames before catch the ball
            pred_nc = scene_info["ball"][0] + x * scene_info["ball_speed"][0]
            bound = pred_nc // 200
            block_pos = scene_info["blocker"][0]
            bound_b = block_pos // 200
            print("xx")
            if bound > 0:
                if bound % 2 == 0:
                    pred_nc = pred_nc - 200 * bound
                else:
                    pred_nc = 200 - (pred_nc - 200 * bound)
            else:
                if bound % 2 == 1:
                    pred_nc = abs(pred_nc - (bound + 1) * 200)
                else:
                    pred_nc = pred_nc + (abs(bound) * 200)

            if bound_b > 0:
                if bound_b % 2 == 0:
                    block_pos = block_pos - 200 * bound_b
                else:
                    block_pos = 200 - (block_pos - 200 * bound_b)
            else:
                if bound_b % 2 == 1:
                    block_pos = abs(block_pos - (bound_b + 1) * 200)
                else:
                    block_pos = block_pos + (abs(bound_b) * 200)
            print("blcok ", block_pos, " ball ", pred_nc)
            if (block_pos + 30 - pred_nc) < 35 and (block_pos + 30 -
                                                    pred_nc) > -5:
                return 1
            else:
                return 0

    def block_speed(x, pre_x):
        vector_x = x - pre_x
        return vector_x

    def ml_loop_for_1P():
        if scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down

            x = (
                scene_info["platform_1P"][1] - scene_info["ball"][1]
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x
            )  # 預測最終位置 # pred means predict ball landing site
            bound = pred // 200  # Determine if it is beyond the boundary
            if (bound > 0):  # pred > 200 # fix landing position
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):  # pred < 0
                if (bound % 2 == 1):
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            if x <= 1 and move_to('1P', pred) == 0:
                if (scene_info["blocker"][0] > 135 or scene_info["blocker"][0]
                        < 35) and scene_info["frame"] < 1000:
                    return cut_ball(0)
                elif scene_info["frame"] > 1000:
                    return cut_ball(1)
            return move_to(player='1P', pred=pred)
        else:  # 球正在向上 # ball goes up
            #          pred =
            return move_to(player='1P', pred=100)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            if x <= 2 and move_to('2P', pred) == 0:
                if scene_info['platform_2P'][0] < 50 and scene_info['blocker'][
                        0] > 150:
                    return cut_ball(1)
                elif scene_info['platform_2P'][0] < 100 and scene_info[
                        'blocker'][0] > 100:
                    return cut_ball(1)
                elif scene_info['platform_2P'][0] < 150 and scene_info[
                        'blocker'][0] > 75:
                    return cut_ball(1)
                elif scene_info['platform_2P'][0] < 180 and scene_info[
                        'blocker'][0] > 80:
                    return cut_ball(1)
                else:
                    return cut_ball(0)

            else:
                return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()
        feature = []
        feature.append(scene_info["blocker"][0])
        feature.append(scene_info["ball"][0])
        feature.append(scene_info["ball"][1])
        feature.append(scene_info["ball_speed"][0])
        feature.append(scene_info["ball_speed"][1])
        print(feature)

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True
        else:
            if side == "1P":
                command = ml_loop_for_1P()
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #28
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process
    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```
    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    blocker_last_x = 0

    class Pred:
        pred = 100
        blocker_pred_x = 0
        last_command = 0
        blocker_vx = 0

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P():
        # ball slicing
        if scene_info["ball_speed"][1] > 0 and (
                scene_info["ball"][1] +
                scene_info["ball_speed"][1]) >= 415 and Pred.last_command == 0:
            print("------")
            ball_x = scene_info["ball"][0]
            ball_y = scene_info["ball"][1]
            ball_vx = scene_info["ball_speed"][0]
            ball_slice_vx = scene_info["ball_speed"][0] + np.sign(
                scene_info["ball_speed"][0]) * 3
            ball_vy = scene_info["ball_speed"][1]
            blocker_x = scene_info['blocker'][0] + Pred.blocker_vx

            y = abs((415 - ball_y) // ball_vy)
            pred_ball_1P = ball_x + ball_vx * y

            y = abs((415 - 260) // ball_vy)
            pred_ball_blocker = pred_ball_1P + ball_slice_vx * y
            bound = pred_ball_blocker // 200  # Determine if it is beyond the boundary
            if (bound > 0):  # pred > 200 # fix landing position
                if (bound % 2 == 0):
                    pred_ball_blocker = pred_ball_blocker - bound * 200
                else:
                    pred_ball_blocker = 200 - (pred_ball_blocker - 200 * bound)
            elif (bound < 0):  # pred < 0
                if (bound % 2 == 1):
                    pred_ball_blocker = abs(pred_ball_blocker -
                                            (bound + 1) * 200)
                else:
                    pred_ball_blocker = pred_ball_blocker + (abs(bound) * 200)

            y = abs((415 - 260) // ball_vy)
            Pred.blocker_pred_x = blocker_x + Pred.blocker_vx * y
            if Pred.blocker_pred_x < 0:
                Pred.blocker_pred_x = abs(Pred.blocker_pred_x)
            elif Pred.blocker_pred_x > 170:
                Pred.blocker_pred_x = 170 - (Pred.blocker_pred_x - 170)

            if pred_ball_blocker >= Pred.blocker_pred_x - 10 and pred_ball_blocker < Pred.blocker_pred_x + 40:
                print("slice will hit blicker")
                # don't slice
                # use origin ball vx to predict will hit blocker or not
                # if will hit blicker let ball go reverse direction
                y = abs((415 - 260) // ball_vy)
                pred_ball_blocker = pred_ball_1P + ball_vx * y
                bound = pred_ball_blocker // 200  # Determine if it is beyond the boundary
                if (bound > 0):  # pred > 200 # fix landing position
                    if (bound % 2 == 0):
                        pred_ball_blocker = pred_ball_blocker - bound * 200
                    else:
                        pred_ball_blocker = 200 - (pred_ball_blocker -
                                                   200 * bound)
                elif (bound < 0):  # pred < 0
                    if (bound % 2 == 1):
                        pred_ball_blocker = abs(pred_ball_blocker -
                                                (bound + 1) * 200)
                    else:
                        pred_ball_blocker = pred_ball_blocker + (abs(bound) *
                                                                 200)

                if pred_ball_blocker >= Pred.blocker_pred_x - 10 and pred_ball_blocker < Pred.blocker_pred_x + 40:
                    print("will hit blocker, hit reversed direction")
                    if scene_info["ball_speed"][0] > 0: return 2
                    else: return 1
                else:
                    print("will not hit blicker, do nothing")
                    return 0
            else:
                # slice
                print("slice will not hit blocker")
                if scene_info["ball_speed"][0] > 0: return 1
                else: return 2

        elif scene_info["ball_speed"][1] > 0:  # 球正在向下 # ball goes down
            x = (
                scene_info["platform_1P"][1] - scene_info["ball"][1]
            ) // scene_info["ball_speed"][
                1]  # 幾個frame以後會需要接  # x means how many frames before catch the ball
            Pred.pred = scene_info["ball"][0] + (
                scene_info["ball_speed"][0] * x
            )  # 預測最終位置 # pred means predict ball landing site
            bound = Pred.pred // 200  # Determine if it is beyond the boundary
            if (bound > 0):  # pred > 200 # fix landing position
                if (bound % 2 == 0):
                    Pred.pred = Pred.pred - bound * 200
                else:
                    Pred.pred = 200 - (Pred.pred - 200 * bound)
            elif (bound < 0):  # pred < 0
                if (bound % 2 == 1):
                    Pred.pred = abs(Pred.pred - (bound + 1) * 200)
                else:
                    Pred.pred = Pred.pred + (abs(bound) * 200)
            return move_to(player='1P', pred=Pred.pred)

        else:  # 球正在向上 # ball goes up
            return move_to(player='1P', pred=100)

    def ml_loop_for_2P():  # as same as 1P
        if scene_info["ball_speed"][1] > 0:
            return move_to(player='2P', pred=100)
        else:
            x = (scene_info["platform_2P"][1] + 30 -
                 scene_info["ball"][1]) // scene_info["ball_speed"][1]
            pred = scene_info["ball"][0] + (scene_info["ball_speed"][0] * x)
            bound = pred // 200
            if (bound > 0):
                if (bound % 2 == 0):
                    pred = pred - bound * 200
                else:
                    pred = 200 - (pred - 200 * bound)
            elif (bound < 0):
                if bound % 2 == 1:
                    pred = abs(pred - (bound + 1) * 200)
                else:
                    pred = pred + (abs(bound) * 200)
            return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            blocker_last_x = scene_info["blocker"][0]
            Pred.last_command = 0
            ball_served = True
        else:
            if side == "1P":
                Pred.blocker_vx = scene_info["blocker"][0] - blocker_last_x
                if scene_info["blocker"][0] == 0: Pred.blocker_vx = 5
                elif scene_info["blocker"][0] == 170: Pred.blocker_vx = -5
                command = ml_loop_for_1P()
                blocker_last_x = scene_info["blocker"][0]
                Pred.last_command = command
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
Example #29
0
def ml_loop(side: str):
    """
    The main loop for the machine learning process

    The `side` parameter can be used for switch the code for either of both sides,
    so you can write the code for both sides in the same script. Such as:
    ```python
    if side == "1P":
        ml_loop_for_1P()
    else:
        ml_loop_for_2P()
    ```

    @param side The side which this script is executed for. Either "1P" or "2P".
    """

    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False
    curPath = os.path.abspath(os.path.dirname(__file__))
    model = tf.keras.models.load_model(curPath + '/saved_model/myModel')

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            return "RESET"

        # 3.3 Put the code here to handle the scene information

        # 3.4 Send the instruction for this frame to the game process
        if not ball_served:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_RIGHT"
            })
            ball_served = True
        else:
            ballX = scene_info["ball"][0]
            ballY = scene_info["ball"][1]
            ball_speed_X = scene_info["ball_speed"][0]
            ball_speed_Y = scene_info["ball_speed"][1]
            platform_1P_X = scene_info["platform_1P"][0]
            blocker_X = scene_info["blocker"][0]
            features = [[
                ballX, ballY, ball_speed_X, ball_speed_Y, platform_1P_X,
                blocker_X
            ]]
            prediction = model.predict(features)
            if prediction > 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
                print("MOVE_RIGHT")
            elif prediction < 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
                print("MOVE_LEFT")
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "SERVE_TO_RIGHT"
                })
                print("NONE")
Example #30
0
def ml_loop(side: str):
    with open(os.path.join(os.path.dirname(__file__), 'save', 'model.pickle'),
              'rb') as f:
        model = pickle.load(f)
    # === Here is the execution order of the loop === #
    # 1. Put the initialization code here
    ball_served = False

    def move_to(player,
                pred):  #move platform to predicted position to catch ball
        if player == '1P':
            """
            if scene_info["platform_1P"][0]+20  > (pred-10) and scene_info["platform_1P"][0]+20 < (pred+10): return 0 # NONE
            elif scene_info["platform_1P"][0]+20 <= (pred-10) : return 1 # goes right
            else : return 2 # goes left
            """
            if scene_info["platform_1P"][0] + 20 > (
                    pred - 10) and scene_info["platform_1P"][0] + 20 < (pred +
                                                                        10):
                if scene_info["platform_1P"][1] + 30 - scene_info[
                        "ball_speed"][1] > scene_info["ball"][1]:  #slice
                    return 0
                    #if scene_info["ball"][0] > scene_info["platform_2P"][0]+20 and scene_info["ball_speed"][0] > 0:
                    #    return 1
                    #elif scene_info["ball"][0] > scene_info["platform_2P"][0]+20 and scene_info["ball_speed"][0] < 0:
                    #    return 1
                else:
                    return 0  # NONE
            elif scene_info["platform_1P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left
        else:
            if scene_info["platform_2P"][0] + 20 > (
                    pred - 10) and scene_info["platform_2P"][0] + 20 < (pred +
                                                                        10):
                if scene_info["platform_2P"][1] + 30 - scene_info[
                        "ball_speed"][1] > scene_info["ball"][1]:  #slice
                    return 0
                    #if scene_info["ball"][0] > scene_info["platform_2P"][0]+20 and scene_info["ball_speed"][0] > 0:
                    #    return 1
                    #elif scene_info["ball"][0] > scene_info["platform_2P"][0]+20 and scene_info["ball_speed"][0] < 0:
                    #    return 1
                else:
                    return 0  # NONE
            elif scene_info["platform_2P"][0] + 20 <= (pred - 10):
                return 1  # goes right
            else:
                return 2  # goes left

    def ml_loop_for_1P(before_block_x, block_x):
        """        
        if scene_info["ball_speed"][1] > 0 : # 球正在向下 # ball goes down
            x = ( scene_info["platform_1P"][1]-scene_info["ball"][1] ) // scene_info["ball_speed"][1] # 幾個frame以後會需要接  # x means how many frames before catch the ball
            pred = scene_info["ball"][0]+(scene_info["ball_speed"][0]*x)  # 預測最終位置 # pred means predict ball landing site 
            bound = pred // 200 # Determine if it is beyond the boundary
            if (bound > 0): # pred > 200 # fix landing position
                if (bound%2 == 0) : 
                    pred = pred - bound*200                    
                else :
                    pred = 200 - (pred - 200*bound)
            elif (bound < 0) : # pred < 0
                if (bound%2 ==1) :
                    pred = abs(pred - (bound+1) *200)
                else :
                    pred = pred + (abs(bound)*200)
            return move_to(player = '1P',pred = pred)
        else : # 球正在向上 # ball goes up
            return move_to(player = '1P',pred = 100)
        """

        ball_x = scene_info["ball"][0]
        ball_y = scene_info["ball"][1]

        platform_x = scene_info["platform_1P"][0]
        platform_y = scene_info["platform_1P"][1]

        block_x = scene_info["blocker"][0]
        block_y = scene_info["blocker"][1]

        ball_x_speed = scene_info["ball_speed"][0]
        ball_y_speed = scene_info["ball_speed"][1]

        frame = scene_info["frame"]

        speed = block_x - before_block_x

        while ball_y < 415:

            if (frame % 200) == 0 and frame >= 200:
                if ball_x_speed > 0:
                    ball_x_speed = abs(ball_x_speed) + 1
                else:
                    ball_x_speed = -abs(ball_x_speed) - 1
                if ball_y_speed > 0:
                    ball_y_speed = abs(ball_y_speed) + 1
                else:
                    ball_y_speed = -abs(ball_y_speed) - 1

            predict_ball_x_speed = ball_x_speed
            predict_ball_y_speed = ball_y_speed
            predict_ball_x = ball_x
            predict_ball_y = ball_y

            hit_y_left = (ball_y_speed / ball_x_speed) * (block_x -
                                                          ball_x) + ball_y
            hit_y_right = (ball_y_speed / ball_x_speed) * (block_x + 30 -
                                                           ball_x) + ball_y
            hit_x_top = (ball_x_speed / ball_y_speed) * (240 - ball_y) + ball_x
            hit_x_down = (ball_x_speed / ball_y_speed) * (260 -
                                                          ball_y) + ball_x
            #print("hit_y_left: ",hit_y_left,"hit_y_right: ",hit_y_right)
            if ball_x + ball_x_speed < block_x + 30 < ball_x and 240 < hit_y_right < 260:
                predict_ball_x = block_x + 30
                predict_ball_x_speed = -ball_x_speed

            elif ball_x < block_x < ball_x + ball_x_speed and 240 < hit_y_left < 260:
                predict_ball_x = block_x
                predict_ball_x_speed = -ball_x_speed

            #print("hit_x_top: ",hit_x_top,"hit_x_down: ",hit_x_down)
            if ball_y + ball_y_speed < 260 < ball_y and block_x < hit_x_down < block_x + 30:
                predict_ball_y = 260
                predict_ball_y_speed = -ball_y_speed

            elif ball_y < 240 < ball_y + ball_y_speed and block_x < hit_x_top < block_x + 30:
                predict_ball_y = 240
                predict_ball_y_speed = -ball_y_speed

            else:
                predict_ball_y = ball_y + ball_y_speed

            if block_x + speed > 170:
                speed = -speed
                predict_block_x = 170

            elif block_x + speed < 0:
                speed = -speed

                predict_block_x = 0

            else:

                predict_block_x = block_x + speed

            if ball_x != predict_ball_x:
                ball_x = predict_ball_x
            else:
                ball_x = ball_x + predict_ball_x_speed

            if ball_y != predict_ball_y:
                ball_y = predict_ball_y
            else:
                ball_y = ball_y + predict_ball_y_speed

            if ball_y >= 415:

                predict_ball_y_speed = -predict_ball_y_speed
                """
                if ball_x_speed>0:
                    if command_1P=="MOVE_LEFT":
                        predict_ball_x_speed=-predict_ball_x_speed
                if ball_x_speed<0:
                    if command_1P=="MOVE_RIGHT":
                        predict_ball_x_speed=-predict_ball_x_speed
                """
                ball_y = 415
            elif ball_y < 80:
                predict_ball_y_speed = -predict_ball_y_speed
                ball_x = 80

            if ball_x > 195:
                predict_ball_x_speed = -predict_ball_x_speed
                ball_x = 195
            elif ball_x < 0:
                predict_ball_x_speed = -predict_ball_x_speed
                ball_x = 0

            ball_x_speed = predict_ball_x_speed
            ball_y_speed = predict_ball_y_speed
            block_x = predict_block_x

            frame += 1

        should_x2 = ball_x
        #print(should_x2)
        print(
            should_x2,
            "PLATFORM_x:",
            scene_info["platform_1P"][0],
            "frame",
            scene_info["frame"],
            "x:",
            scene_info["ball"][0],
            "y:",
            scene_info["ball"][1],
            "block_x:",
            scene_info["blocker"][0],
            "block_y:",
            scene_info["blocker"][1],
            "ball_speed_x:",
            scene_info["ball_speed"][0],
            "ball_speed_y:",
            scene_info["ball_speed"][1],
        )
        return move_to(player='1P', pred=should_x2)
        """
        # if 240<scene_info["ball"][1]<260 and scene_info["ball"][0]!=0 and scene_info["ball"][0]!=195 and ball_x_speed!=before_ball_x_speed:
        #   scene_info["blocker"][0],"block_y:",scene_info["blocker"][1] 


        now_ball_x=ball_x
        now_ball_y=ball_y
        
        now_ball_x=blocker_x

        vector_x_right= True if ball_speed_x>0 else False
        vector_y_down= True if ball_speed_y >0 else False



        hit_y=0

        while hit_y<415:
            if vector_x_right:
                hit_x=195
            else:
                hit_x=0

            if vector_y_down:
                hit_y=415
            else:
                hit_y=80     

            if abs(now_ball_x-hit_x) <abs(now_ball_y-hit_y):
                if vector_y_down:
                    hit_y=((abs(now_ball_x-hit_x)-1)//abs(ball_speed_x)+1)*abs(ball_speed_y)+now_ball_y
                    if hit_y>415:
                        hit_y=((abs(now_ball_x-hit_x))/abs(ball_speed_x))*abs(ball_speed_y)+now_ball_y
                else:
                    hit_y=-((abs(now_ball_x-hit_x)-1)//abs(ball_speed_x)+1)*abs(ball_speed_y)+now_ball_y
                    if hit_y<0:
                        hit_y=-((abs(now_ball_x-hit_x))/abs(ball_speed_x))*abs(ball_speed_y)+now_ball_y
                        
                vector_x_right=not vector_x_right 
            else:
                #這邊可能會切球
                if vector_x_right:
                    hit_x=((abs(now_ball_y-hit_y))/abs(ball_speed_x))*abs(ball_speed_x)+now_ball_x
                else:
                    hit_x=-((abs(now_ball_y-hit_y))/abs(ball_speed_y))*abs(ball_speed_x)+now_ball_x
                vector_y_down=not vector_y_down  




            now_ball_x=hit_x
            now_ball_y=hit_y
        """

    def ml_loop_for_2P():  # as same as 1P
        """
        ball_x=scene_info["ball"][0]
        ball_y=scene_info["ball"][1]

        platform_x=scene_info["platform_1P"][0]
        platform_y=scene_info["platform_1P"][1]

        ball_speed_x=scene_info["ball_speed"][0]
        ball_speed_y=vector_y_down=scene_info["ball_speed"][1]

        now_ball_x=ball_x
        now_ball_y=ball_y

        vector_x_right= True if ball_speed_x>0 else False
        vector_y_down= True if ball_speed_y >0 else False

        hit_y=500


        while hit_y>80:
            if vector_x_right:
                hit_x=195
            else:
                hit_x=0

            if vector_y_down:
                hit_y=415
            else:
                hit_y=80     

            if abs(now_ball_x-hit_x) <abs(now_ball_y-hit_y):
                if vector_y_down:
                    hit_y=((abs(now_ball_x-hit_x)-1)//abs(ball_speed_x)+1)*abs(ball_speed_y)+now_ball_y
                    if hit_y>415:
                        hit_y=((abs(now_ball_x-hit_x))/abs(ball_speed_x))*abs(ball_speed_y)+now_ball_y
                else:
                    hit_y=-((abs(now_ball_x-hit_x)-1)//abs(ball_speed_x)+1)*abs(ball_speed_y)+now_ball_y
                    if hit_y<0:
                        hit_y=-((abs(now_ball_x-hit_x))/abs(ball_speed_x))*abs(ball_speed_y)+now_ball_y
                        
                vector_x_right=not vector_x_right 
            else:
                #這邊可能會切球
                if vector_x_right:
                    hit_x=((abs(now_ball_y-hit_y))/abs(ball_speed_x))*abs(ball_speed_x)+now_ball_x
                else:
                    hit_x=-((abs(now_ball_y-hit_y))/abs(ball_speed_y))*abs(ball_speed_x)+now_ball_x
                vector_y_down=not vector_y_down  
                



            now_ball_x=hit_x
            now_ball_y=hit_y

        should_x=hit_x
        return move_to(player = '2P',pred = should_x)
        """

        # print ("blocker : %s, ball : %s"%(scene_info["blocker"],scene_info["ball"]))
        if scene_info["ball_speed"][1] > 0:
            if scene_info["ball_speed"][0] > 0:
                direction = 0
            else:
                direction = 1
        else:
            if scene_info["ball_speed"][0] > 0:
                direction = 2
            else:
                direction = 3
        X = [
            scene_info["ball"][0], scene_info["ball"][1], direction,
            scene_info["blocker"][0], scene_info["ball_speed"][0],
            scene_info["ball_speed"][1]
        ]
        X = np.array(X).reshape((1, -1))
        pred = model.predict(X)
        return move_to(player='2P', pred=pred)

    # 2. Inform the game process that ml process is ready
    comm.ml_ready()
    i = 0
    block_x = 85

    # 3. Start an endless loop
    while True:
        # 3.1. Receive the scene information sent from the game process
        scene_info = comm.recv_from_game()

        before_block_x = block_x
        block_x = scene_info["blocker"][0]

        # 3.2. If either of two sides wins the game, do the updating or
        #      resetting stuff and inform the game process when the ml process
        #      is ready.
        if scene_info["status"] != "GAME_ALIVE":
            # Do some updating or resetting stuff
            ball_served = False

            # 3.2.1 Inform the game process that
            #       the ml process is ready for the next round
            comm.ml_ready()
            continue

        # 3.3 Put the code here to handle the scene information
        # 3.4 Send the instruction for this frame to the game process
        if i < 150:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "MOVE_LEFT"
            })
            i = i + 1
        elif not ball_served and i == 5:
            comm.send_to_game({
                "frame": scene_info["frame"],
                "command": "SERVE_TO_LEFT"
            })
            ball_served = True

        else:

            if side == "1P":
                command = ml_loop_for_1P(before_block_x, block_x)
            else:
                command = ml_loop_for_2P()

            if command == 0:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "NONE"
                })
            elif command == 1:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_RIGHT"
                })
                #print("right")
            else:
                comm.send_to_game({
                    "frame": scene_info["frame"],
                    "command": "MOVE_LEFT"
                })
                #print("left")
            """