Example #1
0
    def test_push1(self):
        df1 = Dataframe("TEST1", [Car])
        df2 = Dataframe("TEST2", [Car], details=df1.details)
        appname1 = df1.appname
        appname2 = df2.appname
        c = Car(0)

        df2.checkout()
        df2.add_one(Car, c)
        c.xvel = 1
        df2.sync()
        version1 = df1.versioned_heap.version_graph.head.current
        version2 = df2.versioned_heap.version_graph.head.current
        self.assertEqual(version1, version2)
        self.assertDictEqual(df1.versioned_heap.state_to_app, {
            "ROOT": set([appname2]),
            version1: set([appname2])
        })
        self.assertDictEqual(df1.versioned_heap.app_to_state,
                             {appname2: version1})

        self.assertDictEqual(df2.versioned_heap.state_to_app, {
            'ROOT': {appname2},
            version1: {'SOCKETPARENT', appname2}
        })
        self.assertDictEqual(df2.versioned_heap.app_to_state, {
            appname2: version1,
            "SOCKETPARENT": version1
        })
Example #2
0
    def test_push1(self):
        df1 = Dataframe("TEST1", [Car])
        df2 = Dataframe("TEST2", [Car], details=df1.details)
        appname1 = df1.appname
        appname2 = df2.appname
        c = Car(0)
        
        df2.checkout()
        df2.add_one(Car, c)
        c.xvel = 1
        df2.sync()
        version1 = df1.versioned_heap.version_graph.head.current
        version2 = df2.versioned_heap.version_graph.head.current
        self.assertEqual(version1, version2)
        self.assertDictEqual(
            df1.versioned_heap.state_to_app, {"ROOT": set([appname2]), version1: set([appname2])})
        self.assertDictEqual(
            df1.versioned_heap.app_to_state, {appname2: version1})

        self.assertDictEqual(
            df2.versioned_heap.state_to_app,
            {'ROOT': {appname2}, version1: {'SOCKETPARENT', appname2}})
        self.assertDictEqual(
            df2.versioned_heap.app_to_state,
            {appname2: version1, "SOCKETPARENT": version1})
Example #3
0
 def test_basic(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #4
0
    def __call__(self, main_func: Callable):
        # Get the dimensions required for the player dataframe
        start_time = time()

        while self.time_out == 0 or (time() - start_time) < self.time_out:
            try:
                while True:
                    try:
                        df = Dataframe("dimension_getter", [ServerState],
                                       details=(self.host, self.port))
                    except ConnectionRefusedError as e:
                        if (time() - start_time) > self.time_out:
                            raise e
                    else:
                        break

                df.pull()
                df.checkout()

                if df.read_all(ServerState)[0].server_no_longer_joinable:
                    # This server is from an old game and just hasn't exited yet, wait for a new server.
                    sleep(0.1)
                    continue
                else:
                    break

            except (ConnectionResetError, struct.error):
                sleep(0.1)
                continue

        # If we know what game were supposed to be playing, then check to make sure
        # we match the server environment
        server_state = df.read_all(ServerState)[0]
        environment_name = server_state.env_class_name
        dimension_names: [str] = server_state.env_dimensions
        if self.server_environment is not None and self.server_environment.__name__ != environment_name:
            raise ValueError(
                "Client and Server environment mismatch. We are using: {}. Server is using: {}"
                .format(self.server_environment.__name__, environment_name))

        # Create the correct observation type for our connecting dataframe
        observation_class = Observation(dimension_names)
        del df

        def app(*args, **kwargs):
            client = Node(client_app,
                          dataframe=(self.host, self.port),
                          Types=[Player, observation_class, ServerState],
                          threading=True)
            client.start(self, main_func, observation_class, dimension_names,
                         self.host, self.auth_key, *args, **kwargs)

        return app
Example #5
0
def server_df6(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST6", [ClassWithCounter, Counter],
                   resolver={Counter: counter_merge_func})
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.

    df.checkout()
    c1 = ClassWithCounter(0)
    df.add_one(Counter, c1.counter)
    df.add_one(ClassWithCounter, c1)
    c1.counter.count += 1
    # Push record into server.
    df.commit()
    # Setting point C1
    server_ready.set()
    # Client
    # Pull and read the changes.
    # Waiting at point S1
    client_ready.wait()
    client_ready.clear()
Example #6
0
def server_df6(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST6", [ClassWithCounter, Counter])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.

    df.checkout()
    c1 = ClassWithCounter(0)
    df.add_one(Counter, c1.counter)
    df.add_one(ClassWithCounter, c1)
    c1.counter.count += 1
    # Push record into server.
    df.commit()
    # Setting point C1
    server_ready.set()
    # Client 
    # Pull and read the changes.
    # Waiting at point S1
    client_ready.wait()
    client_ready.clear()
Example #7
0
    def __call__(self, main_func: Callable):
        # Get the dimensions required for the player dataframe
        start_time = time()

        while self.time_out == 0 or (time() - start_time) < self.time_out:
            try:
                while True:
                    try:
                        df = Dataframe("dimension_getter", [ServerState],
                                       details=(self.host, self.port))
                    except ConnectionRefusedError as e:
                        if (time() - start_time) > self.time_out:
                            raise e
                    else:
                        break

                df.pull()
                df.checkout()

                if df.read_all(ServerState)[0].server_no_longer_joinable:
                    # This server is from an old game and just hasn't exited yet, wait for a new server.
                    sleep(0.1)
                    continue
                else:
                    break

            except (ConnectionResetError, struct.error):
                sleep(0.1)
                continue

        dimension_names: [str] = df.read_all(ServerState)[0].env_dimensions
        observation_class = Observation(dimension_names)
        del df

        def app(*args, **kwargs):
            client = Node(client_app,
                          dataframe=(self.host, self.port),
                          Types=[Player, observation_class, ServerState])
            client.start(self, main_func, observation_class, dimension_names,
                         self.host, self.auth_key, *args, **kwargs)

        return app
Example #8
0
def client_df6(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [ClassWithCounter, Counter],
                   details=server_name,
                   resolver={Counter: counter_merge_func})
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    ccs = df.read_all(ClassWithCounter)
    assert (1 == len(ccs))
    c = ccs[0]
    assert ("counter" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.counter.oid is 0)
    assert (c.counter.count is 1)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()
Example #9
0
def client_df6(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [ClassWithCounter, Counter], details=server_name)
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    ccs = df.read_all(ClassWithCounter)
    assert (1 == len(ccs))
    c = ccs[0]
    assert ("counter" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.counter.oid is 0)
    assert (c.counter.count is 1)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()    
Example #10
0
 def test_basic(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #11
0
def client_df7(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Blocker], details=server_name)
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    blockers = df.read_all(Blocker)
    assert (1 == len(blockers))
    b1 = blockers[0]
    assert (b1.prop == 1)
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    b1.prop = 10
    assert (b1.prop == 10)
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    assert (b1.prop == 10)
    b1.prop = 5
    df.commit()
    df.push()

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()

    # Waiting at point c4
    #print ("Waiting for C4")
    server_ready.wait()
    server_ready.clear()
Example #12
0
def server_df7(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST7", [Blocker],
                   resolver={Blocker: blocker_merge_func})
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add Counter to server
    b1 = Blocker(0)
    df.add_many(Blocker, [b1])
    assert (b1.prop == 0)
    b1.prop += 1
    assert (b1.prop == 1)
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    assert (b1.prop == 1)
    b1.prop += 1
    assert (b1.prop == 2)
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    assert (b1.prop == 10), b1.prop
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
    assert (b1.prop == 10)
    b1.prop = 20
    assert (b1.prop == 20)
    df.commit()
    df.checkout()
    assert (b1.prop == 5)

    # Setting point C4
    #print ("Setting C4")
    server_ready.set()
Example #13
0
def client_df5(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 0)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()
    # Waiting at point C2
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 1)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    df.checkout()
    c.xpos = 1
    c.ypos = 1
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.push()
    # Setting point S2
    client_ready.set()
    # Waiting at point C3
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    assert (df.read_one(Car, 1) is None)
    assert (df.read_one(Car, 2) is None)
    # Setting point S3
    client_ready.set()
Example #14
0
 def test_basic_delete1(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
     df.commit()
     df.delete_one(Car, c)
     df.commit()
     self.assertListEqual(list(), df.read_all(Car))
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(None, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #15
0
def server_df2(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST2", [Car])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add car to server
    c1 = Car(0)
    c2 = Car(1)
    df.add_many(Car, [c1, c2])
    # Modify the car value.
    c1.xvel = 1
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    c1.yvel = 1
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    c1 = df.read_one(Car, 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 0)
    assert (c1.ypos is 0)
    assert (c1.oid is 0)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 1), c2.yvel
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
Example #16
0
    def connect(self, username: str, timeout: Optional[float] = None) -> int:
        """ Connect to the remote server and wait for the game to start.

        Parameters
        ----------
        username: str
            Your desired Player Name.
        timeout: float
            Optional timout for how long to wait before abandoning connection

        Returns
        -------
        player_number: int
            The assigned player number in the global game.

        Raises
        ------
        ConnectionError
            If we could not connect to the game server successfully.

        Notes
        -----
        This is your absolute player number that will be used for interpreting the full server state
        and the winners after the end of the game.
        """

        # Add this player to the game.
        self.pull_dataframe()
        self._player: Player = Player(name=username, auth_key=self._auth_key)
        self.player_df.add_one(Player, self._player)
        self.push_dataframe()

        # Check to see if adding our Player object to the dataframe worked.
        self.pull_dataframe()

        if timeout:
            self.fr.start_timeout(timeout)

        while True:
            if self.tick() and timeout:
                self._player = None
                raise ConnectionError("Timed out connecting to server.")

            # The server should remove our player object if it doesnt want us to connect.
            if self.player_df.read_one(Player, self._player.pid) is None:
                self._player = None
                raise ConnectionError("Server rejected adding your player.")

            # If the game start timed out, then we break out now.
            if self._server_state.terminal:
                self._player = None
                raise ConnectionError("Server could not successfully start game.")

            # If we have been given a player number, it means the server is ready for a game to start.
            if self._player.number >= 0:
                break

            self.pull_dataframe()

        # Connect to observation dataframe, and get the initial observation.
        assert self._player.observation_port > 0, "Server failed to create an observation dataframe."
        self.observation_df = Dataframe("{}_observation_df".format(self._player.name),
                                        [self._observation_class],
                                        details=(self._host, self._player.observation_port))

        # Receive the first observation and ensure correct game
        self.pull_dataframe()
        self._observation = self.observation_df.read_all(self._observation_class)[0]
        assert all([hasattr(self._observation, dimension) for dimension in self.dimensions]), \
            "Mismatch in game between server and client."

        # Let the server know that we are ready to start.
        self._player.ready_for_start = True
        self.push_dataframe()

        self.connected = True
        return self._player.number
Example #17
0
def server_df5(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST5", [Car])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.

    df.checkout()
    #Add car to server
    c1 = Car(0)
    df.add_one(Car, c1)
    # Modify the car value.
    c1.xvel = 1
    # Push record into server.
    df.commit()
    # Setting point C1
    server_ready.set()
    # Client
    # Pull and read the changes.
    # Waiting at point S1
    client_ready.wait()
    client_ready.clear()
    # modify the object.
    df.checkout()
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.checkout()
    df.delete_one(Car, c2)
    c1.yvel = 1
    df.commit()
    # Setting point C2
    server_ready.set()
    # Waiting at point S2
    client_ready.wait()
    client_ready.clear()

    df.checkout()
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 1)
    assert (c1.ypos is 1)
    assert (c1.oid is 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 0)
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)
    df.commit()

    # Going for delete.
    df.checkout()
    c3 = Car(2)
    df.add_one(Car, c3)
    c4 = df.read_one(Car, 2)
    assert (c3.xvel is c4.xvel)
    assert (c3.yvel is c4.yvel)
    assert (c3.xpos is c4.xpos)
    assert (c3.ypos is c4.ypos)
    assert (c3.oid is c4.oid)
    c2.yvel = 1
    c2.xvel = 1
    df.delete_one(Car, c2)
    assert (df.read_one(Car, 1) is None)
    assert (c2.__r_df__ is None)
    assert (c2.xvel == 1)
    assert (c2.yvel == 1)
    c2.xvel = 2
    c2.yvel = 2
    assert (c2.xvel == 2)
    assert (c2.yvel == 2)
    assert (Car.__r_table__.object_table[1] == {
        "oid": {
            "type": Datatype.INTEGER,
            "value": 1
        },
        "xvel": {
            "type": Datatype.INTEGER,
            "value": 2
        },
        "yvel": {
            "type": Datatype.INTEGER,
            "value": 2
        },
        "xpos": {
            "type": Datatype.INTEGER,
            "value": 0
        },
        "ypos": {
            "type": Datatype.INTEGER,
            "value": 0
        }
    })

    df.delete_one(Car, c3)
    assert (df.read_one(Car, 2) is None)
    df.commit()
    assert (set(df.local_heap.data[Car.__r_meta__.name].keys()) == set([0]))

    # Setting point C3
    server_ready.set()
    # Waiting for S3
    client_ready.wait()
Example #18
0
def server_df7(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST7", [Blocker])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add Counter to server
    b1 = Blocker(0)
    df.add_many(Blocker, [b1])
    assert (b1.prop == 0)
    b1.prop += 1
    assert (b1.prop == 1)
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    assert (b1.prop == 1)
    b1.prop += 1
    assert (b1.prop == 2)
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    assert (b1.prop == 10), b1.prop
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
    assert (b1.prop == 10)
    b1.prop = 20
    assert (b1.prop == 20)
    df.commit()
    df.checkout()
    assert (b1.prop == 5)
    
    # Setting point C4
    #print ("Setting C4")
    server_ready.set()
Example #19
0
def server_df2(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST2", [Car])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add car to server
    c1 = Car(0)
    c2 = Car(1)
    df.add_many(Car, [c1, c2])
    # Modify the car value.
    c1.xvel = 1
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    c1.yvel = 1
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    c1 = df.read_one(Car, 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 0)
    assert (c1.ypos is 0)
    assert (c1.oid is 0)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 1), c2.yvel
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
Example #20
0
def server_df4(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST4", [Car, Counter],
                   resolver={Counter: counter_merge_func})
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add Counter to server
    c1 = Counter(0)
    car1 = Car(0)
    df.add_many(Counter, [c1])
    df.add_many(Car, [car1])
    assert (c1.count == 0)
    # Modify the counter value.
    c1.count += 1
    assert (c1.count == 1)
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    assert (c1.count == 1)
    c1.count += 1
    assert (c1.count == 2)
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    assert (c1.count == 3)
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
Example #21
0
 def test_basic_delete1(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
     df.commit()
     df.delete_one(Car, c)
     df.commit()
     self.assertListEqual(list(), df.read_all(Car))
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(None, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #22
0
 def test_basic_delete2(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
     df.commit()
     df.push_call_back(
         "TEST2", [df.versioned_heap.version_graph.head.current, "NEXT"], {
             Car.__r_meta__.name: {
                 0: {
                     "types": {
                         Car.__r_meta__.name: Event.Delete
                     }
                 }
             }
         })
     df.checkout()
     self.assertListEqual(list(), df.read_all(Car))
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(None, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #23
0
def client_df2(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    cars = df.read_all(Car)
    assert (2 == len(cars))
    c1, c2 = cars
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    c2.yvel = 1
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    c1 = df.read_one(Car, 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 0)
    assert (c1.ypos is 0)
    assert (c1.oid is 0)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 1)
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()
Example #24
0
def client_df7(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Blocker],
                   details=server_name,
                   resolver={Blocker: blocker_merge_func})
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    blockers = df.read_all(Blocker)
    assert (1 == len(blockers))
    b1 = blockers[0]
    assert (b1.prop == 1)
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    b1.prop = 10
    assert (b1.prop == 10)
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    assert (b1.prop == 10)
    b1.prop = 5
    df.commit()
    df.push()

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()

    # Waiting at point c4
    #print ("Waiting for C4")
    server_ready.wait()
    server_ready.clear()
Example #25
0
 def test_one_df_subset(self):
     df = Dataframe("test", [Car, ActiveCar])
     car = Car(0, "BLUE")
     df.add_one(Car, car)
     df.commit()
     self.assertEqual(1, len(df.read_all(Car)))
     self.assertEqual(0, len(df.read_all(ActiveCar)))
     car.start((10, 10))
     self.assertEqual(1, len(df.read_all(Car)))
     self.assertEqual(1, len(df.read_all(ActiveCar)))
     acar = df.read_one(ActiveCar, 0)
     self.assertEqual(acar.details, (0, 10, 10, 0, 0, "BLUE"))
     self.assertIsInstance(acar, ActiveCar)
     df.commit()
     self.assertEqual(1, len(df.read_all(Car)))
     self.assertEqual(1, len(df.read_all(ActiveCar)))
     self.assertEqual(acar.details, (0, 10, 10, 0, 0, "BLUE"))
     self.assertIsInstance(acar, ActiveCar)
Example #26
0
 def test_basic_delete2(self):
     df = Dataframe("TEST", [Car])
     c = Car(0)
     df.checkout()
     df.add_one(Car, c)
     c.xvel = 1
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(df.local_heap, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
     df.commit()
     df.push_call_back(
         "TEST2", [df.versioned_heap.version_graph.head.current, "NEXT"], {
             Car.__r_meta__.name: {
                 0: {
                     "types": {
                         Car.__r_meta__.name: Event.Delete
                     }
                 }
             }
         })
     df.checkout()
     self.assertListEqual(list(), df.read_all(Car))
     self.assertFalse("xvel" in c.__dict__)
     self.assertFalse("yvel" in c.__dict__)
     self.assertFalse("xpos" in c.__dict__)
     self.assertFalse("ypos" in c.__dict__)
     self.assertFalse("oid" in c.__dict__)
     self.assertTrue(hasattr(c, "__r_df__"))
     self.assertEqual(None, c.__r_df__)
     self.assertEqual(c.xvel, 1)
     self.assertEqual(c.yvel, 0)
     self.assertEqual(c.xpos, 0)
     self.assertEqual(c.ypos, 0)
     self.assertEqual(c.oid, 0)
Example #27
0
class ClientEnvironment:
    """ Basic client environment that will work with any server environment and handles most of the connection
    and playing capabilities.
    """
    _TickRate = 60

    def __init__(self,
                 dataframe: Dataframe,
                 dimensions: List[str],
                 observation_class: Type[Observation],
                 host: str,
                 server_environment: Optional[Type[BaseEnvironment]] = None,
                 auth_key: str = ''):
        """ The primary class for interacting with the environment as a remote client.

        Parameters
        ----------
        dataframe : Dataframe
            The spacetime dataframe connected to the game server.
        dimensions : List[str]
            The names of the observation dimensions
        observation_class : Type[Observation]
            The base class of observations in the dataframe.
        host : str
            The hostname of the game server
        server_environment : Optional[Type[BaseEnvironment]]
            The full server environment if we have access to it.
        auth_key : str
            Your authorization key for entering the game if the server has a whitelist.
        """

        self.player_df: Dataframe = dataframe
        self.observation_df: Optional[Dataframe] = None

        self._server_state: ServerState = self.player_df.read_all(ServerState)[0]

        assert self._server_state.terminal is False, "Connecting to a server with no active game."
        assert self._server_state.server_no_longer_joinable is False, "Server is not accepting new connection."

        self._player: Optional[Player] = None
        self._dimensions: List[str] = dimensions
        self._observation: Observation = None
        self._observation_class: Type[Observation] = observation_class

        self._host: str = host
        self._auth_key: str = auth_key

        self._server_environment: Optional[BaseEnvironment] = None
        if server_environment is not None:
            self._server_environment = server_environment(self._server_state.env_config)

        self.fr: FrameRateKeeper = FrameRateKeeper(self._TickRate)
        self.connected: bool = False

    def pull_dataframe(self) -> None:
        """ Helper function to update all dataframes for this environment. """
        self.player_df.pull()
        self.player_df.checkout()

        if self.observation_df is not None:
            self.observation_df.pull()
            self.observation_df.checkout()

    def push_dataframe(self) -> None:
        """ Helper function to push all dataframes for this environment. """
        self.player_df.commit()
        self.player_df.push()

    def check_connection(self) -> None:
        """ Helper function to error out if we are not yet connected to a game server.

        Raises
        ------
        ConnectionError
            If connect() has not been called yet.
        """
        if not self.connected:
            raise ConnectionError("Not connected to game server.")

    def tick(self) -> bool:
        """ Helper function to wait for a tick of the framerate.

        Returns
        -------
        bool
            Whether or not the framerate keeper has raised a timeout.
        """
        return self.fr.tick()

    @property
    def observation(self) -> Dict[str, np.ndarray]:
        """ Get the current observation present for this agent.

        Returns
        -------
        Dict[str, np.ndarray]
            The observation dictionary for this environment.
        """
        self.check_connection()
        return {dimension: getattr(self._observation, dimension) for dimension in self.dimensions}

    @property
    def terminal(self) -> bool:
        """ Check if the game has ended for us or not.

        Returns
        -------
        bool
            Whether or not the game has reached a terminal state.

        Raises
        ------
        ConnectionError
            If connect() has not been called yet.
        """
        self.check_connection()
        return self._server_state.terminal

    @property
    def winners(self) -> Optional[List[int]]:
        """ Get the current list of winners for the game.

        Returns
        -------
        List[int]
            The list of player numbers of the winners.

        Raises
        ------
        ConnectionError
            If connect() has not been called yet.
        ValueError
            If the game is not over yet.
        """
        if not self.terminal:
            raise ValueError("Game has not ended yet.")

        return dill.loads(self._server_state.winners)

    @property
    def server_environment(self) -> Optional[BaseEnvironment]:
        """ Get the full server environment object if we have it available.

        Returns
        -------
        BaseEnvironment
            Server environment or None is not available.
        """
        return self._server_environment

    @property
    def dimensions(self) -> List[str]:
        """ Get all of the observations that we recieve from the server.

        Returns
        -------
        List[str]
            The keys in the observation dictionary.
        """
        return self._dimensions

    @property
    def full_state(self):
        """ Full server state for the game if the environment and the server support it.

        Returns
        -------
        object
            Current server state

        Raises
        ------
        ConnectionError
            If connect() has not been called yet.
        ValueError
            If we do not have access to the full state.
        """

        self.check_connection()

        if not self.server_environment.serializable():
            raise ValueError("Current Environment does not support full state for clients.")

        return self.server_environment.deserialize_state(self._server_state.serialized_state)

    def connect(self, username: str, timeout: Optional[float] = None) -> int:
        """ Connect to the remote server and wait for the game to start.

        Parameters
        ----------
        username: str
            Your desired Player Name.
        timeout: float
            Optional timout for how long to wait before abandoning connection

        Returns
        -------
        player_number: int
            The assigned player number in the global game.

        Raises
        ------
        ConnectionError
            If we could not connect to the game server successfully.

        Notes
        -----
        This is your absolute player number that will be used for interpreting the full server state
        and the winners after the end of the game.
        """

        # Add this player to the game.
        self.pull_dataframe()
        self._player: Player = Player(name=username, auth_key=self._auth_key)
        self.player_df.add_one(Player, self._player)
        self.push_dataframe()

        # Check to see if adding our Player object to the dataframe worked.
        self.pull_dataframe()

        if timeout:
            self.fr.start_timeout(timeout)

        while True:
            if self.tick() and timeout:
                self._player = None
                raise ConnectionError("Timed out connecting to server.")

            # The server should remove our player object if it doesnt want us to connect.
            if self.player_df.read_one(Player, self._player.pid) is None:
                self._player = None
                raise ConnectionError("Server rejected adding your player.")

            # If the game start timed out, then we break out now.
            if self._server_state.terminal:
                self._player = None
                raise ConnectionError("Server could not successfully start game.")

            # If we have been given a player number, it means the server is ready for a game to start.
            if self._player.number >= 0:
                break

            self.pull_dataframe()

        # Connect to observation dataframe, and get the initial observation.
        assert self._player.observation_port > 0, "Server failed to create an observation dataframe."
        self.observation_df = Dataframe("{}_observation_df".format(self._player.name),
                                        [self._observation_class],
                                        details=(self._host, self._player.observation_port))

        # Receive the first observation and ensure correct game
        self.pull_dataframe()
        self._observation = self.observation_df.read_all(self._observation_class)[0]
        assert all([hasattr(self._observation, dimension) for dimension in self.dimensions]), \
            "Mismatch in game between server and client."

        # Let the server know that we are ready to start.
        self._player.ready_for_start = True
        self.push_dataframe()

        self.connected = True
        return self._player.number

    def wait_for_turn(self, timeout: Optional[float] = None):
        """ Block until it is your turn. This is usually only used in the beginning of the game.

        Parameters
        ----------
        timeout: float
            An optional hard timeout on waiting for the game to start.

        Returns
        -------
        observation:
            The player's observation once its turn has arrived.
        """
        assert self.connected, "Not connected to game server."

        if timeout:
            self.fr.start_timeout(timeout)

        while not self._player.turn:
            if self.terminal:
                raise ConnectionError("Server finished game while we were waiting.")

            if self.tick() and timeout:
                raise ConnectionError("Timed out waiting for a game.")

            self.pull_dataframe()

        return self.observation

    def reset(self):
        self.wait_for_start()
        return self.observation

    def wait_for_start(self, timeout: Optional[float] = None):
        """ Secondary name for to be clearer when starting game. """
        self.wait_for_turn(timeout)

    def valid_actions(self):
        """ Get a list of all valid moves for the current state.

        Raises
        ------
        NotImplementedError
            If the client environment does not have access to all of your available moves.

        Returns
        -------
        moves: list[str]
        """
        if self._server_environment is not None:
            return self._server_environment.valid_actions(self.full_state, self._player.number)
        else:
            raise NotImplementedError("No valid_action is implemented in this client and "
                                      "we do not have access to the full server environment")

    def step(self, action: str) -> Tuple[Dict[str, np.ndarray], float, bool, Optional[List[int]]]:
        """ Perform an action and send it to the server. This wil block until it is your turn again.

        Parameters
        ----------
        action: str
            Your action string.

        Returns
        -------
        observation : Dict[str, np.ndarray]
            The new observation dictionary for the new state.
        reward : float
            The reward for the previous action.
        terminal : bool
            Whether or not the game has ended.
        winners : Optional[List[int]]
            If terminal is true, this will be a list of the player numbers that have won
            If terminal is false, this will be None
        """
        if not self.terminal:
            self._player.action = action
            self._player.ready_for_action_to_be_taken = True
            self.push_dataframe()

            while not self._player.turn or self._player.ready_for_action_to_be_taken:
                self.tick()
                self.pull_dataframe()

        reward = self._player.reward_from_last_turn
        terminal = self.terminal

        winners = None
        if terminal:
            winners = dill.loads(self._server_state.winners)
            self._player.acknowledges_game_over = True
            self.push_dataframe()

        return self.observation, reward, terminal, winners
Example #28
0
def server_df4(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST4", [Car, Counter])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.
    #print ("Server at start:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()
    #Add Counter to server
    c1 = Counter(0)
    car1 = Car(0)
    df.add_many(Counter, [c1])
    df.add_many(Car, [car1])
    assert (c1.count == 0)
    # Modify the counter value.
    c1.count += 1
    assert (c1.count == 1)
    # Push record into server.
    df.commit()
    #print ("Server after adding 2 cars:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C1
    #print ("Setting C1")
    server_ready.set()
    # Waiting at point S1
    #print ("Waiting for S1")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client first time:", df.versioned_heap.version_graph.nodes.keys())
    #print (df.versioned_heap.state_to_app)
    df.checkout()
    assert (c1.count == 1)
    c1.count += 1
    assert (c1.count == 2)
    df.commit()
    #print (df.versioned_heap.state_to_app)
    #print ("Server after modifying once:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point C2
    #print ("Setting C2")
    server_ready.set()
    # Waiting at point S2
    #print ("Waiting for S2")
    client_ready.wait()
    client_ready.clear()
    #print ("Server after waiting for client second time.:", df.versioned_heap.version_graph.nodes.keys())

    # Check how the merge worked out.
    df.checkout()
    assert (c1.count == 3)
    # Setting point C3
    #print ("Setting C3")
    server_ready.set()
    # Waiting at point S3
    #print ("Waiting for S3")
    client_ready.wait()
    client_ready.clear()
Example #29
0
def client_df1(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 0)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()
    # Waiting at point C2
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 1)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    df.checkout()
    c.xpos = 1
    c.ypos = 1
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.push()
    # Setting point S2
    client_ready.set()
    # Waiting at point C3
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    assert (df.read_one(Car, 1) is None)
    assert (df.read_one(Car, 2) is None)
    # This does not work yet. Have to figure it out.
    # limitation of making it a framework rather than
    # a programming language itself.
    # Cannot invalidate old references without holding the
    # reference itself.
    #assert ("xvel" not in c2.__dict__)
    #assert ("yvel" not in c2.__dict__)
    #assert ("xpos" not in c2.__dict__)
    #assert ("ypos" not in c2.__dict__)
    #assert ("oid" not in c2.__dict__)
    #assert (c2.xvel is 0)
    #assert (c2.yvel is 0)
    #assert (c2.xpos is 0)
    #assert (c2.ypos is 0)
    #assert (c2.oid is 1)
    #assert (c2.__r_df__ is None)
    #assert (Car.__r_table__.object_table[1] == {
    #            "oid": {"type": Datatype.INTEGER, "value": 0},
    #            "xvel": {"type": Datatype.INTEGER, "value": 0},
    #            "yvel": {"type": Datatype.INTEGER, "value": 0},
    #            "xpos": {"type": Datatype.INTEGER, "value": 0},
    #            "ypos": {"type": Datatype.INTEGER, "value": 0}
    #        })
    # Setting point S3
    client_ready.set()
Example #30
0
def client_df1(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 0)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()
    # Waiting at point C2
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 1)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    df.checkout()
    c.xpos = 1
    c.ypos = 1
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.push()
    # Setting point S2
    client_ready.set()
    # Waiting at point C3
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    assert (df.read_one(Car, 1) is None)
    assert (df.read_one(Car, 2) is None)
    # This does not work yet. Have to figure it out.
    # limitation of making it a framework rather than
    # a programming language itself.
    # Cannot invalidate old references without holding the
    # reference itself.
    #assert ("xvel" not in c2.__dict__)
    #assert ("yvel" not in c2.__dict__)
    #assert ("xpos" not in c2.__dict__)
    #assert ("ypos" not in c2.__dict__)
    #assert ("oid" not in c2.__dict__)
    #assert (c2.xvel is 0)
    #assert (c2.yvel is 0)
    #assert (c2.xpos is 0)
    #assert (c2.ypos is 0)
    #assert (c2.oid is 1)
    #assert (c2.__r_df__ is None)
    #assert (Car.__r_table__.object_table[1] == {
    #            "oid": {"type": Datatype.INTEGER, "value": 0},
    #            "xvel": {"type": Datatype.INTEGER, "value": 0},
    #            "yvel": {"type": Datatype.INTEGER, "value": 0},
    #            "xpos": {"type": Datatype.INTEGER, "value": 0},
    #            "ypos": {"type": Datatype.INTEGER, "value": 0}
    #        })
    # Setting point S3
    client_ready.set()
Example #31
0
def client_df4(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Counter], details=server_name)
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    counters = df.read_all(Counter)
    cars = df.read_all(Car)
    assert (1 == len(counters))
    assert (0 == len(cars))
    c1 = counters[0]
    assert (c1.count == 1)
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    c1.count += 1
    assert (c1.count == 2)
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    assert (c1.count == 3)

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()
Example #32
0
def client_df2(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    cars = df.read_all(Car)
    assert (2 == len(cars))
    c1, c2 = cars
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    c2.yvel = 1
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    c1 = df.read_one(Car, 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 0)
    assert (c1.ypos is 0)
    assert (c1.oid is 0)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 1)
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()
Example #33
0
def server_df5(send_q, recv_q, server_ready, client_ready):
    df = Dataframe("SERVER_TEST5", [Car])
    send_q.put(df.details)
    client_name = recv_q.get()
    # The server goes first.

    df.checkout()
    #Add car to server
    c1 = Car(0)
    df.add_one(Car, c1)
    # Modify the car value.
    c1.xvel = 1
    # Push record into server.
    df.commit()
    # Setting point C1
    server_ready.set()
    # Client 
    # Pull and read the changes.
    # Waiting at point S1
    client_ready.wait()
    client_ready.clear()
    # modify the object.
    df.checkout()
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.checkout()
    df.delete_one(Car, c2)
    c1.yvel = 1
    df.commit()
    # Setting point C2
    server_ready.set()
    # Waiting at point S2
    client_ready.wait()
    client_ready.clear()

    df.checkout()
    assert ("xvel" not in c1.__dict__)
    assert ("yvel" not in c1.__dict__)
    assert ("xpos" not in c1.__dict__)
    assert ("ypos" not in c1.__dict__)
    assert ("oid" not in c1.__dict__)
    assert (c1.xvel is 1)
    assert (c1.yvel is 1)
    assert (c1.xpos is 1)
    assert (c1.ypos is 1)
    assert (c1.oid is 0)
    c2 = df.read_one(Car, 1)
    assert ("xvel" not in c2.__dict__)
    assert ("yvel" not in c2.__dict__)
    assert ("xpos" not in c2.__dict__)
    assert ("ypos" not in c2.__dict__)
    assert ("oid" not in c2.__dict__)
    assert (c2.xvel is 0)
    assert (c2.yvel is 0)
    assert (c2.xpos is 0)
    assert (c2.ypos is 0)
    assert (c2.oid is 1)
    df.commit()

    # Going for delete.
    df.checkout()
    c3 = Car(2)
    df.add_one(Car, c3)
    c4 = df.read_one(Car, 2)
    assert (c3.xvel is c4.xvel)
    assert (c3.yvel is c4.yvel)
    assert (c3.xpos is c4.xpos)
    assert (c3.ypos is c4.ypos)
    assert (c3.oid is c4.oid)
    c2.yvel = 1
    c2.xvel = 1
    df.delete_one(Car, c2)
    assert (df.read_one(Car, 1) is None)
    assert (c2.__r_df__ is None)
    assert (c2.xvel == 1)
    assert (c2.yvel == 1)
    c2.xvel = 2
    c2.yvel = 2
    assert (c2.xvel == 2)
    assert (c2.yvel == 2)
    assert (Car.__r_table__.object_table[1] == {
                "oid": {"type": Datatype.INTEGER, "value": 1},
                "xvel": {"type": Datatype.INTEGER, "value": 2},
                "yvel": {"type": Datatype.INTEGER, "value": 2},
                "xpos": {"type": Datatype.INTEGER, "value": 0},
                "ypos": {"type": Datatype.INTEGER, "value": 0}
            })
    
    df.delete_one(Car, c3)
    assert (df.read_one(Car, 2) is None)
    df.commit()
    assert (set(df.local_heap.data[Car.__r_meta__.name].keys()) == set([0]))
    
    # Setting point C3
    server_ready.set()
    # Waiting for S3
    client_ready.wait()
Example #34
0
def client_df4(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Counter],
                   details=server_name,
                   resolver={Counter: counter_merge_func})
    send_q.put(df.details)
    #print ("Client at start:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C1
    #print ("Waiting for C1")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server first time.:", df.versioned_heap.version_graph.nodes.keys())

    # Pull from the server.
    df.pull()
    #print ("Client after first pull:", df.versioned_heap.version_graph.nodes.keys())
    df.checkout()
    counters = df.read_all(Counter)
    cars = df.read_all(Car)
    assert (1 == len(counters))
    assert (0 == len(cars))
    c1 = counters[0]
    assert (c1.count == 1)
    #print ("Setting S1")
    # Setting point S1
    client_ready.set()
    c1.count += 1
    assert (c1.count == 2)
    df.commit()
    #print ("Client after first modification:", df.versioned_heap.version_graph.nodes.keys())
    # Waiting at point C2
    #print ("Waiting for C2")
    server_ready.wait()
    server_ready.clear()
    #print ("Client after waiting for server:", df.versioned_heap.version_graph.nodes.keys())
    df.push()
    #print ("Client after pushing:", df.versioned_heap.version_graph.nodes.keys())
    # Setting point S2
    #print ("Setting S2")
    client_ready.set()
    # Waiting at point c3
    #print ("Waiting for C3")
    server_ready.wait()
    server_ready.clear()
    df.pull()
    #print ("Client after pulling second time:", df.versioned_heap.version_graph.nodes.keys())

    df.checkout()

    assert (c1.count == 3)

    # Setting point S3
    #print ("Setting S3")
    client_ready.set()
Example #35
0
def client_df5(send_q, recv_q, server_ready, client_ready):
    server_name = recv_q.get()
    df = Dataframe("CLIENT_TEST", [Car], details=server_name)
    send_q.put(df.details)
    # Waiting at point C1
    server_ready.wait()
    server_ready.clear()

    # Pull from the server.
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 0)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    # Setting point S1
    client_ready.set()
    # Waiting at point C2
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    cars = df.read_all(Car)
    assert (1 == len(cars))
    c = cars[0]
    assert ("xvel" not in c.__dict__)
    assert ("yvel" not in c.__dict__)
    assert ("xpos" not in c.__dict__)
    assert ("ypos" not in c.__dict__)
    assert ("oid" not in c.__dict__)
    assert (c.xvel is 1)
    assert (c.yvel is 1)
    assert (c.xpos is 0)
    assert (c.ypos is 0)
    assert (c.oid is 0)
    df.commit()
    df.checkout()
    c.xpos = 1
    c.ypos = 1
    c2 = Car(1)
    df.add_one(Car, c2)
    df.commit()
    df.push()
    # Setting point S2
    client_ready.set()
    # Waiting at point C3
    server_ready.wait()
    server_ready.clear()
    df.pull()
    df.checkout()
    assert (df.read_one(Car, 1) is None)
    assert (df.read_one(Car, 2) is None)
    # Setting point S3
    client_ready.set()
Example #36
0
def server_app(dataframe: Dataframe,
               env_class: Type[BaseEnvironment],
               observation_type: Type,
               args: dict,
               whitelist: list = None,
               ready_event: Event = None):
    timeout = Timeout()

    fr: FrameRateKeeper = FrameRateKeeper(max_frame_rate=args['tick_rate'])

    # Keep track of each player and their associated observations
    observation_dataframes: Dict[int, Dataframe] = {}
    observations: Dict[int, _Observation] = {}
    players: Dict[int, Player] = {}

    # Function to help push all observations
    def push_observations():
        for df in observation_dataframes.values():
            df.commit()

    # Add the server state to the master dataframe
    server_state = ServerState(env_class.__name__, args["config"], env_class.observation_names())
    dataframe.add_one(ServerState, server_state)
    dataframe.commit()

    # Function to help clean up server if it ever needs to shutdown
    def close_server(message: str):
        server_state.terminal = True
        logger.error(message)
        dataframe.commit()
        sleep(5)

    # Create the environment and start the server
    env: BaseEnvironment = env_class(args["config"])

    logger.info("Waiting for enough players to join ({} required)...".format(env.min_players))

    # Add whitelist support, players will be rejected if their key does not match the expected keys
    whitelist = [] if whitelist is None else whitelist
    whitelist_used = len(whitelist) > 0
    whitelist_connected = {key: False for key in whitelist}

    # If we were created by some server manager, inform them we are ready for players
    if ready_event is not None:
        ready_event.set()

    # -----------------------------------------------------------------------------------------------
    # Wait for all players to connect
    # -----------------------------------------------------------------------------------------------
    fr.start_timeout(timeout.connect)
    while len(players) < env.min_players:
        if fr.tick():
            close_server("Game could not find enough players. Shutting down game server.")
            return 1

        dataframe.sync()
        new_players: Dict[int, Player] = dict((p.pid, p) for p in dataframe.read_all(Player))

        # Any players that have connected by have not been acknowledged yet
        for new_id in new_players.keys() - players.keys():
            name = new_players[new_id].name
            auth_key = new_players[new_id].authentication_key

            if whitelist_used and auth_key not in whitelist_connected:
                logger.info("Player tried to join with invalid authentication_key: {}".format(name))
                dataframe.delete_one(Player, new_id)
                del new_players[new_id]
                continue

            if whitelist_used and whitelist_connected[auth_key]:
                logger.info("Player tried to join twice with the same authentication_key: {}".format(name))
                dataframe.delete_one(Player, new_id)
                del new_players[new_id]
                continue

            logger.info("New player joined with name: {}".format(name))

            # Create new observation dataframe for the new player
            obs_df = Dataframe("{}_observation".format(name), [observation_type])
            obs = observation_type(new_id)
            obs_df.add_one(observation_type, obs)

            # Add the dataframes to the database
            observation_dataframes[new_id] = obs_df
            observations[new_id] = obs
            whitelist_connected[auth_key] = True

        # If any players that we have added before have dropped out
        for remove_id in players.keys() - new_players.keys():
            logger.info("Player {} has left.".format(players[remove_id].name))

            auth_key = players[remove_id].authentication_key
            whitelist_connected[auth_key] = False

            del observations[remove_id]
            del observation_dataframes[remove_id]

        players = new_players

    # -----------------------------------------------------------------------------------------------
    # Create all of the player data and wait for the game to begin
    # -----------------------------------------------------------------------------------------------
    logger.info("Finalizing players and setting up new environment.")
    server_state.server_no_longer_joinable = True

    # Create the initial state for the environment and push it if enabled
    state, player_turns = env.new_state(num_players=len(players))
    if not args["observations_only"] and env.serializable():
        server_state.serialized_state = env.serialize_state(state)

    # Set up each player
    for i, (pid, player) in enumerate(players.items()):
        # Add the initial observation to each player
        observations[pid].set_observation(env.state_to_observation(state=state, player=i))

        # Finalize each player by giving it a player number and a port for the dataframe
        player.finalize_player(number=i, observation_port=observation_dataframes[pid].details[1])
        if i in player_turns:
            player.turn = True

    # Push all of the results to the player
    players_by_number: Dict[int, Player] = dict((p.number, p) for p in players.values())
    push_observations()
    dataframe.sync()

    # Wait for all players to be ready
    fr.start_timeout(timeout.start)
    while not all(player.ready_for_start for player in players.values()):
        if fr.tick():
            close_server("Players have dropped out between entering the game and starting the game.")
            return 2

        dataframe.checkout()

    # -----------------------------------------------------------------------------------------------
    # Primary game loop
    # -----------------------------------------------------------------------------------------------
    logger.info("Game started...")
    terminal = False
    winners = None
    dataframe.commit()

    fr.start_timeout(timeout.move)
    while not terminal:
        # Wait for a frame to tick
        move_timeout = fr.tick()

        # Get new data
        dataframe.checkout()

        # Get the player dataframes of the players who's turn it is right now
        current_players: List[Player] = [p for p in players.values() if p.number in player_turns]
        current_actions: List[str] = []

        ready = args['realtime'] or move_timeout or all(p.ready_for_action_to_be_taken for p in current_players)
        if not ready:
            continue

        # Queue up each players action if it is legal
        # If the player failed to respond in time, we will simply execute the previous action
        # If it is invalid, we will pass in a blank string
        for player in current_players:
            if player.action == '' or env.is_valid_action(state=state, player=player.number, action=player.action):
                current_actions.append(player.action)
            else:
                logger.info("Player #{}, {}'s, action of {} was invalid, passing empty string as action"
                            .format(player.number, player.name, player.action))
                current_actions.append('')

        # Execute the current move
        state, player_turns, rewards, terminal, winners = (
            env.next_state(state=state, players=player_turns, actions=current_actions)
        )

        # Update true state if enabled
        if not args["observations_only"] and env.serializable():
            server_state.serialized_state = env.serialize_state(state)

        # Update the player data from the previous move.
        for player, reward in zip(current_players, rewards):
            player.reward_from_last_turn = float(reward)
            player.ready_for_action_to_be_taken = False
            player.turn = False

        # Tell the new players that its their turn and provide observation
        for player_number in player_turns:
            player = players_by_number[player_number]
            observations[player.pid].set_observation(env.state_to_observation(state=state, player=player_number))
            player.turn = True

        if terminal:
            server_state.terminal = True
            server_state.winners = dill.dumps(winners)

            for player_number in winners:
                players_by_number[player_number].winner = True
            logger.info("Player: {} won the game.".format(winners))

        push_observations()
        dataframe.commit()
        fr.start_timeout(timeout.move)

    # -----------------------------------------------------------------------------------------------
    # Clean up after game
    # -----------------------------------------------------------------------------------------------
    for player in players.values():
        player.turn = True

    dataframe.commit()
    dataframe.push()

    # TODO| The code below attempts to ensure that the players have the final state of the game before the server quits.
    # TODO| However, an error is thrown when players disconnect during the checkout. If this snippet was removed,
    # TODO| players would have a similar error when the server would quit while they are pulling.
    # TODO| May need to talk to Rohan about cleanly exiting this kind of situation.
    # TODO| It would also be great if we could instead properly confirm that recipients got a message.
    fr.start_timeout(timeout.end)
    for player in players.values():
        while not player.acknowledges_game_over and not fr.tick():
            dataframe.checkout()

    rankings = env.compute_ranking(state, list(range(len(players))), winners)
    ranking_dict = {players_by_number[number].name: ranking for number, ranking in rankings.items()}

    logger.info("Game has ended. Player {} is the winner.".format([key for key, value in ranking_dict.items() if value == 0]))
    return ranking_dict
Example #37
0
    def test_multiple_types(self):
        df1 = Dataframe("TEST1", [Car, Counter], version_by=VersionBy.TYPE)
        df2 = Dataframe("TEST2", [Car],
                        details=df1.details,
                        version_by=VersionBy.TYPE)
        appname1 = df1.appname
        appname2 = df2.appname
        c = Car(0)
        count = Counter(0)
        df2.checkout()
        df2.add_one(Car, c)
        c.xvel = 1
        df2.commit()

        df1.checkout()
        df1.add_one(Counter, count)
        df1.commit()
        df2.sync()
        df1.checkout()
        self.assertEqual(1, len(df1.read_all(Car)))
        self.assertListEqual(list(), df2.read_all(Counter))