bodice-ripping
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
9.2 KiB

#!/usr/bin/env python3
#(height, width)
import random as rnd
import os
import sys
import itertools
from enum import Enum
import time
import math
from queue import PriorityQueue as pq
from sortedcontainers import SortedList as sl
from intervaltree import IntervalTree as itree
DEBUG=True
# DEBUG=False
class SquareType(Enum):
AISLE = 0
SEAT = 1
WALL = 2
height=0
width=0
grid=[]
# entries=[(3,0)]
entries=[(0,3)]
# entries=[(7,3),(7,43)]
# entries=[(7,3)]
tickTaken = 0
passengers = None
class GridSquare:
#typ: SquareType
def __init__(self, typ):
self.typ = typ
#occupAtTick is an interval tree, stores intervals where the gridSquare is occupied
#intervals are [a,b), a nice sane choice
#values are individuals
self.occupAtTick = itree()
class Passenger:
#dest and curr are both 2-tuples
def __init__(self, dest, curr):
self.dest = dest
self.curr = curr
self.inter = None
#Path is composed of tuples: (pos, t)
self.path = []
def __str__(self):
return "(%s|%s)" % (dest, curr)
def mooreNeighbourhood(pos):
return [i for i in [(pos[0]+1, pos[1]), (pos[0], pos[1]+1), (pos[0]-1, pos[1]), (pos[0], pos[1]-1)] if
i[0] >= 0 and i[1] >= 0 and i[0] < height and i[1] < width]
def findPath(passenger, pid, currTick):
global passengers
global grid
#used when moving into seats
afterTick = 0
dest = passenger.inter
#Element format: (Tick at time of movement, Position, Time stayed in previous square)
q = pq()
time=[[10**10 for x in range(0,width)] for y in range(0,height)]
prev=[[None for x in range(0,width)] for y in range(0,height)]
time[passenger.curr[0]][passenger.curr[1]]=currTick
q.put((currTick, passenger.curr, 1))
while not q.empty():
u = q.get()
if u[1] == dest:
grid[u[1][0]][u[1][1]].occupAtTick.addi(u[0],u[0]+3,pid)
afterTick = u[0]+2
# passenger.path.append((u[1], u[0]))
u=prev[u[1][0]][u[1][1]]
while prev[u[1][0]][u[1][1]] != None:
grid[u[1][0]][u[1][1]].occupAtTick.addi(u[0],u[0]+u[2],pid)
# passenger.path.append((u[1], u[0]))
u=prev[u[1][0]][u[1][1]]
# passenger.path.append((passenger.curr, currTick))
break
#The Art of Standing Still
q.put((u[0] + 1, u[1], 1))
for x in mooreNeighbourhood(u[1]):
alt = 0
if grid[x[0]][x[1]].typ == SquareType.SEAT:
if ( not (grid[u[1][0]][u[1][1]].typ == SquareType.AISLE and u[1][1] != x[1]) and
len(grid[x[0]][x[1]].occupAtTick[u[0]:u[0]+5-1]) == 0):
alt = time[u[1][0]][u[1][1]] + 5
if alt < time[x[0]][x[1]]:
time[x[0]][x[1]] = alt
prev[x[0]][x[1]] = u
q.put((alt, x, 5))
else:
continue
elif grid[x[0]][x[1]].typ == SquareType.AISLE:
if len(grid[x[0]][x[1]].occupAtTick[u[0]+1:u[0]+1+1]) == 0:
alt = time[u[1][0]][u[1][1]] + 1
if alt < time[x[0]][x[1]]:
time[x[0]][x[1]] = alt
prev[x[0]][x[1]] = u
q.put((alt, x, 1))
else:
continue
else:
continue
# print(grid[passenger.path[3][0][0]][passenger.path[3][0][1]].occupAtTick)
dest = passenger.dest
moveDir = None
if dest[0] > passenger.inter[0]:
moveDir = -1
else:
moveDir = 1
mDone=False
while not mDone:
mDone = True
u=passenger.dest
while u != passenger.inter:
occup = list(grid[u[0]+moveDir][u[1]].occupAtTick[afterTick:afterTick+5])
if len(occup) != 0:
if (moveDir == 1 and passengers[occup[0][2]].dest < u) or (moveDir == -1 and passengers[occup[0][2]].dest > u):
# if dest == (6,4):
# print(u)
mDone=False
occup2 = list(grid[u[0]][u[1]].occupAtTick[afterTick:afterTick+5])
if len(occup2) != 0:
grid[u[0]+moveDir][u[1]].occupAtTick.addi(occup[0][0], afterTick, occup[0][2])
grid[u[0]+moveDir][u[1]].occupAtTick.remove(occup[0])
grid[u[0]][u[1]].occupAtTick.addi(occup2[0][0], afterTick, occup2[0][2])
grid[u[0]][u[1]].occupAtTick.remove(occup2[0])
grid[u[0]+moveDir][u[1]].occupAtTick.addi(afterTick,10**11,occup2[0][2])
grid[u[0]][u[1]].occupAtTick.addi(afterTick,10**11,occup[0][2])
else:
grid[u[0]+moveDir][u[1]].occupAtTick.addi(occup[0][0], afterTick, occup[0][2])
grid[u[0]+moveDir][u[1]].occupAtTick.remove(occup[0])
grid[u[0]][u[1]].occupAtTick.addi(afterTick,10**11,occup[0][2])
u = (u[0] + moveDir, u[1])
afterTick+=4
def printPath(p):
print("inter: " + str(p.inter))
print("dest: " + str(p.dest))
for x in p.path:
print(str(x[0]) + ": " + str(grid[x[0][0]][x[0][1]].occupAtTick[x[1]]))
btime = 3 #passengers board every btime ticks
delay = 0.01
#Precomputation of all paths, later code is just output functionality
def compute():
global btime
global passengers
global tickTaken
tick=0
toadd=0
#genderequality #blm #blessed #syria
for (i, prsn) in enumerate(passengers):
for e in entries:
if toadd < len(passengers) and len(grid[e[0]][e[1]].occupAtTick[tick]) == 0:
prsn.curr = (e[0], e[1])
findPath(prsn, i, tick)
if DEBUG:
print("calculating: " + str(i))
tick += btime
toadd += 1
else:
tick += 1
for row in grid:
for x in row:
# print(x.occupAtTick)
if len(x.occupAtTick) != 0:
# print("list(x.occupAtTick.items)[-1][0]: " + str(list(x.occupAtTick.items())[-1][0]))
tickTaken = max(tickTaken, list(x.occupAtTick.items())[-1][0])
print("Time Taken: " + str(tickTaken))
def tick(t):
done=True
global btime
global delay
# print grid
if DEBUG:
print(chr(0x3000), end="")
print(chr(0x3000), end="")
for x in range(0, width):
if x % 10 == 0:
print(chr(0xFF10 + int(x / 10)), end="")
else:
print(chr(0x3000), end="")
print()
print(chr(0x3000), end="")
print(chr(0x3000), end="")
for x in range(0, width):
print(chr(0xFF10 + (x % 10)), end="")
print()
for (i, row) in enumerate(grid):
if i % 10 == 0:
print(chr(0xFF10 + int(i / 10)), end="")
else:
print(chr(0x3000), end="")
print(chr(0xFF10 + (i % 10)), end="")
for guy in row:
if len(guy.occupAtTick[t]) != 0:
print(chr(0x20000 + list(guy.occupAtTick[t])[0][2]), end="")
elif guy.typ == SquareType.SEAT:
print("", end="")
elif guy.typ == SquareType.WALL:
print("", end="")
else:
print("_", end="")
print()
print("---")
printPath(passengers[2])
if DEBUG:
# time.sleep(1.0)
# time.sleep(0.5)
# time.sleep(0.1)
time.sleep(0.05)
# time.sleep(0.02)
# time.sleep(0.01)
# time.sleep(0.001)
os.system("clear")
def init():
global height
global width
global grid
global passengers
passengers = []
arrFile = open("figure2.txt")
height=int(arrFile.readline())
width=int(arrFile.readline())
print(height)
print(width)
grid = [[GridSquare(SquareType.AISLE) for x in range(0,width)] for y in range(0,height)]
for y in range(0,height):
for x in range(0,width+1):
char = arrFile.read(1);
match char:
case 'S':
grid[y][x].typ = SquareType.SEAT
passengers.append(Passenger((y,x),(-1,-1)))
case 'W':
grid[y][x].typ = SquareType.WALL
case '.':
grid[y][x].typ = SquareType.AISLE
for x in passengers:
sign=(-1)**rnd.randint(0,1)
for i in range(1,7):
inc = (-1)**i * sign * math.floor((i+1)/2)
if (inc + x.dest[0] > 0) and (inc + x.dest[0] < height) and (grid[x.dest[0]+inc][x.dest[1]].typ == SquareType.AISLE):
x.inter=(inc + x.dest[0], x.dest[1])
break
def run(end):
t = 0
while t < end:
tick(t)
t += 1
def main():
global passengers
init()
#boarding order
seediter = int(sys.argv[1])
print("Seed: " + str(seediter))
rnd.seed(seediter)
# passengers.reverse()
rnd.shuffle(passengers)
compute()
run(tickTaken)
if __name__ == "__main__":
main()