-- checks if the state is valid (no floor has an unshielded microchip and at
-- least one generator)
checkState :: State -> Bool
checkState state = let
        -- first bool of pair is true if an unshielded microchip exists
        -- second bool of pair is true if at least one generator exists
        checkIS :: ItemSet -> (Bool, Bool) -> Bool
        checkIS 0 (mc, g) = not $ mc && g
        checkIS _ (True, True) = False
        checkIS i (mc, g) =
            -- the way item sets are encoded allows very easy check for
            -- unshielded microchip
            checkIS (i `unsafeShiftR` 2) (mc || i .&. 3 == 2, g || i .&. 1  == 1)
    in
        all (\i -> checkIS (getFloorItems' state i) (False, False)) [0, 1, 2, 3]
checkState :: State -> Bool
checkState state = let
        -- first bool of pair is true if an unshielded microchip exists
        -- second bool of pair is true if at least one generator exists
        checkIS :: ItemSet -> (Bool, Bool) -> Bool
        checkIS 0 (mc, g) = not $ mc && g
        checkIS _ (True, True) = False
        checkIS i (mc, g) =
            -- the way item sets are encoded allows very easy check for
            -- unshielded microchip
            checkIS (i `unsafeShiftR` 2) (mc || i .&. 3 == 2, g || i .&. 1  == 1)
    in
        all (\i -> checkIS (getFloorItems' state i) (False, False)) [0, 1, 2, 3]
checkState state = let
        -- first bool of pair is true if an unshielded microchip exists
        -- second bool of pair is true if at least one generator exists
        checkIS :: ItemSet -> (Bool, Bool) -> Bool
        checkIS 0 (mc, g) = not $ mc && g
        checkIS _ (True, True) = False
        checkIS i (mc, g) =
            -- the way item sets are encoded allows very easy check for
            -- unshielded microchip
            checkIS (i `unsafeShiftR` 2) (mc || i .&. 3 == 2, g || i .&. 1  == 1)
    in
        all (\i -> checkIS (getFloorItems' state i) (False, False)) [0, 1, 2, 3]