NextColony - checking if the 8 explored planets are valid

in #nextcolony6 years ago (edited)

NextColonyTeaser1.jpg

Some users have been wondering why 6 of 8 explored planets are near another planet:

image.png

The chance to find a new planet is 1%. At the moment 930 space coordinates have been explored and 8 planets were found. The current rate is 0.86 %, which is slightly below 1%.

The chance of finding only empty space around the start planet is

99/100 * 99/100 * 99/100 * 99/100 * 99/100 * 99/100 * 99/100 * 99/100 = 0.9227

Thus the chance of finding a planet near the start planet is 0.0774, or 1 of 12.9 found planets should be near the start planet.

At the moment 6 of 8 are near the start planet. This can be explained by the law of large numbers.

The law says that the sample average converges to the expected value for Infinitive trials. So when more and more planets have been found, we should converge to a rate of 1 to 12.9 explored planets that have been explored near the start planet.

Checking all found planets

With the following python script, it is possible to validate the 8 found planets. In order to check if a planet is valid, the transaction id of the explorespace custom_json and the block_num of the virtual explore operation is needed. When the explorespace mission is started, the distance to the goal is calculated and the arrival time is determined. This arrival time defines then the block number of the virtual explore operation.

from beem.block import Block
import hashlib
import datetime
import random
from collections import OrderedDict

def set_seed(seed):
    random.seed(a=seed, version=2)

def get_is_empty_space():
    return random.random() >= 0.01

def get_was_planet_found(block_num, trx_id):
    block = Block(block_num)
    seed = hashlib.md5((trx_id + block["block_id"] + block["previous"]).encode()).hexdigest()     
    set_seed(seed)        
    found = not get_is_empty_space()    
    return found

if __name__ == '__main__':
   
    planet_found_list = [OrderedDict([('id', 35),
              ('user', 'reggaemuffin'),
              ('date', datetime.datetime(2019, 4, 30, 13, 56, 33)),
              ('c_hor', 183),
              ('c_ver', -175),
              ('trx_id', 'ca7093442b53ea5186b4ebecb56570e27e68ed58'),
              ('block_num', 32498931),
              ('planet_id', 'P-ZT52Y2YAEOW')]),
 OrderedDict([('id', 81),
              ('user', 'mancer-sm-alt'),
              ('date', datetime.datetime(2019, 5, 1, 6, 50, 45)),
              ('c_hor', 91),
              ('c_ver', 267),
              ('trx_id', 'dcd914ae73de12a876b9c9688ae54d7574fc79fa'),
              ('block_num', 32519195),
              ('planet_id', 'P-ZIY07VLIZXC')]),
 OrderedDict([('id', 273),
              ('user', 'flauwy'),
              ('date', datetime.datetime(2019, 5, 2, 23, 6, 18)),
              ('c_hor', -227),
              ('c_ver', 209),
              ('trx_id', '29dcd2d88eba9aaa2f413e3a36fac83a69e72a33'),
              ('block_num', 32567483),
              ('planet_id', 'P-ZU1JXAEU4KW')]),
 OrderedDict([('id', 283),
              ('user', 'hanzappedfirst'),
              ('date', datetime.datetime(2019, 5, 3, 0, 56, 48)),
              ('c_hor', 78),
              ('c_ver', -198),
              ('trx_id', '3fddd68f03eedae6dd93970c9d15cc5ff6f0db01'),
              ('block_num', 32569691),
              ('planet_id', 'P-ZBPUNEE2NMO')]),
 OrderedDict([('id', 438),
              ('user', 'kissi'),
              ('date', datetime.datetime(2019, 5, 4, 5, 40, 51)),
              ('c_hor', -221),
              ('c_ver', 175),
              ('trx_id', 'c1f4e868160ca9160f28d426c2738429a8d7ee0e'),
              ('block_num', 32604121),
              ('planet_id', 'P-Z8LN8NEOGE8')]),
 OrderedDict([('id', 737),
              ('user', 'uraniumfuture'),
              ('date', datetime.datetime(2019, 5, 5, 18, 51, 15)),
              ('c_hor', -35),
              ('c_ver', -217),
              ('trx_id', 'b808dafaa97bf34f17fe7a71c20ed6ebb767d103'),
              ('block_num', 32648704),
              ('planet_id', 'P-ZCQ6XF6HTSW')]),
 OrderedDict([('id', 797),
              ('user', 'fantasycrypto'),
              ('date', datetime.datetime(2019, 5, 6, 0, 39, 13)),
              ('c_hor', -290),
              ('c_ver', -42),
              ('trx_id', '646c4548d666293e547d4ab0f19f5a1e38930c3a'),
              ('block_num', 32655660),
              ('planet_id', 'P-Z1L0K1F5PPS')]),
 OrderedDict([('id', 866),
              ('user', 'lordvader'),
              ('date', datetime.datetime(2019, 5, 6, 7, 28, 19)),
              ('c_hor', -289),
              ('c_ver', -167),
              ('trx_id', 'e03e7a66310f67b69e82714a071892dd144caf7c'),
              ('block_num', 32663837),
              ('planet_id', 'P-ZHYWH6QELGG')])]
    
    print("Found %d planets" % len(planet_found_list))
    print("| vops block num | custom_json trx_id | uid | valid |")
    print("| --- | --- | --- | --- |")
    for data in planet_found_list:
        found = get_was_planet_found(data["block_num"], data["trx_id"])
        print("| %d | %s | %s | %s |" % (data["block_num"], data["trx_id"], data["planet_id"], str(found)))

The result of the script is the following:

vops block numcustom_json trx_iduidvalid
32498931ca7093442b53ea5186b4ebecb56570e27e68ed58P-ZT52Y2YAEOWTrue
32519195dcd914ae73de12a876b9c9688ae54d7574fc79faP-ZIY07VLIZXCTrue
3256748329dcd2d88eba9aaa2f413e3a36fac83a69e72a33P-ZU1JXAEU4KWTrue
325696913fddd68f03eedae6dd93970c9d15cc5ff6f0db01P-ZBPUNEE2NMOTrue
32604121c1f4e868160ca9160f28d426c2738429a8d7ee0eP-Z8LN8NEOGE8True
32648704b808dafaa97bf34f17fe7a71c20ed6ebb767d103P-ZCQ6XF6HTSWTrue
32655660646c4548d666293e547d4ab0f19f5a1e38930c3aP-Z1L0K1F5PPSTrue
32663837e03e7a66310f67b69e82714a071892dd144caf7cP-ZHYWH6QELGGTrue

Checking all found empty space coordinates

I did the same for all 930 found empty spaces with the following results:

Found 930 empty spaces
930 / 930 are valid

I used the slightly modified get_empty_space_found function:

def get_empty_space_found(block_num, trx_id):
    block = Block(block_num)
    seed = hashlib.md5((trx_id + block["block_id"] + block["previous"]).encode()).hexdigest()     
    set_seed(seed)        
    notfound = get_is_empty_space()    
    return notfound

Conclusion

All eight planets and all 930 explored coordinates are valid. The distance to the start planet does not play a role, only the transaction id of the custom_json and the block_id and the previous id of the first block after the arrival time.

Sort:  

Thank you Holger for this post. Statistics are sometimes unintuitive when it comes to the law of large numbers. Your post helps a lot to show that this is indeed a result of nothing else but pure randomness.

Sometimes randomness can really amaze me. Thank you Holger for explaning this Effekt!

Cool! and change "change" to "chance" :) e.g., "the change of finding a planet"

ps. someone should write a bot :) to be honest, users like me, it takes too much time to enjoy something. Maybe it's strategy to make people to spend :)

There is a bot offered by @Buildteam that is call NextColony Bot. Check it out. I think this may be what you are look for.

See you around the Galaxy. :)

Thanks for your comment. Actually I know that one, but it's not free :( I can actually make one on my own, but I'm waiting for someone to do that :)

That is awesome work. I have had the same musing about if the found planets were legit or not. Thank you for clearing this up for me and I am sure a lot of other players.

Keep up the great work and hope to see you around the galaxy.

Great analysis! As you may know I was one those who were initially puzzled by this planet discovery pattern. Now it seems to me that this non-intuitive observation is very much related to the surprising outcome of the famous birthday paradox. Thanks for the clarification!

Huh? Birthday too have paradoxes? Incredibru

Thank you so much for participating in the Partiko Delegation Plan Round 1! We really appreciate your support! As part of the delegation benefits, we just gave you a 3.00% upvote! Together, let’s change the world!

Yes! finally real blockchain games. Thanks for this post, Holger.

Empty space? There is always black matter. For free!

Hi @holger80!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your UA account score is currently 7.019 which ranks you at #72 across all Steem accounts.
Your rank has not changed in the last three days.

In our last Algorithmic Curation Round, consisting of 212 contributions, your post is ranked at #5.

Evaluation of your UA score:
  • Your follower network is great!
  • The readers appreciate your great work!
  • Great user engagement! You rock!

Feel free to join our @steem-ua Discord server

Laws of large numbers or Beginners' luck? Yes the former sounds way better. I'm just curious if is possible to script it and predict or forecast the possibility of positive planet discovery. Given the necessary inputs like current block + time + current + destination coordinates.

Hi, @holger80!

You just got a 3.09% upvote from SteemPlus!
To get higher upvotes, earn more SteemPlus Points (SPP). On your Steemit wallet, check your SPP balance and click on "How to earn SPP?" to find out all the ways to earn.
If you're not using SteemPlus yet, please check our last posts in here to see the many ways in which SteemPlus can improve your Steem experience on Steemit and Busy.

thanks for the code @holger80
upvoted?

Do you use beem module in @nextcolony production? Is it stable enough?

Yes, I'm using beem in production, beem is more than stable and I have several projects that are using beem and are running 24/7 without any error.