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.

279 lines
8.6 KiB

#!/usr/bin/env python3
#(height, width)
import random as rnd
import os
import itertools
from enum import Enum
import time
import math
from queue import PriorityQueue as pq
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)]
passengers = None
class GridSquare:
#typ: SquareType, occupant: index
def __init__(self, typ, occupant):
self.typ = typ
self.occupant = occupant
def __str__(self):
return "(%s|%s)" % (str(self.typ), str(self.occupant))
def __repr__(self):
return str(self)
def makeGrid():
return [[GridSquare(SquareType.AISLE, None) for x in range(0,width)] for y in range(0,height)]
class Passenger:
shuffled = 0
inter = None
interback = None
path = []
recalc = True
#dest and curr are both 2-tuples
def __init__(self, dest, curr):
self.dest = dest
self.curr = curr
def __str__(self):
return "(%s|%s)" % (dest, curr)
def manhattanDistance(pos1, pos2):
return abs(pos1[0] - pos2[0]) + abs(pos1[1] - pos2[1])
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 nextSquare(passenger, grid):
passenger.recalc = False
passenger.path=[]
dist=[[0 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)]
dest = None
if passenger.inter == None:
dest = passenger.dest
else:
dest = passenger.inter
q = pq()
for y in range(0,height):
for x in range(0,width):
if x != passenger.curr[1] or y != passenger.curr[0]:
dist[y][x] = 10**10
mn = mooreNeighbourhood(passenger.curr)
for (i, man) in enumerate(mn):
if (grid[passenger.curr[0]][passenger.curr[1]].typ != SquareType.SEAT or man[1] == passenger.curr[1]) and grid[man[0]][man[1]].typ != SquareType.WALL and not (grid[man[0]][man[1]].typ == SquareType.AISLE and grid[man[0]][man[1]].occupant is not None):
q.put((1, man, i))
dist[man[0]][man[1]] = 1
prev[man[0]][man[1]] = (0, passenger.curr, 0)
while not q.empty():
u = q.get()
if u[1] == dest:
while prev[u[1][0]][u[1][1]] != None:
passenger.path.append(u[1])
u=prev[u[1][0]][u[1][1]]
return
for x in mooreNeighbourhood(u[1]):
# if not( grid[x[0]][x[1]].typ == SquareType.SEAT and u[1][1] != x[1]) and grid[x[0]][x[1]].typ != SquareType.WALL and (grid[x[0]][x[1]].occupant == None or grid[x[0]][x[1]].typ == SquareType.SEAT):
if not( grid[x[0]][x[1]].typ == SquareType.SEAT and u[1][1] != x[1]) and grid[x[0]][x[1]].typ != SquareType.WALL:
alt = 0
if grid[x[0]][x[1]].typ == SquareType.SEAT or grid[u[1][0]][u[1][1]].typ == SquareType.SEAT:
if grid[x[0]][x[1]].occupant != None:
alt = dist[u[1][0]][u[1][1]] + 5 + 10
else:
alt = dist[u[1][0]][u[1][1]] + 5
else:
alt = dist[u[1][0]][u[1][1]] + 1
# if alt == 0:
# if x == dest:
# print("mn: " + str(x) + ", alt: " + str(alt))
# print("dist" + str(x) + ": " + str(dist[x[0]][x[1]]))
if alt < dist[x[0]][x[1]]:
dist[x[0]][x[1]] = alt
prev[x[0]][x[1]] = u
q.put((alt, x, u[2]))
passenger.path = [passenger.curr]
def GenPassList():
global height
global width
global grid
border=[]
arrFile = open("figure2.txt")
height=int(arrFile.readline())
width=int(arrFile.readline())
print(height)
print(width)
grid = [[GridSquare(SquareType.AISLE, None) 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
border.append(Passenger((y,x),(-1,-1)))
case 'W':
grid[y][x].typ = SquareType.WALL
case '.':
grid[y][x].typ = SquareType.AISLE
for x in border:
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])
x.interback = x.inter
return border
def nunty(x):
if x is None: return -1
return x
btime = 3 #passengers board every btime ticks
def tick(t, toad):
done=True
global btime
# 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 guy.occupant is not None:
print(chr(0x20000 + guy.occupant), end="")
elif guy.typ == SquareType.SEAT:
print("", end="")
elif guy.typ == SquareType.WALL:
print("", end="")
else:
print("_", end="")
print()
print("---")
# print(grid[3][0].occupant, grid[3][1].occupant, passengers[nunty(grid[3][1].occupant)].dest)
if t % btime == 0:
for x in entries:
if toad < len(passengers) and grid[x[0]][x[1]].occupant is None:
grid[x[0]][x[1]].occupant = toad #added
passengers[toad].curr = (x[0], x[1])
toad += 1
for (i, man) in enumerate(passengers):
if man.curr == man.dest:
continue
if man.inter is not None and man.curr == man.inter:
man.shuffled = 3
man.inter = None
# man.recalc = True
if man.curr == (-1, -1):
continue
# if i == 36 and DEBUG:
# print(nextSquare(man, grid))
done=False
#im sexist
if len(man.path) == 0 or man.recalc:
# if DEBUG:
# print("Recalculating: " + str(man.curr))
nextSquare(man, grid)
nextS = man.path.pop()
if DEBUG:
print(str(man.curr) + ", " + str(man.interback) + ", " + str(man.dest) + ", " + str(nextS) + ", " + str(man.inter))
if passengers[i].shuffled == 0 and not ( grid[nextS[0]][nextS[1]].typ == SquareType.AISLE and grid[nextS[0]][nextS[1]].occupant is not None):
cp = man.curr
man.curr = nextS
other = grid[cp[0]][cp[1]]
other.occupant = grid[man.curr[0]][man.curr[1]].occupant #they move out of there
if other.occupant is not None:
passengers[other.occupant].curr = cp
passengers[other.occupant].shuffled = 5
passengers[other.occupant].recalc = True
man.recalc = True
grid[man.curr[0]][man.curr[1]].occupant = i
for man in passengers:
if man.shuffled != 0:
man.shuffled-=1
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")
if done and toad >= len(passengers):
print("Number of ticks: " + str(t))
return -1
# exit()
return toad
def run():
toad = 0
t = 0
while toad != -1:
toad = tick(t,toad)
t += 1
def main():
global passengers
#boarding order
for seediter in range(43,2000):
passengers = GenPassList()
print("Seed: " + str(seediter))
rnd.seed(seediter)
# passengers.reverse()
rnd.shuffle(passengers)
run()
if __name__ == "__main__":
main()