kcd.Spektor wrote:fdagpigj wrote:Well, I just made a simulation in pygame (python 2). No idea why. Because it's fun, I guess. I feel like I have something pretty close to the original now.
Well I'm not familiar with python, so that code doesn't help any bit
Can you draw a logic tree for your algorithm?
I was almost going to, but I think some pseudocode is better. And I've slightly updated the logic since I posted but not gonna edit my post again because reasons. This logic assumes the following:
Each door always has a valid roomA, but roomB is null if the door is an airlock. Oxygen is a float in the range 0.0 to 100.0. Each room has exactly one oxygen value no matter its size, like in FTL. Each room also has a breaches integer property which represents the total number of hull breaches in that room. oxygenPower() gives the amount of power bars in the oxygen system, allDoors() and allRooms() an array of all rooms and doors on the ship, respectively. tickGame() occurs at set intervals.
Code: Select all
function tickGame() {
for (var room in allRooms()) {tickRoom(room)}
for (var door in allDoors()) {tickDoor(door)}
}
function tickRoom(room) {
room.oxygen -= 0.04 + room.breaches*0.5 //subtract the default depletion rate and a large extra amount per breach... I'm still not 100% happy with the breaches but I can't come up with anything better that's not stupidly complex
if (oxygenPower() > 0) {
var refillRate = (1.0 + ( ( oxygenPower() - 1.0 ) ^ 2 ) / 4.0 ) / 1300.0 //level 2 should refill 1.5x as fast as level 1, level 3 3x, at least IIRC how FTL works
} else {var refillRate = 0}
room.oxygen += (200 - room.oxygen) * refillRate //add oxygen relative to how full the room already is... I'm not sure it's necessary to be relative but I think it makes more sense
room.oxygen = max( min(room.oxygen, 100.0), 0.0 ) //limit the oxygen to between 0 and 100
}
function tickDoor(door) {
if (door.open) {
redistributeOxygen(door.roomA, door.roomB)
}
}
function redistributeOxygen(roomA, roomB)
if (roomB != null) {var oxygenB = roomB.oxygen}
else {var oxygenB = -500.0} //door is an airlock so set the oxygen level to a negative value to force the room to lose oxygen faster than it otherwise could
var difference = abs(roomA.oxygen - oxygenB)
if (roomA.oxygen < oxygenB) {var sign = -1}
else {var sign = 1}
var change = min( max( difference / 20.0, 0.1), difference/2.0 ) //don't change the 2.0 since the maximum change should be half of the difference else the new values will reverse roles
//since we compare the magnitude of the difference to a constant we need to take the absolute value and later multiply by -1 if it used to be negative
roomA.oxygen -= sign * change
if (roomB != null) { //the necessity of this check probably depends on how sensitive the language is, but it doesn't hurt to leave it in
roomB.oxygen += sign * change
if (roomB.oxygen < 0) {roomB.oxygen = 0}
}
if (roomA.oxygen < 0) {roomA.oxygen = 0}
I hope that helps