I have written some codes to draw randomly located points, as many as I wanted to, and make them spread like fluid for a while. Also I wanted them not to get into each other. There is no problem running it, but in some cases it takes really long time to finish a point's spreading, so I realized that's not that efficient.
I would be happy to get some help to make it more efficient.
This is what I meant by "like fluid"
from graphics import *
import time, random
racepoints = {} # {0:[(),()],1:[(),()]}
allpoints = []
races = {}
tx, ty = int(input("x=")), int(input("y="))
def Window():
global win, sure, spreadSize
win = GraphWin("Pencere", tx, ty)
starttime = time.time()
Start()
spreadSize = int(input("Başlangıç boyutu?"))
Spread(spreadSize)
finishtime = time.time()
sure = (finishtime - starttime)
writeTime()
print("Bitti! Ve {} saniye sürdü!".format(sure))
time.sleep(5)
def writeTime():
timefile = open("C:\\Python36\\timefile.py", "r")
gotta_rewrite = timefile.readlines()
timefile.close()
timefile = open("C:\\Python36\\timefile.py", "w")
gotta_rewrite.append("\n{} ırk, {} genişlik, {}*{} alan, {} saniye sürdü.".format(racecount, spreadSize, tx, ty, sure))
timefile.seek(0)
timefile.writelines(gotta_rewrite)
timefile.close()
def Start():
global racecount
racecount = int(input("Kaç tane ırk olsun?"))
for i in range(racecount):
randomcolor = color_rgb(random.randrange(255), random.randrange(255), random.randrange(255))
races[i] = randomcolor
racepoints[i] = []
nx = random.randrange(tx)
ny = random.randrange(ty)
randomstartpoint = Point(nx, ny)
randomstartpoint.setFill(races[i])
randomstartpoint.draw(win)
allpoints.append((nx, ny))
(racepoints[i]).append((nx, ny))
def Spread(maxsize):
defaultsize = maxsize
for i in range(racecount):
maxsize = defaultsize
while maxsize > 0:
for point in list(racepoints[i]):
lx, ly = point
ax, ay = 0, 0
while ax == 0 and ay == 0:
ax = random.choice([-1, 0, 1])
ay = random.choice([-1, 0, 1])
if (lx + ax, ly + ay) not in allpoints:
lx += ax
ly += ay
newpoint = Point(lx, ly)
newpoint.setFill(races[i])
newpoint.draw(win)
(racepoints[i]).append((lx, ly))
allpoints.append((lx, ly))
else:
pass
maxsize -= 1
Window()
I've taken a different approach this time compared to my initial attempt in that this solution relies heavily on set logic to maintain the points. (The colors come off as a bit pastel due to my use of win.plot()
instead of Point.draw()
but that's a minor implementation detail)
As before, I use the color as a dictionary key so my code makes sure the random color chosen is unique.
import time
from random import randrange
from collections import defaultdict
from graphics import *
def Window():
global tx, ty, win
tx, ty = int(input("x = ")), int(input("y = "))
race_count = int(input("How many races do you have? "))
spread_size = int(input("Maximum spread? "))
win = GraphWin("Window", tx, ty)
start_time = time.time()
Start(race_count)
Spread(spread_size)
finish_time = time.time()
time_difference = finish_time - start_time
print("Done! And it took {} seconds!".format(time_difference))
writeTime(time_difference, spread_size, race_count)
time.sleep(5)
def writeTime(sure, spread_size, race_count):
try:
with open("timefile.py") as time_file:
gotta_rewrite = time_file.readlines()
except FileNotFoundError:
gotta_rewrite = []
gotta_rewrite.append("\n{} race, {} width, {} * {} space, {} seconds.".format(race_count, spread_size, tx, ty, sure))
with open("timefile.py", "w") as time_file:
time_file.writelines(gotta_rewrite)
def Start(race_count):
for _ in range(race_count):
random_color = color_rgb(randrange(255), randrange(255), randrange(255))
while random_color in races:
random_color = color_rgb(randrange(255), randrange(255), randrange(255))
nx, ny = randrange(tx), randrange(ty)
win.plot(nx, ny, random_color)
races[random_color].add((nx, ny))
def Spread(spread_size):
for _ in range(spread_size):
for color, points in races.items():
for point in list(points): # need copy of points as it'll be modified in loop
candidates = set()
x, y = point
for dy in range(-1, 2):
for dx in range(-1, 2):
candidates.add((x + dx, y + dy))
candidates = candidates.difference(*races.values())
if candidates:
new_point = candidates.pop()
points.add(new_point)
nx, ny = new_point
if 0 < nx < tx and 0 < ny < ty: # only draw visible points
win.plot(nx, ny, color)
races = defaultdict(set)
Window()
Working the points round robin, rather than completing one and moving onto another, seems truer to the intent. You can compare your new solution on the left to mine on the right where they both have 50 races:
On mine on the right, you can nearly count all 50 races but on yours, you can only spot half that number due to losses from overlap.